From 032ff22ef20b59950a8b5fae8d2ba6d03e93ac93 Mon Sep 17 00:00:00 2001 From: Wojciech Sliwka Date: Wed, 10 Jul 2019 13:48:52 +0200 Subject: Opensourcing new version of Simulator Additional info in README.md Issue-ID: INT-1134 Signed-off-by: Wojciech Sliwka Change-Id: I06d41fd3f361b7a451b30b702882810e4136a129 --- .../netconfsimulator/netconf/__init__.py | 19 +++ .../netconf/initialize_netopeer.sh | 54 +++++++ .../netconfsimulator/netconf/load_server_certs.xml | 40 +++++ .../netconfsimulator/netconf/newmodel.xml | 24 +++ .../netconfsimulator/netconf/newmodel.yang | 9 ++ .../netconf/pnf-simulator.data.xml | 24 +++ .../netconfsimulator/netconf/pnf-simulator.yang | 9 ++ .../netconfsimulator/netconf/set-up-xmls.py | 153 ++++++++++++++++++ .../netconf/test_yang_loader_server.py | 121 +++++++++++++++ .../netconfsimulator/netconf/tls_listen.xml | 48 ++++++ .../netconfsimulator/netconf/yang_loader_server.py | 172 +++++++++++++++++++++ 11 files changed, 673 insertions(+) create mode 100644 test/mocks/pnfsimulator/netconfsimulator/netconf/__init__.py create mode 100755 test/mocks/pnfsimulator/netconfsimulator/netconf/initialize_netopeer.sh create mode 100644 test/mocks/pnfsimulator/netconfsimulator/netconf/load_server_certs.xml create mode 100644 test/mocks/pnfsimulator/netconfsimulator/netconf/newmodel.xml create mode 100644 test/mocks/pnfsimulator/netconfsimulator/netconf/newmodel.yang create mode 100644 test/mocks/pnfsimulator/netconfsimulator/netconf/pnf-simulator.data.xml create mode 100644 test/mocks/pnfsimulator/netconfsimulator/netconf/pnf-simulator.yang create mode 100755 test/mocks/pnfsimulator/netconfsimulator/netconf/set-up-xmls.py create mode 100644 test/mocks/pnfsimulator/netconfsimulator/netconf/test_yang_loader_server.py create mode 100644 test/mocks/pnfsimulator/netconfsimulator/netconf/tls_listen.xml create mode 100644 test/mocks/pnfsimulator/netconfsimulator/netconf/yang_loader_server.py (limited to 'test/mocks/pnfsimulator/netconfsimulator/netconf') diff --git a/test/mocks/pnfsimulator/netconfsimulator/netconf/__init__.py b/test/mocks/pnfsimulator/netconfsimulator/netconf/__init__.py new file mode 100644 index 000000000..0f144c21e --- /dev/null +++ b/test/mocks/pnfsimulator/netconfsimulator/netconf/__init__.py @@ -0,0 +1,19 @@ +### +# ============LICENSE_START======================================================= +# Simulator +# ================================================================================ +# Copyright (C) 2019 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========================================================= +### diff --git a/test/mocks/pnfsimulator/netconfsimulator/netconf/initialize_netopeer.sh b/test/mocks/pnfsimulator/netconfsimulator/netconf/initialize_netopeer.sh new file mode 100755 index 000000000..71c1f215b --- /dev/null +++ b/test/mocks/pnfsimulator/netconfsimulator/netconf/initialize_netopeer.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +### +# ============LICENSE_START======================================================= +# Simulator +# ================================================================================ +# Copyright (C) 2019 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========================================================= +### + +cat > /etc/apt/apt.conf << EOF +Acquire::http { + No-Cache "true"; + No-Store "true"; + Pipeline-Depth "0"; +}; +EOF + +NETOPEER_CHANGE_SAVER=netopeer-change-saver + +cp /tls/* /usr/local/etc/keystored/keys/ +cp /netconf/*.xml /tmp/ + +chmod +x /netconf/set-up-xmls.py +/netconf/set-up-xmls.py /tls ca.crt server_cert.crt server_key.pem /tmp/load_server_certs.xml /tmp/tls_listen.xml + +/usr/bin/supervisord -c /etc/supervisord.conf & +sysrepoctl --install --yang=/netconf/pnf-simulator.yang --owner=netconf:nogroup --permissions=777 +sysrepocfg --import=/netconf/pnf-simulator.data.xml --datastore=startup --format=xml --level=3 pnf-simulator +sysrepocfg --merge=/tmp/load_server_certs.xml --format=xml --datastore=startup ietf-keystore +sysrepocfg --merge=/tmp/tls_listen.xml --format=xml --datastore=startup ietf-netconf-server + +apt-get update +apt-get install -y python3 python3-pip librdkafka-dev +pip3 install flask flask_restful +nohup python3 /netconf/yang_loader_server.py & + +/bin/cp -R /$NETOPEER_CHANGE_SAVER /opt/dev/ +ln -s /opt/dev/sysrepo/build/src/libsysrepo.so /$NETOPEER_CHANGE_SAVER/libsysrepo.so +cd /opt/dev/$NETOPEER_CHANGE_SAVER && cmake . +cd /opt/dev/$NETOPEER_CHANGE_SAVER && make +/opt/dev/$NETOPEER_CHANGE_SAVER/bin/netopeer-change-saver pnf-simulator kafka1 config diff --git a/test/mocks/pnfsimulator/netconfsimulator/netconf/load_server_certs.xml b/test/mocks/pnfsimulator/netconfsimulator/netconf/load_server_certs.xml new file mode 100644 index 000000000..2524e08b0 --- /dev/null +++ b/test/mocks/pnfsimulator/netconfsimulator/netconf/load_server_certs.xml @@ -0,0 +1,40 @@ + + + + + + SERVER_KEY_NAME + + + SERVER_CERT_NAME + SERVER_CERTIFICATE_HERE + + + + + + test_trusted_ca_list + + CA_CERT_NAME + CA_CERTIFICATE_HERE + + + diff --git a/test/mocks/pnfsimulator/netconfsimulator/netconf/newmodel.xml b/test/mocks/pnfsimulator/netconfsimulator/netconf/newmodel.xml new file mode 100644 index 000000000..90a3451d4 --- /dev/null +++ b/test/mocks/pnfsimulator/netconfsimulator/netconf/newmodel.xml @@ -0,0 +1,24 @@ + + + + 500 + 1000 + diff --git a/test/mocks/pnfsimulator/netconfsimulator/netconf/newmodel.yang b/test/mocks/pnfsimulator/netconfsimulator/netconf/newmodel.yang new file mode 100644 index 000000000..544f46725 --- /dev/null +++ b/test/mocks/pnfsimulator/netconfsimulator/netconf/newmodel.yang @@ -0,0 +1,9 @@ +module newmodel { + namespace "http://onap.org/pnf-simulator2"; + prefix config2; + container config2 { + config true; + leaf item1 {type uint32;} + leaf item2 {type uint32;} + } +} diff --git a/test/mocks/pnfsimulator/netconfsimulator/netconf/pnf-simulator.data.xml b/test/mocks/pnfsimulator/netconfsimulator/netconf/pnf-simulator.data.xml new file mode 100644 index 000000000..c235f6405 --- /dev/null +++ b/test/mocks/pnfsimulator/netconfsimulator/netconf/pnf-simulator.data.xml @@ -0,0 +1,24 @@ + + + + 42 + 35 + diff --git a/test/mocks/pnfsimulator/netconfsimulator/netconf/pnf-simulator.yang b/test/mocks/pnfsimulator/netconfsimulator/netconf/pnf-simulator.yang new file mode 100644 index 000000000..ba1158560 --- /dev/null +++ b/test/mocks/pnfsimulator/netconfsimulator/netconf/pnf-simulator.yang @@ -0,0 +1,9 @@ +module pnf-simulator { + namespace "http://onap.org/pnf-simulator"; + prefix config; + container config { + config true; + leaf itemValue1 {type uint32;} + leaf itemValue2 {type uint32;} + } +} diff --git a/test/mocks/pnfsimulator/netconfsimulator/netconf/set-up-xmls.py b/test/mocks/pnfsimulator/netconfsimulator/netconf/set-up-xmls.py new file mode 100755 index 000000000..d46ff91f9 --- /dev/null +++ b/test/mocks/pnfsimulator/netconfsimulator/netconf/set-up-xmls.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python + +### +# ============LICENSE_START======================================================= +# Simulator +# ================================================================================ +# Copyright (C) 2019 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 os +import sys +import logging +import logging.config + +logging.basicConfig() +logger = logging.getLogger() +logger.setLevel(logging.INFO) + +# Placeholders definition - this needs to match placeholders in +# load_server_certs_xml_file and tls_listen_xml_file +SERVER_KEY_NAME = "SERVER_KEY_NAME" +SERVER_CERT_NAME = "SERVER_CERT_NAME" +SERVER_CERTIFICATE_HERE = "SERVER_CERTIFICATE_HERE" +CA_CERT_NAME = "CA_CERT_NAME" +CA_CERTIFICATE_HERE = "CA_CERTIFICATE_HERE" +CA_FINGERPRINT_HERE = "CA_FINGERPRINT_HERE" +CA_FINGERPRINT_ENV = "CA_FINGERPRINT" +SERVER_CERTIFICATE_ENV = "SERVER_CERTIFICATE_ENV" +CA_CERTIFICATE_ENV = "CA_CERTIFICATE_ENV" + + +class FileHelper(object): + @classmethod + def get_file_contents(cls, filename): + with open(filename, "r") as f: + return f.read() + + @classmethod + def write_file_contents(cls, filename, data): + with open(filename, "w+") as f: + f.write(data) + + +class CertHelper(object): + @classmethod + def get_pem_content_stripped(cls, pem_dir, pem_filename): + cmd = "cat {}/{} | grep -v '^-'".format(pem_dir, pem_filename) + content = CertHelper.system(cmd) + return content + + @classmethod + def get_cert_fingerprint(cls, directory, cert_filename): + cmd = "openssl x509 -fingerprint -noout -in {}/{} | sed -e " \ + "'s/SHA1 Fingerprint//; s/=//; s/=//p'" \ + .format(directory, cert_filename) + fingerprint = CertHelper.system(cmd) + return fingerprint + + @classmethod + def print_certs_info(cls, ca_cert, ca_fingerprint, server_cert): + logger.info("Will use server certificate: " + server_cert) + logger.info("Will use CA certificate: " + ca_cert) + logger.info("CA certificate fingerprint: " + ca_fingerprint) + + @classmethod + def system(cls, cmd): + return os.popen(cmd).read().replace("\n", "") + + +class App(object): + @classmethod + def patch_server_certs(cls, data, server_key_filename_noext, + server_cert_filename_noext, ca_cert_filename_noext, + server_cert, ca_cert): + data = data.replace(SERVER_KEY_NAME, server_key_filename_noext) + data = data.replace(SERVER_CERT_NAME, server_cert_filename_noext) + data = data.replace(CA_CERT_NAME, ca_cert_filename_noext) + data = data.replace(SERVER_CERTIFICATE_HERE, server_cert) + data = data.replace(CA_CERTIFICATE_HERE, ca_cert) + return data + + @classmethod + def patch_tls_listen(cls, data, server_cert_filename_noext, ca_fingerprint, + server_cert, ca_cert): + data = data.replace(SERVER_CERT_NAME, server_cert_filename_noext) + data = data.replace(CA_FINGERPRINT_HERE, ca_fingerprint) + data = data.replace(SERVER_CERTIFICATE_HERE, server_cert) + data = data.replace(CA_CERTIFICATE_HERE, ca_cert) + return data + + @classmethod + def run(cls): + # name things + cert_dir = sys.argv[1] + ca_cert_filename = sys.argv[2] + server_cert_filename = sys.argv[3] + server_key_filename = sys.argv[4] + load_server_certs_xml_file = sys.argv[5] + tls_listen_xml_file = sys.argv[6] + + # strip extensions + ca_cert_filename_noext = ca_cert_filename.replace(".crt", "") + server_cert_filename_noext = server_cert_filename.replace(".crt", "") + server_key_filename_noext = server_key_filename.replace(".pem", "") + + # get certificates from files + server_cert = CertHelper.get_pem_content_stripped(cert_dir, + server_cert_filename) + ca_cert = CertHelper.get_pem_content_stripped(cert_dir, + ca_cert_filename) + ca_fingerprint = CertHelper.get_cert_fingerprint(cert_dir, + ca_cert_filename) + CertHelper.print_certs_info(ca_cert, ca_fingerprint, server_cert) + + # patch TLS configuration files + data_srv = FileHelper.get_file_contents(load_server_certs_xml_file) + patched_srv = App.patch_server_certs(data_srv, server_key_filename_noext, + server_cert_filename_noext, + ca_cert_filename_noext, + server_cert, ca_cert) + FileHelper.write_file_contents(load_server_certs_xml_file, patched_srv) + + data_tls = FileHelper.get_file_contents(tls_listen_xml_file) + patched_tls = App.patch_tls_listen(data_tls, server_cert_filename_noext, + ca_fingerprint, server_cert, ca_cert) + FileHelper.write_file_contents(tls_listen_xml_file, patched_tls) + + +def main(): + if len(sys.argv) is not 7: + print("Usage: {1} " + " " + "", sys.argv[0]) + return 1 + App.run() + logger.info("XML files patched successfully") + + +if __name__ == '__main__': + main() diff --git a/test/mocks/pnfsimulator/netconfsimulator/netconf/test_yang_loader_server.py b/test/mocks/pnfsimulator/netconfsimulator/netconf/test_yang_loader_server.py new file mode 100644 index 000000000..f282517b2 --- /dev/null +++ b/test/mocks/pnfsimulator/netconfsimulator/netconf/test_yang_loader_server.py @@ -0,0 +1,121 @@ +### +# ============LICENSE_START======================================================= +# Simulator +# ================================================================================ +# Copyright (C) 2019 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 unittest + +from unittest import mock +from werkzeug.datastructures import FileStorage + +from yang_loader_server import YangLoaderHelper, YangModelServer + + +class TestYangLoaderHelper(unittest.TestCase): + + def test_should_save_file_and_return_path(self): + helper = YangLoaderHelper() + mocked_file = mock.Mock(FileStorage) + mocked_file.filename = "sample" + + path = helper.save_file(mocked_file) + + self.assertEqual(path, "/tmp/sample") + mocked_file.save.assert_called_once_with("/tmp/sample") + + @mock.patch('yang_loader_server.check_output') + def test_should_install_new_yang_model(self, mocked_output): + helper = YangLoaderHelper() + + helper.install_new_model("path") + + mocked_output.assert_called_with( + ['sysrepoctl', '--install', '--yang=path', + '--owner=netconf:nogroup', '--permissions=777'], + stderr=-2, universal_newlines=True) + + @mock.patch('yang_loader_server.check_output') + def test_should_delete_yang_model(self, mocked_output): + helper = YangLoaderHelper() + + helper.uninstall_a_model("modelName") + + mocked_output.assert_called_with( + ['sysrepoctl', '--uninstall', '--module=modelName'], + stderr=-2, universal_newlines=True) + + @mock.patch('yang_loader_server.check_output') + def test_should_set_default_configuration(self, mocked_output): + helper = YangLoaderHelper() + + helper.set_default_configuration("samplePath", "sampleModuleName") + + mocked_output.assert_called_with( + ['sysrepocfg', '--import=samplePath', '--datastore=startup', + '--format=xml', '--level=3', 'sampleModuleName'], + stderr=-2, universal_newlines=True) + + @mock.patch('yang_loader_server.subprocess.Popen') + @mock.patch('yang_loader_server.check_output') + def test_should_verify_change_listener_for_model_properly(self, mocked_output, mocked_popen): + helper = YangLoaderHelper() + + helper.start_change_listener_for_model("sampleModule") + + mocked_output.assert_called_with( + ['pgrep', '-f', '/opt/dev/netopeer-change-saver/bin/netopeer-change-saver sampleModule kafka1 config'], + stderr=-2, universal_newlines=True) + + @mock.patch('yang_loader_server.check_output') + def test_should_raise_exception_when_error_occurred_in_output(self, + mocked_output): + helper = YangLoaderHelper() + mocked_output.return_value = "abcd ERR" + with self.assertRaises(RuntimeError) as context: + helper._run_bash_command("sample command") + + self.assertEqual('abcd ERR', str(context.exception)) + + +class TestYangModelServer(unittest.TestCase): + + def __init__(self, methodName='runTest'): + super().__init__(methodName) + self._mocked_file = mock.Mock(FileStorage) + + def test_should_properly_apply_and_start_new_model(self): + with mock.patch.object(YangModelServer, '_parse_request', + new=self._mock_request): + helper = mock.Mock(YangLoaderHelper) + helper.save_file.return_value = "sampleFile" + server = YangModelServer(helper) + + server.post() + + self.assertEqual(helper.save_file.call_count, 2) + helper.install_new_model.assert_called_once_with('sampleFile') + helper.set_default_configuration.assert_called_once_with( + 'sampleFile', 'sampleModuleName') + helper.start_change_listener_for_model.assert_called_once_with('sampleModuleName') + + def _mock_request(self): + return { + 'yangModel': self._mocked_file, + 'initialConfig': self._mocked_file, + 'moduleName': "sampleModuleName" + } diff --git a/test/mocks/pnfsimulator/netconfsimulator/netconf/tls_listen.xml b/test/mocks/pnfsimulator/netconfsimulator/netconf/tls_listen.xml new file mode 100644 index 000000000..4f45b28a2 --- /dev/null +++ b/test/mocks/pnfsimulator/netconfsimulator/netconf/tls_listen.xml @@ -0,0 +1,48 @@ + + + + + + test_tls_listen_endpt + +
0.0.0.0
+ 6513 + + + SERVER_CERT_NAME + + + + test_trusted_ca_list + + + 1 + + 02:CA_FINGERPRINT_HERE + x509c2n:specified + test + + + +
+
+
+
diff --git a/test/mocks/pnfsimulator/netconfsimulator/netconf/yang_loader_server.py b/test/mocks/pnfsimulator/netconfsimulator/netconf/yang_loader_server.py new file mode 100644 index 000000000..716d0712e --- /dev/null +++ b/test/mocks/pnfsimulator/netconfsimulator/netconf/yang_loader_server.py @@ -0,0 +1,172 @@ +### +# ============LICENSE_START======================================================= +# Simulator +# ================================================================================ +# Copyright (C) 2019 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 +import subprocess +import os +from subprocess import check_output, CalledProcessError +from flask import Flask +from flask_restful import Resource, Api, reqparse +from werkzeug.datastructures import FileStorage +import time + +app = Flask(__name__) +api = Api(app) +logger = logging.getLogger("yang-loader") +logger.addHandler(logging.StreamHandler()) +KAFKA_BROKER_NAME="kafka1" +KAFKA_TOPIC_NAME="config" + + +class YangLoaderHelper(object): + + @classmethod + def save_file(cls, yang_model_file: FileStorage) -> str: + path = "/tmp/" + yang_model_file.filename + yang_model_file.save(path) + return path + + @classmethod + def install_new_model(cls, yang_model_path: str): + logger.info("Installing new model: %s", yang_model_path) + command = "sysrepoctl --install --yang={} --owner=netconf:nogroup --permissions=777" \ + .format(yang_model_path) + cls._run_bash_command(command) + + @classmethod + def uninstall_a_model(cls, yang_model_name: str): + logger.info("Uninstalling a model: %s", yang_model_name) + command = "sysrepoctl --uninstall --module={}" \ + .format(yang_model_name) + cls._run_bash_command(command) + + + @classmethod + def set_default_configuration(cls, init_conf_path: str, module_name: str): + logger.info("Attempting to set default configuration %s for module %s", init_conf_path, module_name) + command = "sysrepocfg --import={} --datastore=startup --format=xml --level=3 {}" \ + .format(init_conf_path, module_name) + cls._run_bash_command(command) + + @classmethod + def start_change_listener_for_model(cls, module_name: str): + logger.info("Starting listener for model: %s", module_name) + command = "/opt/dev/netopeer-change-saver/bin/netopeer-change-saver {} {} {}" \ + .format(module_name, KAFKA_BROKER_NAME, KAFKA_TOPIC_NAME) + try: + check_output(["pgrep", "-f" , command], stderr=subprocess.STDOUT, universal_newlines=True) + logger.info("Change listener for {} already exist.".format(module_name)) + except CalledProcessError: + subprocess.Popen(command.split(), stdout=subprocess.PIPE) + + @classmethod + def stop_change_listener_for_model(cls, model_name): + logger.info("Stopping listener for model %s", model_name) + pid = cls.get_pid_by_name(model_name) + logger.info("pid is %s", pid) + command = "kill -2 {}".format(pid) + cls._run_bash_command(command) + + @classmethod + def _run_bash_command(cls, command: str): + try: + logger.info("Attempts to invoke %s", command) + output = check_output(command.split(), stderr=subprocess.STDOUT, + universal_newlines=True) + logger.info("Output: %s", output) + if "ERR" in output: + raise RuntimeError(str(output)) + except subprocess.CalledProcessError as e: + raise RuntimeError(e, str(e.stdout)) + + @classmethod + def get_pid_by_name(cls, name): + for dirname in os.listdir('/proc'): + if not dirname.isdigit(): + continue + try: + with open('/proc/{}/cmdline'.format(dirname), mode='rb') as fd: + content = fd.read().decode().split('\x00') + except Exception as e: + print(e) + continue + + if name in content: + return dirname + + +class YangModelServer(Resource): + logger = logging.getLogger('YangModelServer') + + def __init__(self, yang_loader_helper: YangLoaderHelper = YangLoaderHelper()): + self._yang_loader_helper = yang_loader_helper + + def post(self): + args = self._parse_request() + yang_model_file = args['yangModel'] + initial_config_file = args['initialConfig'] + module_name = args['moduleName'] + model_path = self._yang_loader_helper.save_file(yang_model_file) + conf_path = self._yang_loader_helper.save_file(initial_config_file) + + try: + self._yang_loader_helper.install_new_model(model_path) + self._yang_loader_helper.set_default_configuration(conf_path, + module_name) + self._yang_loader_helper.start_change_listener_for_model(module_name) + except RuntimeError as e: + self.logger.error(e.args, exc_info=True) + return str(e.args), 400 + return "Successfully started" + + def delete(self): + args = self._parse_request() + yang_model_name = args['yangModelName'] + + try: + self._yang_loader_helper.stop_change_listener_for_model(yang_model_name) + time.sleep(5) + self._yang_loader_helper.uninstall_a_model(yang_model_name) + except RuntimeError as e: + self.logger.error(e.args, exc_info=True) + return str(e.args), 400 + return "Successfully deleted" + + @classmethod + def _parse_request(cls) -> reqparse.Namespace: + parse = reqparse.RequestParser() + parse.add_argument('yangModel', + type=FileStorage, + location='files') + parse.add_argument('initialConfig', + type=FileStorage, + location='files') + parse.add_argument('moduleName', type=str) + parse.add_argument('yangModelName', type=str) + return parse.parse_args() + + +api.add_resource(YangModelServer, '/model') + +if __name__ == '__main__': + logging.basicConfig(filename=os.path.dirname(__file__) + "/yang_loader.log", + filemode="w", + level=logging.DEBUG) + app.run(host='0.0.0.0', port='5002') -- cgit 1.2.3-korg