This commit consists of:
1) Dockerizing the netconf server
2) Update proto2yang to support module imports
3) Provide a set of yang modules derived from the proto files in voltha.
   These files as well as the slight mmodifications to the proto files are
   provided in the experiments/netconf/proto2yang directory
4) Code to automatically pull proto files from voltha into the netconf server,
   compiles them and produce the yang equivalent files.
5) Add a getvoltha netconf API to provide voltha state information (basic at
   this time).  There is potential to make this generic once we experiment
   with additional APIs

Change-Id: I94f3a1f871b8025ad675d5f9b9b626d1be8b8d36
diff --git a/experiments/netconf/proto2yang/voltha.proto b/experiments/netconf/proto2yang/voltha.proto
new file mode 100644
index 0000000..b76d903
--- /dev/null
+++ b/experiments/netconf/proto2yang/voltha.proto
@@ -0,0 +1,421 @@
+/*
+ * Top-level Voltha API definition
+ *
+ * For details, see individual definition files.
+ */
+
+syntax = "proto3";
+
+package voltha;
+
+import "google/protobuf/empty.proto";
+import "google/api/annotations.proto";
+
+import public "meta.proto";
+import public "common.proto";
+import public "health.proto";
+import public "logical_device.proto";
+import public "device.proto";
+import public "adapter.proto";
+import public "openflow_13.proto";
+
+option java_package = "org.opencord.voltha";
+option java_outer_classname = "VolthaProtos";
+option csharp_namespace = "Opencord.Voltha.Voltha";
+
+message DeviceGroup {
+
+    string id = 1 [(access) = READ_ONLY];
+
+    repeated LogicalDevice logical_devices = 2 [(child_node) = {key: "id"}];
+
+    repeated Device devices = 3 [(child_node) = {key: "id"}];
+}
+
+message DeviceGroups {
+    repeated DeviceGroup items = 1;
+}
+
+// Top-level (root) node for a Voltha Instance
+message VolthaInstance {
+
+    string instance_id = 1  [(access) = READ_ONLY];
+
+    string version = 2 [(access) = READ_ONLY];
+
+    LogLevel log_level = 3;
+
+    HealthStatus health = 10 [(child_node) = {}];
+
+    repeated Adapter adapters = 11 [(child_node) = {key: "id" }];
+
+    repeated LogicalDevice logical_devices = 12 [(child_node) = {key: "id"}];
+
+    repeated Device devices = 13 [(child_node) = {key: "id"}];
+
+    repeated DeviceType device_types = 14 [(child_node) = {key: "id"}];
+
+    repeated DeviceGroup device_groups = 15 [(child_node) = {key: "id"}];
+}
+
+message VolthaInstances {
+    repeated string items = 1;
+}
+
+// Voltha representing the entire Voltha cluster
+message Voltha {
+
+    string version = 1 [(access) = READ_ONLY];
+
+    LogLevel log_level = 2;
+
+    repeated VolthaInstance instances = 3 [(child_node) = {key: "instance_id"}];
+
+    repeated Adapter adapters = 11 [(child_node) = {key: "id"}];
+
+    repeated LogicalDevice logical_devices = 12 [(child_node) = {key: "id"}];
+
+    repeated Device devices = 13 [(child_node) = {key: "id"}];
+
+    repeated DeviceGroup device_groups = 15 [(child_node) = {key: "id"}];
+
+}
+
+
+/*
+ * Cluster-wide Voltha APIs
+ *
+ * These APIs are potentially dispatched to the leader of the Voltha cluster,
+ * to a specific Voltha instance which owns the given device or logical device.
+ *
+ */
+service VolthaGlobalService {
+
+    // Get high level information on the Voltha cluster
+    rpc GetVoltha(google.protobuf.Empty) returns(Voltha) {
+        option (google.api.http) = {
+            get: "/api/v1"
+        };
+    }
+
+    // List all Voltha cluster instances
+    rpc ListVolthaInstances(google.protobuf.Empty) returns(VolthaInstances) {
+        option (google.api.http) = {
+            get: "/api/v1/instances"
+        };
+    }
+
+    // Get details on a Voltha cluster instance
+    rpc GetVolthaInstance(ID) returns(VolthaInstance) {
+        option (google.api.http) = {
+            get: "/api/v1/instances/{id}"
+        };
+    }
+
+    // List all logical devices managed by the Voltha cluster
+    rpc ListLogicalDevices(google.protobuf.Empty) returns(LogicalDevices) {
+        option (google.api.http) = {
+            get: "/api/v1/logical_devices"
+        };
+    }
+
+    // Get additional information on a given logical device
+    rpc GetLogicalDevice(ID) returns(LogicalDevice) {
+        option (google.api.http) = {
+            get: "/api/v1/logical_devices/{id}"
+        };
+    }
+
+    // List ports of a logical device
+    rpc ListLogicalDevicePorts(ID) returns(LogicalPorts) {
+        option (google.api.http) = {
+            get: "/api/v1/logical_devices/{id}/ports"
+        };
+    }
+
+    // List all flows of a logical device
+    rpc ListLogicalDeviceFlows(ID) returns(openflow_13.Flows) {
+        option (google.api.http) = {
+            get: "/api/v1/logical_devices/{id}/flows"
+        };
+    }
+
+    // Update flow table for logical device
+    rpc UpdateLogicalDeviceFlowTable(openflow_13.FlowTableUpdate)
+            returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/logical_devices/{id}/flows"
+            body: "*"
+        };
+    }
+
+    // List all flow groups of a logical device
+    rpc ListLogicalDeviceFlowGroups(ID) returns(openflow_13.FlowGroups) {
+        option (google.api.http) = {
+            get: "/api/v1/logical_devices/{id}/flow_groups"
+        };
+    }
+
+    // Update group table for device
+    rpc UpdateLogicalDeviceFlowGroupTable(openflow_13.FlowGroupTableUpdate)
+            returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/logical_devices/{id}/flow_groups"
+            body: "*"
+        };
+    }
+
+    // List all physical devices controlled by the Voltha cluster
+    rpc ListDevices(google.protobuf.Empty) returns(Devices) {
+        option (google.api.http) = {
+            get: "/api/v1/devices"
+        };
+    }
+
+    // Get more information on a given physical device
+    rpc GetDevice(ID) returns(Device) {
+        option (google.api.http) = {
+            get: "/api/v1/devices/{id}"
+        };
+    }
+
+    // Pre-provision a new physical device
+    rpc CreateDevice(Device) returns(Device) {
+        option (google.api.http) = {
+            post: "/api/v1/devices"
+            body: "*"
+        };
+    }
+
+    // Activate a pre-provisioned device
+    rpc ActivateDevice(ID) returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/devices/{id}/activate"
+        };
+    }
+
+    // List ports of a device
+    rpc ListDevicePorts(ID) returns(Ports) {
+        option (google.api.http) = {
+            get: "/api/v1/devices/{id}/ports"
+        };
+    }
+
+    // List all flows of a device
+    rpc ListDeviceFlows(ID) returns(openflow_13.Flows) {
+        option (google.api.http) = {
+            get: "/api/v1/devices/{id}/flows"
+        };
+    }
+
+    // List all flow groups of a device
+    rpc ListDeviceFlowGroups(ID) returns(openflow_13.FlowGroups) {
+        option (google.api.http) = {
+            get: "/api/v1/devices/{id}/flow_groups"
+        };
+    }
+
+    // List device types known to Voltha
+    rpc ListDeviceTypes(google.protobuf.Empty) returns(DeviceTypes) {
+        option (google.api.http) = {
+            get: "/api/v1/device_types"
+        };
+    }
+
+    // Get additional information on a device type
+    rpc GetDeviceType(ID) returns(DeviceType) {
+        option (google.api.http) = {
+            get: "/api/v1/device_types/{id}"
+        };
+    }
+
+    // List all device sharding groups
+    rpc ListDeviceGroups(google.protobuf.Empty) returns(DeviceGroups) {
+        option (google.api.http) = {
+            get: "/api/v1/device_groups"
+        };
+    }
+
+    // Get additional information on a device group
+    rpc GetDeviceGroup(ID) returns(DeviceGroup) {
+        option (google.api.http) = {
+            get: "/api/v1/device_groups/{id}"
+        };
+    }
+
+}
+
+/*
+ * Per-instance APIs
+ *
+ * These APIs are always served locally by the Voltha instance on which the
+ * call is made.
+ */
+service VolthaLocalService {
+
+    // Get information on this Voltha instance
+    rpc GetVolthaInstance(google.protobuf.Empty) returns(VolthaInstance) {
+        option (google.api.http) = {
+            get: "/api/v1/local"
+        };
+    }
+
+    // Get the health state of the Voltha instance
+    rpc GetHealth(google.protobuf.Empty) returns(HealthStatus) {
+        option (google.api.http) = {
+            get: "/api/v1/local/health"
+        };
+    }
+
+    // List all active adapters (plugins) in this Voltha instance
+    rpc ListAdapters(google.protobuf.Empty) returns(Adapters) {
+        option (google.api.http) = {
+            get: "/api/v1/local/adapters"
+        };
+    }
+
+    // List all logical devices managed by this Voltha instance
+    rpc ListLogicalDevices(google.protobuf.Empty) returns(LogicalDevices) {
+        option (google.api.http) = {
+            get: "/api/v1/local/logical_devices"
+        };
+    }
+
+    // Get additional information on given logical device
+    rpc GetLogicalDevice(ID) returns(LogicalDevice) {
+        option (google.api.http) = {
+            get: "/api/v1/local/logical_devices/{id}"
+        };
+    }
+
+    // List ports of a logical device
+    rpc ListLogicalDevicePorts(ID) returns(LogicalPorts) {
+        option (google.api.http) = {
+            get: "/api/v1/local/logical_devices/{id}/ports"
+        };
+    }
+
+    // List all flows of a logical device
+    rpc ListLogicalDeviceFlows(ID) returns(openflow_13.Flows) {
+        option (google.api.http) = {
+            get: "/api/v1/local/logical_devices/{id}/flows"
+        };
+    }
+
+    // Update flow table for logical device
+    rpc UpdateLogicalDeviceFlowTable(openflow_13.FlowTableUpdate)
+            returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/local/logical_devices/{id}/flows"
+            body: "*"
+        };
+    }
+
+    // List all flow groups of a logical device
+    rpc ListLogicalDeviceFlowGroups(ID) returns(openflow_13.FlowGroups) {
+        option (google.api.http) = {
+            get: "/api/v1/local/logical_devices/{id}/flow_groups"
+        };
+    }
+
+    // Update group table for logical device
+    rpc UpdateLogicalDeviceFlowGroupTable(openflow_13.FlowGroupTableUpdate)
+            returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/local/logical_devices/{id}/flow_groups"
+            body: "*"
+        };
+    }
+
+    // List all physical devices managed by this Voltha instance
+    rpc ListDevices(google.protobuf.Empty) returns(Devices) {
+        option (google.api.http) = {
+            get: "/api/v1/local/devices"
+        };
+    }
+
+    // Get additional information on this device
+    rpc GetDevice(ID) returns(Device) {
+        option (google.api.http) = {
+            get: "/api/v1/local/devices/{id}"
+        };
+    }
+
+    // Pre-provision a new physical device
+    rpc CreateDevice(Device) returns(Device) {
+        option (google.api.http) = {
+            post: "/api/v1/local/devices"
+            body: "*"
+        };
+    }
+
+    // Activate a pre-provisioned device
+    rpc ActivateDevice(ID) returns(google.protobuf.Empty) {
+        option (google.api.http) = {
+            post: "/api/v1/local/devices/{id}/activate"
+            body: "{}"
+        };
+    }
+
+    // List ports of a device
+    rpc ListDevicePorts(ID) returns(Ports) {
+        option (google.api.http) = {
+            get: "/api/v1/local/devices/{id}/ports"
+        };
+    }
+
+    // List all flows of a device
+    rpc ListDeviceFlows(ID) returns(openflow_13.Flows) {
+        option (google.api.http) = {
+            get: "/api/v1/local/devices/{id}/flows"
+        };
+    }
+
+    // List all flow groups of a device
+    rpc ListDeviceFlowGroups(ID) returns(openflow_13.FlowGroups) {
+        option (google.api.http) = {
+            get: "/api/v1/local/devices/{id}/flow_groups"
+        };
+    }
+
+    // List device types know to Voltha instance
+    rpc ListDeviceTypes(google.protobuf.Empty) returns(DeviceTypes) {
+        option (google.api.http) = {
+            get: "/api/v1/local/device_types"
+        };
+    }
+
+    // Get additional information on given device type
+    rpc GetDeviceType(ID) returns(DeviceType) {
+        option (google.api.http) = {
+            get: "/api/v1/local/device_types/{id}"
+        };
+    }
+
+    // List device sharding groups managed by this Voltha instance
+    rpc ListDeviceGroups(google.protobuf.Empty) returns(DeviceGroups) {
+        option (google.api.http) = {
+            get: "/api/v1/local/device_groups"
+        };
+    }
+
+    // Get more information on given device shard
+    rpc GetDeviceGroup(ID) returns(DeviceGroup) {
+        option (google.api.http) = {
+            get: "/api/v1/local/device_groups/{id}"
+        };
+    }
+
+    // Stream control packets to the dataplane
+    rpc StreamPacketsOut(stream openflow_13.PacketOut)
+        returns(google.protobuf.Empty) {
+        // This does not have an HTTP representation
+    }
+
+    // Receive control packet stream
+    rpc ReceivePacketsIn(google.protobuf.Empty)
+        returns(stream openflow_13.PacketIn) {
+        // This does not have an HTTP representation
+    }
+
+}