aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdyta Krukowska <edyta.krukowska@nokia.com>2021-03-25 14:55:24 +0100
committerEdyta Krukowska <edyta.krukowska@nokia.com>2021-03-26 14:36:47 +0100
commit480e3de63f475477138c45f551def992ba8d8b9d (patch)
treebcb768aedee6c9eeb48c3474cbe05588d59f794a
parentd8facaa17d35af37291192d09a783c620bc379c5 (diff)
Add endopint for config change
Issue-ID: INT-1869 Signed-off-by: Edyta Krukowska <edyta.krukowska@nokia.com> Change-Id: Ib016779b3539ebaac186d92d3cd95a19f81e45cd
-rw-r--r--Dockerfile3
-rwxr-xr-xscripts/run-netconf-server-application.sh15
-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.py53
-rw-r--r--src/python/netconf_server/netconf_change_listener.py2
-rw-r--r--src/python/netconf_server/netconf_change_listener_factory.py2
-rw-r--r--src/python/netconf_server/netconf_rest_server.py15
-rw-r--r--src/python/netconf_server/sysrepo_configuration/sysrepo_configuration_manager.py41
-rw-r--r--src/python/netconf_server/sysrepo_interface/sysrepo_client.py2
-rw-r--r--src/python/tests/netconf_server/sysrepo_configuration/test_sysrepo_configuration_manager_.py31
-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
11 files changed, 161 insertions, 20 deletions
diff --git a/Dockerfile b/Dockerfile
index 2175b10..d56d20a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -7,7 +7,8 @@ RUN mkdir /logs
COPY ./models /resources/models
COPY ./scripts ./scripts
COPY ./src/python/netconf_server ./application/netconf_server
-COPY ./src/python/netconf_server_application.py ./application/netconf_server_application.py
+COPY src/python/netconf_change_listener_application.py ./application/netconf_change_listener_application.py
+COPY ./src/python/netconf_rest_application.py ./application/netconf_rest_application.py
COPY ./src/python/requirements.txt ./application/requirements.txt
COPY ./src/python/setup.py ./application/setup.py
diff --git a/scripts/run-netconf-server-application.sh b/scripts/run-netconf-server-application.sh
index 5cc51f4..b07da8a 100755
--- a/scripts/run-netconf-server-application.sh
+++ b/scripts/run-netconf-server-application.sh
@@ -21,9 +21,18 @@
if [ "$#" -eq 2 ]; then
- echo "Starting NETCONF server"
- python3 ./application/netconf_server_application.py $1/$2 &
+ ## Set up variable
+ MODELS_CONFIG_PATH=$1
+ MODELS_CONFIG_NAME=$2
+
+ echo "Starting NETCONF Change listener"
+ python3 ./application/netconf_change_listener_application.py $MODELS_CONFIG_PATH/$MODELS_CONFIG_NAME &
+
+
+ echo "Starting NETCONF Rest server"
+ python3 ./application/netconf_rest_application.py $MODELS_CONFIG_PATH/$MODELS_CONFIG_NAME &
+
else
- echo "Missing argument: path to file with models to subscribe to."
+ echo "[ERROR] Invalid number of arguments. Please provide all required arguments."
fi
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