diff options
author | Edyta Krukowska <edyta.krukowska@nokia.com> | 2021-03-25 14:55:24 +0100 |
---|---|---|
committer | Edyta Krukowska <edyta.krukowska@nokia.com> | 2021-03-26 14:36:47 +0100 |
commit | 480e3de63f475477138c45f551def992ba8d8b9d (patch) | |
tree | bcb768aedee6c9eeb48c3474cbe05588d59f794a /src/python | |
parent | d8facaa17d35af37291192d09a783c620bc379c5 (diff) |
Add endopint for config change
Issue-ID: INT-1869
Signed-off-by: Edyta Krukowska <edyta.krukowska@nokia.com>
Change-Id: Ib016779b3539ebaac186d92d3cd95a19f81e45cd
Diffstat (limited to 'src/python')
-rw-r--r-- | src/python/netconf_change_listener_application.py (renamed from src/python/netconf_server_application.py) | 17 | ||||
-rw-r--r-- | src/python/netconf_rest_application.py | 53 | ||||
-rw-r--r-- | src/python/netconf_server/netconf_change_listener.py | 2 | ||||
-rw-r--r-- | src/python/netconf_server/netconf_change_listener_factory.py | 2 | ||||
-rw-r--r-- | src/python/netconf_server/netconf_rest_server.py | 15 | ||||
-rw-r--r-- | src/python/netconf_server/sysrepo_configuration/sysrepo_configuration_manager.py | 41 | ||||
-rw-r--r-- | src/python/netconf_server/sysrepo_interface/sysrepo_client.py | 2 | ||||
-rw-r--r-- | src/python/tests/netconf_server/sysrepo_configuration/test_sysrepo_configuration_manager_.py | 31 | ||||
-rw-r--r-- | src/python/tests/netconf_server/test_netconf_chang_listener.py (renamed from src/python/tests/netconf_server/test_netconf_server.py) | 0 |
9 files changed, 147 insertions, 16 deletions
diff --git a/src/python/netconf_server_application.py b/src/python/netconf_change_listener_application.py index 09dea83..a4dd8bd 100644 --- a/src/python/netconf_server_application.py +++ b/src/python/netconf_change_listener_application.py @@ -17,9 +17,11 @@ # limitations under the License. # ============LICENSE_END========================================================= ### +import asyncio import sys import logging from netconf_server.netconf_rest_server import NetconfRestServer +from netconf_server.sysrepo_configuration.sysrepo_configuration_manager import SysrepoConfigurationManager from netconf_server.netconf_change_listener import NetconfChangeListener from netconf_server.netconf_change_listener_factory import NetconfChangeListenerFactory @@ -28,15 +30,15 @@ from netconf_server.sysrepo_configuration.sysrepo_configuration_loader import Sy from netconf_server.sysrepo_interface.sysrepo_client import SysrepoClient logging.basicConfig( - handlers=[logging.StreamHandler(), logging.FileHandler("/logs/netconf_server.log")], + handlers=[logging.StreamHandler(), logging.FileHandler("/logs/netconf_change_listener.log")], level=logging.DEBUG ) -logger = logging.getLogger("netconf_server") +logger = logging.getLogger("netconf_change_listener") -def run_server_forever(session, change_listener: NetconfChangeListener, server_rest: NetconfRestServer): +def run_server_forever(session, connection, change_listener: NetconfChangeListener): change_listener.run(session) - server_rest.start() + asyncio.get_event_loop().run_forever() def create_change_listener() -> NetconfChangeListener: @@ -44,16 +46,11 @@ def create_change_listener() -> NetconfChangeListener: 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_change_listener = create_change_listener() - rest_server = create_rest_server() - SysrepoClient().run_in_session(run_server_forever, netconf_change_listener, rest_server) + SysrepoClient().run_in_session(run_server_forever, netconf_change_listener) except ConfigLoadingException: logger.error("File to load configuration from file %s" % sys.argv[1]) else: diff --git a/src/python/netconf_rest_application.py b/src/python/netconf_rest_application.py new file mode 100644 index 0000000..79f2336 --- /dev/null +++ b/src/python/netconf_rest_application.py @@ -0,0 +1,53 @@ +### +# ============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 sys +import logging +from netconf_server.netconf_rest_server import NetconfRestServer +from netconf_server.sysrepo_configuration.sysrepo_configuration_manager import SysrepoConfigurationManager + +from netconf_server.sysrepo_configuration.sysrepo_configuration_loader import ConfigLoadingException +from netconf_server.sysrepo_interface.sysrepo_client import SysrepoClient + +logging.basicConfig( + handlers=[logging.StreamHandler(), logging.FileHandler("/logs/netconf_rest_application.log")], + level=logging.DEBUG +) +logger = logging.getLogger("netconf_rest_application") + + +def start_rest_server(session, connection, server_rest: NetconfRestServer): + sysrepo_cfg_manager = create_conf_manager(session, connection) + server_rest.start(sysrepo_cfg_manager) + + +def create_rest_server() -> NetconfRestServer: + return NetconfRestServer() + + +def create_conf_manager(session, connection) -> SysrepoConfigurationManager: + return SysrepoConfigurationManager(session, connection) + + +if __name__ == "__main__": + if len(sys.argv) >= 2: + rest_server = create_rest_server() + SysrepoClient().run_in_session(start_rest_server, rest_server) + else: + logger.error("Missing path to file with configuration argument required to start netconf server.") diff --git a/src/python/netconf_server/netconf_change_listener.py b/src/python/netconf_server/netconf_change_listener.py index 4bb748c..44910d1 100644 --- a/src/python/netconf_server/netconf_change_listener.py +++ b/src/python/netconf_server/netconf_change_listener.py @@ -21,7 +21,7 @@ import logging from netconf_server.sysrepo_interface.config_change_data import ConfigChangeData -logger = logging.getLogger("netconf_saver") +logger = logging.getLogger(__name__) class NetconfChangeListener(object): diff --git a/src/python/netconf_server/netconf_change_listener_factory.py b/src/python/netconf_server/netconf_change_listener_factory.py index 00725dc..fa5e071 100644 --- a/src/python/netconf_server/netconf_change_listener_factory.py +++ b/src/python/netconf_server/netconf_change_listener_factory.py @@ -22,7 +22,7 @@ import logging from netconf_server.netconf_change_listener import NetconfChangeListener from netconf_server.sysrepo_interface.config_change_subscriber import ConfigChangeSubscriber -logger = logging.getLogger("netconf_saver") +logger = logging.getLogger(__name__) class NetconfChangeListenerFactory(object): diff --git a/src/python/netconf_server/netconf_rest_server.py b/src/python/netconf_server/netconf_rest_server.py index 2c44029..dce4f82 100644 --- a/src/python/netconf_server/netconf_rest_server.py +++ b/src/python/netconf_server/netconf_rest_server.py @@ -19,19 +19,21 @@ ### import logging as sys_logging -from flask import Flask, logging, make_response, Response +from flask import Flask, logging, make_response, Response, request +from netconf_server.sysrepo_configuration.sysrepo_configuration_manager import SysrepoConfigurationManager class NetconfRestServer: _rest_server: Flask = Flask("server") - sys_logging.basicConfig(level=sys_logging.DEBUG) logger = logging.create_logger(_rest_server) + _configuration_manager: SysrepoConfigurationManager def __init__(self, host='0.0.0.0', port=6555): self._host = host self._port = port - def start(self): + def start(self, configuration_manager: SysrepoConfigurationManager): + NetconfRestServer._configuration_manager = configuration_manager Flask.run( NetconfRestServer._rest_server, host=self._host, @@ -44,6 +46,13 @@ class NetconfRestServer: return "UP" @staticmethod + @_rest_server.route("/change_config/<path:module_name>", methods=['POST']) + def __change_config(module_name): + config_data = request.data.decode("utf-8") + NetconfRestServer._configuration_manager.change_configuration(config_data, module_name) + return NetconfRestServer.__create_http_response(202, "Accepted") + + @staticmethod def __create_http_response(code, message): return make_response( Response(message, headers={'Content-Type': 'application/json'}), diff --git a/src/python/netconf_server/sysrepo_configuration/sysrepo_configuration_manager.py b/src/python/netconf_server/sysrepo_configuration/sysrepo_configuration_manager.py new file mode 100644 index 0000000..0e8ad94 --- /dev/null +++ b/src/python/netconf_server/sysrepo_configuration/sysrepo_configuration_manager.py @@ -0,0 +1,41 @@ +# ================================================================================ +# 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 + + +class SysrepoConfigurationManager(object): + logger = logging.getLogger(__name__) + + def __init__(self, session, connection): + self._connection = connection + self._session = session + + def __parse_config_data(self, config_data): + self.logger.debug(config_data) + ctx = self._connection.get_ly_ctx() + data = ctx.parse_data_mem( + config_data, + "xml", + config=True, + strict=False, + ) + return data + + def change_configuration(self, config_data: str, module_name: str): + data = self.__parse_config_data(config_data) + self._session.replace_config_ly(data, module_name) diff --git a/src/python/netconf_server/sysrepo_interface/sysrepo_client.py b/src/python/netconf_server/sysrepo_interface/sysrepo_client.py index fcd29e2..3528747 100644 --- a/src/python/netconf_server/sysrepo_interface/sysrepo_client.py +++ b/src/python/netconf_server/sysrepo_interface/sysrepo_client.py @@ -26,4 +26,4 @@ class SysrepoClient(object): def run_in_session(method_to_run: callable, *extra_args): with sysrepo.SysrepoConnection() as connection: with connection.start_session() as session: - method_to_run(session, *extra_args) + method_to_run(session, connection, *extra_args) diff --git a/src/python/tests/netconf_server/sysrepo_configuration/test_sysrepo_configuration_manager_.py b/src/python/tests/netconf_server/sysrepo_configuration/test_sysrepo_configuration_manager_.py new file mode 100644 index 0000000..5194218 --- /dev/null +++ b/src/python/tests/netconf_server/sysrepo_configuration/test_sysrepo_configuration_manager_.py @@ -0,0 +1,31 @@ +import unittest +from unittest.mock import MagicMock +from netconf_server.sysrepo_configuration.sysrepo_configuration_manager import SysrepoConfigurationManager + + +class TestSysrepoConfigurationManager(unittest.TestCase): + + def test_should_change_configuration(self): + # given + expected_parse_data = "parse_data" + + ctx = MagicMock() + ctx.parse_data_mem = MagicMock(return_value=expected_parse_data) + connection = MagicMock() + connection.get_ly_ctx = MagicMock(return_value=ctx) + session = MagicMock() + session.replace_config_ly = MagicMock() + + config_data = '''<config xmlns="http://onap.org/pnf-simulator"> + <itemValue1>12</itemValue1> + <itemValue2>12</itemValue2> + </config>''' + module_name = "pnf-simulator" + + # when + config_manager = SysrepoConfigurationManager(session=session, connection=connection) + config_manager.change_configuration(config_data=config_data, module_name=module_name) + + # then + ctx.parse_data_mem.assert_called_with(config_data, "xml", config=True, strict=False) + session.replace_config_ly.assert_called_with(expected_parse_data, module_name) diff --git a/src/python/tests/netconf_server/test_netconf_server.py b/src/python/tests/netconf_server/test_netconf_chang_listener.py index c2889f1..c2889f1 100644 --- a/src/python/tests/netconf_server/test_netconf_server.py +++ b/src/python/tests/netconf_server/test_netconf_chang_listener.py |