Run flask at image start 91/119791/2
authorEdyta Krukowska <edyta.krukowska@nokia.com>
Thu, 25 Mar 2021 07:26:18 +0000 (08:26 +0100)
committerEdyta Krukowska <edyta.krukowska@nokia.com>
Thu, 25 Mar 2021 08:55:52 +0000 (09:55 +0100)
Issue-ID: INT-1869
Signed-off-by: Edyta Krukowska <edyta.krukowska@nokia.com>
Change-Id: I4fa3e16e5d4520b449274b67d8f7bca3c16f57a6

Dockerfile
docker-compose.yml
src/python/netconf_server/netconf_change_listener.py [moved from src/python/netconf_server/netconf_server.py with 97% similarity]
src/python/netconf_server/netconf_change_listener_factory.py [moved from src/python/netconf_server/netconf_server_factory.py with 86% similarity]
src/python/netconf_server/netconf_rest_server.py [new file with mode: 0644]
src/python/netconf_server_application.py
src/python/requirements.txt
src/python/tests/netconf_server/test_netconf_server.py

index fc15339..2175b10 100644 (file)
@@ -1,4 +1,9 @@
 FROM docker.io/sysrepo/sysrepo-netopeer2:latest
+
+RUN apt-get update && apt-get install -y python3 python3-pip
+
+RUN mkdir /logs
+
 COPY ./models /resources/models
 COPY ./scripts ./scripts
 COPY ./src/python/netconf_server ./application/netconf_server
@@ -6,12 +11,11 @@ COPY ./src/python/netconf_server_application.py ./application/netconf_server_app
 COPY ./src/python/requirements.txt ./application/requirements.txt
 COPY ./src/python/setup.py ./application/setup.py
 
-RUN apt-get update && apt-get install -y python3 python3-pip &&  pip3 install -e ./application/
-
-ENV ENABLE_TLS=false
+RUN pip3 install -e ./application/
 
 RUN mkdir -p /resources/certs && \
     ./scripts/generate-certificates.sh /resources/certs
-RUN mkdir /logs
+
+ENV ENABLE_TLS=false
 
 ENTRYPOINT ["./scripts/set-up-netopeer.sh", "/resources/models", "/resources/certs"]
index a4080dc..bf43ff5 100644 (file)
@@ -10,3 +10,4 @@ services:
     ports:
      - "830:830"
      - "6513:6513"
+     - "6555:6555"
@@ -24,7 +24,7 @@ from netconf_server.sysrepo_interface.config_change_data import ConfigChangeData
 logger = logging.getLogger("netconf_saver")
 
 
-class NetconfServer(object):
+class NetconfChangeListener(object):
 
     def __init__(self, subscriptions: list):
         self.subscriptions = subscriptions
 ###
 import logging
 
-from netconf_server.netconf_server import NetconfServer
+from netconf_server.netconf_change_listener import NetconfChangeListener
 from netconf_server.sysrepo_interface.config_change_subscriber import ConfigChangeSubscriber
 
 logger = logging.getLogger("netconf_saver")
 
 
-class NetconfServerFactory(object):
+class NetconfChangeListenerFactory(object):
 
     def __init__(self, modules_to_subscribe_names: list):
         self.modules_to_subscribe_names = modules_to_subscribe_names
 
-    def create(self) -> NetconfServer:
+    def create(self) -> NetconfChangeListener:
         subscriptions = list()
         for module_name in self.modules_to_subscribe_names:
             subscriptions.append(
                 ConfigChangeSubscriber(module_name)
             )
-        return NetconfServer(subscriptions)
+        return NetconfChangeListener(subscriptions)
 
diff --git a/src/python/netconf_server/netconf_rest_server.py b/src/python/netconf_server/netconf_rest_server.py
new file mode 100644 (file)
index 0000000..2c44029
--- /dev/null
@@ -0,0 +1,50 @@
+###
+# ============LICENSE_START=======================================================
+# Netconf Server
+# ================================================================================
+# Copyright (C) 2021 Nokia. All rights reserved.
+# ================================================================================
+# 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.
+# ============LICENSE_END=========================================================
+###
+
+import logging as sys_logging
+from flask import Flask, logging, make_response, Response
+
+
+class NetconfRestServer:
+    _rest_server: Flask = Flask("server")
+    sys_logging.basicConfig(level=sys_logging.DEBUG)
+    logger = logging.create_logger(_rest_server)
+
+    def __init__(self, host='0.0.0.0', port=6555):
+        self._host = host
+        self._port = port
+
+    def start(self):
+        Flask.run(
+            NetconfRestServer._rest_server,
+            host=self._host,
+            port=self._port
+        )
+
+    @staticmethod
+    @_rest_server.route("/healthcheck")
+    def __health_check():
+        return "UP"
+
+    @staticmethod
+    def __create_http_response(code, message):
+        return make_response(
+            Response(message, headers={'Content-Type': 'application/json'}),
+            code)
index e112490..09dea83 100644 (file)
 # limitations under the License.
 # ============LICENSE_END=========================================================
 ###
