This is the initial commit of the netconf server code. It consists
of the following:
1) The server is built using Twisted Conch
2) It adapted an existing opensource netconf server (https://github.com/choppsv1/netconf)
to handle some low-level protocols. The adaptation is mostly around
using Twisted Conch instead of Python Threads
3) A microservice to interface with Voltha on the SB and Netconf client on
the NB
4) A set of credentials for the server and clients. At this time these
credentials are local and in files. Additional work is required to
secure these files
5) A rough-in to handle the rpc requests from Netconf clients
6) Code for initial handshaking is in place (hello)
Change-Id: I1ca0505d0ac35ff06066b107019ae87ae30e38f8
diff --git a/netconf/connection_mgr.py b/netconf/connection_mgr.py
new file mode 100644
index 0000000..20dc184
--- /dev/null
+++ b/netconf/connection_mgr.py
@@ -0,0 +1,111 @@
+#
+# 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 twisted.internet.defer import inlineCallbacks, returnValue
+
+from common.utils.consulhelpers import get_endpoint_from_consul
+from structlog import get_logger
+from netconf.nc_server import NCServer
+
+log = get_logger()
+
+
+class ConnectionManager(object):
+ def __init__(self,
+ consul_endpoint,
+ voltha_endpoint,
+ netconf_port,
+ server_private_key_file,
+ server_public_key_file,
+ client_public_keys_file,
+ client_passwords_file,
+ voltha_retry_interval=0.5,
+ devices_refresh_interval=5):
+
+ log.info('init-connection-manager')
+ self.netconf_port = netconf_port
+ self.server_private_key_file = server_private_key_file
+ self.server_public_key_file = server_public_key_file
+ self.client_public_keys_file = client_public_keys_file
+ self.client_passwords_file = client_passwords_file
+ self.consul_endpoint = consul_endpoint
+ self.voltha_endpoint = voltha_endpoint
+
+ self.channel = None
+ self.grpc_client = None # single, shared gRPC client to Voltha
+
+ self.nc_server = None
+
+ self.voltha_retry_interval = voltha_retry_interval
+ self.devices_refresh_interval = devices_refresh_interval
+
+ self.running = False
+
+ @inlineCallbacks
+ def start(self):
+
+ if self.running:
+ return
+
+ log.debug('starting')
+
+ self.running = True
+
+ # # Get voltha grpc endpoint
+ # self.channel = self.get_grpc_channel_with_voltha()
+ #
+ # # Create shared gRPC API object
+ # self.grpc_client = GrpcClient(self, self.channel).start()
+
+ # Start the netconf server
+ self.nc_server = yield self.start_netconf_server().start()
+
+ log.info('started')
+
+ returnValue(self)
+
+ def stop(self):
+ log.debug('stopping')
+ self.running = False
+ # clean the netconf server
+ self.nc_server.stop()
+ log.info('stopped')
+
+ def resolve_endpoint(self, endpoint):
+ ip_port_endpoint = endpoint
+ if endpoint.startswith('@'):
+ try:
+ ip_port_endpoint = get_endpoint_from_consul(
+ self.consul_endpoint, endpoint[1:])
+ log.debug('found-service-from-consul', endpoint=endpoint,
+ ip_port=ip_port_endpoint)
+
+ except Exception as e:
+ log.error('not-found-service-from-consul',
+ endpoint=endpoint, exception=repr(e))
+
+ return
+ if ip_port_endpoint:
+ host, port = ip_port_endpoint.split(':', 2)
+ return host, int(port)
+
+ def start_netconf_server(self):
+ return NCServer(self.netconf_port,
+ self.server_private_key_file,
+ self.server_public_key_file,
+ self.client_public_keys_file,
+ self.client_passwords_file,
+ self.grpc_client)