Netopeer NETCONF server integration
Amendments:
- Removed local copy of golang package. Added instructions to download it.
- Removed cached files which are created when transapi is built.
- Added netopeer as a build-able Makefile component.
Updated documentation.
Change-Id: I532e813b81a0531648c5a6bcb048208700cf57a4
diff --git a/netopeer/voltha-grpc-client/voltha.go b/netopeer/voltha-grpc-client/voltha.go
new file mode 100644
index 0000000..2c7853a
--- /dev/null
+++ b/netopeer/voltha-grpc-client/voltha.go
@@ -0,0 +1,497 @@
+//package voltha
+package main
+
+/*
+#include <stdlib.h>
+#include "voltha-defs.h"
+ */
+import "C"
+
+import (
+ "log"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+ "github.com/golang/protobuf/ptypes/empty"
+ "github.com/hashicorp/consul/api"
+ pb "github.com/opencord/voltha/netconf/translator/voltha"
+ pb_health "github.com/opencord/voltha/netconf/translator/voltha/health"
+ pb_device "github.com/opencord/voltha/netconf/translator/voltha/device"
+ pb_adapter "github.com/opencord/voltha/netconf/translator/voltha/adapter"
+ pb_logical_device "github.com/opencord/voltha/netconf/translator/voltha/logical_device"
+ pb_openflow "github.com/opencord/voltha/netconf/translator/voltha/openflow_13"
+ pb_any "github.com/golang/protobuf/ptypes/any"
+ "unsafe"
+ "fmt"
+)
+
+const (
+ default_consul_address = "10.100.198.220:8500"
+ default_grpc_address = "localhost:50555"
+ grpc_service_name = "voltha-grpc"
+)
+
+var (
+ GrpcConn *grpc.ClientConn = nil
+ VolthaGlobalClient pb.VolthaGlobalServiceClient = nil
+ HealthClient pb_health.HealthServiceClient = nil
+ ConsulClient *api.Client = nil
+ GrpcServiceAddress string = "localhost:50555"
+)
+
+func init() {
+ ConsulClient = connect_to_consul(default_consul_address)
+ GrpcServiceAddress = get_consul_service_address(grpc_service_name)
+ GrpcConn = connect_to_grpc(GrpcServiceAddress)
+
+ VolthaGlobalClient = pb.NewVolthaGlobalServiceClient(GrpcConn)
+ HealthClient = pb_health.NewHealthServiceClient(GrpcConn)
+}
+
+func connect_to_consul(consul_address string) *api.Client {
+ cfg := api.Config{Address: consul_address }
+
+ log.Printf("Connecting to consul - address: %s", consul_address)
+
+ client, err := api.NewClient(&cfg)
+ if err != nil {
+ panic(err)
+ }
+
+ log.Printf("Connected to consul - address: %s", consul_address)
+
+ return client
+}
+
+func get_consul_service_address(service_name string) string {
+ var service []*api.CatalogService
+ var err error
+
+ log.Printf("Getting consul service - name:%s", service_name)
+
+ if service, _, _ = ConsulClient.Catalog().Service(service_name, "", nil); err != nil {
+ panic(err)
+ }
+
+ address := fmt.Sprintf("%s:%d", service[0].ServiceAddress, service[0].ServicePort)
+
+ log.Printf("Got consul service - name:%s, address:%s", service_name, address)
+
+ return address
+}
+
+func connect_to_grpc(grpc_address string) *grpc.ClientConn {
+ var err error
+ var client *grpc.ClientConn
+
+ log.Printf("Connecting to grpc - address: %s", grpc_address)
+
+ // Set up a connection to the server.
+ client, err = grpc.Dial(grpc_address, grpc.WithInsecure())
+ if err != nil {
+ log.Fatalf("did not connect: %s", err.Error())
+ }
+
+ log.Printf("Connected to grpc - address: %s", grpc_address)
+
+ return client
+}
+// Utility methods
+
+// -------------------------------------------------
+// C to Protobuf conversion methods
+// -------------------------------------------------
+
+func _c_to_proto_Address(address C.isDevice_Address) *pb_device.Device {
+ var device *pb_device.Device
+
+ // Identify the address type to assign
+ switch address.Type {
+ case C.MAC:
+ device.Address = &pb_device.Device_MacAddress{
+ MacAddress: C.GoString(address.Value),
+ }
+ break
+ case C.IPV4:
+ device.Address = &pb_device.Device_Ipv4Address{
+ Ipv4Address: C.GoString(address.Value),
+ }
+ break
+ case C.IPV6:
+ device.Address = &pb_device.Device_Ipv6Address{
+ Ipv6Address: C.GoString(address.Value),
+ }
+ break
+ case C.HOST_AND_PORT:
+ device.Address = &pb_device.Device_HostAndPort{
+ HostAndPort: C.GoString(address.Value),
+ }
+ break
+ }
+
+ return device
+}
+
+// -------------------------------------------------
+// Protobuf to C conversion methods
+// -------------------------------------------------
+
+func _proto_to_c_Adapters(instances []*pb_adapter.Adapter) C.AdapterArray {
+ // TODO: not implemented
+ var result C.AdapterArray
+ return result
+}
+func _proto_to_c_LogicalDevices(instances []*pb_logical_device.LogicalDevice) C.LogicalDeviceArray {
+ // TODO: not implemented
+ var result C.LogicalDeviceArray
+ return result
+}
+func _proto_to_c_DeviceTypes(instances []*pb_device.DeviceType) C.DeviceTypeArray {
+ // TODO: not implemented
+ var result C.DeviceTypeArray
+ return result
+}
+func _proto_to_c_AlarmFilters(instances []*pb.AlarmFilter) C.AlarmFilterArray {
+ // TODO: not implemented
+ var result C.AlarmFilterArray
+ return result
+}
+func _proto_to_c_DeviceGroups(instances []*pb.DeviceGroup) C.DeviceGroupArray {
+ // TODO: not implemented
+ var result C.DeviceGroupArray
+ return result
+}
+func _proto_to_c_ProxyAddress(proxyAddress *pb_device.Device_ProxyAddress) *C.Device_ProxyAddress {
+ // TODO: not implemented
+ var result *C.Device_ProxyAddress
+ defer C.free(unsafe.Pointer(result))
+ return result
+}
+func _proto_to_c_Ports(ports []*pb_device.Port) C.PortArray {
+ // TODO: not implemented
+ var result C.PortArray
+ return result
+}
+func _proto_to_c_Flows(flows *pb_openflow.Flows) *C.Flows {
+ // TODO: not implemented
+ var result *C.Flows
+ defer C.free(unsafe.Pointer(result))
+ return result
+}
+func _proto_to_c_FlowGroups(groups *pb_openflow.FlowGroups) *C.FlowGroups {
+ // TODO: not implemented
+ var result *C.FlowGroups
+ defer C.free(unsafe.Pointer(result))
+ return result
+}
+func _proto_to_c_PmConfigs(configs *pb_device.PmConfigs) *C.PmConfigs {
+ // TODO: not implemented
+ var result *C.PmConfigs
+ defer C.free(unsafe.Pointer(result))
+ return result
+}
+func _proto_to_c_Custom(configs *pb_any.Any) *C.Any {
+ // TODO: not implemented
+ var result *C.Any
+ defer C.free(unsafe.Pointer(result))
+ return result
+}
+func _proto_to_c_HealthStatus(health *pb_health.HealthStatus) C.HealthStatus {
+ var result C.HealthStatus
+
+ var c_string *C.char
+ defer C.free(unsafe.Pointer(c_string))
+
+ if c_string = C.CString(health.GetState().String()); c_string != nil {
+ result.State = c_string
+ }
+
+ return result
+}
+
+func _proto_to_c_VolthaInstances(instances []*pb.VolthaInstance) C.VolthaInstanceArray {
+ var result C.VolthaInstanceArray
+ var c_string *C.char
+ var c_voltha_instance C.VolthaInstance
+ defer C.free(unsafe.Pointer(c_string))
+
+ sizeof := unsafe.Sizeof(c_voltha_instance)
+ count := len(instances)
+ result.size = C.int(count)
+
+ c_items := C.malloc(C.size_t(result.size) * C.size_t(sizeof))
+ defer C.free(unsafe.Pointer(c_items))
+
+ // Array to the allocated space
+ c_array := (*[1<<30 - 1]C.VolthaInstance)(c_items)
+
+ for index, value := range instances {
+ if c_string = C.CString(value.GetInstanceId()); c_string != nil {
+ c_voltha_instance.InstanceId = c_string
+ }
+ if c_string = C.CString(value.GetVersion()); c_string != nil {
+ c_voltha_instance.Version = c_string
+ }
+ if c_string = C.CString(value.GetLogLevel().String()); c_string != nil {
+ c_voltha_instance.LogLevel = c_string
+ }
+ c_voltha_instance.Health = _proto_to_c_HealthStatus(value.GetHealth())
+ c_voltha_instance.Adapters = _proto_to_c_Adapters(value.GetAdapters())
+ c_voltha_instance.LogicalDevices = _proto_to_c_LogicalDevices(value.GetLogicalDevices())
+ c_voltha_instance.Devices = _proto_to_c_Devices(value.GetDevices())
+ c_voltha_instance.DeviceTypes = _proto_to_c_DeviceTypes(value.GetDeviceTypes())
+ c_voltha_instance.DeviceGroups = _proto_to_c_DeviceGroups(value.GetDeviceGroups())
+ c_voltha_instance.AlarmFilters = _proto_to_c_AlarmFilters(value.GetAlarmFilters())
+
+ c_array[index] = c_voltha_instance
+ }
+
+ result.items = (*C.VolthaInstance)(unsafe.Pointer(c_array))
+
+ return result
+}
+func _proto_to_c_Devices(instances []*pb_device.Device) C.DeviceArray {
+ var result C.DeviceArray
+ var c_string *C.char
+ var c_device_instance C.Device
+ defer C.free(unsafe.Pointer(c_string))
+
+ sizeof := unsafe.Sizeof(c_device_instance)
+ count := len(instances)
+ result.size = C.int(count)
+
+ c_items := C.malloc(C.size_t(result.size) * C.size_t(sizeof))
+ defer C.free(unsafe.Pointer(c_items))
+
+ c_array := (*[1<<30 - 1]C.Device)(c_items)
+
+ for index, value := range instances {
+ c_array[index] = _proto_to_c_Device(value)
+ }
+
+ result.items = (*C.Device)(unsafe.Pointer(c_array))
+
+ return result
+}
+func _proto_to_c_Voltha(voltha *pb.Voltha) C.Voltha {
+ var result C.Voltha
+ var c_string *C.char
+ defer C.free(unsafe.Pointer(c_string))
+
+ if c_string = C.CString(voltha.GetVersion()); c_string != nil {
+ result.Version = c_string
+ }
+ if c_string = C.CString(voltha.GetLogLevel().String()); c_string != nil {
+ result.LogLevel = c_string
+ }
+
+ result.Instances = _proto_to_c_VolthaInstances(voltha.GetInstances())
+ result.Adapters = _proto_to_c_Adapters(voltha.GetAdapters())
+ result.LogicalDevices = _proto_to_c_LogicalDevices(voltha.GetLogicalDevices())
+ result.Devices = _proto_to_c_Devices(voltha.GetDevices())
+ result.DeviceGroups = _proto_to_c_DeviceGroups(voltha.GetDeviceGroups())
+
+ return result
+}
+
+func _proto_to_c_Address(device *pb_device.Device) C.isDevice_Address {
+ var address C.isDevice_Address
+ var c_string *C.char
+ defer C.free(unsafe.Pointer(c_string))
+
+ switch device.GetAddress().(type) {
+ case *pb_device.Device_MacAddress:
+ address.Type = C.MAC
+ c_string = C.CString(device.GetMacAddress())
+ address.Value = c_string
+ case *pb_device.Device_Ipv4Address:
+ address.Type = C.IPV4
+ c_string = C.CString(device.GetIpv4Address())
+ address.Value = c_string
+ case *pb_device.Device_Ipv6Address:
+ address.Type = C.IPV6
+ c_string = C.CString(device.GetIpv6Address())
+ address.Value = c_string
+ case *pb_device.Device_HostAndPort:
+ address.Type = C.HOST_AND_PORT
+ c_string = C.CString(device.GetHostAndPort())
+ address.Value = c_string
+ }
+ return address
+}
+
+func _proto_to_c_Device(device *pb_device.Device) C.Device {
+ var result C.Device
+ var c_string *C.char
+ defer C.free(unsafe.Pointer(c_string))
+
+ if c_string = C.CString(device.GetId()); c_string != nil {
+ result.Id = c_string
+ }
+ if c_string = C.CString(device.GetType()); c_string != nil {
+ result.Type = c_string
+ }
+ if device.GetRoot() {
+ result.Root = C.int(1)
+ } else {
+ result.Root = C.int(0)
+ }
+ if c_string = C.CString(device.GetParentId()); c_string != nil {
+ result.ParentId = c_string
+ }
+
+ result.ParentPortNo = C.uint32_t(device.GetParentPortNo())
+
+ if c_string = C.CString(device.GetVendor()); c_string != nil {
+ result.Vendor = c_string
+ }
+ if c_string = C.CString(device.GetModel()); c_string != nil {
+ result.Model = c_string
+ }
+ if c_string = C.CString(device.GetHardwareVersion()); c_string != nil {
+ result.HardwareVersion = c_string
+ }
+ if c_string = C.CString(device.GetFirmwareVersion()); c_string != nil {
+ result.FirmwareVersion = c_string
+ }
+ if c_string = C.CString(device.GetSoftwareVersion()); c_string != nil {
+ result.SoftwareVersion = c_string
+ }
+ if c_string = C.CString(device.GetSerialNumber()); c_string != nil {
+ result.SerialNumber = c_string
+ }
+ if c_string = C.CString(device.GetAdapter()); c_string != nil {
+ result.Adapter = c_string
+ }
+
+ result.Vlan = C.uint32_t(device.GetVlan())
+ result.ProxyAddress = _proto_to_c_ProxyAddress(device.GetProxyAddress())
+
+ if c_string = C.CString(device.GetAdminState().String()); c_string != nil {
+ result.AdminState = c_string
+ }
+ if c_string = C.CString(device.GetOperStatus().String()); c_string != nil {
+ result.OperStatus = c_string
+ }
+ if c_string = C.CString(device.GetReason()); c_string != nil {
+ result.Reason = c_string
+ }
+ if c_string = C.CString(device.GetConnectStatus().String()); c_string != nil {
+ result.ConnectStatus = c_string
+ }
+
+ result.Custom = _proto_to_c_Custom(device.GetCustom())
+ result.Ports = _proto_to_c_Ports(device.GetPorts())
+ result.Flows = _proto_to_c_Flows(device.GetFlows())
+ result.FlowGroups = _proto_to_c_FlowGroups(device.GetFlowGroups())
+ result.PmConfigs = _proto_to_c_PmConfigs(device.GetPmConfigs())
+ result.Address = _proto_to_c_Address(device)
+
+ return result
+}
+
+// ---------------------------------------------------------
+// Exported methods accessible through the shared library
+// ---------------------------------------------------------
+
+//export GetHealthStatus
+func GetHealthStatus() C.HealthStatus {
+ var output *pb_health.HealthStatus
+ var err error
+
+ if output, err = HealthClient.GetHealthStatus(context.Background(), &empty.Empty{}); output == nil || err != nil {
+ log.Fatalf("Failed to retrieve health status: %s", err.Error())
+ }
+
+ return _proto_to_c_HealthStatus(output)
+}
+
+//export GetVoltha
+func GetVoltha() C.Voltha {
+ var output *pb.Voltha
+ var err error
+ if output, err = VolthaGlobalClient.GetVoltha(context.Background(), &empty.Empty{}); output == nil || err != nil {
+ log.Fatalf("Failed to retrieve voltha information: %s", err.Error())
+ }
+
+ return _proto_to_c_Voltha(output)
+}
+
+//export ListDevices
+func ListDevices() C.DeviceArray {
+ var output *pb_device.Devices
+ var err error
+ if output, err = VolthaGlobalClient.ListDevices(context.Background(), &empty.Empty{});
+ output == nil || err != nil {
+ log.Fatalf("Failed to retrieve voltha information: %s", err.Error())
+ }
+
+ return _proto_to_c_Devices(output.Items)
+}
+
+//export ListVolthaInstances
+func ListVolthaInstances() *C.char {
+ return nil
+}
+
+//export ListLogicalDevices
+func ListLogicalDevices() *C.char {
+ return nil
+}
+
+//export GetLogicalDevice
+func GetLogicalDevice(input *C.char) *C.char {
+ return nil
+}
+
+//export ListLogicalDevicePorts
+func ListLogicalDevicePorts(input *C.char) *C.char {
+ return nil
+}
+
+//export ListLogicalDeviceFlows
+func ListLogicalDeviceFlows(input *C.char) *C.char {
+ return nil
+}
+
+//export CreateDevice
+func CreateDevice(input C.Device) C.Device {
+ log.Printf("Incoming C Device - type:%v, address_type: %v, address_value:%s",
+ C.GoString(input.Type),
+ C.int(input.Address.Type),
+ C.GoString(input.Address.Value),
+ )
+
+ device := _c_to_proto_Address(input.Address)
+ device.Type = C.GoString(input.Type)
+
+ var output *pb_device.Device
+ var err error
+
+ if output, err = VolthaGlobalClient.CreateDevice(context.Background(), device);
+ output == nil || err != nil {
+ log.Fatalf("Failed to create device: %s", err.Error())
+ }
+
+ return _proto_to_c_Device(output)
+}
+
+// Debugging code
+func TestSerialize() {
+ var object C.Device
+
+ object.Type = C.CString("simulated_olt")
+ object.Address.Type = 3
+ object.Address.Value = C.CString("172.16.1.233:123")
+
+ //xmlObject, _ := xml.Marshal(object)
+ //
+ //log.Printf("object: %+v", string(xmlObject))
+
+ CreateDevice(object)
+}
+
+func main() {
+ // We need the main function to make possible
+ // CGO compiler to compile the package as C shared library
+ //TestSerialize()
+}