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/netconf/nc_rpc/base/close_session.py b/netconf/nc_rpc/base/close_session.py
index 43babb8..ce187cd 100644
--- a/netconf/nc_rpc/base/close_session.py
+++ b/netconf/nc_rpc/base/close_session.py
@@ -24,8 +24,9 @@
class CloseSession(Rpc):
- def __init__(self, rpc_request, rpc_method, session):
- super(CloseSession, self).__init__(rpc_request, rpc_method, session)
+ def __init__(self, rpc_request, rpc_method, grpc_client, session):
+ super(CloseSession, self).__init__(rpc_request, rpc_method,
+ grpc_client, session)
self._validate_parameters()
def execute(self):
diff --git a/netconf/nc_rpc/base/commit.py b/netconf/nc_rpc/base/commit.py
index 61b7604..8933dc3 100644
--- a/netconf/nc_rpc/base/commit.py
+++ b/netconf/nc_rpc/base/commit.py
@@ -24,8 +24,9 @@
class Commit(Rpc):
- def __init__(self, rpc_request, rpc_method, session):
- super(Commit, self).__init__(rpc_request, rpc_method, session)
+ def __init__(self, rpc_request, rpc_method, grpc_client, session):
+ super(Commit, self).__init__(rpc_request, rpc_method, grpc_client,
+ session)
self._validate_parameters()
def execute(self):
diff --git a/netconf/nc_rpc/base/copy_config.py b/netconf/nc_rpc/base/copy_config.py
index cf2fc82..e287770 100644
--- a/netconf/nc_rpc/base/copy_config.py
+++ b/netconf/nc_rpc/base/copy_config.py
@@ -23,8 +23,9 @@
class CopyConfig(Rpc):
- def __init__(self, rpc_request, rpc_method, session):
- super(CopyConfig, self).__init__(rpc_request, rpc_method, session)
+ def __init__(self, rpc_request, rpc_method, grpc_client, session):
+ super(CopyConfig, self).__init__(rpc_request, rpc_method,
+ grpc_client, session)
self._validate_parameters()
def execute(self):
diff --git a/netconf/nc_rpc/base/delete_config.py b/netconf/nc_rpc/base/delete_config.py
index 7163ee6..e267807 100644
--- a/netconf/nc_rpc/base/delete_config.py
+++ b/netconf/nc_rpc/base/delete_config.py
@@ -23,8 +23,9 @@
class DeleteConfig(Rpc):
- def __init__(self, rpc_request, rpc_method, session):
- super(DeleteConfig, self).__init__(rpc_request, rpc_method, session)
+ def __init__(self, rpc_request, rpc_method, grpc_client, session):
+ super(DeleteConfig, self).__init__(rpc_request, rpc_method,
+ grpc_client, session)
self._validate_parameters()
def execute(self):
diff --git a/netconf/nc_rpc/base/discard_changes.py b/netconf/nc_rpc/base/discard_changes.py
index c41d32e..57bdfed 100644
--- a/netconf/nc_rpc/base/discard_changes.py
+++ b/netconf/nc_rpc/base/discard_changes.py
@@ -23,8 +23,9 @@
class DiscardChanges(Rpc):
- def __init__(self, rpc_request, rpc_method, session):
- super(DiscardChanges, self).__init__(rpc_request, rpc_method, session)
+ def __init__(self, rpc_request, rpc_method, grpc_client, session):
+ super(DiscardChanges, self).__init__(rpc_request, rpc_method,
+ grpc_client, session)
self._validate_parameters()
def execute(self):
diff --git a/netconf/nc_rpc/base/edit_config.py b/netconf/nc_rpc/base/edit_config.py
index 5c7599a..469e957 100644
--- a/netconf/nc_rpc/base/edit_config.py
+++ b/netconf/nc_rpc/base/edit_config.py
@@ -23,8 +23,9 @@
class EditConfig(Rpc):
- def __init__(self, rpc_request, rpc_method, session):
- super(EditConfig, self).__init__(rpc_request, rpc_method, session)
+ def __init__(self, rpc_request, rpc_method, grpc_client, session):
+ super(EditConfig, self).__init__(rpc_request, rpc_method,
+ grpc_client, session)
self._validate_parameters()
def execute(self):
diff --git a/netconf/nc_rpc/base/get.py b/netconf/nc_rpc/base/get.py
index c6cdfab..39e095c 100644
--- a/netconf/nc_rpc/base/get.py
+++ b/netconf/nc_rpc/base/get.py
@@ -25,8 +25,9 @@
class Get(Rpc):
- def __init__(self, rpc_request, rpc_method, session):
- super(Get, self).__init__(rpc_request, rpc_method, session)
+ def __init__(self, rpc_request, rpc_method, grpc_client, session):
+ super(Get, self).__init__(rpc_request, rpc_method, grpc_client,
+ session)
self._validate_parameters()
def execute(self):
diff --git a/netconf/nc_rpc/base/get_config.py b/netconf/nc_rpc/base/get_config.py
index dffe0d6..09f90b4 100644
--- a/netconf/nc_rpc/base/get_config.py
+++ b/netconf/nc_rpc/base/get_config.py
@@ -26,8 +26,9 @@
class GetConfig(Rpc):
- def __init__(self, rpc_request, rpc_method, session):
- super(GetConfig, self).__init__(rpc_request, rpc_method, session)
+ def __init__(self, rpc_request, rpc_method, grpc_client, session):
+ super(GetConfig, self).__init__(rpc_request, rpc_method,
+ grpc_client, session)
self._validate_parameters()
def execute(self):
diff --git a/netconf/nc_rpc/base/kill_session.py b/netconf/nc_rpc/base/kill_session.py
index 08a2e7a..c9a3352 100644
--- a/netconf/nc_rpc/base/kill_session.py
+++ b/netconf/nc_rpc/base/kill_session.py
@@ -25,8 +25,9 @@
class KillSession(Rpc):
- def __init__(self, rpc_request, rpc_method, session):
- super(KillSession, self).__init__(rpc_request, rpc_method, session)
+ def __init__(self, rpc_request, rpc_method, grpc_client, session):
+ super(KillSession, self).__init__(rpc_request, rpc_method,
+ grpc_client, session)
self._validate_parameters()
def execute(self):
diff --git a/netconf/nc_rpc/base/lock.py b/netconf/nc_rpc/base/lock.py
index fc74e83..2f0130d 100644
--- a/netconf/nc_rpc/base/lock.py
+++ b/netconf/nc_rpc/base/lock.py
@@ -23,8 +23,9 @@
class Lock(Rpc):
- def __init__(self, rpc_request, rpc_method, session):
- super(Lock, self).__init__(rpc_request, rpc_method, session)
+ def __init__(self, rpc_request, rpc_method, grpc_client, session):
+ super(Lock, self).__init__(rpc_request, rpc_method, grpc_client,
+ session)
self._validate_parameters()
def execute(self):
diff --git a/netconf/nc_rpc/base/unlock.py b/netconf/nc_rpc/base/unlock.py
index 78c59f1..f9ef062 100644
--- a/netconf/nc_rpc/base/unlock.py
+++ b/netconf/nc_rpc/base/unlock.py
@@ -23,8 +23,9 @@
class UnLock(Rpc):
- def __init__(self, rpc_request, rpc_method, session):
- super(UnLock, self).__init__(rpc_request, rpc_method, session)
+ def __init__(self, rpc_request, rpc_method, grpc_client, session):
+ super(UnLock, self).__init__(rpc_request, rpc_method, grpc_client,
+ session)
self._validate_parameters()
def execute(self):
diff --git a/netconf/nc_rpc/base/validate.py b/netconf/nc_rpc/base/validate.py
index 1cb84af..93faf60 100644
--- a/netconf/nc_rpc/base/validate.py
+++ b/netconf/nc_rpc/base/validate.py
@@ -23,8 +23,9 @@
class Validate(Rpc):
- def __init__(self, rpc_request, rpc_method, session):
- super(Validate, self).__init__(rpc_request, rpc_method, session)
+ def __init__(self, rpc_request, rpc_method, grpc_client, session):
+ super(Validate, self).__init__(rpc_request, rpc_method,
+ grpc_client, session)
self._validate_parameters()
def execute(self):
diff --git a/netconf/nc_rpc/ext/__init__.py b/netconf/nc_rpc/ext/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/netconf/nc_rpc/ext/__init__.py
diff --git a/netconf/nc_rpc/ext/get_voltha.py b/netconf/nc_rpc/ext/get_voltha.py
new file mode 100644
index 0000000..a619875
--- /dev/null
+++ b/netconf/nc_rpc/ext/get_voltha.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+#
+# Copyright 2016 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+from lxml import etree
+import structlog
+from netconf.nc_rpc.rpc import Rpc
+import netconf.nc_common.error as ncerror
+from netconf.constants import Constants as C
+from netconf.utils import filter_tag_match
+from twisted.internet.defer import inlineCallbacks, returnValue
+import dicttoxml
+from simplejson import dumps, load
+
+log = structlog.get_logger()
+
+
+class GetVoltha(Rpc):
+ def __init__(self, rpc_request, rpc_method, grpc_client, session):
+ super(GetVoltha, self).__init__(rpc_request, rpc_method,
+ grpc_client, session)
+ self._validate_parameters()
+
+ @inlineCallbacks
+ def execute(self):
+ log.info('get-voltha-request', session=self.session.session_id)
+ if self.rpc_response.is_error:
+ returnValue(self.rpc_response)
+
+ # Invoke voltha via the grpc client
+ res_dict = yield self.grpc_client.get_voltha_instance()
+
+ # convert dict to xml
+ xml = dicttoxml.dicttoxml(res_dict)
+ log.info('voltha-info', res=res_dict, xml=xml)
+
+ self.rpc_response.node = self.get_root_element(xml)
+ self.rpc_response.is_error = False
+
+ returnValue(self.rpc_response)
+
+
+ def _validate_parameters(self):
+ log.info('validate-parameters', session=self.session.session_id)
+ self.params = self.rpc_method.getchildren()
+ if len(self.params) > 1:
+ self.rpc_response.is_error = True
+ self.rpc_response.node = ncerror.BadMsg(self.rpc_request)
+ return
+
+ if self.params and not filter_tag_match(self.params[0], C.NC_FILTER):
+ self.rpc_response.is_error = True
+ self.rpc_response.node = ncerror.UnknownElement(
+ self.rpc_request, self.params[0])
+ return
+
+ if not self.params:
+ self.params = [None]
diff --git a/netconf/nc_rpc/rpc.py b/netconf/nc_rpc/rpc.py
index 3dd2f17..ff9b303 100644
--- a/netconf/nc_rpc/rpc.py
+++ b/netconf/nc_rpc/rpc.py
@@ -18,12 +18,15 @@
#
from rpc_response import RpcResponse
+from lxml import etree
+import io
class Rpc(object):
- def __init__(self,rpc_request, rpc_method, session):
+ def __init__(self,rpc_request, rpc_method, grpc_client, session):
self.rpc_request = rpc_request
self.rpc_method = rpc_method
self.rpc_response = RpcResponse()
+ self.grpc_client = grpc_client
self.session = session
def execute(self):
@@ -36,3 +39,8 @@
def _validate_parameters(self, rpc_request):
"""Sets and validates the node as well"""
pass
+
+ def get_root_element(self, xml_msg):
+ tree = etree.parse(io.BytesIO(xml_msg))
+ return tree.getroot()
+
diff --git a/netconf/nc_rpc/rpc_factory.py b/netconf/nc_rpc/rpc_factory.py
index f3ec0cc..eb13b8d 100644
--- a/netconf/nc_rpc/rpc_factory.py
+++ b/netconf/nc_rpc/rpc_factory.py
@@ -28,6 +28,7 @@
from base.unlock import UnLock
from base.close_session import CloseSession
from base.kill_session import KillSession
+from ext.get_voltha import GetVoltha
from netconf import NSMAP, qmap
import netconf.nc_common.error as ncerror
log = structlog.get_logger()
@@ -36,7 +37,7 @@
instance = None
- def get_rpc_handler(self, rpc_node, msg, session):
+ def get_rpc_handler(self, rpc_node, msg, grpc_channel, session):
try:
msg_id = rpc_node.get('message-id')
log.info("Received-rpc-message-id", msg_id=msg_id)
@@ -59,12 +60,13 @@
class_handler = self.rpc_class_handlers.get(rpc_name, None)
if class_handler is not None:
- return class_handler(rpc_node, rpc_method, session)
+ return class_handler(rpc_node, rpc_method, grpc_channel, session)
log.error("rpc-not-implemented", rpc=rpc_name)
rpc_class_handlers = {
+ 'getvoltha' : GetVoltha,
'get-config': GetConfig,
'get': Get,
'edit-config': EditConfig,
@@ -83,3 +85,8 @@
RpcFactory.instance = RpcFactory()
return RpcFactory.instance
+
+if __name__ == '__main__':
+ fac = get_rpc_factory_instance()
+ rpc = fac.rpc_class_handlers.get('getvoltha', None)
+ print rpc(None,None,None)
\ No newline at end of file