-import asyncio
 import sys
 import logging
+from netconf_server.netconf_rest_server import NetconfRestServer
 
-from netconf_server.netconf_server import NetconfServer
-from netconf_server.netconf_server_factory import NetconfServerFactory
+from netconf_server.netconf_change_listener import NetconfChangeListener
+from netconf_server.netconf_change_listener_factory import NetconfChangeListenerFactory
 from netconf_server.sysrepo_configuration.sysrepo_configuration_loader import SysrepoConfigurationLoader, \
     ConfigLoadingException
 from netconf_server.sysrepo_interface.sysrepo_client import SysrepoClient
 
 logging.basicConfig(
-    handlers=[logging.StreamHandler(), logging.FileHandler("/logs/netconf_saver.log")],
+    handlers=[logging.StreamHandler(), logging.FileHandler("/logs/netconf_server.log")],
     level=logging.DEBUG
 )
-logger = logging.getLogger("netconf_saver")
+logger = logging.getLogger("netconf_server")
 
 
-def run_server_forever(session, server: NetconfServer):
-    server.run(session)
-    asyncio.get_event_loop().run_forever()
+def run_server_forever(session, change_listener: NetconfChangeListener, server_rest: NetconfRestServer):
+    change_listener.run(session)
+    server_rest.start()
 
 
-def create_configured_server() -> NetconfServer:
+def create_change_listener() -> NetconfChangeListener:
     configuration = SysrepoConfigurationLoader.load_configuration(sys.argv[1])
-    return NetconfServerFactory(configuration.models_to_subscribe_to).create()
+    return NetconfChangeListenerFactory(configuration.models_to_subscribe_to).create()
+
+
+def create_rest_server() -> NetconfRestServer:
+    return NetconfRestServer()
 
 
 if __name__ == "__main__":
     if len(sys.argv) >= 2:
         try:
-            netconf_server = create_configured_server()
-            SysrepoClient().run_in_session(run_server_forever, netconf_server)
+            netconf_change_listener = create_change_listener()
+            rest_server = create_rest_server()
+            SysrepoClient().run_in_session(run_server_forever, netconf_change_listener, rest_server)
         except ConfigLoadingException:
             logger.error("File to load configuration from file %s" % sys.argv[1])
     else:
index ee6c404..0dc606a 100644 (file)
@@ -19,3 +19,4 @@
 ###
 
 sysrepo==0.4.2
+Flask==1.1.1
index 6306dd9..c2889f1 100644 (file)
@@ -20,7 +20,7 @@
 import unittest
 from unittest.mock import MagicMock
 
-from netconf_server.netconf_server_factory import NetconfServerFactory
+from netconf_server.netconf_change_listener_factory import NetconfChangeListenerFactory
 from tests.mocs.mocked_session import MockedSession
 
 
@@ -29,7 +29,7 @@ class TestNetconfServer(unittest.TestCase):
     def test_should_create_and_run_netconf_server_with_one_model(self):
         # given
         modules_to_subscribe_names = ["test"]
-        server = NetconfServerFactory(modules_to_subscribe_names).create()
+        server = NetconfChangeListenerFactory(modules_to_subscribe_names).create()
         session = MockedSession()
         session.subscribe_module_change = MagicMock()
 
@@ -42,7 +42,7 @@ class TestNetconfServer(unittest.TestCase):
     def test_should_create_and_run_netconf_server_with_multiple_models(self):
         # given
         modules_to_subscribe_names = ["test", "test2", "test3"]
-        server = NetconfServerFactory(modules_to_subscribe_names).create()
+        server = NetconfChangeListenerFactory(modules_to_subscribe_names).create()
         session = MockedSession()
         session.subscribe_module_change = MagicMock()