From 6eacd18f8d28c7cce629da5f03900ab073ed8493 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 3 Sep 2020 09:30:29 +0200 Subject: [PATCH 001/318] Implemented prompt position changes into user_input --- vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py | 6 +++++- vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py | 8 ++------ .../Huawei/Base/Huawei_Base/userViewCommandProcessor.py | 8 ++------ 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py index 54d4d65..af2c08e 100644 --- a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py @@ -23,7 +23,11 @@ class BaseCommandProcessor(base.CommandProcessor): def user_input(self, prompt): self._write(prompt) - return self._read().strip() + prompt_end_pos = self.prompt_end_pos + self.prompt_end_pos = len(prompt) - 1 + input = self._read().strip() + self.prompt_end_pos = prompt_end_pos + return input def do_quit(self, command, *args, context=None): raise exceptions.TerminalExitError() diff --git a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py index 1014024..47583e7 100644 --- a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py @@ -26,17 +26,13 @@ def do_disable(self, command, *args, context=None): raise exc def do_quit(self, command, *args, context=None): - hint = " Check whether system data has been changed. Please save data before logout.\n" - logout_checkt = "Are you sure to log out? (y/n)[n]:" - prompt_end_pos = self.prompt_end_pos - self.prompt_end_pos = len(logout_checkt) - answer = self.user_input(hint + logout_checkt) + self._write(" Check whether system data has been changed. Please save data before logout.\n") + answer = self.user_input("Are you sure to log out? (y/n)[n]:") if answer == "y": self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) exc = exceptions.TerminalExitError() exc.return_to = 'sysexit' raise exc - self.prompt_end_pos = prompt_end_pos return def on_unknown_command(self, command, *args, context=None): diff --git a/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py index b466f94..f0a6099 100644 --- a/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py @@ -36,17 +36,13 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_quit(self, command, *args, context=None): - hint = " Check whether system data has been changed. Please save data before logout.\n" - logout_checkt = "Are you sure to log out? (y/n)[n]:" - prompt_end_pos = self.prompt_end_pos - self.prompt_end_pos = len(logout_checkt) - answer = self.user_input(hint + logout_checkt) + self._write(" Check whether system data has been changed. Please save data before logout.\n") + answer = self.user_input("Are you sure to log out? (y/n)[n]:") if answer == "y": self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) exc = exceptions.TerminalExitError() exc.return_to = 'sysexit' raise exc - self.prompt_end_pos = prompt_end_pos return def on_help(self, command, args, context=None): From a3be6214f35d894358cecdf098d9c5867eb9c171 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 3 Sep 2020 13:43:30 +0200 Subject: [PATCH 002/318] Added standalone functionality for cli --- bootup/box.sh | 10 + bootup/conf/bootstraps/create-alcatel-7360.sh | 0 .../conf/bootstraps/create-box-port-vlan.sh | 0 bootup/conf/bootstraps/create-huawei-5623.sh | 0 .../bootstraps/create-vendors-and-models.sh | 0 bootup/conf/bootstraps/functions.sh | 0 bootup/conf/nesi.conf | 2 +- cli.py | 208 ++++++++++-------- nesi/softbox/api/__init__.py | 5 + nesi/softbox/api/config.py | 1 + 10 files changed, 133 insertions(+), 93 deletions(-) mode change 100644 => 100755 bootup/conf/bootstraps/create-alcatel-7360.sh mode change 100644 => 100755 bootup/conf/bootstraps/create-box-port-vlan.sh mode change 100644 => 100755 bootup/conf/bootstraps/create-huawei-5623.sh mode change 100644 => 100755 bootup/conf/bootstraps/create-vendors-and-models.sh mode change 100644 => 100755 bootup/conf/bootstraps/functions.sh diff --git a/bootup/box.sh b/bootup/box.sh index 96737eb..4f20ef9 100755 --- a/bootup/box.sh +++ b/bootup/box.sh @@ -17,6 +17,7 @@ Usage: $0 [options] --box-uuid Start a box instance in CLI mode --daemon Start a box instance in daemon mode (ssh or telnet socket) --debug Start a box with debug mode enabled + --standalone EOF ) @@ -24,6 +25,7 @@ uuid=0 list_boxen=false daemon=false debug=false +standalone=false POSITIONAL=() for arg in "$@" @@ -50,6 +52,10 @@ do list_boxen=true shift # past argument ;; + --standalone) + standalone=true + shift # past argument + ;; esac done @@ -65,6 +71,10 @@ elif [ "$uuid" != "" ]; then if $debug; then args="${args} --debug" fi + + if $standalone; then + args="${args} --standalone" + fi python3 ./cli.py --service-root http://127.0.0.1:5000/nesi/v1 --template-root templates/ --box-uuid $uuid $args fi diff --git a/bootup/conf/bootstraps/create-alcatel-7360.sh b/bootup/conf/bootstraps/create-alcatel-7360.sh old mode 100644 new mode 100755 diff --git a/bootup/conf/bootstraps/create-box-port-vlan.sh b/bootup/conf/bootstraps/create-box-port-vlan.sh old mode 100644 new mode 100755 diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh old mode 100644 new mode 100755 diff --git a/bootup/conf/bootstraps/create-vendors-and-models.sh b/bootup/conf/bootstraps/create-vendors-and-models.sh old mode 100644 new mode 100755 diff --git a/bootup/conf/bootstraps/functions.sh b/bootup/conf/bootstraps/functions.sh old mode 100644 new mode 100755 diff --git a/bootup/conf/nesi.conf b/bootup/conf/nesi.conf index d7eddda..248f448 100644 --- a/bootup/conf/nesi.conf +++ b/bootup/conf/nesi.conf @@ -18,7 +18,7 @@ SQLALCHEMY_DATABASE_URI = 'sqlite:////tmp/nesi-restapi.db' SQLALCHEMY_ECHO = False SECRET_KEY = '\xaf\x24\x5f\xa1@i\xd1>V\x70\xab\x8fb\x16#Z\x0b\x81\xeb\x16' -DEBUG = True +DEBUG = False NESI_LISTEN_IP = '127.0.0.1' NESI_LISTEN_PORT = 5000 diff --git a/cli.py b/cli.py index eb33370..5a41059 100644 --- a/cli.py +++ b/cli.py @@ -26,6 +26,13 @@ import pydevd_pycharm import pytest +import subprocess +from nesi.softbox.api import app +from nesi.softbox.api import db +from nesi.softbox.api.views import * # noqa +import pydevd_pycharm +import time + LOG = logging.getLogger(__name__) @@ -80,113 +87,130 @@ def main(): '--test', metavar='', type=str, help='Run CLI instance with test cases') + parser.add_argument( + '--standalone', action='store_true', + help='Run Cli without starting api') + args = parser.parse_args() - if args.debug: - pydevd_pycharm.settrace('localhost', port=3001, stdoutToServer=True, stderrToServer=True) - - if args.test == 'Alcatel': - pytest.main(['--pyargs', 'test_cases.unit_tests.alcatel', '-rA', '--disable-warnings']) - return - elif args.test == 'Huawei': - pytest.main(['--pyargs', 'test_cases.unit_tests.huawei', '-rA', '--disable-warnings']) - return - elif args.test == 'Edgecore': - pytest.main(['--pyargs', 'test_cases.unit_tests.edgecore', '-rA', '--disable-warnings']) - return - elif args.test == 'Keymile': - pytest.main(['--pyargs', 'test_cases.unit_tests.keymile', '-rA', '--disable-warnings']) - return - elif args.test == 'Pbn': - pytest.main(['--pyargs', 'test_cases.unit_tests.pbn', '-rA', '--disable-warnings']) - return - elif args.test == 'Zhone': - pytest.main(['--pyargs', 'test_cases.unit_tests.zhone', '-rA', '--disable-warnings']) - return - elif args.test is not None: - parser.error('--test has invalid argument') - return - - if not args.service_root: - parser.error('--service-root is required') - return - - service_root = urlparse(args.service_root) - prefix = os.path.dirname(service_root.path) - filename = os.path.basename(service_root.path) - - conn = rest_client.RestClient( - '%s://%s%s/' % (service_root.scheme, service_root.netloc, prefix), - verify=not args.insecure, - ) - - root_resource = root.Root(conn, path=filename) - - if args.list_boxen: - for model in root_resource.boxen(): - print('Vendor %s, model %s, version %s, uuid %s' % ( - model.vendor, model.model, model.version, model.uuid)) - return 0 - - if not args.box_uuid: - parser.error('--box-uuid is required') - return - - for model in root_resource.boxen(): - if model.uuid == args.box_uuid: - LOG.debug('Found requested box with UUID %s', model.uuid) - break - else: - parser.error('Requested box with UUID %s not found' % args.box_uuid) - return + if args.standalone: + config = os.path.abspath(os.getcwd()) + '/bootup/conf/nesi.conf' + subprocess.run(['python3', 'api.py', '--config', config, '--recreate-db']) + p = subprocess.Popen(['python3', 'api.py', '--config', config]) - try: - model = root_resource.get_box(base.get_member_identity(model.json), model.vendor) - main = importlib.import_module('vendors.' + model.vendor + '.' + model.model + '.' + model.vendor + '_' + model.model + '.main') - cli = main.PreLoginCommandProcessor + time.sleep(2) + os.system("./bootup/conf/bootstraps/create-vendors-and-models.sh") + os.system("./bootup/conf/bootstraps/create-alcatel-7360.sh") - except exceptions.ExtensionNotFoundError as exc: - parser.error(exc) - return + try: - if args.daemon: - if model.network_address is not None: - ip_address = model.network_address - else: - ip_address = args.ip_address + if args.debug: + pydevd_pycharm.settrace('localhost', port=3001, stdoutToServer=True, stderrToServer=True) - if model.network_port is not None: - port = model.network_port - else: - port = args.port + if args.test == 'Alcatel': + pytest.main(['--pyargs', 'test_cases.unit_tests.alcatel', '-rA', '--disable-warnings']) + return + elif args.test == 'Huawei': + pytest.main(['--pyargs', 'test_cases.unit_tests.huawei', '-rA', '--disable-warnings']) + return + elif args.test == 'Edgecore': + pytest.main(['--pyargs', 'test_cases.unit_tests.edgecore', '-rA', '--disable-warnings']) + return + elif args.test == 'Keymile': + pytest.main(['--pyargs', 'test_cases.unit_tests.keymile', '-rA', '--disable-warnings']) + return + elif args.test == 'Pbn': + pytest.main(['--pyargs', 'test_cases.unit_tests.pbn', '-rA', '--disable-warnings']) + return + elif args.test == 'Zhone': + pytest.main(['--pyargs', 'test_cases.unit_tests.zhone', '-rA', '--disable-warnings']) + return + elif args.test is not None: + parser.error('--test has invalid argument') + return - if port is None or ip_address is None: - parser.error('ip-address and port are required') + if not args.service_root: + parser.error('--service-root is required') return - if model.network_protocol == 'telnet': - telnet = TelnetSocket(cli, model, args.template_root, ip_address, int(port)) - telnet.start() - elif model.network_protocol == 'ssh': - ssh = None - # TODO: add ssh-socket daemon + service_root = urlparse(args.service_root) + prefix = os.path.dirname(service_root.path) + filename = os.path.basename(service_root.path) - else: - stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0) - stdout = os.fdopen(sys.stdout.fileno(), 'wb', 0) + conn = rest_client.RestClient( + '%s://%s%s/' % (service_root.scheme, service_root.netloc, prefix), + verify=not args.insecure, + ) - command_processor = cli( - model, stdin, stdout, (), template_root=args.template_root, daemon=False) + root_resource = root.Root(conn, path=filename) + if args.list_boxen: + for model in root_resource.boxen(): + print('Vendor %s, model %s, version %s, uuid %s' % ( + model.vendor, model.model, model.version, model.uuid)) + return 0 + if not args.box_uuid: + parser.error('--box-uuid is required') + return + + for model in root_resource.boxen(): + if model.uuid == args.box_uuid: + LOG.debug('Found requested box with UUID %s', model.uuid) + break + else: + parser.error('Requested box with UUID %s not found' % args.box_uuid) + return try: - context = dict() - context['login_banner'] = model.login_banner - command_processor.loop(context=context) - except exceptions.TerminalExitError as exc: - if exc.return_to is not None and exc.return_to != 'sysexit': - raise exc + model = root_resource.get_box(base.get_member_identity(model.json), model.vendor) + main = importlib.import_module('vendors.' + model.vendor + '.' + model.model + '.' + model.vendor + '_' + model.model + '.main') + cli = main.PreLoginCommandProcessor + + except exceptions.ExtensionNotFoundError as exc: + parser.error(exc) + return + + if args.daemon: + if model.network_address is not None: + ip_address = model.network_address + else: + ip_address = args.ip_address + + if model.network_port is not None: + port = model.network_port + else: + port = args.port + + if port is None or ip_address is None: + parser.error('ip-address and port are required') + return + + if model.network_protocol == 'telnet': + telnet = TelnetSocket(cli, model, args.template_root, ip_address, int(port)) + telnet.start() + elif model.network_protocol == 'ssh': + ssh = None + # TODO: add ssh-socket daemon + + else: + stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0) + stdout = os.fdopen(sys.stdout.fileno(), 'wb', 0) + + command_processor = cli( + model, stdin, stdout, (), template_root=args.template_root, daemon=False) + + try: + context = dict() + context['login_banner'] = model.login_banner + command_processor.loop(context=context) + except exceptions.TerminalExitError as exc: + if exc.return_to is not None and exc.return_to != 'sysexit': + raise exc + finally: + if args.standalone: + p.terminate() + p.kill() if __name__ == '__main__': diff --git a/nesi/softbox/api/__init__.py b/nesi/softbox/api/__init__.py index 8a0ce2c..e54045c 100644 --- a/nesi/softbox/api/__init__.py +++ b/nesi/softbox/api/__init__.py @@ -15,12 +15,17 @@ from flask import Flask from flask_marshmallow import Marshmallow from flask_sqlalchemy import SQLAlchemy +import logging from nesi.softbox.api import config app = Flask(__name__) +log = logging.getLogger('werkzeug') +log.disabled = False +app.logger.disabled = False + app.url_map.strict_slashes = False app.config.from_object(config.DefaultConfig) diff --git a/nesi/softbox/api/config.py b/nesi/softbox/api/config.py index bcf6e3f..33c5255 100644 --- a/nesi/softbox/api/config.py +++ b/nesi/softbox/api/config.py @@ -13,6 +13,7 @@ class DefaultConfig(object): SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory' + SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_ECHO = False DEBUG = False From 9e37590b089510d2d9ebfe9019d5519ffc7638ab Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 3 Sep 2020 15:24:51 +0200 Subject: [PATCH 003/318] Added simulated backup + trafficvlan functionality --- .../huawei/api/schemas/huawei_port_schemas.py | 2 +- nesi/huawei/huawei_resources/huawei_port.py | 4 +++ nesi/softbox/api/models/port_models.py | 1 + .../Huawei_Base/configCommandProcessor.py | 30 +++++++------------ 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/nesi/huawei/api/schemas/huawei_port_schemas.py b/nesi/huawei/api/schemas/huawei_port_schemas.py index fbb11cf..202c202 100644 --- a/nesi/huawei/api/schemas/huawei_port_schemas.py +++ b/nesi/huawei/api/schemas/huawei_port_schemas.py @@ -75,4 +75,4 @@ class Meta: 'auto_sensing', 'alm_prof_15_min', 'warn_prof_15_min', 'alm_prof_24_hour', 'warn_prof_24_hour', 'optic_status', 'combo_status', 'temperature_h_exact', 'supply_voltage_h_exact', 'tx_bias_current_h_exact', 'tx_power_h_exact', - 'rx_power_h_exact', 'rx_power_h') + 'rx_power_h_exact', 'vlan_id', 'rx_power_h') diff --git a/nesi/huawei/huawei_resources/huawei_port.py b/nesi/huawei/huawei_resources/huawei_port.py index 693dd41..4fedbf7 100644 --- a/nesi/huawei/huawei_resources/huawei_port.py +++ b/nesi/huawei/huawei_resources/huawei_port.py @@ -205,6 +205,7 @@ class HuaweiPort(Port): tx_power_h_exact = base.Field('tx_power_h_exact') rx_power_h_exact = base.Field('rx_power_h_exact') rx_power_h = base.Field('rx_power_h') + vlan_id = base.Field('vlan_id') def admin_up(self): """Set the admin port state to up""" @@ -228,6 +229,9 @@ def port_downstream_set(self, ds_rate): def port_upstream_set(self, us_rate): self.update(upstream_max=us_rate) + def set_vlan_id(self, id): + self.update(vlan_id=id) + class HuaweiPortCollection(PortCollection): """Represent a collection of ports.""" diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 114fb79..94b83bc 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -303,3 +303,4 @@ class Port(db.Model): alm_prof_24_hour = db.Column(db.String(), default='-') warn_prof_24_hour = db.Column(db.String(), default='-') combo_status = db.Column(db.Enum('-', 'optic', 'electric'), default='optic') + vlan_id = db.Column(db.Integer()) diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index e50f3cb..47a3fe3 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -12,6 +12,7 @@ import random import datetime import re +import time from nesi import exceptions from .huaweiBaseCommandProcessor import HuaweiBaseCommandProcessor @@ -48,6 +49,14 @@ def on_unknown_command(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_backup(self, command, *args, context=None): + if self._validate(args, 'configuration', 'tftp', str, str): + ip, path = self._dissect(args, 'configuration', 'tftp', str, str) + time.sleep(5) + return + else: + raise exceptions.CommandSyntaxError(command=command) + def do_interface(self, command, *args, context=None): from .interfaceCommandProcessor import InterfaceCommandProcessor @@ -856,26 +865,7 @@ def do_port(self, command, *args, context=None): except (exceptions.SoftboxenError, AssertionError): raise exceptions.CommandSyntaxError(command=command) - try: # Check if s_port exists - service_port = self._model.get_service_port("name", portident) - except exceptions.SoftboxenError: - self._model.add_service_port(name=portident, connected_id=port.id, connected_type='port', - bytes_us=port.total_bytes_us, packets_us=port.total_packets_us, - bytes_ds=port.total_bytes_ds, packets_ds=port.total_packets_ds) - try: - service_port = self._model.get_service_port("name", portident) - except (exceptions.SoftboxenError, AssertionError): - raise exceptions.CommandSyntaxError(command=command) - - params = dict(name=str(vlan.number), service_port_id=service_port.id) - service_vlan = self._model.get_service_vlan_by_values(params) - if service_vlan is None: - self._model.add_service_vlan(name=vlan.number, vlan_id=vlan.id, service_port_id=service_port.id) - try: - service_vlan = self._model.get_service_vlan_by_values(params) - except (exceptions.SoftboxenError, AssertionError): - raise exceptions.CommandSyntaxError(command=command) - + port.set_vlan_id(vlan.id) else: raise exceptions.CommandSyntaxError(command=command) From 63fefecc23676d75b7ad78674e351e407030bc44 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 4 Sep 2020 13:21:24 +0200 Subject: [PATCH 004/318] Added user management --- bootup/conf/bootstraps/create-alcatel-7360.sh | 10 +- bootup/conf/bootstraps/create-huawei-5623.sh | 20 ++- .../sockets/__pycache__/telnet.cpython-38.pyc | Bin 0 -> 2303 bytes nesi/alcatel/alcatel_resources/alcatel_box.py | 8 ++ .../huawei/api/schemas/huawei_user_schemas.py | 8 ++ nesi/huawei/huawei_resources/__init__.py | 2 +- nesi/huawei/huawei_resources/huawei_box.py | 41 ++++++ nesi/huawei/huawei_resources/huawei_user.py | 50 +++++++ nesi/huawei/huawei_resources/huawei_vlan.py | 5 +- nesi/softbox/api/models/box_models.py | 2 + nesi/softbox/api/models/credential_models.py | 1 - nesi/softbox/api/models/user_models.py | 28 ++++ nesi/softbox/api/schemas/box_schemas.py | 17 ++- nesi/softbox/api/schemas/user_schemas.py | 47 ++++++ nesi/softbox/api/views/__init__.py | 2 +- nesi/softbox/api/views/box_views.py | 7 +- nesi/softbox/api/views/user_views.py | 53 +++++++ nesi/softbox/base_resources/box.py | 4 + nesi/softbox/base_resources/credentials.py | 1 + nesi/softbox/base_resources/user.py | 33 +++++ templates/Huawei/5623/A/login/user_locked.j2 | 4 + .../display_terminal_user_all_bottom.j2 | 3 + .../display_terminal_user_all_middle.j2 | 2 + .../config/display_terminal_user_all_top.j2 | 5 + .../enable/config/user_already_exists.j2 | 2 + .../enable/config/user_already_unlocked.j2 | 4 + .../mainloop/enable/config/user_created.j2 | 2 + .../mainloop/enable/config/user_level.j2 | 2 + .../display_terminal_user_all_bottom.j2 | 3 + .../display_terminal_user_all_middle.j2 | 2 + .../enable/display_terminal_user_all_top.j2 | 5 + .../Alcatel_Base/userViewCommandProcessor.py | 1 + vendors/Huawei/5623/Huawei_5623/main.py | 35 ++++- vendors/Huawei/Base/Huawei_Base/baseMixIn.py | 9 ++ .../Huawei_Base/configCommandProcessor.py | 135 +++++++++++++++--- .../Huawei_Base/diagnoseCommandProcessor.py | 6 +- .../Huawei_Base/enableCommandProcessor.py | 12 +- .../Huawei_Base/huaweiBaseCommandProcessor.py | 36 +++++ .../Huawei_Base/userViewCommandProcessor.py | 2 + 39 files changed, 567 insertions(+), 42 deletions(-) create mode 100644 bootup/sockets/__pycache__/telnet.cpython-38.pyc create mode 100644 nesi/huawei/api/schemas/huawei_user_schemas.py create mode 100644 nesi/huawei/huawei_resources/huawei_user.py create mode 100644 nesi/softbox/api/models/user_models.py create mode 100644 nesi/softbox/api/schemas/user_schemas.py create mode 100644 nesi/softbox/api/views/user_views.py create mode 100644 nesi/softbox/base_resources/user.py create mode 100644 templates/Huawei/5623/A/login/user_locked.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/user_already_exists.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/user_already_unlocked.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/user_created.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/user_level.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_top.j2 diff --git a/bootup/conf/bootstraps/create-alcatel-7360.sh b/bootup/conf/bootstraps/create-alcatel-7360.sh index 94832e0..3fc88a3 100755 --- a/bootup/conf/bootstraps/create-alcatel-7360.sh +++ b/bootup/conf/bootstraps/create-alcatel-7360.sh @@ -107,7 +107,15 @@ req='{ "password": "secret" }' -credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) +admin_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# Admin user +req='{ + "name": "admin", + "credentials_id": '$admin_credential_id' +}' + +admin_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) # PortProfile 1 req='{ diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index be01f26..f64e34a 100755 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -36,13 +36,27 @@ req='{ box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 -# Create login credentials at the switch (admin operation) +# Super Admin credentials req='{ - "username": "admin", + "username": "root", "password": "secret" }' -credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) +root_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# Super Admin user +req='{ + "name": "root", + "credentials_id": '$root_credential_id', + "level": "Super", + "profile": "root", + "append_info": "Super Admin", + "reenter_num": 3, + "reenter_num_temp": 3, + "lock_status": "Unlocked" +}' + +root_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) # PortProfile 1 req='{ diff --git a/bootup/sockets/__pycache__/telnet.cpython-38.pyc b/bootup/sockets/__pycache__/telnet.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..678e8f43c2163a8eb29ede6ea2c9301b344c5dd0 GIT binary patch literal 2303 zcmZuyOK%)S5bmD0*Sn4%Bqkw%6(vF=kQZ`5A_~YMG6(@132y|fkcP>0C!Wph%%-Ou zlGWzqNSyK?*2nx8P8|EnDSsgc#8*9DVmsTTuBm=iRabpgeYewTF*NtjJIVDW#{Qwf z$>w6PgI;fg2qt*J2F;%jIL1!ljNF0C*|$u%!h6nycjyc}!S`6~zrq>Ti@9mZCz%}U zyejLA=1w*bgB^6MK{Ap$a0D05b2f0_NR{5uKXeCy@I`=?P=wGBnRZ_mrPO;>_E739 zI3bvLl6{+G{|++srYvDoACylys55my-Kh)eX@BNxe;A;LM>HQz*)W-Ma3MBIvCu*T`VB8Blev%Fu`Iu%06x;EapQrfs#ksE(h30atqmZNcz zYMH32(k7^_^(MUaP4ZoDw{MpB?%e)9+3Wwbd+SHTA>m$L3KJB0tz~IKNRp+l&63_% zG8K9Gz<57Egz*Z{I51uO6k0zv$krrK-E*{k+J>535q8 zdcQkK&(FMt00+l+(Cbe?&LW^e6%f_L-4~&V5dT0d!Q-vT#wiuYFrX;R8}S5U3xg|Q zG#m060&GJ{FmNplJPQM#0{N2n;y|rouL=6r#cC4+MVVs4d02zS9kHkA{&rDaBJMpR zNunrhM1|7rcOk zpIO=Wm|hv4d)QKcacHpGS7&R-+QKv1;AvX1dfeIi+ZO)HO6M086iVjaWc6Bo<66Cy zRb?qNEycEVVLx^(giRn)IjTz2E~*E4ncPdUO`*JmIH2VdJ=ti^i@bg#BHm~svH`Cl zdfB6cTuHS`qaYoRB{C~ivXE&ljXzd-shcpKP9NimJk#oZI)*f>#)?pD*7{P7@-i)U zpX7R1sY*2{@w1|WygheKBd^<@V9i&CG(xiP1k?Lb2 z^ah?#Yu!QVZGxuodGxOw literal 0 HcmV?d00001 diff --git a/nesi/alcatel/alcatel_resources/alcatel_box.py b/nesi/alcatel/alcatel_resources/alcatel_box.py index 3c9d9b4..25facc8 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_box.py +++ b/nesi/alcatel/alcatel_resources/alcatel_box.py @@ -14,6 +14,7 @@ from nesi.alcatel.alcatel_resources import * import logging from nesi.softbox.base_resources import credentials +from nesi.softbox.base_resources import user from nesi.softbox.base_resources import route from nesi.softbox.base_resources.box import Box, BoxCollection, base, os @@ -64,6 +65,13 @@ def credentials(self): self._conn, base.get_sub_resource_path_by( self, 'credentials')) + @property + def users(self): + """Return `UserCollection` object.""" + return user.UserCollection( + self._conn, base.get_sub_resource_path_by( + self, 'users')) + @property def routes(self): """Return `RouteCollection` object.""" diff --git a/nesi/huawei/api/schemas/huawei_user_schemas.py b/nesi/huawei/api/schemas/huawei_user_schemas.py new file mode 100644 index 0000000..2ab3e86 --- /dev/null +++ b/nesi/huawei/api/schemas/huawei_user_schemas.py @@ -0,0 +1,8 @@ +from nesi.softbox.api.schemas.user_schemas import * + + +class HuaweiUserSchema(UserSchema): + class Meta: + model = User + fields = UserSchema.Meta.fields + ('level', 'status', 'profile', 'append_info', 'reenter_num', + 'reenter_num_temp', 'lock_status') diff --git a/nesi/huawei/huawei_resources/__init__.py b/nesi/huawei/huawei_resources/__init__.py index c2fdaaf..59961a2 100644 --- a/nesi/huawei/huawei_resources/__init__.py +++ b/nesi/huawei/huawei_resources/__init__.py @@ -1,3 +1,3 @@ __all__ = ["huawei_card", "huawei_vlan", "huawei_port_profile", "huawei_cpe_port", "huawei_cpe", "huawei_emu", "huawei_ont_port", "huawei_ont", "huawei_port", "huawei_subrack", "huawei_service_port", - "huawei_service_vlan", "huawei_vlan_interface", "huawei_route"] + "huawei_service_vlan", "huawei_vlan_interface", "huawei_route", "huawei_user"] diff --git a/nesi/huawei/huawei_resources/huawei_box.py b/nesi/huawei/huawei_resources/huawei_box.py index 10690dd..a4d5825 100644 --- a/nesi/huawei/huawei_resources/huawei_box.py +++ b/nesi/huawei/huawei_resources/huawei_box.py @@ -35,6 +35,13 @@ def credentials(self): self._conn, base.get_sub_resource_path_by( self, 'credentials')) + @property + def users(self): + """Return `UserCollection` object.""" + return huawei_user.HuaweiUserCollection( + self._conn, base.get_sub_resource_path_by( + self, 'users')) + @property def routes(self): """Return `RouteCollection` object.""" @@ -118,6 +125,24 @@ def vlan_interfaces(self): """Return `VlanInterfaceCollection` object.""" return huawei_vlan_interface.HuaweiVlanInterfaceCollection( self._conn, base.get_sub_resource_path_by(self, 'vlan_interfaces')) + + def get_user(self, field, value): + """Get specific user object.""" + return huawei_user.HuaweiUserCollection( + self._conn, base.get_sub_resource_path_by(self, 'users'), + params={field: value}).find_by_field_value(field, value) + + def get_users(self, field, value): + """Get specific user objects.""" + return huawei_user.HuaweiUserCollection( + self._conn, base.get_sub_resource_path_by(self, 'users'), + params={field: value}) + + def get_credentials(self, field, value): + """Get specific user object.""" + return credentials.CredentialsCollection( + self._conn, base.get_sub_resource_path_by(self, 'credentials'), + params={field: value}).find_by_field_value(field, value) def get_subrack(self, field, value): """Get specific subrack object.""" @@ -272,6 +297,22 @@ def get_service_vlan_by_values(self, params=None): else: return None + def add_credentials(self, **fields): + """Add a new pair of credentials""" + return credentials.Credentials.create( + self._conn, + os.path.join(self.path, 'credentials'), + **fields + ) + + def add_user(self, **fields): + """Add a new user""" + return huawei_user.HuaweiUser.create( + self._conn, + os.path.join(self.path, 'users'), + **fields + ) + def add_vlan(self, **fields): """Add new vlan.""" huawei_vlan.HuaweiVlan.create( diff --git a/nesi/huawei/huawei_resources/huawei_user.py b/nesi/huawei/huawei_resources/huawei_user.py new file mode 100644 index 0000000..e0af311 --- /dev/null +++ b/nesi/huawei/huawei_resources/huawei_user.py @@ -0,0 +1,50 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.user import User, UserCollection, base, logging + +LOG = logging.getLogger(__name__) + + +class HuaweiUser(User): + """Represents a logical User resource""" + + level = base.Field('level') + status = base.Field('status') + profile = base.Field('profile') + append_info = base.Field('append_info') + reenter_num = base.Field('reenter_num') + reenter_num_temp = base.Field('reenter_num_temp') + lock_status = base.Field('lock_status') + + def set_online(self): + self.update(status='Online') + + def set_offline(self): + self.update(status='Offline') + + def lock(self): + self.update(lock_status='Locked') + + def unlock(self): + self.update(lock_status='Unlocked') + + def set_reenter_num_temp(self, num): + self.update(reenter_num_temp=num) + + +class HuaweiUserCollection(UserCollection): + """Represent the collection of Users.""" + + @property + def _resource_type(self): + return HuaweiUser diff --git a/nesi/huawei/huawei_resources/huawei_vlan.py b/nesi/huawei/huawei_resources/huawei_vlan.py index a252251..d243442 100644 --- a/nesi/huawei/huawei_resources/huawei_vlan.py +++ b/nesi/huawei/huawei_resources/huawei_vlan.py @@ -42,14 +42,15 @@ def set_tag(self, tag): """Set the tag to given value.""" self.update(tag=tag) - def set_type(self, type): - """Change thetype""" + def set_type_smart(self): + """Change the type to smart""" self.update(type="smart") def set_service_profile_id(self, id): """Set service profile_id""" self.update(bind_service_profile_id=id) + class HuaweiVlanCollection(VlanCollection): """Represent the collection of VLANs.""" diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 2c8c29f..2ed16e5 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -26,6 +26,7 @@ from .vlan_interface_models import VlanInterface from .route_models import Route from .emu_models import Emu +from .user_models import User class Box(db.Model): @@ -50,6 +51,7 @@ class Box(db.Model): welcome_banner = db.Column(db.String, default="") credentials = db.relationship('Credential', backref='Box', lazy='dynamic') credential_details = db.relationship('Credential', backref='credentials', lazy='dynamic') + users = db.relationship('User', backref='Box', lazy='dynamic') subracks = db.relationship('Subrack', backref='Box', lazy='dynamic') subrack_details = db.relationship('Subrack', backref='subracks', lazy='dynamic') cards = db.relationship('Card', backref='Box', lazy='dynamic') diff --git a/nesi/softbox/api/models/credential_models.py b/nesi/softbox/api/models/credential_models.py index f65c7d8..7271d64 100644 --- a/nesi/softbox/api/models/credential_models.py +++ b/nesi/softbox/api/models/credential_models.py @@ -9,7 +9,6 @@ # - Alexander Dincher # # License: https://github.com/inexio/NESi/LICENSE.rst -import uuid from nesi.softbox.api import db diff --git a/nesi/softbox/api/models/user_models.py b/nesi/softbox/api/models/user_models.py new file mode 100644 index 0000000..2add0be --- /dev/null +++ b/nesi/softbox/api/models/user_models.py @@ -0,0 +1,28 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + + +from nesi.softbox.api import db + + +class User(db.Model): + id = db.Column(db.Integer(), primary_key=True) + box_id = db.Column(db.Integer(), db.ForeignKey('box.id')) + credentials_id = db.Column(db.Integer(), db.ForeignKey('credential.id')) + name = db.Column(db.String(), default='user') + level = db.Column(db.Enum('Super', 'Admin', 'Operator', 'User'), default='User') + status = db.Column(db.Enum('Online', 'Offline'), default='Offline') + profile = db.Column(db.Enum('root', 'admin', 'operator', 'commonuser'), default='commonuser') + append_info = db.Column(db.String(), default='-----') + reenter_num = db.Column(db.Integer(), default=3) + reenter_num_temp = db.Column(db.Integer(), default=3) + lock_status = db.Column(db.Enum('Locked', 'Unlocked'), default='Unlocked') diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index 85b1a80..af4a27b 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -29,9 +29,12 @@ class Meta: class BoxSchema(ma.ModelSchema): class Meta: model = Box - fields = ('id', 'vendor', 'model', 'version', 'software_version', 'network_protocol', 'network_address', 'network_port', 'uuid', 'description', - 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', - 'subracks', 'subrack_details', 'cards', 'ports', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', 'cpe_ports', 'routes', 'login_banner', + fields = ('id', 'vendor', 'model', 'version', 'software_version', 'network_protocol', 'network_address', + 'network_port', 'uuid', 'description', + 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', + 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', + 'subracks', 'subrack_details', 'cards', 'ports', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', + 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') credentials = ma.Hyperlinks( @@ -40,6 +43,10 @@ class Meta: credential_details = ma.Nested(CredentialsSchema.CredentialSchema, many=True) + users = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_users', box_id='')}}) + subracks = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_subracks', box_id='')}}) @@ -90,6 +97,10 @@ class Meta: vlan_details = ma.Nested(VlansSchema.VlanSchema, many=True) + vlan_interfaces = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_vlan_interfaces', box_id='')}}) + routes = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_routes', box_id='')}}) diff --git a/nesi/softbox/api/schemas/user_schemas.py b/nesi/softbox/api/schemas/user_schemas.py new file mode 100644 index 0000000..f2f93e5 --- /dev/null +++ b/nesi/softbox/api/schemas/user_schemas.py @@ -0,0 +1,47 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.user_models import User + + +class UserSchema(ma.ModelSchema): + class Meta: + model = User + fields = ('id', 'box', 'credentials_id', 'name', '_links') + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_user', box_id='', id=''), + 'collection': ma.URLFor('show_users', box_id='')}) + + +class UsersSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class UserSchema(ma.ModelSchema): + class Meta: + model = User + fields = ('id', 'name', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_user', box_id='', id='')}) + + members = ma.Nested(UserSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_users', box_id='')}) diff --git a/nesi/softbox/api/views/__init__.py b/nesi/softbox/api/views/__init__.py index d96b6aa..c37245d 100644 --- a/nesi/softbox/api/views/__init__.py +++ b/nesi/softbox/api/views/__init__.py @@ -1,4 +1,4 @@ __all__ = ["box_views", "credential_views", "route_views", "subrack_views", "card_views", "port_views", "ont_views", "ontport_views", "cpe_views", "cpeport_views", "vlan_views", "portprofile_views", "emu_views", "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", - "qos_interface_views", "vlan_interface_views"] + "qos_interface_views", "vlan_interface_views", "user_views"] diff --git a/nesi/softbox/api/views/box_views.py b/nesi/softbox/api/views/box_views.py index 3a9d5d0..a08b6b9 100644 --- a/nesi/softbox/api/views/box_views.py +++ b/nesi/softbox/api/views/box_views.py @@ -94,7 +94,8 @@ def new_box(): box_data = req.copy() # Additional components have to be wiped from box_data as a box can otherwise not be created - components = ('credentials', 'subracks', 'cards', 'ports', 'onts', 'ont_ports', 'cpes', 'cpe_ports', 'vlans', 'port_profiles', 'routes') + components = ('credentials', 'subracks', 'cards', 'ports', 'onts', 'ont_ports', 'cpes', 'cpe_ports', 'vlans', + 'port_profiles', 'routes') for component in components: if component in req: del box_data[component] @@ -246,6 +247,10 @@ def del_sub_components(component_collection): del_sub_components(box.vlans) del_sub_components(box.port_profiles) del_sub_components(box.routes) + del_sub_components(box.vlan_interfaces) + del_sub_components(box.emus) + del_sub_components(box.qos_interfaces) + del_sub_components(box.users) db.session.delete(box) db.session.commit() diff --git a/nesi/softbox/api/views/user_views.py b/nesi/softbox/api/views/user_views.py new file mode 100644 index 0000000..a71b67e --- /dev/null +++ b/nesi/softbox/api/views/user_views.py @@ -0,0 +1,53 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from ..schemas.user_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//users', methods=['GET']) +def show_users(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(UsersSchema(), User, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//users/', methods=['GET']) +def show_user(box_id, id): + response = show_component(User, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//users', methods=['POST']) +def new_user(box_id): + req = flask.request.json + response = new_component(UserSchema(), User, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//users/', methods=['PUT']) +def update_user(box_id, id): + req = flask.request.json + update_component(User, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//users/', methods=['DELETE']) +def del_user(box_id, id): + del_component(User, box_id, id) + return flask.Response(status=204) diff --git a/nesi/softbox/base_resources/box.py b/nesi/softbox/base_resources/box.py index d04b216..8815617 100644 --- a/nesi/softbox/base_resources/box.py +++ b/nesi/softbox/base_resources/box.py @@ -93,6 +93,10 @@ def set_sntp_server_ip_address(self, address): def credentials(self): raise PropertyNotFoundError("abstract credentials properties") + @property + def users(self): + raise PropertyNotFoundError("abstract users properties") + @property def routes(self): raise PropertyNotFoundError("abstract routes properties") diff --git a/nesi/softbox/base_resources/credentials.py b/nesi/softbox/base_resources/credentials.py index 2139d0f..a441972 100644 --- a/nesi/softbox/base_resources/credentials.py +++ b/nesi/softbox/base_resources/credentials.py @@ -20,6 +20,7 @@ class Credentials(base.Resource): """Represent user credentials.""" + id = base.Field('id') protocol = base.Field('protocol') username = base.Field('username') password = base.Field('password') diff --git a/nesi/softbox/base_resources/user.py b/nesi/softbox/base_resources/user.py new file mode 100644 index 0000000..2272dc0 --- /dev/null +++ b/nesi/softbox/base_resources/user.py @@ -0,0 +1,33 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import logging +from nesi.softbox import base + +LOG = logging.getLogger(__name__) + + +class User(base.Resource): + """Represents a logical User resource""" + + id = base.Field('id') + credentials_id = base.Field('credentials_id') + name = base.Field('name') + + +class UserCollection(base.ResourceCollection): + """Represent the collection of Users.""" + + @property + def _resource_type(self): + return User + diff --git a/templates/Huawei/5623/A/login/user_locked.j2 b/templates/Huawei/5623/A/login/user_locked.j2 new file mode 100644 index 0000000..3b90316 --- /dev/null +++ b/templates/Huawei/5623/A/login/user_locked.j2 @@ -0,0 +1,4 @@ + This user has been locked. Please ask an administrator to unlock it for you. + + + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_bottom.j2 new file mode 100644 index 0000000..6df62d4 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_bottom.j2 @@ -0,0 +1,3 @@ + ---------------------------------------------------------------------------- + Total record(s) number: {{ context.user_counter }} + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_middle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_middle.j2 new file mode 100644 index 0000000..a10cfae --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_middle.j2 @@ -0,0 +1,2 @@ + {{ context.user.name }}{{ context.spacer1 }}{{ context.user.level }}{{ context.spacer2 }}{{ context.user.status }}{{ context.spacer3 }}{{ context.user.reenter_num }}{{ context.spacer4 }}{{ context.user.profile }}{{ context.spacer5 }}{{ context.user.append_info }} + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_top.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_top.j2 new file mode 100644 index 0000000..5846900 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_top.j2 @@ -0,0 +1,5 @@ + ---------------------------------------------------------------------------- + Name Level Status Reenter Profile Append + Num Info + ---------------------------------------------------------------------------- + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/user_already_exists.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/user_already_exists.j2 new file mode 100644 index 0000000..b592014 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/user_already_exists.j2 @@ -0,0 +1,2 @@ + User {{ context.user_name }} already exists. + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/user_already_unlocked.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/user_already_unlocked.j2 new file mode 100644 index 0000000..328e191 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/user_already_unlocked.j2 @@ -0,0 +1,4 @@ + This user has been unlocked already. + + + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/user_created.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/user_created.j2 new file mode 100644 index 0000000..d7a0d62 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/user_created.j2 @@ -0,0 +1,2 @@ + User has been created successfully + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/user_level.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/user_level.j2 new file mode 100644 index 0000000..fa43e0e --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/user_level.j2 @@ -0,0 +1,2 @@ + User's Level: + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_bottom.j2 new file mode 100644 index 0000000..6df62d4 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_bottom.j2 @@ -0,0 +1,3 @@ + ---------------------------------------------------------------------------- + Total record(s) number: {{ context.user_counter }} + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_middle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_middle.j2 new file mode 100644 index 0000000..a10cfae --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_middle.j2 @@ -0,0 +1,2 @@ + {{ context.user.name }}{{ context.spacer1 }}{{ context.user.level }}{{ context.spacer2 }}{{ context.user.status }}{{ context.spacer3 }}{{ context.user.reenter_num }}{{ context.spacer4 }}{{ context.user.profile }}{{ context.spacer5 }}{{ context.user.append_info }} + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_top.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_top.j2 new file mode 100644 index 0000000..5846900 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_top.j2 @@ -0,0 +1,5 @@ + ---------------------------------------------------------------------------- + Name Level Status Reenter Profile Append + Num Info + ---------------------------------------------------------------------------- + diff --git a/vendors/Alcatel/Base/Alcatel_Base/userViewCommandProcessor.py b/vendors/Alcatel/Base/Alcatel_Base/userViewCommandProcessor.py index 15f49db..6b6de27 100644 --- a/vendors/Alcatel/Base/Alcatel_Base/userViewCommandProcessor.py +++ b/vendors/Alcatel/Base/Alcatel_Base/userViewCommandProcessor.py @@ -14,6 +14,7 @@ from .baseCommandProcessor import BaseCommandProcessor from.baseMixIn import BaseMixIn + class UserViewCommandProcessor(BaseCommandProcessor, BaseMixIn): def on_unknown_command(self, command, *args, context=None): diff --git a/vendors/Huawei/5623/Huawei_5623/main.py b/vendors/Huawei/5623/Huawei_5623/main.py index fd3562e..4b39ef7 100644 --- a/vendors/Huawei/5623/Huawei_5623/main.py +++ b/vendors/Huawei/5623/Huawei_5623/main.py @@ -50,12 +50,41 @@ def on_unknown_command(self, command, *args, context=None): for creds in self._model.credentials: if creds.username == username and creds.password == password: + user = self._model.get_user('credentials_id', creds.id) + if user.lock_status == 'Locked': + text = self._render('user_locked', context=context) + self._write(text) + raise exceptions.TerminalExitError() + num = user.reenter_num + user.set_reenter_num_temp(num) + user.set_online() break else: - text = self._render('password', context=context) - self._write(text) - raise exceptions.TerminalExitError() + try: + user = self._model.get_user('name', username) + except exceptions.SoftboxenError: + text = self._render('password', context=context) + self._write(text) + raise exceptions.TerminalExitError() + else: + if user.reenter_num_temp < 0: + if user.level == 'Admin': + user.set_reenter_num_temp(user.reenter_num) + text = self._render('password', context=context) + self._write(text) + raise exceptions.TerminalExitError() + else: + user.lock() + text = self._render('user_locked', context=context) + self._write(text) + raise exceptions.TerminalExitError() + else: + num = user.reenter_num_temp - 1 + user.set_reenter_num_temp(num) + text = self._render('password', context=context) + self._write(text) + raise exceptions.TerminalExitError() self._output.write(bytes(False)) self._output.write(bytes(False)) diff --git a/vendors/Huawei/Base/Huawei_Base/baseMixIn.py b/vendors/Huawei/Base/Huawei_Base/baseMixIn.py index 9450174..2c80975 100644 --- a/vendors/Huawei/Base/Huawei_Base/baseMixIn.py +++ b/vendors/Huawei/Base/Huawei_Base/baseMixIn.py @@ -10,6 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst +from nesi import exceptions + class BaseMixIn: @@ -30,6 +32,13 @@ def do_config(self, command, *args, context=None): from .enableCommandProcessor import EnableCommandProcessor from .configCommandProcessor import ConfigCommandProcessor + + try: + admin = self._model.get_user('status', 'Online') + assert admin.level != 'User' + except (exceptions.SoftboxenError, AssertionError): + raise exceptions.CommandSyntaxError(command=command) + if args.__contains__('?'): text = self._render('?', context=context) self._write(text) diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 47a3fe3..8ad0ee5 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -317,6 +317,9 @@ def generate_ont_info_summary(port): text = self._render('display_emu_id', context=dict(context, emu=emu)) self._write(text) + elif self._validate(args, 'terminal', 'user', 'all'): + self.display_terminal_user(command, context) + else: raise exceptions.CommandSyntaxError(command=command) @@ -832,26 +835,97 @@ def do_system(self, command, *args, context=None): # TODO: Functionality else: raise exceptions.CommandSyntaxError(command=command) - def do_terminal(self, command, *args, context=None): # TODO: Functionality + def do_terminal(self, command, *args, context=None): # TODO: create user + credentials if self._validate(args, 'user', 'name'): - _ = self.user_input("Login: ") - _ = self.user_input("Password: ") - _ = self.user_input("Repeat Password: ") - root = self.user_input("root: ") - if root != 'root': - raise exceptions.InvalidInputError - var3 = self.user_input("3: ") - if var3 != '3': - raise exceptions.InvalidInputError - var4 = self.user_input("4: ") - if var4 != '4': - raise exceptions.InvalidInputError - enter = self.user_input("enter: ") - if enter != '': - raise exceptions.InvalidInputError - var_n = self.user_input("n: ") - if var_n != 'n': - raise exceptions.InvalidInputError + login = self.user_input(" User Name(length<6,15>):") + + try: + usr = self._model.get_user('name', login) + except exceptions.SoftboxenError: + pass + else: + context['user_name'] = login + text = self._render('user_already_exists', context=context) + self._write(text) + return + if (len(login) < 6) or (len(login) > 15): + raise exceptions.CommandSyntaxError(command=command) + + password = self.user_input(" User Password(length<6,15>):") + password_repeat = self.user_input(" Confirm Password(length<6,15>):") + if (len(password) < 6) or (len(password) > 15) or (len(password_repeat) < 6) or (len(password_repeat) > 15)\ + or (password != password_repeat): + raise exceptions.CommandSyntaxError(command=command) + + profile = self.user_input(" User profile name(<=15 chars)[root]:") + if (profile != 'root') and (profile != 'admin') and (profile != 'operator') and (profile != 'commonuser'): + raise exceptions.CommandSyntaxError(command=command) + + text = self._render('user_level', context=context) + self._write(text) + level = self.user_input(" 1. Common User 2. Operator 3. Administrator:") + if (level != '1') and (level != '2') and (level != '3'): + raise exceptions.CommandSyntaxError(command=command) + + if level == '1': + lvl = 'User' + elif level == '2': + lvl = 'Operator' + elif level == '3': + lvl = 'Admin' + else: + raise exceptions.CommandSyntaxError(command=command) + + reenter_num = self.user_input(" Permitted Reenter Number(0--20):") + if (int(reenter_num) < 0) or (int(reenter_num) > 20): + raise exceptions.CommandSyntaxError(command=command) + + info = self.user_input(" User's Appended Info(<=30 chars):") + if len(info) > 30: + raise exceptions.CommandSyntaxError(command=command) + + box = self._model + box.add_credentials(username=login, password=password) + try: + creds = self._model.get_credentials('username', login) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + box.add_user(name=login, credentials_id=creds.id, level=lvl, profile=profile, reenter_num=reenter_num, + reenter_num_temp=reenter_num, append_info=info, lock_status='Unlocked') + try: + user = self._model.get_user('name', login) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + text = self._render('user_created', context=context) + self._write(text) + + var_n = self.user_input(" Repeat this operation? (y/n)[n]:") + if var_n == 'y': + self.do_terminal(command, 'user', 'name', context=context) + return + elif var_n == 'n': + return + + elif self._validate(args, 'unlock', 'user', str): + user_name, = self._dissect(args, 'unlock', 'user', str) + + try: + locked_user = self._model.get_user('name', user_name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + if locked_user.lock_status == 'Locked': + locked_user.set_reenter_num_temp(locked_user.reenter_num) + locked_user.unlock() + return + elif locked_user.lock_status == 'Unlocked': + text = self._render('user_already_unlocked', context=context) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) + else: raise exceptions.CommandSyntaxError(command=command) @@ -862,10 +936,29 @@ def do_port(self, command, *args, context=None): try: port = self._model.get_port("name", portident) vlan = self._model.get_vlan("number", int(trafficvlan)) - except (exceptions.SoftboxenError, AssertionError): + except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - port.set_vlan_id(vlan.id) + try: # Check if s_port exists + service_port = self._model.get_service_port("name", portident) + except exceptions.SoftboxenError: + self._model.add_service_port(name=portident, connected_id=port.id, connected_type='port', + bytes_us=port.total_bytes_us, packets_us=port.total_packets_us, + bytes_ds=port.total_bytes_ds, packets_ds=port.total_packets_ds) + try: + service_port = self._model.get_service_port("name", portident) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + params = dict(name=str(vlan.number), service_port_id=service_port.id) + service_vlan = self._model.get_service_vlan_by_values(params) + if service_vlan is None: + self._model.add_service_vlan(name=vlan.number, vlan_id=vlan.id, service_port_id=service_port.id) + try: + service_vlan = self._model.get_service_vlan_by_values(params) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py index af4e37e..a908cbd 100644 --- a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py @@ -15,9 +15,6 @@ from .baseCommandProcessor import BaseCommandProcessor from .baseMixIn import BaseMixIn -# TODO: you can jump from enable to diagnose -# TODO: when doing 'quit', you get into enable again - class DiagnoseCommandProcessor(BaseCommandProcessor, BaseMixIn): @@ -46,7 +43,8 @@ def do_system(self, command, *args, context=None): for card in self._model.cards: result = ['Abnormal', 'Normal'][card.board_status == 'Normal' or card.board_status == 'Active_normal'] context['spacer'] = self.create_spacers((9,), (result,))[0] * ' ' - text += self._render('display_system_status_collection_1', context=dict(context, card=card, result=result)) + text += self._render('display_system_status_collection_1', + context=dict(context, card=card, result=result)) text += self._render('display_system_status_collection_2', context=context) text2 = '' for subrack in self._model.subracks: diff --git a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py index 47583e7..fb50256 100644 --- a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py @@ -30,6 +30,8 @@ def do_quit(self, command, *args, context=None): answer = self.user_input("Are you sure to log out? (y/n)[n]:") if answer == "y": self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) + user = self._model.get_user('status', 'Online') + user.set_offline() exc = exceptions.TerminalExitError() exc.return_to = 'sysexit' raise exc @@ -46,6 +48,12 @@ def do_config(self, command, *args, context=None): from .configCommandProcessor import ConfigCommandProcessor + try: + admin = self._model.get_user('status', 'Online') + assert admin.level != 'User' + except (exceptions.SoftboxenError, AssertionError): + raise exceptions.CommandSyntaxError(command=command) + subprocessor = self._create_subprocessor( ConfigCommandProcessor, 'login', 'mainloop', 'enable', 'config') @@ -193,6 +201,9 @@ def do_display(self, command, *args, context=None): context=context) self._write(text) + elif self._validate(args, 'terminal', 'user', 'all'): + self.display_terminal_user(command, context) + else: raise exceptions.CommandSyntaxError(command=command) @@ -201,4 +212,3 @@ def do_save(self, command, *args, context=None): # TODO: Functionality return else: raise exceptions.CommandSyntaxError(command=command) - diff --git a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py index c507fae..e048a17 100644 --- a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py @@ -494,3 +494,39 @@ def prepare_template_vars(self, s_port, command): raise exceptions.CommandSyntaxError(command=command) return port, card, vlan, porttype + + def display_terminal_user(self, command, context): + text = self._render('display_terminal_user_all_top', context=context) + user_counter = 0 + + try: + exec_user = self._model.get_user('status', 'Online') + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + for user in self._model.users: + if (exec_user.level == 'User') and (user.level == 'User'): + check = True + elif (exec_user.level == 'Operator') and ((user.level == 'User') or (user.level == 'Operator')): + check = True + elif (exec_user.level == 'Admin') and (user.level != 'Super'): + check = True + elif exec_user.level == 'Super': + check = True + else: + check = False + + if check: + context['spacer1'] = self.create_spacers((16,), (user.name,))[0] * ' ' + context['spacer2'] = self.create_spacers((9,), (user.level,))[0] * ' ' + context['spacer3'] = self.create_spacers((15,), (user.status + str(user.reenter_num),))[0] * ' ' + context['spacer4'] = self.create_spacers((1,), ('',))[0] * ' ' + context['spacer5'] = self.create_spacers((16,), (user.profile,))[0] * ' ' + + text += self._render('display_terminal_user_all_middle', context=dict(context, user=user)) + user_counter += 1 + + context['user_counter'] = user_counter + text += self._render('display_terminal_user_all_bottom', context=context) + self._write(text) + return diff --git a/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py index f0a6099..16dd980 100644 --- a/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py @@ -40,6 +40,8 @@ def do_quit(self, command, *args, context=None): answer = self.user_input("Are you sure to log out? (y/n)[n]:") if answer == "y": self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) + user = self._model.get_user('status', 'Online') + user.set_offline() exc = exceptions.TerminalExitError() exc.return_to = 'sysexit' raise exc From 6afbeecf138c0fcb3a1e82cc04eb32e5e8c2cb4e Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 4 Sep 2020 14:42:57 +0200 Subject: [PATCH 005/318] Added some error handling to the user creation process --- .../enable/config/terminal_error_choice.j2 | 2 + .../enable/config/terminal_level_error.j2 | 2 + .../enable/config/terminal_name_long.j2 | 2 + .../enable/config/terminal_name_short.j2 | 2 + .../enable/config/terminal_profile_error.j2 | 2 + .../enable/config/terminal_pw_error.j2 | 2 + .../enable/config/terminal_pw_long.j2 | 2 + .../enable/config/terminal_pw_short.j2 | 2 + .../Huawei_Base/configCommandProcessor.py | 54 ++++++++++++++----- 9 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/terminal_error_choice.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/terminal_level_error.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/terminal_name_long.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/terminal_name_short.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/terminal_profile_error.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_error.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_long.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_short.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_error_choice.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_error_choice.j2 new file mode 100644 index 0000000..58bf483 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_error_choice.j2 @@ -0,0 +1,2 @@ + Failure: Error Choice + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_level_error.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_level_error.j2 new file mode 100644 index 0000000..eb029ef --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_level_error.j2 @@ -0,0 +1,2 @@ + Failure: Error choice or the input level higher than owns + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_name_long.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_name_long.j2 new file mode 100644 index 0000000..ee98b4b --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_name_long.j2 @@ -0,0 +1,2 @@ + Failure: The user name must be equal to or less than 15 characters + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_name_short.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_name_short.j2 new file mode 100644 index 0000000..470dcef --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_name_short.j2 @@ -0,0 +1,2 @@ + Failure: The user name must be equal to or more than 6 characters + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_profile_error.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_profile_error.j2 new file mode 100644 index 0000000..5b9c8f7 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_profile_error.j2 @@ -0,0 +1,2 @@ + Failure: This user-profile does not exist + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_error.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_error.j2 new file mode 100644 index 0000000..667cb88 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_error.j2 @@ -0,0 +1,2 @@ + Failure: Error Password + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_long.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_long.j2 new file mode 100644 index 0000000..ee98b4b --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_long.j2 @@ -0,0 +1,2 @@ + Failure: The user name must be equal to or less than 15 characters + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_short.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_short.j2 new file mode 100644 index 0000000..470dcef --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_short.j2 @@ -0,0 +1,2 @@ + Failure: The user name must be equal to or more than 6 characters + diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 8ad0ee5..50f2743 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -835,7 +835,7 @@ def do_system(self, command, *args, context=None): # TODO: Functionality else: raise exceptions.CommandSyntaxError(command=command) - def do_terminal(self, command, *args, context=None): # TODO: create user + credentials + def do_terminal(self, command, *args, context=None): if self._validate(args, 'user', 'name'): login = self.user_input(" User Name(length<6,15>):") @@ -848,24 +848,46 @@ def do_terminal(self, command, *args, context=None): # TODO: create user + cred text = self._render('user_already_exists', context=context) self._write(text) return - if (len(login) < 6) or (len(login) > 15): - raise exceptions.CommandSyntaxError(command=command) + while len(login) < 6: + text = self._render('terminal_name_short', context=context) + self._write(text) + login = self.user_input(" User Name(length<6,15>):") + while len(login) > 15: + text = self._render('terminal_name_long', context=context) + self._write(text) + login = self.user_input(" User Name(length<6,15>):") password = self.user_input(" User Password(length<6,15>):") + while len(password) < 6: + text = self._render('terminal_pw_short', context=context) + self._write(text) + password = self.user_input(" User Password(length<6,15>):") + while len(password) > 15: + text = self._render('terminal_pw_long', context=context) + self._write(text) + password = self.user_input(" User Password(length<6,15>):") + password_repeat = self.user_input(" Confirm Password(length<6,15>):") - if (len(password) < 6) or (len(password) > 15) or (len(password_repeat) < 6) or (len(password_repeat) > 15)\ - or (password != password_repeat): - raise exceptions.CommandSyntaxError(command=command) + while password != password_repeat: + text = self._render('terminal_pw_error', context=context) + self._write(text) + password_repeat = self.user_input(" Confirm Password(length<6,15>):") profile = self.user_input(" User profile name(<=15 chars)[root]:") - if (profile != 'root') and (profile != 'admin') and (profile != 'operator') and (profile != 'commonuser'): - raise exceptions.CommandSyntaxError(command=command) + while (profile != 'root') and (profile != 'admin') and (profile != 'operator') and (profile != 'commonuser'): + text = self._render('terminal_profile_error', context=context) + self._write(text) + profile = self.user_input(" User profile name(<=15 chars)[root]:") text = self._render('user_level', context=context) self._write(text) level = self.user_input(" 1. Common User 2. Operator 3. Administrator:") - if (level != '1') and (level != '2') and (level != '3'): - raise exceptions.CommandSyntaxError(command=command) + while (level != '1') and (level != '2') and (level != '3'): + text = self._render('terminal_level_error', context=context) + self._write(text) + text = self._render('user_level', context=context) + self._write(text) + level = self.user_input(" 1. Common User 2. Operator 3. Administrator:") if level == '1': lvl = 'User' @@ -877,12 +899,16 @@ def do_terminal(self, command, *args, context=None): # TODO: create user + cred raise exceptions.CommandSyntaxError(command=command) reenter_num = self.user_input(" Permitted Reenter Number(0--20):") - if (int(reenter_num) < 0) or (int(reenter_num) > 20): - raise exceptions.CommandSyntaxError(command=command) + while (int(reenter_num) < 0) or (int(reenter_num) > 20): + text = self._render('terminal_error_choice', context=context) + self._write(text) + reenter_num = self.user_input(" Permitted Reenter Number(0--20):") info = self.user_input(" User's Appended Info(<=30 chars):") - if len(info) > 30: - raise exceptions.CommandSyntaxError(command=command) + while len(info) > 30: + text = self._render('terminal_error_choice', context=context) + self._write(text) + info = self.user_input(" User's Appended Info(<=30 chars):") box = self._model box.add_credentials(username=login, password=password) From b99ec6a32c100ca389ad88c67a325de63c82d857 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 4 Sep 2020 16:36:32 +0200 Subject: [PATCH 006/318] Several changes to the CLI interpreter. Such as: login credentials aren't tracked in the local history anymore, Password fields don't show the user typing the password anymore, In huawei user_input the history_can be disabled, Usernames are now compared more strictly to the username given in the credentials --- cli.py | 1 + nesi/softbox/cli/base.py | 33 ++++++++++++------ vendors/Alcatel/7360/Alcatel_7360/main.py | 4 ++- vendors/Huawei/5623/Huawei_5623/main.py | 4 ++- .../Base/Huawei_Base/baseCommandProcessor.py | 6 +++- .../Huawei_Base/configCommandProcessor.py | 34 +++++++++---------- 6 files changed, 51 insertions(+), 31 deletions(-) diff --git a/cli.py b/cli.py index 5a41059..937638e 100644 --- a/cli.py +++ b/cli.py @@ -203,6 +203,7 @@ def main(): try: context = dict() context['login_banner'] = model.login_banner + command_processor.history_enabled = False command_processor.loop(context=context) except exceptions.TerminalExitError as exc: if exc.return_to is not None and exc.return_to != 'sysexit': diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 7dd4403..d2389fc 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -65,6 +65,10 @@ def __init__(self, model, input_stream, output_stream, history, if template_root else None), trim_blocks=True, lstrip_blocks=True, autoescape=True) self.daemon = daemon + + # CLI specific attributes + self.history_enabled = True + self.hide_input = False self.history_pos = 0 self.history = history self.prompt_end_pos = self.get_prompt_len() - 1 @@ -119,9 +123,15 @@ def get(self): k = inkey(self._input).decode('utf-8') if k != '': break if k == '\x1b[A': # up-arrow - return 'history', self.history_up() + if self.history_enabled: + return 'history', self.history_up() + else: + return None, None elif k == '\x1b[B': # down-arrow - return 'history', self.history_down() + if self.history_enabled: + return 'history', self.history_down() + else: + return None, None elif k == '\x1b[C': # right-arrow self.move_right() return None, None @@ -137,6 +147,8 @@ def get(self): return 'del', '' elif k == '': # ctrl-v return 'paste', pyperclip.paste() + elif k == '': # ctrl-c + return 'cancel', '' elif k == 'OF' or k == '': # command + right-arrow or end-key self.cursor_pos = self.cursor_boundary return 'cursor', '' @@ -173,32 +185,31 @@ def getline(self): line = line[:self.cursor_pos - self.prompt_end_pos - 2] + line[self.cursor_pos - self.prompt_end_pos - 1:] self.cursor_pos -= 1 self.cursor_boundary -= 1 - self.updateline(line) - continue elif option == 'del': line = line[:(self.cursor_pos - self.prompt_end_pos) - 1] + line[(self.cursor_pos - self.prompt_end_pos):] self.cursor_boundary -= 1 - self.updateline(line) - continue elif option == 'history': self.cursor_pos = self.prompt_end_pos + 1 + len(char) self.cursor_boundary = self.prompt_end_pos + 1 + len(char) - self.updateline(char) line = char - elif option == 'cursor': - self.updateline(line) elif option == 'paste': line = line[:(self.cursor_pos - self.prompt_end_pos - 1)] + char + line[(self.cursor_pos - self.prompt_end_pos - 1):] self.cursor_boundary = self.cursor_boundary + len(char) self.cursor_pos = self.cursor_pos + len(char) - self.updateline(line) elif option == 'character': line = line[:(self.cursor_pos - self.prompt_end_pos - 1)] + char + line[(self.cursor_pos - self.prompt_end_pos - 1):] self.cursor_pos += 1 self.cursor_boundary += 1 + elif option == 'cursor': + pass + elif option == 'cancel': + line = '\r' + break + + if not self.hide_input: self.updateline(line) - if line != '\r' and line != '': + if line != '\r' and line != '' and self.history_enabled: self.history += (line.replace('\r', '').rstrip(),) self._write('\n') diff --git a/vendors/Alcatel/7360/Alcatel_7360/main.py b/vendors/Alcatel/7360/Alcatel_7360/main.py index 10458c8..f2d11bb 100644 --- a/vendors/Alcatel/7360/Alcatel_7360/main.py +++ b/vendors/Alcatel/7360/Alcatel_7360/main.py @@ -30,9 +30,11 @@ def on_unknown_command(self, command, *args, context=None): subprocessor = self._create_subprocessor( LoginCommandProcessor, 'login') - context['username'] = command + context['username'] = context['raw_line'] try: + subprocessor.history_enabled = False + subprocessor.hide_input = True subprocessor.loop(context=context) except exceptions.TerminalExitError as exc: if exc.return_to is not None and exc.return_to != 'sysexit': diff --git a/vendors/Huawei/5623/Huawei_5623/main.py b/vendors/Huawei/5623/Huawei_5623/main.py index 4b39ef7..ea48ab8 100644 --- a/vendors/Huawei/5623/Huawei_5623/main.py +++ b/vendors/Huawei/5623/Huawei_5623/main.py @@ -30,9 +30,11 @@ def on_unknown_command(self, command, *args, context=None): subprocessor = self._create_subprocessor( LoginCommandProcessor, 'login') - context['username'] = command + context['username'] = context['raw_line'] try: + subprocessor.history_enabled = False + subprocessor.hide_input = True subprocessor.loop(context=context) except exceptions.TerminalExitError as exc: if exc.return_to is not None and exc.return_to != 'sysexit': diff --git a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py index af2c08e..2b00780 100644 --- a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py @@ -21,11 +21,15 @@ class BaseCommandProcessor(base.CommandProcessor): MODEL = 'Base' VERSION = '1' - def user_input(self, prompt): + def user_input(self, prompt, allow_history=True): self._write(prompt) prompt_end_pos = self.prompt_end_pos self.prompt_end_pos = len(prompt) - 1 + if not allow_history: + self.history_enabled = False input = self._read().strip() + if not allow_history: + self.history_enabled = True self.prompt_end_pos = prompt_end_pos return input diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 50f2743..c251ea2 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -837,7 +837,7 @@ def do_system(self, command, *args, context=None): # TODO: Functionality def do_terminal(self, command, *args, context=None): if self._validate(args, 'user', 'name'): - login = self.user_input(" User Name(length<6,15>):") + login = self.user_input(" User Name(length<6,15>):", False) try: usr = self._model.get_user('name', login) @@ -851,43 +851,43 @@ def do_terminal(self, command, *args, context=None): while len(login) < 6: text = self._render('terminal_name_short', context=context) self._write(text) - login = self.user_input(" User Name(length<6,15>):") + login = self.user_input(" User Name(length<6,15>):", False) while len(login) > 15: text = self._render('terminal_name_long', context=context) self._write(text) - login = self.user_input(" User Name(length<6,15>):") + login = self.user_input(" User Name(length<6,15>):", False) - password = self.user_input(" User Password(length<6,15>):") + password = self.user_input(" User Password(length<6,15>):", False) while len(password) < 6: text = self._render('terminal_pw_short', context=context) self._write(text) - password = self.user_input(" User Password(length<6,15>):") + password = self.user_input(" User Password(length<6,15>):", False) while len(password) > 15: text = self._render('terminal_pw_long', context=context) self._write(text) - password = self.user_input(" User Password(length<6,15>):") + password = self.user_input(" User Password(length<6,15>):", False) - password_repeat = self.user_input(" Confirm Password(length<6,15>):") + password_repeat = self.user_input(" Confirm Password(length<6,15>):", False) while password != password_repeat: text = self._render('terminal_pw_error', context=context) self._write(text) - password_repeat = self.user_input(" Confirm Password(length<6,15>):") + password_repeat = self.user_input(" Confirm Password(length<6,15>):", False) - profile = self.user_input(" User profile name(<=15 chars)[root]:") + profile = self.user_input(" User profile name(<=15 chars)[root]:", False) while (profile != 'root') and (profile != 'admin') and (profile != 'operator') and (profile != 'commonuser'): text = self._render('terminal_profile_error', context=context) self._write(text) - profile = self.user_input(" User profile name(<=15 chars)[root]:") + profile = self.user_input(" User profile name(<=15 chars)[root]:", False) text = self._render('user_level', context=context) self._write(text) - level = self.user_input(" 1. Common User 2. Operator 3. Administrator:") + level = self.user_input(" 1. Common User 2. Operator 3. Administrator:", False) while (level != '1') and (level != '2') and (level != '3'): text = self._render('terminal_level_error', context=context) self._write(text) text = self._render('user_level', context=context) self._write(text) - level = self.user_input(" 1. Common User 2. Operator 3. Administrator:") + level = self.user_input(" 1. Common User 2. Operator 3. Administrator:", False) if level == '1': lvl = 'User' @@ -898,17 +898,17 @@ def do_terminal(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - reenter_num = self.user_input(" Permitted Reenter Number(0--20):") + reenter_num = self.user_input(" Permitted Reenter Number(0--20):", False) while (int(reenter_num) < 0) or (int(reenter_num) > 20): text = self._render('terminal_error_choice', context=context) self._write(text) - reenter_num = self.user_input(" Permitted Reenter Number(0--20):") + reenter_num = self.user_input(" Permitted Reenter Number(0--20):", False) - info = self.user_input(" User's Appended Info(<=30 chars):") + info = self.user_input(" User's Appended Info(<=30 chars):", False) while len(info) > 30: text = self._render('terminal_error_choice', context=context) self._write(text) - info = self.user_input(" User's Appended Info(<=30 chars):") + info = self.user_input(" User's Appended Info(<=30 chars):", False) box = self._model box.add_credentials(username=login, password=password) @@ -927,7 +927,7 @@ def do_terminal(self, command, *args, context=None): text = self._render('user_created', context=context) self._write(text) - var_n = self.user_input(" Repeat this operation? (y/n)[n]:") + var_n = self.user_input(" Repeat this operation? (y/n)[n]:", False) if var_n == 'y': self.do_terminal(command, 'user', 'name', context=context) return From 400cdddceb372c9e949a36a70ee98d550c207740 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 7 Sep 2020 09:15:22 +0200 Subject: [PATCH 007/318] Added temporery boundary to _read function, to not read characters beyond the given limit --- nesi/softbox/cli/base.py | 13 ++++++++++--- .../Huawei/Base/Huawei_Base/baseCommandProcessor.py | 4 ++-- .../Base/Huawei_Base/configCommandProcessor.py | 6 +++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index d2389fc..1c87f11 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -168,7 +168,7 @@ def updateline(self, line): self._write('\r') # reset cursor to start of line self._write('\033[' + str(self.cursor_pos) + 'C') # move cursor to correct position - def getline(self): + def getline(self, tmp_boundary=None): char = None line = '' self.history_pos = len(self.history) @@ -193,10 +193,17 @@ def getline(self): self.cursor_boundary = self.prompt_end_pos + 1 + len(char) line = char elif option == 'paste': + if tmp_boundary is not None: + char_len = (self.prompt_end_pos + 1 + tmp_boundary) - self.cursor_pos + char = char[:char_len] + if tmp_boundary is not None and self.cursor_pos + len(char) > self.prompt_end_pos + 1 + tmp_boundary: + continue line = line[:(self.cursor_pos - self.prompt_end_pos - 1)] + char + line[(self.cursor_pos - self.prompt_end_pos - 1):] self.cursor_boundary = self.cursor_boundary + len(char) self.cursor_pos = self.cursor_pos + len(char) elif option == 'character': + if tmp_boundary is not None and self.cursor_pos + 1 > self.prompt_end_pos + 1 + tmp_boundary: + continue line = line[:(self.cursor_pos - self.prompt_end_pos - 1)] + char + line[(self.cursor_pos - self.prompt_end_pos - 1):] self.cursor_pos += 1 self.cursor_boundary += 1 @@ -256,11 +263,11 @@ def _default_command_handler(self, command, *args, context=None): self._write(text) - def _read(self): + def _read(self, tmp_boundary=None): if self.daemon: line = self._input.readline().decode('utf-8') else: - line = self.getline() + line = self.getline(tmp_boundary) return line diff --git a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py index 2b00780..77b62ec 100644 --- a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py @@ -21,13 +21,13 @@ class BaseCommandProcessor(base.CommandProcessor): MODEL = 'Base' VERSION = '1' - def user_input(self, prompt, allow_history=True): + def user_input(self, prompt, allow_history=True, tmp_boundary=None): self._write(prompt) prompt_end_pos = self.prompt_end_pos self.prompt_end_pos = len(prompt) - 1 if not allow_history: self.history_enabled = False - input = self._read().strip() + input = self._read(tmp_boundary).strip() if not allow_history: self.history_enabled = True self.prompt_end_pos = prompt_end_pos diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index c251ea2..d3c5ce2 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -837,7 +837,7 @@ def do_system(self, command, *args, context=None): # TODO: Functionality def do_terminal(self, command, *args, context=None): if self._validate(args, 'user', 'name'): - login = self.user_input(" User Name(length<6,15>):", False) + login = self.user_input(" User Name(length<6,15>):", False, 15) try: usr = self._model.get_user('name', login) @@ -851,11 +851,11 @@ def do_terminal(self, command, *args, context=None): while len(login) < 6: text = self._render('terminal_name_short', context=context) self._write(text) - login = self.user_input(" User Name(length<6,15>):", False) + login = self.user_input(" User Name(length<6,15>):", False, 15) while len(login) > 15: text = self._render('terminal_name_long', context=context) self._write(text) - login = self.user_input(" User Name(length<6,15>):", False) + login = self.user_input(" User Name(length<6,15>):", False, 15) password = self.user_input(" User Password(length<6,15>):", False) while len(password) < 6: From 94504172bc7b73501fbb666cdf5c7e29fa598dd6 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 7 Sep 2020 09:31:50 +0200 Subject: [PATCH 008/318] Fixed terminal user creation prompts with fixed length --- .../Huawei_Base/configCommandProcessor.py | 26 +++++-------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index d3c5ce2..a935ab7 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -852,32 +852,24 @@ def do_terminal(self, command, *args, context=None): text = self._render('terminal_name_short', context=context) self._write(text) login = self.user_input(" User Name(length<6,15>):", False, 15) - while len(login) > 15: - text = self._render('terminal_name_long', context=context) - self._write(text) - login = self.user_input(" User Name(length<6,15>):", False, 15) - password = self.user_input(" User Password(length<6,15>):", False) + password = self.user_input(" User Password(length<6,15>):", False, ) while len(password) < 6: text = self._render('terminal_pw_short', context=context) self._write(text) - password = self.user_input(" User Password(length<6,15>):", False) - while len(password) > 15: - text = self._render('terminal_pw_long', context=context) - self._write(text) - password = self.user_input(" User Password(length<6,15>):", False) + password = self.user_input(" User Password(length<6,15>):", False, 15) password_repeat = self.user_input(" Confirm Password(length<6,15>):", False) while password != password_repeat: text = self._render('terminal_pw_error', context=context) self._write(text) - password_repeat = self.user_input(" Confirm Password(length<6,15>):", False) + password_repeat = self.user_input(" Confirm Password(length<6,15>):", False, 15) profile = self.user_input(" User profile name(<=15 chars)[root]:", False) while (profile != 'root') and (profile != 'admin') and (profile != 'operator') and (profile != 'commonuser'): text = self._render('terminal_profile_error', context=context) self._write(text) - profile = self.user_input(" User profile name(<=15 chars)[root]:", False) + profile = self.user_input(" User profile name(<=15 chars)[root]:", False, 15) text = self._render('user_level', context=context) self._write(text) @@ -898,17 +890,13 @@ def do_terminal(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - reenter_num = self.user_input(" Permitted Reenter Number(0--20):", False) + reenter_num = self.user_input(" Permitted Reenter Number(0--20):", False, 2) while (int(reenter_num) < 0) or (int(reenter_num) > 20): text = self._render('terminal_error_choice', context=context) self._write(text) - reenter_num = self.user_input(" Permitted Reenter Number(0--20):", False) + reenter_num = self.user_input(" Permitted Reenter Number(0--20):", False, 2) - info = self.user_input(" User's Appended Info(<=30 chars):", False) - while len(info) > 30: - text = self._render('terminal_error_choice', context=context) - self._write(text) - info = self.user_input(" User's Appended Info(<=30 chars):", False) + info = self.user_input(" User's Appended Info(<=30 chars):", False, 30) box = self._model box.add_credentials(username=login, password=password) From ec570f4a24b45fcfeadf30092acf0081dc4ca5ac Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 7 Sep 2020 17:28:03 +0200 Subject: [PATCH 009/318] Started work on clean huawei setup script and refactored admin and operational_state to enum logic --- bootup/conf/bootstraps/create-alcatel-7360.sh | 217 +++---- .../conf/bootstraps/create-box-port-vlan.sh | 4 +- .../bootstraps/create-custom-benchmark-box.sh | 14 +- bootup/conf/bootstraps/create-huawei-5623.sh | 525 +++++---------- .../conf/bootstraps/create-huawei-5623_old.sh | 596 ++++++++++++++++++ bootup/conf/bootstraps/test-api-endpoints.sh | 12 +- nesi/alcatel/alcatel_resources/alcatel_cpe.py | 4 +- nesi/alcatel/alcatel_resources/alcatel_ont.py | 12 +- .../alcatel_resources/alcatel_ont_port.py | 8 +- .../huawei_resources/huawei_ont_port.py | 4 +- nesi/huawei/huawei_resources/huawei_port.py | 8 +- nesi/softbox/api/models/card_models.py | 4 +- nesi/softbox/api/models/cpe_models.py | 2 +- nesi/softbox/api/models/ont_models.py | 4 +- nesi/softbox/api/models/ontport_models.py | 4 +- nesi/softbox/api/models/port_models.py | 4 +- .../softbox/api/models/service_port_models.py | 4 +- nesi/softbox/api/models/subrack_models.py | 4 +- nesi/softbox/base_resources/port.py | 8 +- ...nfigure_ethernet_line_identifier_detail.j2 | 2 +- ...t_line_identifier_mau_identifier_detail.j2 | 2 +- .../mainloop/show/equipment_slot_middle.j2 | 2 +- ...ipe_match_match_exact_product_line_port.j2 | 2 +- .../config/interface/display_port_state.j2 | 2 +- .../display_system_status_collection_8.j2 | 2 +- test_cases/unit_tests/alcatel/test_alcatel.py | 56 +- .../unit_tests/edgecore/test_edgecore.py | 12 +- test_cases/unit_tests/huawei/test_huawei.py | 12 +- test_cases/unit_tests/keymile/test_keymile.py | 12 +- .../Base/Alcatel_Base/baseCommandProcessor.py | 29 + .../Alcatel_Base/configureCommandProcessor.py | 14 +- .../Base/Alcatel_Base/showCommandProcessor.py | 23 +- .../Alcatel_Base/userViewCommandProcessor.py | 6 +- .../Base/Huawei_Base/baseCommandProcessor.py | 37 ++ .../Huawei_Base/enableCommandProcessor.py | 4 +- .../Huawei_Base/huaweiBaseCommandProcessor.py | 5 +- .../Huawei_Base/interfaceCommandProcessor.py | 1 + 37 files changed, 1056 insertions(+), 605 deletions(-) mode change 100755 => 100644 bootup/conf/bootstraps/create-huawei-5623.sh create mode 100755 bootup/conf/bootstraps/create-huawei-5623_old.sh diff --git a/bootup/conf/bootstraps/create-alcatel-7360.sh b/bootup/conf/bootstraps/create-alcatel-7360.sh index 3fc88a3..e01beac 100755 --- a/bootup/conf/bootstraps/create-alcatel-7360.sh +++ b/bootup/conf/bootstraps/create-alcatel-7360.sh @@ -336,8 +336,8 @@ req='{ "description": "Physical subrack #1", "planned_type": "rvxs-a", "actual_type": "rvxs-a", - "operational_state": "enabled", - "admin_state": "unlock", + "operational_state": "1", + "admin_state": "1", "err_state": "no-error", "availability": "available", "mode": "no-extended-lt-slots", @@ -361,7 +361,7 @@ req='{ "description": "Physical Management card", "planned_type": "rant-a", "actual_type": "rant-a", - "operational_state": "enabled", + "operational_state": "1", "err_state": "no-error", "availability": "available", "alarm_profile": "none", @@ -394,8 +394,8 @@ req='{ "name": "nt-a:xfp:1", "position": "nt-a:xfp:1", "description": "Management port #1", - "operational_state": "up", - "admin_state": "up", + "operational_state": "1", + "admin_state": "1", "upstream": 0, "downstream": 0, "upstream_max": 100000, @@ -483,8 +483,8 @@ req='{ "connected_id": '$port_mgmt', "connected_type": "port", "name": "nt-a:xfp:1", - "admin_state": "up", - "operational_state": "up" + "admin_state": "1", + "operational_state": "1" }' service_port_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -499,8 +499,8 @@ req='{ "description": "Physical card 1/1/1", "planned_type": "rdlt-c", "actual_type": "rdlt-c", - "operational_state": "enabled", - "admin_state": "unlock", + "operational_state": "1", + "admin_state": "1", "err_state": "no-error", "availability": "available", "alarm_profile": "none", @@ -532,8 +532,8 @@ card_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) req='{ "card_id": '$card_1_1_1', "description": "Physical port 1/1/1/1", - "operational_state": "up", - "admin_state": "up", + "operational_state": "1", + "admin_state": "1", "upstream": 10000, "downstream": 25000, "upstream_max": 100000, @@ -621,8 +621,8 @@ req='{ "connected_id": '$port_1_1_1_1', "connected_type": "port", "name": "1/1/1/1", - "admin_state": "up", - "operational_state": "up" + "admin_state": "1", + "operational_state": "1" }' service_port_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -655,8 +655,8 @@ req='{ "name": "1/1/1/1:1:32", "connected_id": '$port_1_1_1_1', "connected_type": "port", - "admin_state": "up", - "operational_state": "up" + "admin_state": "1", + "operational_state": "1" }' service_port_1_1_1_1_1_32=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -680,7 +680,7 @@ req='{ "port_id": '$port_1_1_1_1', "description": "Cpe 1/1/1/1/1", "serial_no": "ABCD123456EF", - "admin_state": "up", + "admin_state": "1", "mac": "8f:db:82:ef:ea:17" }' @@ -703,8 +703,8 @@ req='{ "connected_id": '$cpe_port_1_1_1_1_1_1', "connected_type": "cpe", "name": "1/1/1/1/1/1", - "admin_state": "up", - "operational_state": "up" + "admin_state": "1", + "operational_state": "1" }' service_port_1_1_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -738,8 +738,8 @@ service_vlan_=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlans) req='{ "card_id": '$card_1_1_1', "description": "Physical port 1/1/1/2", - "operational_state": "down", - "admin_state": "up", + "operational_state": "0", + "admin_state": "1", "upstream": 0, "downstream": 0, "upstream_max": 100000, @@ -827,8 +827,8 @@ req='{ "connected_id": '$port_1_1_1_2', "connected_type": "port", "name": "1/1/1/1", - "admin_state": "up", - "operational_state": "down" + "admin_state": "1", + "operational_state": "0" }' service_port_1_1_1_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -863,7 +863,7 @@ req='{ "port_id": '$port_1_1_1_2', "description": "Cpe 1/1/1/2/1", "serial_no": "ABCD654321FE", - "admin_state": "down", + "admin_state": "0", "mac": "8d:dc:81:ea:fe:12" }' @@ -887,8 +887,8 @@ cpe_port_1_1_1_2_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) req='{ "card_id": '$card_1_1_1', "description": "Physical port 1/1/1/3", - "operational_state": "down", - "admin_state": "down", + "operational_state": "0", + "admin_state": "0", "upstream": 0, "downstream": 0, "upstream_max": 100000, @@ -976,8 +976,8 @@ req='{ "connected_id": '$port_1_1_1_3', "connected_type": "port", "name": "1/1/1/3", - "admin_state": "down", - "operational_state": "down" + "admin_state": "0", + "operational_state": "0" }' service_port_1_1_1_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -1013,8 +1013,8 @@ req='{ "description": "Physical card 1/1/2", "planned_type": "rdlt-c", "actual_type": "rdlt-c", - "operational_state": "enabled", - "admin_state": "unlock", + "operational_state": "1", + "admin_state": "1", "err_state": "no-error", "availability": "available", "alarm_profile": "none", @@ -1046,8 +1046,8 @@ card_1_1_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) req='{ "card_id": '$card_1_1_2', "description": "Physical port 1/1/2/1", - "operational_state": "up", - "admin_state": "up", + "operational_state": "1", + "admin_state": "1", "upstream": 10000, "downstream": 25000, "upstream_max": 100000, @@ -1135,8 +1135,8 @@ req='{ "connected_id": '$port_1_1_2_1', "connected_type": "port", "name": "1/1/2/1", - "admin_state": "up", - "operational_state": "up" + "admin_state": "1", + "operational_state": "1" }' service_port_1_1_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -1171,7 +1171,7 @@ req='{ "port_id": '$port_1_1_2_1', "description": "Cpe 1/1/2/1/1", "serial_no": "GFED123456BA", - "admin_state": "up", + "admin_state": "1", "mac": "2a:87:19:09:ae:2f" }' @@ -1195,8 +1195,8 @@ cpe_port_1_1_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) req='{ "card_id": '$card_1_1_2', "description": "Physical port 1/1/2/2", - "operational_state": "down", - "admin_state": "up", + "operational_state": "0", + "admin_state": "1", "upstream": 0, "downstream": 0, "upstream_max": 100000, @@ -1284,8 +1284,8 @@ req='{ "connected_id": '$port_1_1_2_2', "connected_type": "port", "name": "1/1/2/1", - "admin_state": "up", - "operational_state": "down" + "admin_state": "1", + "operational_state": "0" }' service_port_1_1_2_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -1320,7 +1320,7 @@ req='{ "port_id": '$port_1_1_2_2', "description": "Cpe 1/1/2/2/1", "serial_no": "DEFG654321AB", - "admin_state": "down", + "admin_state": "0", "mac": "2e:78:09:e6:dc:4e" }' @@ -1344,8 +1344,8 @@ cpe_port_1_1_2_2_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) req='{ "card_id": '$card_1_1_2', "description": "Physical port 1/1/2/3", - "operational_state": "down", - "admin_state": "down", + "operational_state": "0", + "admin_state": "0", "upstream": 0, "downstream": 0, "upstream_max": 100000, @@ -1433,8 +1433,8 @@ req='{ "connected_id": '$port_1_1_2_3', "connected_type": "port", "name": "1/1/2/3", - "admin_state": "down", - "operational_state": "down" + "admin_state": "0", + "operational_state": "0" }' service_port_1_1_2_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -1470,8 +1470,8 @@ req='{ "description": "Physical card 1/1/3", "planned_type": "nant-a", "actual_type": "nant-a", - "operational_state": "enabled", - "admin_state": "unlock", + "operational_state": "1", + "admin_state": "1", "err_state": "no-error", "availability": "available", "alarm_profile": "none", @@ -1503,8 +1503,8 @@ card_1_1_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) req='{ "card_id": '$card_1_1_3', "description": "Physical port 1/1/3/1", - "operational_state": "up", - "admin_state": "up", + "operational_state": "1", + "admin_state": "1", "upstream": 10000, "downstream": 25000, "upstream_max": 100000, @@ -1592,8 +1592,8 @@ req='{ "connected_id": '$port_1_1_3_1', "connected_type": "port", "name": "1/1/3/1", - "admin_state": "up", - "operational_state": "up" + "admin_state": "1", + "operational_state": "1" }' service_port_1_1_3_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -1628,7 +1628,7 @@ req='{ "port_id": '$port_1_1_3_1', "description": "Cpe 1/1/3/1/1", "serial_no": "WXYZ123456BA", - "admin_state": "up", + "admin_state": "1", "mac": "fd:28:2e:25:a2:99" }' @@ -1652,8 +1652,8 @@ cpe_port_1_1_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) req='{ "card_id": '$card_1_1_3', "description": "Physical port 1/1/3/2", - "operational_state": "down", - "admin_state": "up", + "operational_state": "0", + "admin_state": "1", "upstream": 0, "downstream": 0, "upstream_max": 100000, @@ -1741,8 +1741,8 @@ req='{ "connected_id": '$port_1_1_3_2', "connected_type": "port", "name": "1/1/3/2", - "admin_state": "up", - "operational_state": "down" + "admin_state": "1", + "operational_state": "0" }' service_port_1_1_3_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -1777,7 +1777,7 @@ req='{ "port_id": '$port_1_1_3_2', "description": "Cpe 1/1/3/2/1", "serial_no": "DEFG654321AB", - "admin_state": "down", + "admin_state": "0", "mac": "c3:3e:81:30:3d:10" }' @@ -1801,8 +1801,8 @@ cpe_port_1_1_3_2_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) req='{ "card_id": '$card_1_1_3', "description": "Physical port 1/1/3/3", - "operational_state": "down", - "admin_state": "down", + "operational_state": "0", + "admin_state": "0", "upstream": 0, "downstream": 0, "upstream_max": 100000, @@ -1890,8 +1890,8 @@ req='{ "connected_id": '$port_1_1_3_3', "connected_type": "port", "name": "1/1/3/3", - "admin_state": "down", - "operational_state": "down" + "admin_state": "0", + "operational_state": "0" }' service_port_1_1_3_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -1927,8 +1927,8 @@ req='{ "description": "Physical card 1/1/4", "planned_type": "relt-a", "actual_type": "relt-a", - "operational_state": "enabled", - "admin_state": "unlock", + "operational_state": "1", + "admin_state": "1", "err_state": "no-error", "availability": "available", "alarm_profile": "none", @@ -1960,8 +1960,8 @@ card_1_1_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) req='{ "card_id": '$card_1_1_4', "description": "Physical port 1/1/4/1", - "operational_state": "up", - "admin_state": "up", + "operational_state": "1", + "admin_state": "1", "upstream": 10000, "downstream": 25000, "upstream_max": 100000, @@ -2049,8 +2049,8 @@ req='{ "connected_id": '$port_1_1_4_1', "connected_type": "port", "name": "1/1/4/1", - "admin_state": "up", - "operational_state": "up" + "admin_state": "1", + "operational_state": "1" }' service_port_1_1_4_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -2084,7 +2084,7 @@ service_vlan_=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlans) req='{ "port_id":'$port_1_1_4_1', "description": "Ont 1/1/4/1/1", - "admin_state": "up", + "admin_state": "1", "index": 1, "type": "10gbaselr", "basebx10d": "yes", @@ -2131,7 +2131,7 @@ ont_1_1_4_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) req='{ "ont_id": '$ont_1_1_4_1_1', "description": "OntPort 1/1/4/1/1/1/1", - "admin_state": "up" + "admin_state": "1" }' ont_port_1_1_4_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) @@ -2142,8 +2142,8 @@ req='{ "connected_id": '$ont_port_1_1_4_1_1_1_1', "connected_type": "port", "name": "1/1/4/1/1/1/1", - "admin_state": "up", - "operational_state": "up" + "admin_state": "1", + "operational_state": "1" }' service_port_1_1_4_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -2178,7 +2178,7 @@ req='{ "ont_port_id": '$ont_port_1_1_4_1_1_1_1', "description": "Cpe 1/1/4/1/1/1/1/1", "serial_no": "GFED123456XY", - "admin_state": "up", + "admin_state": "1", "mac": "a4:c9:21:bd:11:c3" }' @@ -2202,8 +2202,8 @@ cpe_port_1_1_4_1_1_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ req='{ "card_id": '$card_1_1_4', "description": "Physical port 1/1/4/2", - "operational_state": "down", - "admin_state": "up", + "operational_state": "0", + "admin_state": "1", "upstream": 0, "downstream": 0, "upstream_max": 100000, @@ -2291,8 +2291,8 @@ req='{ "connected_id": '$port_1_1_4_2', "connected_type": "port", "name": "1/1/4/2", - "admin_state": "up", - "operational_state": "down" + "admin_state": "1", + "operational_state": "0" }' service_port_1_1_4_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -2326,7 +2326,7 @@ service_vlan_=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlans) req='{ "port_id":'$port_1_1_4_2', "description": "Ont 1/1/4/2/1", - "admin_state": "up", + "admin_state": "1", "index": 1, "type": "10gbaselr", "basebx10d": "yes", @@ -2375,7 +2375,7 @@ ont_1_1_4_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) req='{ "ont_id": '$ont_1_1_4_2_1', "description": "OntPort 1/1/4/2/1/1/1", - "admin_state": "down" + "admin_state": "0" }' ont_port_1_1_4_2_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) @@ -2386,8 +2386,8 @@ req='{ "connected_id": '$ont_port_1_1_4_2_1_1_1', "connected_type": "port", "name": "1/1/4/2/1/1/1", - "admin_state": "up", - "operational_state": "up" + "admin_state": "1", + "operational_state": "1" }' service_port_1_1_4_2_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -2422,7 +2422,7 @@ req='{ "ont_port_id": '$ont_port_1_1_4_2_1_1_1', "description": "Cpe 1/1/4/2/1/1/1/1", "serial_no": "GFED123456YZ", - "admin_state": "down", + "admin_state": "0", "mac": "04:1f:1a:14:fc:35" }' @@ -2446,8 +2446,8 @@ cpe_port_1_1_4_2_1_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ req='{ "card_id": '$card_1_1_4', "description": "Physical port 1/1/4/3", - "operational_state": "down", - "admin_state": "down", + "operational_state": "0", + "admin_state": "0", "upstream": 0, "downstream": 0, "upstream_max": 100000, @@ -2535,8 +2535,8 @@ req='{ "connected_id": '$port_1_1_4_3', "connected_type": "port", "name": "1/1/4/2", - "admin_state": "down", - "operational_state": "down" + "admin_state": "0", + "operational_state": "0" }' service_port_1_1_4_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -2570,7 +2570,7 @@ service_vlan_=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlans) req='{ "port_id":'$port_1_1_4_3', "description": "Ont 1/1/4/3/1", - "admin_state": "down", + "admin_state": "0", "index": 1, "type": "10gbaselr", "basebx10d": "yes", @@ -2619,7 +2619,7 @@ ont_1_1_4_3_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) req='{ "ont_id": '$ont_1_1_4_3_1', "description": "OntPort 1/1/4/3/1/1/1", - "admin_state": "down" + "admin_state": "0" }' ont_port_1_1_4_3_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) @@ -2630,8 +2630,8 @@ req='{ "connected_id": '$ont_port_1_1_4_3_1_1_1', "connected_type": "port", "name": "1/1/4/3/1/1/1", - "admin_state": "down", - "operational_state": "down" + "admin_state": "0", + "operational_state": "0" }' service_port_1_1_4_3_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -2666,7 +2666,7 @@ req='{ "ont_port_id": '$ont_port_1_1_4_3_1_1_1', "description": "Cpe 1/1/4/3/1/1/1/1", "serial_no": "GFED123456WQ", - "admin_state": "down", + "admin_state": "0", "mac": "5b:8a:36:50:d4:8b" }' @@ -2692,8 +2692,8 @@ req='{ "description": "Physical card 1/1/5", "planned_type": "fant-f", "actual_type": "fant-f", - "operational_state": "enabled", - "admin_state": "unlock", + "operational_state": "1", + "admin_state": "1", "err_state": "no-error", "availability": "available", "alarm_profile": "none", @@ -2725,8 +2725,8 @@ card_1_1_5=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) req='{ "card_id": '$card_1_1_5', "description": "Physical port 1/1/5/1", - "operational_state": "up", - "admin_state": "up", + "operational_state": "1", + "admin_state": "1", "upstream": 10000, "downstream": 25000, "upstream_max": 100000, @@ -2814,8 +2814,8 @@ req='{ "connected_id": '$port_1_1_5_1', "connected_type": "port", "name": "1/1/5/1", - "admin_state": "up", - "operational_state": "up" + "admin_state": "1", + "operational_state": "1" }' service_port_1_1_5_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -2849,7 +2849,7 @@ service_vlan_=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlans) req='{ "port_id":'$port_1_1_5_1', "description": "Ont 1/1/5/1/1", - "admin_state": "up", + "admin_state": "1", "index": 1, "type": "10gbaselr", "basebx10d": "yes", @@ -2898,7 +2898,8 @@ ont_1_1_5_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) req='{ "ont_id": '$ont_1_1_5_1_1', "description": "OntPort 1/1/5/1/1/1/1", - "admin_state": "up" + "admin_state": "1", + "operational_state": "1" }' ont_port_1_1_5_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) @@ -2909,8 +2910,8 @@ req='{ "connected_id": '$ont_port_1_1_5_1_1_1_1', "connected_type": "ont", "name": "1/1/5/1/1/1/1", - "admin_state": "up", - "operational_state": "up" + "admin_state": "1", + "operational_state": "1" }' service_port_1_1_5_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -2945,7 +2946,7 @@ req='{ "ont_port_id": '$ont_port_1_1_5_1_1_1_1', "description": "Cpe 1/1/5/1/1/1/1/1", "serial_no": "GFED135790XY", - "admin_state": "up", + "admin_state": "1", "mac": "29:62:57:a6:60:69" }' @@ -2969,7 +2970,7 @@ cpe_port_1_1_5_1_1_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ req='{ "port_id":'$port_1_1_5_1', "description": "Ont 1/1/5/1/2", - "admin_state": "up", + "admin_state": "1", "index": 1, "type": "10gbaselr", "basebx10d": "yes", @@ -3018,7 +3019,7 @@ ont_1_1_5_1_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) req='{ "ont_id": '$ont_1_1_5_1_2', "description": "OntPort 1/1/5/1/2/1/1", - "admin_state": "up" + "admin_state": "1" }' ont_port_1_1_5_1_2_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) @@ -3029,8 +3030,8 @@ req='{ "connected_id": '$ont_port_1_1_5_1_2_1_1', "connected_type": "ont", "name": "1/1/5/1/2/1/1", - "admin_state": "up", - "operational_state": "up" + "admin_state": "1", + "operational_state": "1" }' service_port_1_1_5_1_2_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -3065,7 +3066,7 @@ req='{ "ont_port_id": '$ont_port_1_1_5_1_2_1_1', "description": "Cpe 1/1/5/1/2/1/1/1", "serial_no": "GFED132546XY", - "admin_state": "up", + "admin_state": "1", "mac": "08:97:dc:ca:07:8e" }' @@ -3089,7 +3090,7 @@ cpe_port_1_1_5_1_2_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ req='{ "ont_id": '$ont_1_1_5_1_2', "description": "OntPort 1/1/5/1/2/1/2", - "admin_state": "up" + "admin_state": "1" }' ont_port_1_1_5_1_2_1_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) @@ -3100,8 +3101,8 @@ req='{ "connected_id": '$ont_port_1_1_5_1_2_1_2', "connected_type": "ont", "name": "1/1/5/1/2/1/2", - "admin_state": "up", - "operational_state": "up" + "admin_state": "1", + "operational_state": "1" }' service_port_1_1_5_1_2_1_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) @@ -3136,7 +3137,7 @@ req='{ "ont_port_id": '$ont_port_1_1_5_1_2_1_2', "description": "Cpe 1/1/5/1/2/1/2/1", "serial_no": "GFED213465XY", - "admin_state": "up", + "admin_state": "1", "mac": "6f:4a:1e:b4:51:f5" }' diff --git a/bootup/conf/bootstraps/create-box-port-vlan.sh b/bootup/conf/bootstraps/create-box-port-vlan.sh index 246c498..ae09875 100755 --- a/bootup/conf/bootstraps/create-box-port-vlan.sh +++ b/bootup/conf/bootstraps/create-box-port-vlan.sh @@ -74,8 +74,8 @@ req='{ "description": "Physical subrack #1", "planned_type": "rant-a", "actual_type": "rant-a", - "operational_state": "enabled", - "admin_state": "unlock", + "operational_state": "1", + "admin_state": "1", "err_state": "no-error", "availability": "available", "mode": "no-extended-lt-slots", diff --git a/bootup/conf/bootstraps/create-custom-benchmark-box.sh b/bootup/conf/bootstraps/create-custom-benchmark-box.sh index 3749fc5..68793b1 100755 --- a/bootup/conf/bootstraps/create-custom-benchmark-box.sh +++ b/bootup/conf/bootstraps/create-custom-benchmark-box.sh @@ -178,7 +178,7 @@ do "name": "'$name'", "description": "Physical port #'$k'", "card_id": '$total_card_count', - "operational_state": "up", + "operational_state": "1", "admin_state": "'$admin'" },' >> $ports_file @@ -333,8 +333,8 @@ do "name": "1/'$i'/'$j'", "description": "Physical card #'$j'", "subrack_id": '$total_subrack_count', - "operational_state": "enabled", - "admin_state": "unlock", + "operational_state": "1", + "admin_state": "1", "product": "'$card_type'", "ppc": "'$ppc'" },' >> $cards_file @@ -344,8 +344,8 @@ do "name": "'`expr $i - 1`'/'`expr $j - 1`'", "description": "Physical card #'$j'", "subrack_id": '$total_subrack_count', - "operational_state": "enabled", - "admin_state": "unlock", + "operational_state": "1", + "admin_state": "1", "product": "'$card_type'", "ppc": "'$ppc'", "board_name": "'$board_name'" @@ -362,8 +362,8 @@ do echo ' "'$i'": { "name": "'$name'", "description": "Physical subrack #'$i'", - "operational_state": "enabled", - "admin_state": "unlock" + "operational_state": "1", + "admin_state": "1" },' >> $subracks_file ((i++)) ((total_subrack_count++)) diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh old mode 100755 new mode 100644 index f64e34a..0d38caa --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -19,6 +19,56 @@ path="`dirname \"$0\"`" . $path/functions.sh +#--------------------------------------------------------# +# # +# Subrack 1/1 # +# |---> Card 1/1/1 (vdsl) # +# | |-> Port 1/1/1/1 # +# | | |-> Cpe 1/1/1/1/1 # +# | | |-> CpePort 1/1/1/1/1/1 # +# | |-> Port 1/1/1/2 # +# | | |-> Cpe 1/1/1/2/1 # +# | | |-> CpePort 1/1/1/2/1/1 # +# | |-> Port 1/1/1/3 # +# | # +# |---> Card 1/1/2 (adsl) # +# | |-> Port 1/1/2/1 # +# | | |-> Cpe 1/1/2/1/1 # +# | | |-> CpePort 1/1/2/1/1/1 # +# | |-> Port 1/1/2/2 # +# | | |-> Cpe 1/1/2/2/1 # +# | | |-> CpePort 1/1/2/2/1/1 # +# | |-> Port 1/1/2/3 # +# | # +# |---> Card 1/1/4 (ftth) # +# | |-> Port 1/1/4/1 # +# | | |-> Ont 1/1/4/1/1 # +# | | |-> OntPort 1/1/4/1/1/1/1 # +# | | |-> Cpe 1/1/4/1/1/1/1/1 # +# | | |-> CpePort 1/1/4/1/1/1/1/1/1 # +# | |-> Port 1/1/4/2 # +# | | |-> Ont 1/1/4/2/1 # +# | | |-> OntPort 1/1/4/2/1/1/1 # +# | | |-> Cpe 1/1/4/2/1/1/1/1 # +# | | |-> CpePort 1/1/4/2/1/1/1/1/1 # +# | |-> Port 1/1/4/3 # +# | # +# |---> Card 1/1/5 (ftth-pon) # +# |-> Port 1/1/5/1 # +# |-> Ont 1/1/5/1/1 # +# | |-> OntPort 1/1/5/1/1/1/1 # +# | |-> Cpe 1/1/5/1/1/1/1/1 # +# | |-> CpePort 1/1/5/1/1/1/1/1/1 # +# |-> Ont 1/1/5/1/2 # +# |-> OntPort 1/1/5/1/2/1/1 # +# | |-> Cpe 1/1/5/1/2/1/1/1 # +# | |-> CpePort 1/1/5/1/2/1/1/1/1 # +# |-> OntPort 1/1/5/1/2/1/2 # +# |-> Cpe 1/1/5/1/2/1/2/1 # +# |-> CpePort 1/1/5/1/2/1/2/1/1 # +# # +#--------------------------------------------------------# + # Create a network device (admin operation) req='{ "vendor": "Huawei", @@ -58,479 +108,202 @@ req='{ root_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) -# PortProfile 1 -req='{ - "name": "PPPoe", - "type": "service", - "description": "PortProfile #1" -}' - -port_profile_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/port_profiles) - -# VLAN 1 -req='{ - "number": 2602, - "name": "VLAN_2602", - "description": "VLAN #1", - "type": "smart", - "attribute": "common", - "bind_service_profile_id": '$port_profile_id', - "bind_RAIO_profile_index": "-", - "priority": "-", - "state": "up", - "native_vlan" : "1" -}' - -vlan_id1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlans) - -### Emu 0 ### - -# Create a physical emu at the network device (admin operation) -req='{ - "type": "FAN", - "number": 0 -}' -emu_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/emus) - -req='{ - "number": 1 -}' -emu_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/emus) - -### Emu 0 ### - -# Create a physical emu at the network device (admin operation) -req='{ - "type": "H831PMU", - "number": 2 -}' -emu_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/emus) - ### Subrack 0 ### # Create a physical subrack at the network device (admin operation) req='{ "name": "0", - "description": "Physical subrack #1" + "description": "Physical subrack 0" }' -subrack_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks) +subrack_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks) -### Card 1 ### +### Card 0/0 ### # Create a physical card at the network device (admin operation) req='{ - "subrack_id": '$subrack_id', - "description": "Physical card #1", + "subrack_id": '$subrack_0', + "description": "Physical card 0/0", "product": "vdsl", "board_name": "H83BVCMM" }' -card1_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - -### Card 2 ### - -# Create a physical card at the network device (admin operation) -req='{ - "subrack_id": '$subrack_id', - "description": "Physical card #2", - "product": "adsl", - "board_name": "H83BVCNN" -}' - -card2_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - -### Card 3 ### - -# Create a physical card at the network device (admin operation) -req='{ - "subrack_id": '$subrack_id', - "description": "Physical card #3", - "product": "ftth-pon", - "board_name": "H807GPBH" -}' - -card3_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - -### Card 4 ### - -# Create a physical card at the network device (admin operation) -req='{ - "subrack_id": '$subrack_id', - "description": "Physical card #4", - "product": "ftth", - "board_name": "H831EIUD" -}' - -card4_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - -### Card 5 ### - -# Create a physical card at the network device (admin operation) -req='{ - "subrack_id": '$subrack_id', - "description": "Physical card #5", - "product": "ftth", - "board_name": "H802OPGE" -}' - -card5_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - -### Card 6 ### - -# Create a physical card at the network device (admin operation) -req='{ - "subrack_id": '$subrack_id', - "description": "Physical card #6", - "product": "ftth-pon", - "board_name": "H807GPBH" -}' - -card6_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +card_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) -### Card 7 ### - -# Create a physical card at the network device (admin operation) -req='{ - "subrack_id": '$subrack_id', - "description": "Physical card #7", - "product": "ftth-pon", - "board_name": "H807GPBH" -}' - -card7_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - -### PORT 1 and deps ### +### PORT 0/0/0 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card1_id', - "description": "Physical port #1 on this card", + "card_id": '$card_0_0', + "description": "Physical port 0/0/0", "loopback": "disable", - "upstream": 1234, - "downstream": 4321, + "upstream": 10000, + "downstream": 25000, "upstream_max": 100000, "downstream_max": 100000, - "admin_state": "deactivated" + "admin_state": "1", + "operational_state": "1" }' -port1_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### PORT 2 and deps ### +### PORT 0/0/1 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card2_id', - "description": "Physical port #1 on this card", + "card_id": '$card_0_0', + "description": "Physical port 0/0/1", "loopback": "disable", - "upstream": 1234, - "downstream": 4321, + "upstream": 0, + "downstream": 0, "upstream_max": 100000, "downstream_max": 100000, - "admin_state": "deactivated" + "admin_state": "1", + "operational_state": "0" }' -port2_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) - +port_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### PORT 3 and deps ### +### PORT 0/0/2 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card3_id', - "description": "Physical port #1 on this card", + "card_id": '$card_0_0', + "description": "Physical port 0/0/2", + "loopback": "disable", "upstream": 0, "downstream": 0, "upstream_max": 100000, "downstream_max": 100000, - "loopback": "disable", - "admin_state": "deactivated" + "admin_state": "0", + "operational_state": "0" }' -port3_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_0_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### PORT 4 and deps ### +### Card 0/1 ### -# Create a physical port at the network device (admin operation) +# Create a physical card at the network device (admin operation) req='{ - "card_id": '$card4_id', - "description": "Physical port #1 on this card", - "loopback": "disable", - "upstream": 1234, - "downstream": 4321, - "upstream_max": 100000, - "downstream_max": 100000, - "admin_state": "deactivated" + "subrack_id": '$subrack_0', + "description": "Physical card 0/1", + "product": "adsl", + "board_name": "H83BVCNN" }' -port4_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +card_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) -### PORT 5 and deps ### +### PORT 0/1/0 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card5_id', - "description": "Physical port #1 on this card", + "card_id": '$card_0_1', + "description": "Physical port 0/1/0", "loopback": "disable", - "upstream": 1234, - "downstream": 4321, + "upstream": 10000, + "downstream": 25000, "upstream_max": 100000, "downstream_max": 100000, - "admin_state": "deactivated" + "admin_state": "1", + "operational_state": "1" }' -port5_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) - +port_0_1_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### PORT 6 and deps ### +### PORT 0/1/1 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card5_id', - "description": "Physical port #2 on this card", + "card_id": '$card_0_1', + "description": "Physical port 0/1/1", "loopback": "disable", - "upstream": 1234, - "downstream": 4321, + "upstream": 0, + "downstream": 0, "upstream_max": 100000, "downstream_max": 100000, - "admin_state": "deactivated", - "link": "failed" + "admin_state": "1", + "operational_state": "0" }' -port6_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### PORT 7 and deps ### +### PORT 0/1/2 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card6_id', - "description": "Physical port #7 on this card", + "card_id": '$card_0_0', + "description": "Physical port 0/1/2", "loopback": "disable", - "upstream": 1234, - "downstream": 4321, + "upstream": 0, + "downstream": 0, "upstream_max": 100000, "downstream_max": 100000, - "admin_state": "deactivated", - "link": "failed" + "admin_state": "0", + "operational_state": "0" }' -port7_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_1_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### PORT 8 and deps ### +### Card 0/2 ### -# Create a physical port at the network device (admin operation) +# Create a physical card at the network device (admin operation) req='{ - "card_id": '$card7_id', - "description": "Physical port #8 on this card", - "loopback": "disable", - "upstream": 1234, - "downstream": 4321, - "upstream_max": 100000, - "downstream_max": 100000, - "admin_state": "deactivated", - "link": "failed" + "subrack_id": '$subrack_0', + "description": "Physical card 0/2", + "product": "ftth", + "board_name": "H831EIUD" }' -port8_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +card_0_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) -### PORT 9 and deps ### +### PORT 0/2/0 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card7_id', - "description": "Physical port #9 on this card", + "card_id": '$card_0_2', + "description": "Physical port 0/2/0", "loopback": "disable", - "upstream": 1234, - "downstream": 4321, + "upstream": 10000, + "downstream": 25000, "upstream_max": 100000, "downstream_max": 100000, - "admin_state": "deactivated", - "link": "failed" -}' - -port9_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) - -### Ont 1 ### - -# Create a physical ont at the network device (admin operation) - -req='{ - "port_id":'$port3_id', - "description": "Ont #1", - "memory_occupation": "50%", - "cpu_occupation": "1%", - "index": 0 -}' - -ont_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) - -### Ont 2 ### - -# Create a physical ont at the network device (admin operation) - -req='{ - "port_id":'$port7_id', - "description": "Ont #2", - "index": 0 -}' - -ont2_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) - -### Ont 3 ### - -# Create a physical ont at the network device (admin operation) - -req='{ - "port_id":'$port7_id', - "description": "Ont #3", - "index": 1 -}' - -ont3_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) - -### Ont 4 ### - -# Create a physical ont at the network device (admin operation) - -req='{ - "port_id":'$port7_id', - "description": "Ont #4", - "index": 2 -}' - -ont4_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) - -### Ont 5 ### - -# Create a physical ont at the network device (admin operation) - -req='{ - "port_id":'$port8_id', - "description": "Ont #5", - "index": 0 -}' - -ont5_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) - -### Ont 6 ### - -# Create a physical ont at the network device (admin operation) - -req='{ - "port_id":'$port9_id', - "description": "Ont #6", - "index": 1 -}' - -ont7id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) - -### OntPort 1 ### - -# Create a physical ont-port at the ont (admin operation) - -req='{ - "ont_id": '$ont_id', - "ont_port_index": 0, - "description": "OntPort #1", - "ont_port_type": "ETH" -}' - -ont_port_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) - -### OntPort 1 ### - -# Create a physical ont-port at the ont (admin operation) - -req='{ - "ont_id": '$ont2_id', - "ont_port_index": 0, - "description": "OntPort #2", - "ont_port_type": "ETH" -}' - -ont_port2_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) - -### Cpe 1 ### - -# Create a physical cpe at the ont-port (admin operation) - -req='{ - "ont_port_id": '$ont_port_id', - "description": "Cpe #1", - "mac": "8f:db:82:ef:ea:17" -}' - -cpe_id1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) - -### Cpe 2 ### - -# Create a physical cpe at the vdsl-port (admin operation) - -req='{ - "port_id": '$port1_id', - "description": "Cpe #2", - "mac": "8f:db:82:ef:ea:17" -}' - -cpe_id2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) - -### Cpe 3 ### - -# Create a physical cpe at the adsl-port (admin operation) - -req='{ - "port_id": '$port2_id', - "description": "Cpe #3", - "mac": "8f:db:82:ef:ea:17" -}' - -cpe_id3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) - -### CpePort 1 ### - -# Create a physical cpe-port at the cpe (admin operation) - -req='{ - "cpe_id": '$cpe_id1', - "description": "CpePort #1" + "admin_state": "1", + "operational_state": "1" }' -cpe_port_id1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +port_0_2_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### CpePort 2 ### - -# Create a physical cpe-port at the vdsl-cpe (admin operation) +### PORT 0/2/1 and deps ### +# Create a physical port at the network device (admin operation) req='{ - "cpe_id": '$cpe_id2', - "description": "CpePort #2" + "card_id": '$card_0_2', + "description": "Physical port 0/2/1", + "loopback": "disable", + "upstream": 0, + "downstream": 0, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "1", + "operational_state": "0" }' -cpe_port_id2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) - -### CpePort 3 ### +port_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -# Create a physical cpe-port at the vdsl-cpe (admin operation) +### PORT 0/2/2 and deps ### +# Create a physical port at the network device (admin operation) req='{ - "cpe_id": '$cpe_id3', - "description": "CpePort #3" + "card_id": '$card_0_2', + "description": "Physical port 0/2/2", + "loopback": "disable", + "upstream": 0, + "downstream": 0, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "0", + "operational_state": "0" }' -cpe_port_id3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) - -### VlanInterface 1 ### - -# Create a vlan interface - -req='{ - "name": "vlanif2602", - "vlan_id": '$vlan_id1', - "admin_state": "UP", - "line_proto_state": "DOWN", - "internet_protocol": "enabled", - "internet_address": "127.0.0.1", - "subnet_num": "24" -}' +port_0_1_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -vlan_interface_id1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlan_interfaces) diff --git a/bootup/conf/bootstraps/create-huawei-5623_old.sh b/bootup/conf/bootstraps/create-huawei-5623_old.sh new file mode 100755 index 0000000..d70f608 --- /dev/null +++ b/bootup/conf/bootstraps/create-huawei-5623_old.sh @@ -0,0 +1,596 @@ +#!/bin/bash +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst +# +# Example NESi REST API server bootstrapping +# + +ENDPOINT=http://localhost:5000/nesi/v1 + +path="`dirname \"$0\"`" + +. $path/functions.sh + +#--------------------------------------------------------# +# # +# Subrack 1/1 # +# |---> Card 1/1/1 (xdsl) # +# | |-> Port 1/1/1/1 # +# | | |-> Cpe 1/1/1/1/1 # +# | | |-> CpePort 1/1/1/1/1/1 # +# | |-> Port 1/1/1/2 # +# | | |-> Cpe 1/1/1/2/1 # +# | | |-> CpePort 1/1/1/2/1/1 # +# | |-> Port 1/1/1/3 # +# | # +# |---> Card 1/1/2 (vdsl) # +# | |-> Port 1/1/2/1 # +# | | |-> Cpe 1/1/2/1/1 # +# | | |-> CpePort 1/1/2/1/1/1 # +# | |-> Port 1/1/2/2 # +# | | |-> Cpe 1/1/2/2/1 # +# | | |-> CpePort 1/1/2/2/1/1 # +# | |-> Port 1/1/2/3 # +# | # +# |---> Card 1/1/3 (adsl) # +# | |-> Port 1/1/3/1 # +# | | |-> Cpe 1/1/3/1/1 # +# | | |-> CpePort 1/1/3/1/1/1 # +# | |-> Port 1/1/3/2 # +# | | |-> Cpe 1/1/3/2/1 # +# | | |-> CpePort 1/1/3/2/1/1 # +# | |-> Port 1/1/3/3 # +# | # +# |---> Card 1/1/4 (ftth) # +# | |-> Port 1/1/4/1 # +# | | |-> Ont 1/1/4/1/1 # +# | | |-> OntPort 1/1/4/1/1/1/1 # +# | | |-> Cpe 1/1/4/1/1/1/1/1 # +# | | |-> CpePort 1/1/4/1/1/1/1/1/1 # +# | |-> Port 1/1/4/2 # +# | | |-> Ont 1/1/4/2/1 # +# | | |-> OntPort 1/1/4/2/1/1/1 # +# | | |-> Cpe 1/1/4/2/1/1/1/1 # +# | | |-> CpePort 1/1/4/2/1/1/1/1/1 # +# | |-> Port 1/1/4/3 # +# | # +# |---> Card 1/1/5 (ftth-pon) # +# |-> Port 1/1/5/1 # +# |-> Ont 1/1/5/1/1 # +# | |-> OntPort 1/1/5/1/1/1/1 # +# | |-> Cpe 1/1/5/1/1/1/1/1 # +# | |-> CpePort 1/1/5/1/1/1/1/1/1 # +# |-> Ont 1/1/5/1/2 # +# |-> OntPort 1/1/5/1/2/1/1 # +# | |-> Cpe 1/1/5/1/2/1/1/1 # +# | |-> CpePort 1/1/5/1/2/1/1/1/1 # +# |-> OntPort 1/1/5/1/2/1/2 # +# |-> Cpe 1/1/5/1/2/1/2/1 # +# |-> CpePort 1/1/5/1/2/1/2/1/1 # +# # +#--------------------------------------------------------# + +# Create a network device (admin operation) +req='{ + "vendor": "Huawei", + "model": "5623", + "version": "A", + "description": "Example Switch", + "hostname": "Huawei_5623A", + "mgmt_address": "10.0.0.12", + "software_version": "MA5623V800R016C00", + "network_protocol": "telnet", + "network_address": "127.0.0.1", + "network_port": 9023, + "uuid": "5623" +}' + +box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 + +# Super Admin credentials +req='{ + "username": "root", + "password": "secret" +}' + +root_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# Super Admin user +req='{ + "name": "root", + "credentials_id": '$root_credential_id', + "level": "Super", + "profile": "root", + "append_info": "Super Admin", + "reenter_num": 3, + "reenter_num_temp": 3, + "lock_status": "Unlocked" +}' + +root_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) + +# PortProfile 1 +req='{ + "name": "PPPoe", + "type": "service", + "description": "PortProfile #1" +}' + +port_profile_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/port_profiles) + +# VLAN 1 +req='{ + "number": 2602, + "name": "VLAN_2602", + "description": "VLAN #1", + "type": "smart", + "attribute": "common", + "bind_service_profile_id": '$port_profile_id', + "bind_RAIO_profile_index": "-", + "priority": "-", + "state": "up", + "native_vlan" : "1" +}' + +vlan_id1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlans) + +### Emu 0 ### + +# Create a physical emu at the network device (admin operation) +req='{ + "type": "FAN", + "number": 0 +}' +emu_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/emus) + +req='{ + "number": 1 +}' +emu_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/emus) + +### Emu 0 ### + +# Create a physical emu at the network device (admin operation) +req='{ + "type": "H831PMU", + "number": 2 +}' +emu_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/emus) + +### Subrack 0 ### + +# Create a physical subrack at the network device (admin operation) +req='{ + "name": "0", + "description": "Physical subrack #1" +}' + +subrack_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks) + +### Card 1 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "description": "Physical card #1", + "product": "vdsl", + "board_name": "H83BVCMM" +}' + +card1_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Card 2 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "description": "Physical card #2", + "product": "adsl", + "board_name": "H83BVCNN" +}' + +card2_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Card 3 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "description": "Physical card #3", + "product": "ftth-pon", + "board_name": "H807GPBH" +}' + +card3_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Card 4 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "description": "Physical card #4", + "product": "ftth", + "board_name": "H831EIUD" +}' + +card4_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Card 5 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "description": "Physical card #5", + "product": "ftth", + "board_name": "H802OPGE" +}' + +card5_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Card 6 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "description": "Physical card #6", + "product": "ftth-pon", + "board_name": "H807GPBH" +}' + +card6_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Card 7 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "description": "Physical card #7", + "product": "ftth-pon", + "board_name": "H807GPBH" +}' + +card7_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### PORT 1 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card1_id', + "description": "Physical port #1 on this card", + "loopback": "disable", + "upstream": 1234, + "downstream": 4321, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "0" +}' + +port1_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### PORT 0/0/0 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card2_id', + "description": "Physical port #1 on this card", + "loopback": "disable", + "upstream": 1234, + "downstream": 4321, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "0" +}' + +port2_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + + +### PORT 3 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card3_id', + "description": "Physical port #1 on this card", + "upstream": 0, + "downstream": 0, + "upstream_max": 100000, + "downstream_max": 100000, + "loopback": "disable", + "admin_state": "0" +}' + +port3_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### PORT 4 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card4_id', + "description": "Physical port #1 on this card", + "loopback": "disable", + "upstream": 1234, + "downstream": 4321, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "0" +}' + +port4_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### PORT 5 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card5_id', + "description": "Physical port #1 on this card", + "loopback": "disable", + "upstream": 1234, + "downstream": 4321, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "0" +}' + +port5_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + + +### PORT 6 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card5_id', + "description": "Physical port #2 on this card", + "loopback": "disable", + "upstream": 1234, + "downstream": 4321, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "0", + "link": "failed" +}' + +port6_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### PORT 7 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card6_id', + "description": "Physical port #7 on this card", + "loopback": "disable", + "upstream": 1234, + "downstream": 4321, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "0", + "link": "failed" +}' + +port7_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### PORT 8 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card7_id', + "description": "Physical port #8 on this card", + "loopback": "disable", + "upstream": 1234, + "downstream": 4321, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "0", + "link": "failed" +}' + +port8_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### PORT 9 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card7_id', + "description": "Physical port #9 on this card", + "loopback": "disable", + "upstream": 1234, + "downstream": 4321, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "0", + "link": "failed" +}' + +port9_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Ont 1 ### + +# Create a physical ont at the network device (admin operation) + +req='{ + "port_id":'$port3_id', + "description": "Ont #1", + "memory_occupation": "50%", + "cpu_occupation": "1%", + "index": 0 +}' + +ont_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### Ont 2 ### + +# Create a physical ont at the network device (admin operation) + +req='{ + "port_id":'$port7_id', + "description": "Ont #2", + "index": 0 +}' + +ont2_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### Ont 3 ### + +# Create a physical ont at the network device (admin operation) + +req='{ + "port_id":'$port7_id', + "description": "Ont #3", + "index": 1 +}' + +ont3_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### Ont 4 ### + +# Create a physical ont at the network device (admin operation) + +req='{ + "port_id":'$port7_id', + "description": "Ont #4", + "index": 2 +}' + +ont4_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### Ont 5 ### + +# Create a physical ont at the network device (admin operation) + +req='{ + "port_id":'$port8_id', + "description": "Ont #5", + "index": 0 +}' + +ont5_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### Ont 6 ### + +# Create a physical ont at the network device (admin operation) + +req='{ + "port_id":'$port9_id', + "description": "Ont #6", + "index": 1 +}' + +ont7id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### OntPort 1 ### + +# Create a physical ont-port at the ont (admin operation) + +req='{ + "ont_id": '$ont_id', + "ont_port_index": 0, + "description": "OntPort #1", + "ont_port_type": "ETH" +}' + +ont_port_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) + +### OntPort 1 ### + +# Create a physical ont-port at the ont (admin operation) + +req='{ + "ont_id": '$ont2_id', + "ont_port_index": 0, + "description": "OntPort #2", + "ont_port_type": "ETH" +}' + +ont_port2_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) + +### Cpe 1 ### + +# Create a physical cpe at the ont-port (admin operation) + +req='{ + "ont_port_id": '$ont_port_id', + "description": "Cpe #1", + "mac": "8f:db:82:ef:ea:17" +}' + +cpe_id1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### Cpe 2 ### + +# Create a physical cpe at the vdsl-port (admin operation) + +req='{ + "port_id": '$port1_id', + "description": "Cpe #2", + "mac": "8f:db:82:ef:ea:17" +}' + +cpe_id2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### Cpe 3 ### + +# Create a physical cpe at the adsl-port (admin operation) + +req='{ + "port_id": '$port2_id', + "description": "Cpe #3", + "mac": "8f:db:82:ef:ea:17" +}' + +cpe_id3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 1 ### + +# Create a physical cpe-port at the cpe (admin operation) + +req='{ + "cpe_id": '$cpe_id1', + "description": "CpePort #1" +}' + +cpe_port_id1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + +### CpePort 2 ### + +# Create a physical cpe-port at the vdsl-cpe (admin operation) + +req='{ + "cpe_id": '$cpe_id2', + "description": "CpePort #2" +}' + +cpe_port_id2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + +### CpePort 3 ### + +# Create a physical cpe-port at the vdsl-cpe (admin operation) + +req='{ + "cpe_id": '$cpe_id3', + "description": "CpePort #3" +}' + +cpe_port_id3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + +### VlanInterface 1 ### + +# Create a vlan interface + +req='{ + "name": "vlanif2602", + "vlan_id": '$vlan_id1', + "admin_state": "UP", + "line_proto_state": "DOWN", + "internet_protocol": "enabled", + "internet_address": "127.0.0.1", + "subnet_num": "24" +}' + +vlan_interface_id1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlan_interfaces) diff --git a/bootup/conf/bootstraps/test-api-endpoints.sh b/bootup/conf/bootstraps/test-api-endpoints.sh index 288223b..4f47a2f 100755 --- a/bootup/conf/bootstraps/test-api-endpoints.sh +++ b/bootup/conf/bootstraps/test-api-endpoints.sh @@ -109,8 +109,8 @@ req='{ "description": "Physical subrack #1", "planned_type": "rant-a", "actual_type": "rant-a", - "operational_state": "enabled", - "admin_state": "unlock", + "operational_state": "1", + "admin_state": "1", "err_state": "no-error", "availability": "available", "mode": "no-extended-lt-slots", @@ -142,8 +142,8 @@ req='{ "description": "Physical card #1", "planned_type": "fant-f", "actual_type": "fant-f", - "operational_state": "enabled", - "admin_state": "unlock", + "operational_state": "1", + "admin_state": "1", "err_state": "no-error", "availability": "available", "alarm_profile": "none", @@ -186,8 +186,8 @@ req='{ "name": "1/1/1/1", "card_id": '$card_id', "description": "Physical port #1", - "operational_state": "down", - "admin_state": "down", + "operational_state": "0", + "admin_state": "0", "upstream": 0, "downstream": 0, "upstream_max": 100000, diff --git a/nesi/alcatel/alcatel_resources/alcatel_cpe.py b/nesi/alcatel/alcatel_resources/alcatel_cpe.py index 6e0d0ef..07e6353 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_cpe.py +++ b/nesi/alcatel/alcatel_resources/alcatel_cpe.py @@ -22,11 +22,11 @@ class AlcatelCpe(Cpe): def admin_up(self): """Change cpe admin state to up.""" - self.update(admin_state="up") + self.update(admin_state='1') def admin_down(self): """Change cpe admin state to down.""" - self.update(admin_state="down") + self.update(admin_state='0') class AlcatelCpeCollection(CpeCollection): diff --git a/nesi/alcatel/alcatel_resources/alcatel_ont.py b/nesi/alcatel/alcatel_resources/alcatel_ont.py index ef8a0f4..00c2847 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_ont.py +++ b/nesi/alcatel/alcatel_resources/alcatel_ont.py @@ -106,13 +106,13 @@ class AlcatelOnt(Ont): def power_up(self): """Change ont admin state to up.""" - self.update(admin_state="up") - self.update(operational_state="up") + self.update(admin_state='1') + self.update(operational_state='1') def power_down(self): """Change ont admin state to down.""" - self.update(admin_state="down") - self.update(operational_state="down") + self.update(admin_state='0') + self.update(operational_state='0') def set_type(self, type): """Change ont type.""" @@ -129,11 +129,11 @@ def set_cap1000base_xfd(self, value): def admin_up(self): """Change ont admin state to up.""" - self.update(admin_state="up") + self.update(admin_state='1') def admin_down(self): """Change ont admin state to down.""" - self.update(admin_state="down") + self.update(admin_state='0') class AlcatelOntCollection(OntCollection): diff --git a/nesi/alcatel/alcatel_resources/alcatel_ont_port.py b/nesi/alcatel/alcatel_resources/alcatel_ont_port.py index 6d603c4..061f765 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_ont_port.py +++ b/nesi/alcatel/alcatel_resources/alcatel_ont_port.py @@ -27,19 +27,19 @@ class AlcatelOntPort(OntPort): def port_up(self): """Change ont port state to up.""" - self.update(operational_state="up") + self.update(operational_state='1') def port_down(self): """Change ont port state to down.""" - self.update(operational_state="down") + self.update(operational_state='0') def admin_up(self): """Change ont port admin state to up.""" - self.update(admin_state="up") + self.update(admin_state='1') def admin_down(self): """Change ont port admin state to down.""" - self.update(admin_state="down") + self.update(admin_state='0') def set_description(self, user): """Set the description of the ont port""" diff --git a/nesi/huawei/huawei_resources/huawei_ont_port.py b/nesi/huawei/huawei_resources/huawei_ont_port.py index 3193e26..bd26ea7 100644 --- a/nesi/huawei/huawei_resources/huawei_ont_port.py +++ b/nesi/huawei/huawei_resources/huawei_ont_port.py @@ -49,11 +49,11 @@ class HuaweiOntPort(OntPort): def operational_state_down(self): """Change ont port operational state to down.""" - self.update(operational_state="down") + self.update(operational_state='0') def operational_state_up(self): """Change ont port operational state to up.""" - self.update(operational_state="up") + self.update(operational_state='1') class HuaweiOntPortCollection(OntPortCollection): diff --git a/nesi/huawei/huawei_resources/huawei_port.py b/nesi/huawei/huawei_resources/huawei_port.py index 4fedbf7..9a4206f 100644 --- a/nesi/huawei/huawei_resources/huawei_port.py +++ b/nesi/huawei/huawei_resources/huawei_port.py @@ -209,19 +209,19 @@ class HuaweiPort(Port): def admin_up(self): """Set the admin port state to up""" - self.update(admin_state="activated") + self.update(admin_state='1') def admin_down(self): """Set the admin port state to down""" - self.update(admin_state="deactivated") + self.update(admin_state='0') def port_up(self): """Set the port status to 'UP'""" - self.update(operational_state="up") + self.update(operational_state='1') def port_down(self): """Set the port status to 'DOWN'""" - self.update(operational_state="down") + self.update(operational_state='0') def port_downstream_set(self, ds_rate): self.update(downstream_max=ds_rate) diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index fea5ecd..a7d2188 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -34,8 +34,8 @@ class Card(db.Model): dual_tag_mode = db.Column(db.Boolean(), default=False) actual_type = db.Column(db.Enum('rdlt-c', 'rant-a', 'nant-a', 'nrnt-a', 'fant-f', 'relt-a', 'nelt-b', 'fglt-b', 'ngfc-f', 'empty'), default='empty') - admin_state = db.Column(db.Enum('unlock', 'disabled'), default='disabled') - operational_state = db.Column(db.Enum('enabled', 'disabled'), default='disabled') + admin_state = db.Column(db.Enum('0', '1'), default='0') # Alcatel: 0 => disabled, 1 => unlock + operational_state = db.Column(db.Enum('0', '1'), default='0') # Alcatel: 0 => disabled, 1 => enabled err_state = db.Column(db.Enum('no-error', 'error', 'type-mismatch'), default='no-error') availability = db.Column(db.Enum('available', 'unavailable', 'not-installed'), default='available') alarm_profile = db.Column(db.Enum('none'), default='none') diff --git a/nesi/softbox/api/models/cpe_models.py b/nesi/softbox/api/models/cpe_models.py index f4cddf5..c16758e 100644 --- a/nesi/softbox/api/models/cpe_models.py +++ b/nesi/softbox/api/models/cpe_models.py @@ -23,7 +23,7 @@ class Cpe(db.Model): cpe_ports = db.relationship('CpePort', backref='Cpe', lazy='dynamic') name = db.Column(db.String(64)) serial_no = db.Column(db.String(), default='ABCD123456EF') - admin_state = db.Column(db.Enum('up', 'down'), default='down') + admin_state = db.Column(db.Enum('0', '1'), default='0') # 0 => down, 1 => up description = db.Column(db.String()) mac = db.Column(db.String(64), nullable=False) diff --git a/nesi/softbox/api/models/ont_models.py b/nesi/softbox/api/models/ont_models.py index cef3c39..add3395 100644 --- a/nesi/softbox/api/models/ont_models.py +++ b/nesi/softbox/api/models/ont_models.py @@ -18,8 +18,8 @@ class Ont(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) description = db.Column(db.String()) - admin_state = db.Column(db.Enum('up', 'down'), nullable=False, default='down') - operational_state = db.Column(db.Enum('up', 'down'), nullable=False, default='down') + admin_state = db.Column(db.Enum('0', '1'), default='0') # Alcatel: 0 => down, 1 => up; Huawei: 0 => offline, 1 => online + operational_state = db.Column(db.Enum('0', '1'), default='0') # Alcatel: 0 => down, 1 => up; Huawei: 0 => offline, 1 => online box_id = db.Column(db.Integer, db.ForeignKey('box.id')) port_id = db.Column(db.Integer, db.ForeignKey('port.id')) diff --git a/nesi/softbox/api/models/ontport_models.py b/nesi/softbox/api/models/ontport_models.py index f094828..ccb551b 100644 --- a/nesi/softbox/api/models/ontport_models.py +++ b/nesi/softbox/api/models/ontport_models.py @@ -18,8 +18,8 @@ class OntPort(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) description = db.Column(db.String()) - operational_state = db.Column(db.Enum('up', 'down'), default='down') - admin_state = db.Column(db.Enum('up', 'down', 'not-appl'), default='down') + operational_state = db.Column(db.Enum('0', '1'), default='0') # Alcatel: 0 => down, 1 => up; Huawei: 0 => offline, 1 => online + admin_state = db.Column(db.Enum('0', '1', '2'), default='0') # Alcatel: 0 => down, 1 => up, 2 => not-appl; Huawei: 0 => offline, 1 => online # pon uni_idx = db.Column(db.String(64)) config_indicator = db.Column(db.String(), default='100baset-fd') diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 94b83bc..a839eda 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -29,8 +29,8 @@ class Port(db.Model): type = db.Column(db.Enum('pon', 'ethernet-line'), default='pon') shutdown = db.Column(db.Boolean(), default=False) speed = db.Column(db.Enum('10M', '1G', '10G'), default='1G') - operational_state = db.Column(db.Enum('up', 'down'), default='down') - admin_state = db.Column(db.Enum('up', 'down', 'not-appl', 'activated', 'activating', 'deactivated'), default='down') + operational_state = db.Column(db.Enum('0', '1', '2'), default='0') # Alcatel: 0 => down, 1 => up, 2 => not-appl; Huawei: 0 => deactivated, 1 => activated, 2 => activating + admin_state = db.Column(db.Enum('0', '1', '2'), default='0') # Alcatel: 0 => down, 1 => up, 2 => not-appl; Huawei: 0 => deactivated, 1 => activated, 2 => activating upstream = db.Column(db.Integer(), default=0) downstream = db.Column(db.Integer(), default=0) upstream_max = db.Column(db.Integer(), default=100000) diff --git a/nesi/softbox/api/models/service_port_models.py b/nesi/softbox/api/models/service_port_models.py index aeb4f01..2e7ca0a 100644 --- a/nesi/softbox/api/models/service_port_models.py +++ b/nesi/softbox/api/models/service_port_models.py @@ -5,8 +5,8 @@ class ServicePort(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) - admin_state = db.Column(db.Enum('enable', 'disable', 'up', 'down', 'not-appl'), default='enable') - operational_state = db.Column(db.Enum('up', 'down'), default='down') + admin_state = db.Column(db.Enum('0', '1', '2'), default='0') # Alcatel: 0 => down, 1 => up, 2 => not-appl; Huawei: 0 => disable, 1 => enable + operational_state = db.Column(db.Enum('0', '1'), default='0') # Alcatel: 0 => down, 1 => up; Huawei: 0 => disable, 1 => enable connected_id = db.Column(db.Integer(), nullable=False) connected_type = db.Column(db.Enum('port', 'ont', 'cpe'), nullable=False) diff --git a/nesi/softbox/api/models/subrack_models.py b/nesi/softbox/api/models/subrack_models.py index 9ad077f..a4cfa6e 100644 --- a/nesi/softbox/api/models/subrack_models.py +++ b/nesi/softbox/api/models/subrack_models.py @@ -24,8 +24,8 @@ class Subrack(db.Model): description = db.Column(db.String(), default='') planned_type = db.Column(db.Enum('rvxs-a', 'not-planned', 'planned', 'nfxs-f'), default='not-planned') actual_type = db.Column(db.Enum('rvxs-a', 'not-planned', 'planned', 'nfxs-f'), default='not-planned') - admin_state = db.Column(db.Enum('unlock', 'lock'), default='unlock') - operational_state = db.Column(db.Enum('enabled', 'disabled'), default='disabled') + admin_state = db.Column(db.Enum('0', '1'), default='0') # 0 => lock, 1 => unlock + operational_state = db.Column(db.Enum('0', '1'), default='0') # 0 => disabled, 1 => enabled err_state = db.Column(db.Enum('no-error', 'error'), default='no-error') availability = db.Column(db.Enum('available', 'unavailable', 'not-installed'), default='not-installed') mode = db.Column(db.Enum('no-extended-lt-slots', 'extended-lt-slots'), default='extended-lt-slots') diff --git a/nesi/softbox/base_resources/port.py b/nesi/softbox/base_resources/port.py index febdca6..74adc98 100644 --- a/nesi/softbox/base_resources/port.py +++ b/nesi/softbox/base_resources/port.py @@ -30,19 +30,19 @@ class Port(base.Resource): def admin_up(self): """Set the admin port state to up""" - self.update(admin_state="up") + self.update(admin_state='1') def admin_down(self): """Set the admin port state to down""" - self.update(admin_state="down") + self.update(admin_state='0') def down(self): """Set the port state to down""" - self.update(operational_state="down") + self.update(operational_state='0') def up(self): """Set the port state to down""" - self.update(operational_state="up") + self.update(operational_state='1') class PortCollection(base.ResourceCollection): diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_ethernet_line_identifier_detail.j2 b/templates/Alcatel/Base/1/login/mainloop/configure_ethernet_line_identifier_detail.j2 index e2ae388..d0f26e8 100644 --- a/templates/Alcatel/Base/1/login/mainloop/configure_ethernet_line_identifier_detail.j2 +++ b/templates/Alcatel/Base/1/login/mainloop/configure_ethernet_line_identifier_detail.j2 @@ -18,7 +18,7 @@ line {{ context.port.name }} exit mau 1 type {{ context.mau.type }} - power {% if 'up' in context.mau.admin_state %}on + power {% if '1' in context.mau.admin_state %}on {% else %}off {% endif %} no speed-auto-sense diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_ethernet_line_identifier_mau_identifier_detail.j2 b/templates/Alcatel/Base/1/login/mainloop/configure_ethernet_line_identifier_mau_identifier_detail.j2 index b607678..a01e5b2 100644 --- a/templates/Alcatel/Base/1/login/mainloop/configure_ethernet_line_identifier_mau_identifier_detail.j2 +++ b/templates/Alcatel/Base/1/login/mainloop/configure_ethernet_line_identifier_mau_identifier_detail.j2 @@ -4,7 +4,7 @@ echo "ethernet" #--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- mau {{ context.mau.index }} type {{ context.mau.type }} - power {% if 'up' in context.mau.admin_state %}on + power {% if '1' in context.mau.admin_state %}on {% else %}off {% endif %} no speed-auto-sense diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_middle.j2 b/templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_middle.j2 index 99f244a..86d2d1e 100644 --- a/templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_middle.j2 +++ b/templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_middle.j2 @@ -1,2 +1,2 @@ -{{ context.slot_name }}{{ context.spacer1 }}{{ context.card.actual_type }}{{ context.spacer2 }}{% if 'enabled' == context.card.operational_state %}yes{% else %}no{% endif %}{{ context.spacer3 }}{{ context.card.err_state }}{{ context.spacer4 }}{{ context.card.availability }}{{ context.spacer5 }}{{ context.card.restrt_cnt }} +{{ context.slot_name }}{{ context.spacer1 }}{{ context.card.actual_type }}{{ context.spacer2 }}{% if '1' == context.card.operational_state %}yes{% else %}no{% endif %}{{ context.spacer3 }}{{ context.card.err_state }}{{ context.spacer4 }}{{ context.card.availability }}{{ context.spacer5 }}{{ context.card.restrt_cnt }} diff --git a/templates/Alcatel/Base/1/login/mainloop/show/interface_port_pipe_match_match_exact_product_line_port.j2 b/templates/Alcatel/Base/1/login/mainloop/show/interface_port_pipe_match_match_exact_product_line_port.j2 index a4af702..4efb491 100644 --- a/templates/Alcatel/Base/1/login/mainloop/show/interface_port_pipe_match_match_exact_product_line_port.j2 +++ b/templates/Alcatel/Base/1/login/mainloop/show/interface_port_pipe_match_match_exact_product_line_port.j2 @@ -1,2 +1,2 @@ -{{ context.card.product }}-line:{{ context.port_ident }}{{ context.spacer1 }}{{ context.port.admin_state }}{{ context.spacer2 }}{{ context.port.admin_state }} +{{ context.card.product }}-line:{{ context.port_ident }}{{ context.spacer1 }}{{ context.port.admin_state }}{{ context.spacer2 }}{{ context.port.operational_state }} diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state.j2 index eb8db6c..5d96efe 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state.j2 @@ -2,7 +2,7 @@ Port Information ---------------------------------------------------------------------------- F/S/P {{ context.port.name }} - Port state {% if context.port.operational_state == 'down' %}Offline{% endif %}{% if context.port.operational_state == 'up' %}Online{% endif %} + Port state {% if context.port.operational_state == '0' %}Offline{% endif %}{% if context.port.operational_state == '1' %}Online{% endif %} Last down cause {{ context.port.last_down_cause }} Last up time {{ context.port.last_up_time }} diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_8.j2 b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_8.j2 index daef168..0a0bcf5 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_8.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_8.j2 @@ -1,4 +1,4 @@ - Port state {{ context.port.name }} {{ context.result }}{{ context.spacer }}{% if 'activated' == context.port.admin_state %}normal + Port state {{ context.port.name }} {{ context.result }}{{ context.spacer }}{% if '1' == context.port.admin_state %}normal {% else %}fail {% endif %} diff --git a/test_cases/unit_tests/alcatel/test_alcatel.py b/test_cases/unit_tests/alcatel/test_alcatel.py index e84b924..fa7e402 100644 --- a/test_cases/unit_tests/alcatel/test_alcatel.py +++ b/test_cases/unit_tests/alcatel/test_alcatel.py @@ -24,11 +24,11 @@ class TestAlcatel(TestCore): def test_ontportup_portdown(self): port = self.model.get_ont_port("name", '1/1/4/2/1/1/1') - assert (self.model.get_ont_port("name", '1/1/4/2/1/1/1').admin_state == 'down') + assert (self.model.get_ont_port("name", '1/1/4/2/1/1/1').admin_state == '0') port.admin_up() - assert (self.model.get_ont_port("name", '1/1/4/2/1/1/1').admin_state == 'up') + assert (self.model.get_ont_port("name", '1/1/4/2/1/1/1').admin_state == '1') port.admin_down() - assert (self.model.get_ont_port("name", '1/1/4/2/1/1/1').admin_state == 'down') + assert (self.model.get_ont_port("name", '1/1/4/2/1/1/1').admin_state == '0') def test_card_types(self): card = self.model.get_card("name", '1/1/1') @@ -104,9 +104,9 @@ def test_card_rest(self): except exceptions.SoftboxenError: assert True - assert card.admin_state == 'unlock' - card.set_admin_state('disabled') - assert card.admin_state == 'disabled' + assert card.admin_state == '1' + card.set_admin_state('0') + assert card.admin_state == '0' try: card.set_admin_state('failure') assert False @@ -135,17 +135,17 @@ def test_mngt_card(self): def test_port_states(self): port = self.model.get_port("name", '1/1/1/3') - assert (port.admin_state == 'down') + assert (port.admin_state == '0') port.admin_up() - assert (port.admin_state == 'up') + assert (port.admin_state == '1') port.admin_down() - assert (port.admin_state == 'down') + assert (port.admin_state == '0') port.admin_up() - assert (port.admin_state == 'up') + assert (port.admin_state == '1') port.down() - assert (port.operational_state == 'down') + assert (port.operational_state == '0') port.up() - assert (port.operational_state == 'up') + assert (port.operational_state == '1') def test_port_rest(self): port = self.model.get_port("name", '1/1/1/1') @@ -188,25 +188,25 @@ def test_port_rest(self): def test_cpe_states(self): port = self.model.get_cpe("name", '1/1/1/1/1') - assert (port.admin_state == 'up') + assert (port.admin_state == '1') port.admin_down() - assert (port.admin_state == 'down') + assert (port.admin_state == '0') port.admin_up() - assert (port.admin_state == 'up') + assert (port.admin_state == '1') def test_ont_states(self): port = self.model.get_ont("name", '1/1/4/1/1') port.power_down() - assert (port.admin_state == 'down') - assert (port.operational_state == 'down') + assert (port.admin_state == '0') + assert (port.operational_state == '0') port.admin_up() - assert (port.admin_state == 'up') - assert (port.operational_state == 'down') + assert (port.admin_state == '1') + assert (port.operational_state == '0') port.admin_down() - assert (port.admin_state == 'down') + assert (port.admin_state == '0') port.power_up() - assert (port.admin_state == 'up') - assert (port.operational_state == 'up') + assert (port.admin_state == '1') + assert (port.operational_state == '1') def test_ont_rest(self): port = self.model.get_ont("name", '1/1/4/1/1') @@ -236,16 +236,16 @@ def test_ont_rest(self): def test_ontport_states(self): port = self.model.get_ont_port("name", '1/1/4/1/1/1/1') - assert (port.admin_state == 'up') + assert (port.admin_state == '1') port.admin_down() - assert (port.admin_state == 'down') + assert (port.admin_state == '0') port.admin_up() - assert (port.admin_state == 'up') - assert (port.operational_state == 'down') + assert (port.admin_state == '1') + assert (port.operational_state == '0') port.port_up() - assert (port.operational_state == 'up') + assert (port.operational_state == '1') port.port_down() - assert (port.operational_state == 'down') + assert (port.operational_state == '0') def test_ontport_rest(self): port = self.model.get_ont_port("name", '1/1/4/1/1/1/1') diff --git a/test_cases/unit_tests/edgecore/test_edgecore.py b/test_cases/unit_tests/edgecore/test_edgecore.py index f91892e..2bc31a7 100644 --- a/test_cases/unit_tests/edgecore/test_edgecore.py +++ b/test_cases/unit_tests/edgecore/test_edgecore.py @@ -17,17 +17,17 @@ class TestEdgecore(TestCore): def test_portup_portdown(self): port = self.model.get_port("name", '1/1/1/1') - assert(self.model.get_port("name", '1/1/1/1').admin_state == 'down') + assert(self.model.get_port("name", '1/1/1/1').admin_state == '0') port.admin_up() - assert(self.model.get_port("name", '1/1/1/1').admin_state == 'up') + assert(self.model.get_port("name", '1/1/1/1').admin_state == '1') port.admin_down() - assert(self.model.get_port("name", '1/1/1/1').admin_state == 'down') + assert(self.model.get_port("name", '1/1/1/1').admin_state == '0') def test_ontportup_portdown(self): port = self.model.get_ont_port("name", '1/1/4/1/1/1/1') - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == 'down') + assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '0') port.admin_up() - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == 'up') + assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '1') port.admin_down() - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == 'down') + assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '0') diff --git a/test_cases/unit_tests/huawei/test_huawei.py b/test_cases/unit_tests/huawei/test_huawei.py index 213439b..6e99798 100644 --- a/test_cases/unit_tests/huawei/test_huawei.py +++ b/test_cases/unit_tests/huawei/test_huawei.py @@ -17,17 +17,17 @@ class TestHuawei(TestCore): def test_portup_portdown(self): port = self.model.get_port("name", '0/0/0') - assert(self.model.get_port("name", '0/0/0').admin_state == 'deactivated') + assert(self.model.get_port("name", '0/0/0').admin_state == '0') port.admin_up() - assert(self.model.get_port("name", '0/0/0').admin_state == 'activated') + assert(self.model.get_port("name", '0/0/0').admin_state == '1') port.admin_down() - assert(self.model.get_port("name", '0/0/0').admin_state == 'deactivated') + assert(self.model.get_port("name", '0/0/0').admin_state == '0') def test_ontportup_portdown(self): port = self.model.get_ont_port("name", '0/2/0/0/1') - assert(self.model.get_ont_port("name", '0/2/0/0/1').operational_state == 'down') + assert(self.model.get_ont_port("name", '0/2/0/0/1').operational_state == '0') port.operational_state_up() - assert(self.model.get_ont_port("name", '0/2/0/0/1').operational_state == 'up') + assert(self.model.get_ont_port("name", '0/2/0/0/1').operational_state == '1') port.operational_state_down() - assert(self.model.get_ont_port("name", '0/2/0/0/1').operational_state == 'down') + assert(self.model.get_ont_port("name", '0/2/0/0/1').operational_state == '0') diff --git a/test_cases/unit_tests/keymile/test_keymile.py b/test_cases/unit_tests/keymile/test_keymile.py index c7aa1ef..db82172 100644 --- a/test_cases/unit_tests/keymile/test_keymile.py +++ b/test_cases/unit_tests/keymile/test_keymile.py @@ -17,17 +17,17 @@ class TestKeymile(TestCore): def test_portup_portdown(self): port = self.model.get_port("name", '1/1/1/1') - assert(self.model.get_port("name", '1/1/1/1').admin_state == 'down') + assert(self.model.get_port("name", '1/1/1/1').admin_state == '0') port.admin_up() - assert(self.model.get_port("name", '1/1/1/1').admin_state == 'up') + assert(self.model.get_port("name", '1/1/1/1').admin_state == '1') port.admin_down() - assert(self.model.get_port("name", '1/1/1/1').admin_state == 'down') + assert(self.model.get_port("name", '1/1/1/1').admin_state == '0') def test_ontportup_portdown(self): port = self.model.get_ont_port("name", '1/1/4/1/1/1/1') - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == 'down') + assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '0') port.admin_up() - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == 'up') + assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '1') port.admin_down() - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == 'down') + assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '0') diff --git a/vendors/Alcatel/Base/Alcatel_Base/baseCommandProcessor.py b/vendors/Alcatel/Base/Alcatel_Base/baseCommandProcessor.py index f087899..56b8669 100644 --- a/vendors/Alcatel/Base/Alcatel_Base/baseCommandProcessor.py +++ b/vendors/Alcatel/Base/Alcatel_Base/baseCommandProcessor.py @@ -29,6 +29,35 @@ def do_logout(self, command, *args, context=None): exc.return_to = 'sysexit' raise exc + def map_states(self, object, type): + if object.admin_state == '0': + if type == 'subrack': + object.admin_state = 'lock' + elif type in ('card', 'port', 'ont', 'ont_port', 'cpe', 'service_port'): + object.admin_state = 'down' + elif object.admin_state == '1': + if type == 'subrack': + object.admin_state = 'unlock' + elif type in ('card', 'port', 'ont', 'ont_port', 'cpe', 'service_port'): + object.admin_state = 'up' + elif object.admin_state == '2': + if type == 'port': + object.admin_state = 'not-appl' + + if object.operational_state == '0': + if type in ('subrack', 'card'): + object.operational_state = 'disabled' + elif type in ('port', 'ont', 'ont_port', 'service_port'): + object.operational_state = 'down' + elif object.operational_state == '1': + if type in ('subrack', 'card'): + object.operational_state = 'enabled' + elif type in ('port', 'ont', 'ont_port', 'service_port'): + object.operational_state = 'up' + elif object.operational_state == '2': + if type in ('port', 'ont_port'): + object.operational_state = 'not-appl' + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/Alcatel/Base/Alcatel_Base/configureCommandProcessor.py b/vendors/Alcatel/Base/Alcatel_Base/configureCommandProcessor.py index 08d1263..1c76be3 100644 --- a/vendors/Alcatel/Base/Alcatel_Base/configureCommandProcessor.py +++ b/vendors/Alcatel/Base/Alcatel_Base/configureCommandProcessor.py @@ -43,7 +43,7 @@ def do_atm(self, command, *args, context=None): try: s_port = self._model.get_service_port('name', port_identifier) except exceptions.SoftboxenError: - self._model.add_service_port(name=port_identifier, connected_id=port.id, connected_type='port', admin_state='down', pvc=True) + self._model.add_service_port(name=port_identifier, connected_id=port.id, connected_type='port', admin_state='0', pvc=True) return @@ -66,17 +66,17 @@ def do_atm(self, command, *args, context=None): s_port = self._model.get_service_port('name', port_identifier) except exceptions.SoftboxenError: if admin_prefix == 'no' and args[3] == 'admin-down': - self._model.add_service_port(name=port_identifier, connected_id=port.id, connected_type='port', admin_state='up', pvc=True) + self._model.add_service_port(name=port_identifier, connected_id=port.id, connected_type='port', admin_state='1', pvc=True) elif admin_prefix == 'admin-down': - self._model.add_service_port(name=port_identifier, connected_id=port.id, connected_type='port', admin_state='down', pvc=True) + self._model.add_service_port(name=port_identifier, connected_id=port.id, connected_type='port', admin_state='0', pvc=True) else: raise exceptions.CommandSyntaxError(command=command) return if admin_prefix == 'no' and args[3] == 'admin-down': - s_port.set_admin_state('up') + s_port.set_admin_state('1') elif admin_prefix == 'admin-down': - s_port.set_admin_state('down') + s_port.set_admin_state('0') else: raise exceptions.CommandSyntaxError(command=command) @@ -138,7 +138,7 @@ def do_interface(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - card.set_admin_state('unlock') + card.set_admin_state('1') else: raise exceptions.CommandSyntaxError(command=command) @@ -181,7 +181,7 @@ def do_equipment(self, command, *args, context=None): try: card = self._model.get_card("name", identifier) card.set_planned_type(planned_type) - card.set_admin_state('unlock') + card.set_admin_state('1') except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/Alcatel/Base/Alcatel_Base/showCommandProcessor.py b/vendors/Alcatel/Base/Alcatel_Base/showCommandProcessor.py index 11560f2..f3a370a 100644 --- a/vendors/Alcatel/Base/Alcatel_Base/showCommandProcessor.py +++ b/vendors/Alcatel/Base/Alcatel_Base/showCommandProcessor.py @@ -66,6 +66,7 @@ def product(self, command, *args, context=None): port_identifier, = self._dissect(args, 'operational-data', 'line', str, 'detail') port = self.command_port_check(command, port_identifier) + self.map_states(port, 'port') context['spacer1'] = self.create_spacers((29,), (port.name, port.admin_state))[0] * ' ' context['spacer2'] = self.create_spacers((28,), (port.operational_state, port.upstream))[0] * ' ' @@ -124,6 +125,7 @@ def do_equipment(self, command, *args, context=None): try: subrack = self._model.get_subrack("name", subrack_id) + self.map_states(subrack, 'subrack') except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -138,6 +140,7 @@ def do_equipment(self, command, *args, context=None): if lt_identifier == 'nt-a' or lt_identifier == 'nt-b' or lt_identifier == 'acu:1/1': try: card = self._model.get_card('name', lt_identifier) + self.map_states(card, 'card') except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -169,6 +172,7 @@ def do_equipment(self, command, *args, context=None): text = self._render('equipment_slot_detail_head', context=context) for card in self._model.cards: + self.map_states(card, 'card') if card.position == 'network:0': context['spacer1'] = self.create_spacers((25,), (card.name, ))[0] * ' ' else: @@ -190,7 +194,7 @@ def do_equipment(self, command, *args, context=None): enabled = 'no' - if card.operational_state == 'enabled': + if card.operational_state == '1': enabled = 'yes' args = (context['slot_name'], card.actual_type, enabled, card.err_state, card.availability, @@ -332,12 +336,8 @@ def do_equipment(self, command, *args, context=None): counter = 0 for subrack in self._model.subracks: - enabled = 'no' - - if subrack.operational_state == 'enabled': - enabled = 'yes' + self.map_states(subrack, 'subrack') context['subrack'] = subrack - context['enabled'] = enabled context['spacer'] = self.create_spacers((25,), (subrack.actual_type,))[0] * ' ' text += self._render('equipment_shelf_detail_body', context=context) counter += 1 @@ -352,7 +352,7 @@ def do_equipment(self, command, *args, context=None): for subrack in self._model.subracks: enabled = 'no' - if subrack.operational_state == 'enabled': + if subrack.operational_state == '1': enabled = 'yes' context['subrack'] = subrack context['enabled'] = enabled @@ -471,6 +471,7 @@ def do_interface(self, command, *args, context=None): text = '' for port in self._model.ports: + self.map_states(port, 'port') if port.card_id == card.id: context['port_ident'] = port.name context['spacer1'] = self.create_spacers((40,), (port.name,))[0] * ' ' @@ -493,7 +494,9 @@ def do_interface(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) text = '' + card.product = 'ethernet' for port in self._model.ports: + self.map_states(port, 'port') if port.card_id == card.id: context['port_ident'] = port.name context['spacer1'] = self.create_spacers((36,), (port.name,))[0] * ' ' @@ -518,6 +521,7 @@ def do_interface(self, command, *args, context=None): return for component in self._model.ports: + self.map_states(component, 'port') if port.name in component.name: try: card = self._model.get_card('id', component.card_id) @@ -546,6 +550,7 @@ def do_interface(self, command, *args, context=None): text += self._render('interface_port_pipe_match_match_exact_port', context=context) for component in self._model.service_ports: + self.map_states(component, 'service_port') if port.name in component.name: if component.pvc: component_indent = 'atm-pvc:' + component.name @@ -584,6 +589,7 @@ def do_interface(self, command, *args, context=None): try: port_type, port_identifier = port_identifier.split(':') port = self._model.get_port("name", port_identifier) + self.map_states(port, 'port') card = self._model.get_card("id", port.card_id) if port_type == 'pon': assert card.product == 'ftth-pon' @@ -611,6 +617,7 @@ def do_interface(self, command, *args, context=None): self._write(self._render('interface_port_top', context=context)) context['count'] = 0 for port in self._model.ports: + self.map_states(port, 'port') card = self._model.get_card("id", port.card_id) if card.product == 'ftth': context['port_type'] = 'ethernet-line' @@ -629,6 +636,7 @@ def do_interface(self, command, *args, context=None): context['count'] += 1 for ont in self._model.onts: + self.map_states(ont, 'ont') positions = (48, 61) args = (ont.name, ont.admin_state, ont.operational_state) spacers = self.create_spacers(positions, args) @@ -703,6 +711,7 @@ def do_vlan(self, command, *args, context=None): try: service_port = self._model.get_service_port('name', port_identifier) + self.map_states(service_port, 'service_port') except exceptions.SoftboxenError: text = self._render('instance_does_not_exist', context=context) self._write(text) diff --git a/vendors/Alcatel/Base/Alcatel_Base/userViewCommandProcessor.py b/vendors/Alcatel/Base/Alcatel_Base/userViewCommandProcessor.py index 6b6de27..5f5bada 100644 --- a/vendors/Alcatel/Base/Alcatel_Base/userViewCommandProcessor.py +++ b/vendors/Alcatel/Base/Alcatel_Base/userViewCommandProcessor.py @@ -97,7 +97,7 @@ def do_info(self, command, *args, context=None): card = self._model.get_card("id", port.card_id) assert (card.product == 'ftth') - if port.admin_state == 'up': + if port.admin_state == '1': context['admin_state'] = "admin-up" else: context['admin_state'] = "no admin-up" @@ -117,7 +117,7 @@ def do_info(self, command, *args, context=None): card = self._model.get_card("id", port.card_id) assert (product == 'adsl' or product == 'vdsl' or product == 'xdsl' or product == 'sdsl') assert (card.product == product) - if port.admin_state == 'up': + if port.admin_state == '1': context['admin_state'] = "admin-up" else: context['admin_state'] = "no admin-up" @@ -160,10 +160,10 @@ def do_info(self, command, *args, context=None): try: ont_port = self._model.get_ont_port("name", port_identifier) + self.map_states(ont_port, 'ont_port') ont = self._model.get_ont('id', ont_port.ont_id) port = self._model.get_port('id', ont.port_id) card = self._model.get_card('id', port.card_id) - except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py index 77b62ec..4d32ec2 100644 --- a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py @@ -21,6 +21,43 @@ class BaseCommandProcessor(base.CommandProcessor): MODEL = 'Base' VERSION = '1' + def map_states(self, object, type): + if object.admin_state == '0': + if type == 'subrack': + object.admin_state = 'lock' + elif type in ('card', 'port', 'ont_port', 'service_port'): + object.admin_state = 'deactivated' + elif type in ('ont', 'ont_port', 'cpe'): + object.admin_state = 'offline' + elif object.admin_state == '1': + if type == 'subrack': + object.admin_state = 'unlock' + elif type in ('card', 'port', 'ont_port', 'service_port'): + object.admin_state = 'activated' + elif type in ('ont', 'ont_port', 'cpe'): + object.admin_state = 'online' + elif object.admin_state == '2': + if type == 'port': + object.admin_state = 'activating' + + if object.operational_state == '0': + if type in ('subrack', 'card'): + object.operational_state = 'disabled' + elif type in ('port', 'service_port'): + object.operational_state = 'deactivated' + elif type in ('ont', 'ont_port'): + object.operational_state = 'offline' + elif object.operational_state == '1': + if type in ('subrack', 'card'): + object.operational_state = 'enabled' + elif type in ('port', 'service_port'): + object.operational_state = 'activated' + elif type in ('ont', 'ont_port'): + object.operational_state = 'online' + elif object.operational_state == '2': + if type in ('port', 'ont_port'): + object.operational_state = 'activating' + def user_input(self, prompt, allow_history=True, tmp_boundary=None): self._write(prompt) prompt_end_pos = self.prompt_end_pos diff --git a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py index fb50256..ae4868d 100644 --- a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py @@ -75,6 +75,7 @@ def do_display(self, command, *args, context=None): try: port = self._model.get_port("name", port_identifier) + self.map_states(port, 'port') card = self._model.get_card('id', port.card_id) except exceptions.SoftboxenError: @@ -105,6 +106,7 @@ def do_display(self, command, *args, context=None): try: port = self._model.get_port("name", port_identifier) + self.map_states(port, 'port') card = self._model.get_card('id', port.card_id) except exceptions.SoftboxenError: @@ -119,7 +121,7 @@ def do_display(self, command, *args, context=None): context['channelname'] = channelname text = '' - if port.admin_state == 'activated': + if port.admin_state == '1': context['spacer1'] = self.create_spacers((7,), (portname,))[0] * ' ' context['spacer2'] = self.create_spacers((15,), (port.admin_state,))[0] * ' ' context['spacer3'] = self.create_spacers((25,), (port.loopback,))[0] * ' ' diff --git a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py index e048a17..227994d 100644 --- a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py @@ -60,6 +60,7 @@ def display_board(self, command, args, context=None): port_counter = 0 for port in ports: + self.map_states(port, 'port') if card.id == port.card_id: if port.admin_state == 'activated': activated_count += 1 @@ -387,6 +388,7 @@ def display_service_port(self, command, args, context): s_port_up = 0 s_port_down = 0 for s_port in s_ports: + self.map_states(s_port, 'service_port') port, card, vlan, porttype = self.prepare_template_vars(s_port, command) context['porttype'] = porttype @@ -411,7 +413,7 @@ def display_service_port(self, command, args, context): text += self._render('display_service_port_all_middle', context=dict(context, port=port, s_port=s_port, vlan=vlan)) - if s_port.operational_state == 'up': + if s_port.operational_state == '1': s_port_up += 1 else: s_port_down += 1 @@ -427,6 +429,7 @@ def display_service_port(self, command, args, context): try: s_port = self._model.get_service_port('name', s_port_idx) + self.map_states(s_port, 'service_port') except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index bdf46ba..91bd76d 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -70,6 +70,7 @@ def do_display(self, command, *args, context=None): try: port = self._model.get_port("name", portname) + self.map_states(port, 'port') except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) From eea1afa072d30d237f0bde65bb2b0608694c96da Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Tue, 8 Sep 2020 10:32:04 +0200 Subject: [PATCH 010/318] Added possibility to create port profiles under Huawei --- .../schemas/huawei_port_profile_schemas.py | 35 ++ nesi/huawei/huawei_resources/huawei_box.py | 8 + .../huawei_resources/huawei_port_profile.py | 65 +++- nesi/softbox/api/models/port_models.py | 2 +- nesi/softbox/api/models/portprofile_models.py | 66 +++- nesi/softbox/api/views/portprofile_views.py | 7 + nesi/softbox/base_resources/port_profile.py | 2 +- .../config/port_profile_already_exists.j2 | 2 + .../config/port_profile_does_not_exist.j2 | 2 + vendors/Huawei/5623/Huawei_5623/main.py | 2 +- .../Huawei_Base/configCommandProcessor.py | 364 +++++++++++++++++- .../Huawei_Base/diagnoseCommandProcessor.py | 16 +- 12 files changed, 545 insertions(+), 26 deletions(-) create mode 100644 nesi/huawei/api/schemas/huawei_port_profile_schemas.py create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/port_profile_already_exists.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/port_profile_does_not_exist.j2 diff --git a/nesi/huawei/api/schemas/huawei_port_profile_schemas.py b/nesi/huawei/api/schemas/huawei_port_profile_schemas.py new file mode 100644 index 0000000..25138ec --- /dev/null +++ b/nesi/huawei/api/schemas/huawei_port_profile_schemas.py @@ -0,0 +1,35 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.portprofile_schemas import * + + +class HuaweiPortProfileSchema(PortProfileSchema): + class Meta: + model = PortProfile + fields = PortProfileSchema.Meta.fields + ('maximum_bit_error_ratio', 'path_mode', 'rate', 'etr_max', 'etr_min', + 'ndr_max', 'working_mode', 'eside_electrical_length', + 'assumed_exchange_psd', 'eside_cable_model', 'min_usable_signal', + 'span_frequency', 'dpbo_calculation', 'snr_margin', 'rate_adapt', + 'snr_mode', 'inp_4khz', 'inp_8khz', 'interleaved_delay', + 'delay_variation', 'channel_policy', 'nominal_transmit_PSD_ds', + 'nominal_transmit_PSD_us', 'aggregate_transmit_power_ds', + 'aggregate_transmit_power_us', 'aggregate_receive_power_us', + 'upstream_psd_mask_selection', 'psd_class_mask', 'psd_limit_mask', + 'l0_time', 'l2_time', 'l3_time', 'max_transmite_power_reduction', + 'total_max_power_reduction', 'bit_swap_ds', 'bit_swap_us', + 'overhead_datarate_us', 'overhead_datarate_ds', + 'allow_transitions_to_idle', 'allow_transitions_to_lowpower', + 'reference_clock', 'cyclic_extension_flag', 'force_inp_ds', + 'force_inp_us', 'g_993_2_profile', 'mode_specific', 'transmode', + 'T1_413', 'G_992_1', 'G_992_2', 'G_992_3', 'G_992_4', 'G_992_5', + 'AnnexB_G_993_2', 'ETSI', 'us0_psd_mask', 'vdsltoneblackout') diff --git a/nesi/huawei/huawei_resources/huawei_box.py b/nesi/huawei/huawei_resources/huawei_box.py index a4d5825..d1d280c 100644 --- a/nesi/huawei/huawei_resources/huawei_box.py +++ b/nesi/huawei/huawei_resources/huawei_box.py @@ -367,6 +367,14 @@ def add_route(self, **fields): **fields ) + def add_port_profile(self, **fields): + """Add a new port profile""" + return huawei_port_profile.HuaweiPortProfile.create( + self._conn, + os.path.join(self.path, 'port_profiles'), + **fields + ) + def change_hostname(self, name): """Change the hostname of a box""" self.update(hostname=name) diff --git a/nesi/huawei/huawei_resources/huawei_port_profile.py b/nesi/huawei/huawei_resources/huawei_port_profile.py index 032c0dc..69d28cc 100644 --- a/nesi/huawei/huawei_resources/huawei_port_profile.py +++ b/nesi/huawei/huawei_resources/huawei_port_profile.py @@ -10,7 +10,7 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.port_profile import PortProfile, PortProfileCollection, logging +from nesi.softbox.base_resources.port_profile import PortProfile, PortProfileCollection, base, logging LOG = logging.getLogger(__name__) @@ -18,7 +18,68 @@ class HuaweiPortProfile(PortProfile): """Represent a PortProfile resource.""" - # huawei specific data fields + maximum_bit_error_ratio = base.Field('maximum_bit_error_ratio') + path_mode = base.Field('path_mode') + rate = base.Field('rate') + etr_max = base.Field('etr_max') + etr_min = base.Field('etr_min') + ndr_max = base.Field('ndr_max') + working_mode = base.Field('working_mode') + eside_electrical_length = base.Field('eside_electrical_length') + assumed_exchange_psd = base.Field('assumed_exchange_psd') + eside_cable_model = base.Field('eside_cable_model') + min_usable_signal = base.Field('min_usable_signal') + span_frequency = base.Field('span_frequency') + dpbo_calculation = base.Field('dpbo_calculation') + snr_margin = base.Field('snr_margin') + rate_adapt = base.Field('rate_adapt') + snr_mode = base.Field('snr_mode') + inp_4khz = base.Field('inp_4khz') + inp_8khz = base.Field('inp_8khz') + interleaved_delay = base.Field('interleaved_delay') + delay_variation = base.Field('delay_variation') + channel_policy = base.Field('channel_policy') + nominal_transmit_PSD_ds = base.Field('nominal_transmit_PSD_ds') + nominal_transmit_PSD_us = base.Field('nominal_transmit_PSD_us') + aggregate_transmit_power_ds = base.Field('aggregate_transmit_power_ds') + aggregate_transmit_power_us = base.Field('aggregate_transmit_power_us') + aggregate_receive_power_us = base.Field('aggregate_receive_power_us') + upstream_psd_mask_selection = base.Field('upstream_psd_mask_selection') + psd_class_mask = base.Field('psd_class_mask') + psd_limit_mask = base.Field('psd_limit_mask') + l0_time = base.Field('l0_time') + l2_time = base.Field('l2_time') + l3_time = base.Field('l3_time') + max_transmite_power_reduction = base.Field('max_transmite_power_reduction') + total_max_power_reduction = base.Field('total_max_power_reduction') + bit_swap_ds = base.Field('bit_swap_ds') + bit_swap_us = base.Field('bit_swap_us') + overhead_datarate_us = base.Field('overhead_datarate_us') + overhead_datarate_ds = base.Field('overhead_datarate_ds') + allow_transitions_to_idle = base.Field('allow_transitions_to_idle') + allow_transitions_to_lowpower = base.Field('allow_transitions_to_lowpower') + reference_clock = base.Field('reference_clock') + cyclic_extension_flag = base.Field('cyclic_extension_flag') + force_inp_ds = base.Field('force_inp_ds') + force_inp_us = base.Field('force_inp_us') + g_993_2_profile = base.Field('g_993_2_profile') + mode_specific = base.Field('mode_specific') + transmode = base.Field('transmode') + T1_413 = base.Field('T1_413') + G_992_1 = base.Field('G_992_1') + G_992_2 = base.Field('G_992_1') + G_992_3 = base.Field('G_992_3') + G_992_4 = base.Field('G_992_4') + G_992_5 = base.Field('G_992_5') + AnnexB_G_993_2 = base.Field('AnnexB_G_993_2') + ETSI = base.Field('ETSI') + us0_psd_mask = base.Field('us0_psd_mask') + vdsltoneblackout = base.Field('vdsltoneblackout') + + + def set(self, field, value): + mapping = {field: value} + self.update(**mapping) class HuaweiPortProfileCollection(PortProfileCollection): diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index a839eda..a502013 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -164,7 +164,7 @@ class Port(db.Model): channel_current_us = db.Column(db.Integer(), default=2008) channel_packets_discarded_ds = db.Column(db.Integer(), default=0) - channel_ds_data_rate_profile = db.Column(db.Enum('No.1016 QUICK_DSL_16000', ''), default='') + channel_ds_data_rate_profile = db.Column(db.Enum('No.1016 TEST_DSL_16000', ''), default='') channel_ds_data_rate_profile_num = db.Column(db.Integer(), nullable=True, default=None) channel_us_data_rate_profile = db.Column(db.Enum('No.2001 UP_1000', ''), default='') channel_us_data_rate_profile_num = db.Column(db.Integer(), nullable=True, default=None) diff --git a/nesi/softbox/api/models/portprofile_models.py b/nesi/softbox/api/models/portprofile_models.py index c687ab3..6092ade 100644 --- a/nesi/softbox/api/models/portprofile_models.py +++ b/nesi/softbox/api/models/portprofile_models.py @@ -18,10 +18,72 @@ class PortProfile(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) description = db.Column(db.String()) - type = db.Column(db.Enum('service', 'spectrum', 'dpbo', 'rtx', 'vect', 'sos', 'ghs', 'qos', 'policer', 'vce')) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + type = db.Column(db.Enum('service', 'spectrum', 'dpbo', 'rtx', 'vect', 'sos', 'ghs', 'qos', 'policer', 'vce', + 'data-rate', 'noise-margin', 'inp-delay', 'mode-specific-psd')) + + # Alcatel Data up_policer = db.Column(db.String(), default=None, nullable=True) down_policer = db.Column(db.String(), default=None, nullable=True) committed_info_rate = db.Column(db.Integer(), default=0, nullable=False) committed_burst_size = db.Column(db.Integer(), default=0, nullable=False) logical_flow_type = db.Column(db.Enum('generic'), default='generic') - box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + + # Huawei data + maximum_bit_error_ratio = db.Column(db.Integer(), default=None) + path_mode = db.Column(db.Integer(), default=None) + rate = db.Column(db.String(), default=None) + etr_max = db.Column(db.Integer(), default=None) + etr_min = db.Column(db.Integer(), default=None) + ndr_max = db.Column(db.Integer(), default=None) + working_mode = db.Column(db.Integer(), default=None) + eside_electrical_length = db.Column(db.String(), default=None) + assumed_exchange_psd = db.Column(db.String(), default=None) + eside_cable_model = db.Column(db.String(), default=None) + min_usable_signal = db.Column(db.Integer(), default=None) + span_frequency = db.Column(db.String(), default=None) + dpbo_calculation = db.Column(db.Integer(), default=None) + snr_margin = db.Column(db.String(), default=None) + rate_adapt = db.Column(db.String(), default=None) + snr_mode = db.Column(db.String(), default=None) + inp_4khz = db.Column(db.String(), default=None) + inp_8khz = db.Column(db.String(), default=None) + interleaved_delay = db.Column(db.String(), default=None) + delay_variation = db.Column(db.Integer(), default=None) + channel_policy = db.Column(db.Integer(), default=None) + nominal_transmit_PSD_ds = db.Column(db.Integer(), default=None) + nominal_transmit_PSD_us = db.Column(db.Integer(), default=None) + aggregate_transmit_power_ds = db.Column(db.Integer(), default=None) + aggregate_transmit_power_us = db.Column(db.Integer(), default=None) + aggregate_receive_power_us = db.Column(db.Integer(), default=None) + upstream_psd_mask_selection = db.Column(db.Integer(), default=None) + psd_class_mask = db.Column(db.Integer(), default=None) + psd_limit_mask = db.Column(db.Integer(), default=None) + l0_time = db.Column(db.Integer(), default=None) + l2_time = db.Column(db.Integer(), default=None) + l3_time = db.Column(db.Integer(), default=None) + max_transmite_power_reduction = db.Column(db.Integer(), default=None) + total_max_power_reduction = db.Column(db.Integer(), default=None) + bit_swap_ds = db.Column(db.Integer(), default=None) + bit_swap_us = db.Column(db.Integer(), default=None) + overhead_datarate_us = db.Column(db.Integer(), default=None) + overhead_datarate_ds = db.Column(db.Integer(), default=None) + allow_transitions_to_idle = db.Column(db.Integer(), default=None) + allow_transitions_to_lowpower = db.Column(db.Integer(), default=None) + reference_clock = db.Column(db.String(), default=None) + cyclic_extension_flag = db.Column(db.Integer(), default=None) + force_inp_ds = db.Column(db.Integer(), default=None) + force_inp_us = db.Column(db.Integer(), default=None) + g_993_2_profile = db.Column(db.Integer(), default=None) + mode_specific = db.Column(db.String(), default=None) + transmode = db.Column(db.String(), default=None) + T1_413 = db.Column(db.String(), default=None) + G_992_1 = db.Column(db.String(), default=None) + G_992_2 = db.Column(db.String(), default=None) + G_992_3 = db.Column(db.String(), default=None) + G_992_4 = db.Column(db.String(), default=None) + G_992_5 = db.Column(db.String(), default=None) + AnnexB_G_993_2 = db.Column(db.String(), default=None) + ETSI = db.Column(db.String(), default=None) + us0_psd_mask = db.Column(db.Integer(), default=None) + vdsltoneblackout = db.Column(db.String(), default=None) diff --git a/nesi/softbox/api/views/portprofile_views.py b/nesi/softbox/api/views/portprofile_views.py index 145ca88..cc46c37 100644 --- a/nesi/softbox/api/views/portprofile_views.py +++ b/nesi/softbox/api/views/portprofile_views.py @@ -40,6 +40,13 @@ def new_port_profile(box_id): return response, 201 +@app.route(PREFIX + '/boxen//port_profiles/', methods=['PUT']) +def update_port_profile(box_id, id): + req = flask.request.json + update_component(PortProfile, req, box_id, id) + return flask.Response(status=200) + + @app.route(PREFIX + '/boxen//port_profiles/', methods=['DELETE']) def del_port_profile(box_id, id): del_component(PortProfile, box_id, id) diff --git a/nesi/softbox/base_resources/port_profile.py b/nesi/softbox/base_resources/port_profile.py index 09c867c..b70bf69 100644 --- a/nesi/softbox/base_resources/port_profile.py +++ b/nesi/softbox/base_resources/port_profile.py @@ -18,7 +18,7 @@ class PortProfile(base.Resource): - """Represent a VLAN resource.""" + """Represent a port profile resource.""" id = base.Field('id') name = base.Field('name') diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/port_profile_already_exists.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/port_profile_already_exists.j2 new file mode 100644 index 0000000..e8adae5 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/port_profile_already_exists.j2 @@ -0,0 +1,2 @@ + Failure: The profile has existed + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/port_profile_does_not_exist.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/port_profile_does_not_exist.j2 new file mode 100644 index 0000000..4839223 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/port_profile_does_not_exist.j2 @@ -0,0 +1,2 @@ + Failure: The profile does not exist + diff --git a/vendors/Huawei/5623/Huawei_5623/main.py b/vendors/Huawei/5623/Huawei_5623/main.py index ea48ab8..3528735 100644 --- a/vendors/Huawei/5623/Huawei_5623/main.py +++ b/vendors/Huawei/5623/Huawei_5623/main.py @@ -71,7 +71,7 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.TerminalExitError() else: if user.reenter_num_temp < 0: - if user.level == 'Admin': + if (user.level == 'Admin') or (user.level == 'Super'): user.set_reenter_num_temp(user.reenter_num) text = self._render('password', context=context) self._write(text) diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index a935ab7..c00c3c3 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -260,7 +260,8 @@ def generate_ont_info_summary(port): elif self._validate(args, 'current-configuration', 'section', 'vlan-srvprof'): self.user_input('{ || }:') - text = self._render('display_current_configuration_section_vlan_srvprof_top', context=dict(context, box=self._model)) + text = self._render('display_current_configuration_section_vlan_srvprof_top', + context=dict(context, box=self._model)) text2 = '' for vlan in self._model.vlans: try: @@ -377,7 +378,7 @@ def do_service_port(self, command, *args, context=None): self._dissect(args, str, 'vlan', str, 'adsl', str, 'vpi', str, 'vci', str, 'multi-service', 'user-encap', 'pppoe', 'inbound', 'traffic-table', 'index', str, 'outbound', 'traffic-table', 'index', str) - + try: card = self._model.get_card('id', port.card_id) assert card.product == 'adsl' @@ -511,7 +512,7 @@ def do_service_port(self, command, *args, context=None): def do_ntp_service(self, command, *args, context=None): if self._validate(args, 'unicast-server', str): - addr, = self._dissect(args, 'unicast-server', str) + addr, = self._dissect(args, 'unicast-server', str) try: assert addr.count('.') == 3 for i in addr.split('.'): @@ -558,11 +559,11 @@ def do_vlan(self, command, *args, context=None): return elif self._validate(args, str, 'smart'): - trafficvlan, = self._dissect(args, str, 'smart') + trafficvlan, = self._dissect(args, str, 'smart') try: vlan = self._model.get_vlan("number", int(trafficvlan)) except exceptions.SoftboxenError: - self._model.add_vlan(number=int(trafficvlan), name='VLAN_'+trafficvlan) + self._model.add_vlan(number=int(trafficvlan), name='VLAN_' + trafficvlan) try: vlan = self._model.get_vlan("number", int(trafficvlan)) interface_name = 'vlanif' + trafficvlan @@ -804,7 +805,7 @@ def do_undo(self, command, *args, context=None): # TODO: Functionality vlan.delete() return - text = self._render('delete_vlan_if_first', context=context) # TODO: create template + text = self._render('delete_vlan_if_first', context=context) self._write(text) return @@ -865,8 +866,9 @@ def do_terminal(self, command, *args, context=None): self._write(text) password_repeat = self.user_input(" Confirm Password(length<6,15>):", False, 15) - profile = self.user_input(" User profile name(<=15 chars)[root]:", False) - while (profile != 'root') and (profile != 'admin') and (profile != 'operator') and (profile != 'commonuser'): + profile = self.user_input(" User profile name(<=15 chars)[root]:") + while (profile != 'root') and (profile != 'admin') and (profile != 'operator') \ + and (profile != 'commonuser'): text = self._render('terminal_profile_error', context=context) self._write(text) profile = self.user_input(" User profile name(<=15 chars)[root]:", False, 15) @@ -953,7 +955,7 @@ def do_port(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - try: # Check if s_port exists + try: # Check if s_port exists service_port = self._model.get_service_port("name", portident) except exceptions.SoftboxenError: self._model.add_service_port(name=portident, connected_id=port.id, connected_type='port', @@ -982,8 +984,8 @@ def do_deactivate(self, command, *args, context=None): # TODO: Functionality else: raise exceptions.CommandSyntaxError(command=command) - def do_xdsl(self, command, *args, context=None): # TODO: Functionality - if self._validate(args, 'vectoring-group', 'link', 'add', str, str): + def do_xdsl(self, command, *args, context=None): + if self._validate(args, 'vectoring-group', 'link', 'add', str, str): # TODO: Functionality profile_idx, port_idx = self._dissect(args, 'vectoring-group', 'link', 'add', str, str) portname = port_idx[0:3] + '/' + port_idx[4] @@ -995,7 +997,7 @@ def do_xdsl(self, command, *args, context=None): # TODO: Functionality return - elif self._validate(args, 'vectoring-group', 'link', 'delete', str, str): + elif self._validate(args, 'vectoring-group', 'link', 'delete', str, str): # TODO: Functionality profile_idx, port_idx = self._dissect(args, 'vectoring-group', 'link', 'delete', str, str) portname = port_idx[0:3] + '/' + port_idx[4] @@ -1007,6 +1009,215 @@ def do_xdsl(self, command, *args, context=None): # TODO: Functionality return + elif self._validate(args[:3], 'data-rate-profile', 'quickadd', str): + profile_num, = self._dissect(args[:3], 'data-rate-profile', 'quickadd', str) + name = 'data_rate_' + profile_num + try: + _ = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + self._model.add_port_profile(name=name, type='data-rate') + try: + port_profile = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + text = self._render('port_profile_already_exists', context=context) + self._write(text) + return + + self.data_rate_profile_setup(port_profile, args, command) + + elif self._validate(args[:3], 'data-rate-profile', 'quickmodify', str): + profile_num, = self._dissect(args[:3], 'data-rate-profile', 'quickmodify', str) + name = 'data_rate_' + profile_num + try: + port_profile = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + text = self._render('port_profile_does_not_exist', context=context) + self._write(text) + return + self.data_rate_profile_setup(port_profile, args, command) + + elif self._validate(args[:3], 'dpbo-profile', 'quickadd', str): + profile_num, = self._dissect(args[:3], 'dpbo-profile', 'quickadd', str) + name = 'dpbo_' + profile_num + try: + _ = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + self._model.add_port_profile(name=name, type='dpbo') + try: + port_profile = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + text = self._render('port_profile_already_exists', context=context) + self._write(text) + return + + i = 3 + while i < len(args): + try: + if args[i] == 'working-mode' and re.match("[0-9]+", args[i+1]): + port_profile.set('working_mode', int(args[i+1])) + elif args[i] == 'eside-electrical-length' and re.match("[0-9]+", args[i+1]) \ + and re.match("[0-9]+", args[i+2]): + length = args[i+1] + ' ' + args[i+2] + port_profile.set('eside_electrical_length', length) + elif args[i] == 'assumed-exchange-psd' and args[i+1] == 'enable': + exchange_psd = args[i+1] + ' ' + args[i+2] + port_profile.set('assumed_exchange_psd', exchange_psd) + elif args[i] == 'eside-cable-model' and re.match("[0-9]+", args[i+1])\ + and re.match("[0-9]+", args[i+2]) and re.match("[0-9]+", args[i+3]): + model = args[i+1] + ' ' + args[i+2] + ' ' + args[i+3] + port_profile.set('eside_cable_model', model) + elif args[i] == 'min-usable-signal' and re.match("[0-9]+", args[i+1]): + port_profile.set('min_usable_signal', int(args[i+1])) + elif args[i] == 'span-frequency' and re.match("[0-9]+", args[i+1]) and re.match("[0-9]+", args[i+2]): + freq = args[i+1] + ' ' + args[i+2] + port_profile.set('span_frequency', freq) + elif args[i] == 'dpbo-calculation' and re.match("[0-9]+", args[i+1]): + port_profile.set('dpbo_calculation', int(args[i+1])) + elif args[i] == 'desc': + port_profile.set('description', args[i + 1]) + except IndexError: + raise exceptions.CommandSyntaxError(command=command) + + i += 1 + + elif self._validate(args[:3], 'noise-margin-profile', 'quickadd', str): + profile_num, = self._dissect(args[:3], 'noise-margin-profile', 'quickadd', str) + name = 'noise_margin_' + profile_num + try: + _ = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + self._model.add_port_profile(name=name, type='noise-margin') + try: + port_profile = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + text = self._render('port_profile_already_exists', context=context) + self._write(text) + return + + i = 3 + while i < len(args): + try: + if args[i] == 'snr-margin' and re.match("[0-9]+", args[i + 1]) and re.match("[0-9]+", args[i + 2]) \ + and re.match("[0-9]+", args[i + 3]) and re.match("[0-9]+", args[i + 4]) \ + and re.match("[0-9]+", args[i + 5]) and re.match("[0-9]+", args[i + 6]): + margin = args[i+1] + ' ' + args[i+2] + ' ' + args[i+3] + ' ' + args[i+4] + ' ' + args[i+5] + ' ' + \ + args[i+6] + port_profile.set('snr_margin', margin) + elif args[i] == 'rate-adapt' and re.match("[0-9]+", args[i+1]) and re.match("[0-9]+", args[i+2]): + adapt = args[i+1] + ' ' + args[i+2] + port_profile.set('rate_adapt', adapt) + elif args[i] == 'snr-mode': + snr_mode = args[i+1] + ' ' + args[i+2] + port_profile.set('snr_mode', snr_mode) + elif args[i] == 'desc': + port_profile.set('description', args[i+1]) + except IndexError: + raise exceptions.CommandSyntaxError(command=command) + + i += 1 + + elif self._validate(args[:3], 'inp-delay-profile', 'quickadd', str): + profile_num, = self._dissect(args[:3], 'inp-delay-profile', 'quickadd', str) + name = 'inp_delay_' + profile_num + try: + _ = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + self._model.add_port_profile(name=profile_num, type='inp-delay') + try: + port_profile = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + text = self._render('port_profile_already_exists', context=context) + self._write(text) + return + + i = 3 + while i < len(args): + try: + if args[i] == ' inp-4.3125khz' and re.match("[0-9]+", args[i+1]) and re.match("[0-9]+", args[i+2]): + inp_4 = args[i+1] + ' ' + args[i+2] + port_profile.set('inp_4khz', inp_4) + elif args[i] == 'inp-8.625khz' and re.match("[0-9]+", args[i+1]) and re.match("[0-9]+", args[i+2]): + inp_8 = args[i + 1] + ' ' + args[i + 2] + port_profile.set('inp_8khz', inp_8) + elif args[i] == 'interleaved-delay' and re.match("[0-9]+", args[i+1]) \ + and re.match("[0-9]+", args[i+2]): + delay = args[i+1] + ' ' + args[i+2] + port_profile.set('interleaved_delay', delay) + elif args[i] == 'delay-variation' and re.match("[0-9]+", args[i+1]): + port_profile.set('delay_variation', int(args[i+1])) + elif args[i] == 'channel-policy' and re.match("[0-9]+", args[i+1]): + port_profile.set('channel_policy', int(args[i+1])) + elif args[i] == 'desc': + port_profile.set('description', args[i + 1]) + except IndexError: + raise exceptions.CommandSyntaxError(command=command) + + i += 1 + + elif self._validate(args[:3], 'mode-specific-psd-profile', 'quickadd', str): + profile_num, = self._dissect(args[:3], 'mode-specific-psd-profile', 'quickadd', str) + name = 'mode_specific_psd_' + profile_num + try: + _ = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + self._model.add_port_profile(name=name, type='mode-specific-psd') + try: + port_profile = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + text = self._render('port_profile_already_exists', context=context) + self._write(text) + return + self.mode_specific_psd_profile_setup(port_profile, args, command) + + elif self._validate(args[:3], 'mode-specific-psd-profile', 'quickmodify', str): + profile_num, = self._dissect(args[:3], 'mode-specific-psd-profile', 'quickmodify', str) + name = 'mode_specific_psd_' + profile_num + try: + port_profile = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + text = self._render('port_profile_does_not_exist', context=context) + self._write(text) + return + self.mode_specific_psd_profile_setup(port_profile, args, command) + + elif self._validate(args[:3], 'line-spectrum-profile', 'quickadd', str): + profile_num, = self._dissect(args[:3], 'line-spectrum-profile', 'quickadd', str) + name = 'line_spectrum_' + profile_num + try: + _ = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + self._model.add_port_profile(name=name, type='spectrum') + try: + port_profile = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + text = self._render('port_profile_already_exists', context=context) + self._write(text) + return + self.line_spectrum_profile_setup(port_profile, args, command) + + elif self._validate(args[:3], 'line-spectrum-profile', 'quickmodify', str): + profile_num, = self._dissect(args[:3], 'line-spectrum-profile', 'quickmodify', str) + name = 'line_spectrum_' + profile_num + try: + port_profile = self._model.get_port_profile('name', name) + except exceptions.SoftboxenError: + text = self._render('port_profile_does_not_exist', context=context) + self._write(text) + return + self.line_spectrum_profile_setup(port_profile, args, command) + else: raise exceptions.CommandSyntaxError(command=command) @@ -1041,7 +1252,7 @@ def do_load(self, command, *args, context=None): # TODO: Read in file except (AssertionError, ValueError): raise exceptions.CommandSyntaxError(command=command) - if not(file_name.endswith('.txt')): + if not (file_name.endswith('.txt')): raise exceptions.CommandSyntaxError(command=command) return @@ -1076,3 +1287,130 @@ def do_ip(self, command, *args, context=None): self._model.add_route(dst=dst, gw=gw, sub_mask=sub) else: raise exceptions.CommandSyntaxError(command=command) + + def data_rate_profile_setup(self, port_profile, args, command): + i = 3 + while i < len(args): + try: + if args[i] == 'maximum-bit-error-ratio' and re.match("[0-9]+", args[i + 1]): + port_profile.set('maximum_bit_error_ratio', int(args[i + 1])) + elif args[i] == 'path-mode' and re.match("[0-9]+", args[i + 1]): + port_profile.set('path_mode', int(args[i + 1])) + elif args[i] == 'rate' and re.match("[0-9]+", args[i + 1]) and re.match("[0-9]+", args[i + 2]) \ + and re.match("[0-9]+", args[i + 3]) and re.match("[0-9]+", args[i + 4]) \ + and re.match("[0-9]+", args[i + 5]) and re.match("[0-9]+", args[i + 6]): + + rate = args[i + 1] + ' ' + args[i + 2] + ' ' + args[i + 3] + ' ' + args[i + 4] + ' ' + args[ + i + 5] + ' ' + args[i + 6] + port_profile.set('rate', rate) + elif args[i] == 'etr-min' and re.match("[0-9]+", args[i + 1]): + port_profile.set('etr_min', int(args[i + 1])) + elif args[i] == 'etr-max' and re.match("[0-9]+", args[i + 1]): + port_profile.set('etr_max', int(args[i + 1])) + elif args[i] == 'ndr-max' and re.match("[0-9]+", args[i + 1]): + port_profile.set('ndr_max', int(args[i + 1])) + elif args[i] == 'desc': + port_profile.set('description', args[i + 1]) + except IndexError: + raise exceptions.CommandSyntaxError(command=command) + + i += 1 + return + + def mode_specific_psd_profile_setup(self, port_profile, args, command): + i = 3 + while i < len(args): + try: + if args[i] == 'nominal-transmit-PSD-ds' and re.match("[0-9]+", args[i + 1]): + port_profile.set('nominal_transmit_PSD_ds', int(args[i + 1])) + elif args[i] == 'nominal-transmit-PSD-us' and re.match("[0-9]+", args[i + 1]): + port_profile.set('nominal_transmit_PSD_us', int(args[i + 1])) + elif args[i] == 'aggregate-transmit-power-ds' and re.match("[0-9]+", args[i + 1]): + port_profile.set('aggregate_transmit_power_ds', int(args[i + 1])) + elif args[i] == 'aggregate-transmit-power-us' and re.match("[0-9]+", args[i + 1]): + port_profile.set('aggregate_transmit_power_us', int(args[i + 1])) + elif args[i] == 'aggregate-receive-power-us' and re.match("[0-9]+", args[i + 1]): + port_profile.set('aggregate_receive_power_us', int(args[i + 1])) + elif args[i] == 'upstream-psd-mask-selection' and re.match("[0-9]+", args[i + 1]): + port_profile.set('upstream_psd_mask_selection', int(args[i + 1])) + elif args[i] == 'psd-class-mask' and re.match("[0-9]+", args[i + 1]): + port_profile.set('psd_class_mask', int(args[i + 1])) + elif args[i] == 'psd-limit-mask' and re.match("[0-9]+", args[i + 1]): + port_profile.set('psd_limit_mask', int(args[i + 1])) + elif args[i] == 'desc': + port_profile.set('description', args[i + 1]) + except IndexError: + raise exceptions.CommandSyntaxError(command=command) + + i += 1 + return + + def line_spectrum_profile_setup(self, port_profile, args, command): + i = 3 + while i < len(args): + try: + if args[i] == 'l0-time ' and re.match("[0-9]+", args[i + 1]): + port_profile.set('l0_time', int(args[i + 1])) + elif args[i] == 'l2-time' and re.match("[0-9]+", args[i + 1]): + port_profile.set('l2_time', int(args[i + 1])) + elif args[i] == 'l3-time' and re.match("[0-9]+", args[i + 1]): + port_profile.set('l3_time', int(args[i + 1])) + elif args[i] == 'max-transmite-power-reduction' and re.match("[0-9]+", args[i + 1]): + port_profile.set('max_transmite_power_reduction', int(args[i + 1])) + elif args[i] == 'total-max-power-reduction' and re.match("[0-9]+", args[i + 1]): + port_profile.set('total_max_power_reduction', int(args[i + 1])) + elif args[i] == 'bit-swap-ds' and re.match("[0-9]+", args[i + 1]): + port_profile.set('bit_swap_ds', int(args[i + 1])) + elif args[i] == 'bit-swap-us' and re.match("[0-9]+", args[i + 1]): + port_profile.set('bit_swap_us', int(args[i + 1])) + elif args[i] == 'overhead-datarate-us' and re.match("[0-9]+", args[i + 1]): + port_profile.set('overhead_datarate_us', int(args[i + 1])) + elif args[i] == 'overhead-datarate-ds' and re.match("[0-9]+", args[i + 1]): + port_profile.set('overhead_datarate_ds', int(args[i + 1])) + elif args[i] == 'allow-transitions-to-idle' and re.match("[0-9]+", args[i + 1]): + port_profile.set('allow_transitions_to_idle', int(args[i + 1])) + elif args[i] == 'allow-transitions-to-lowpower' and re.match("[0-9]+", args[i + 1]): + port_profile.set('allow_transitions_to_lowpower', int(args[i + 1])) + elif args[i] == 'reference-clock': + port_profile.set('reference_clock', args[i + 1]) + elif args[i] == 'cyclic-extension-flag' and re.match("[0-9]+", args[i + 1]): + port_profile.set('cyclic_extension_flag', int(args[i + 1])) + elif args[i] == 'force-inp-ds' and re.match("[0-9]+", args[i + 1]): + port_profile.set('force_inp_ds', int(args[i + 1])) + elif args[i] == 'force-inp-us' and re.match("[0-9]+", args[i + 1]): + port_profile.set('force_inp_us', int(args[i + 1])) + elif args[i] == 'g.993.2-profile' and re.match("[0-9]+", args[i + 1]): + port_profile.set('g_993_2_profile', int(args[i + 1])) + elif args[i] == 'mode-specific' and re.match("[a-z]+", args[i+1]) and re.match("[0-9]+", args[i+2])\ + and re.match("[0-9]+", args[i+3]): + mode = args[i+1] + ' ' + args[i+2] + ' ' + args[i+3] + port_profile.set('mode_specific', mode) + elif args[i] == 'transmode': + port_profile.set('transmode', args[i+1]) + elif args[i] == 'T1.413': + port_profile.set('T1_413', args[i+1]) + elif args[i] == 'G.992.1': + port_profile.set('G_992_1', args[i+1]) + elif args[i] == 'G.992.2': + port_profile.set('G_992_2', args[i+1]) + elif args[i] == 'G.992.3': + port_profile.set('G_992_3', args[i+1]) + elif args[i] == 'G.992.4': + port_profile.set('G_992_4', args[i+1]) + elif args[i] == 'G.992.5': + port_profile.set('G_992_5', args[i+1]) + elif args[i] == 'AnnexB' and args[i+1] == 'G.993.2': + port_profile.set('AnnexB_G_993_2', args[i+2]) + elif args[i] == 'ETSI': + port_profile.set('ETSI', args[i+1]) + elif args[i] == 'us0-psd-mask' and re.match("[0-9]+", args[i + 1]): + port_profile.set('us0_psd_mask', int(args[i + 1])) + elif args[i] == 'vdsltoneblackout': + blackout = args[i+1] + ' ' + args[i+2] + port_profile.set('vdsltoneblackout', blackout) + elif args[i] == 'desc': + port_profile.set('description', args[i + 1]) + except IndexError: + raise exceptions.CommandSyntaxError(command=command) + i += 1 + return diff --git a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py index a908cbd..2b42b79 100644 --- a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py @@ -50,10 +50,12 @@ def do_system(self, command, *args, context=None): for subrack in self._model.subracks: result = ['Abnormal', 'Normal'][subrack.frame_status == 'active'] context['spacer'] = self.create_spacers((9,), (result,))[0] * ' ' - text += self._render('display_system_status_collection_3', context=dict(context, subrack=subrack, result=result)) + text += self._render('display_system_status_collection_3', + context=dict(context, subrack=subrack, result=result)) result = ['Abnormal', 'Normal'][int(subrack.temperature[:-1]) <= 80] context['spacer'] = self.create_spacers((9,), (result,))[0] * ' ' - text2 += self._render('display_system_status_collection_4', context=dict(context, subrack=subrack, result=result)) + text2 += self._render('display_system_status_collection_4', + context=dict(context, subrack=subrack, result=result)) text += self._render('display_system_status_collection_2', context=context) text += text2 @@ -64,7 +66,7 @@ def do_system(self, command, *args, context=None): result = ['Abnormal', 'Normal'][emu.emu_state == 'Normal'] context['spacer'] = self.create_spacers((9,), (result,))[0] * ' ' text += self._render('display_system_status_collection_6', - context=dict(context, emu=emu, result=result)) + context=dict(context, emu=emu, result=result)) else: result = ['Abnormal', 'Normal'][emu.emu_state == 'Normal'] context['spacer'] = self.create_spacers((9,), (result,))[0] * ' ' @@ -74,10 +76,12 @@ def do_system(self, command, *args, context=None): for port in self._model.ports: result = ['Abnormal', 'Normal'][port.admin_state == 'activated'] context['spacer'] = self.create_spacers((9,), (result,))[0] * ' ' - text += self._render('display_system_status_collection_8', context=dict(context, port=port, result=result)) + text += self._render('display_system_status_collection_8', + context=dict(context, port=port, result=result)) text += self._render('display_system_status_collection_5', context=context) text += text2 - text += self._render('display_system_status_collection_10', context=dict(context, time=datetime.now().strftime("%m/%d/%Y %H:%M:%S"))) + text += self._render('display_system_status_collection_10', + context=dict(context, time=datetime.now().strftime("%m/%d/%Y %H:%M:%S"))) context['text'] = text else: raise exceptions.CommandSyntaxError(command=command) @@ -106,7 +110,7 @@ def do_switch(self, command, *args, context=None): # TODO: Functionality (that aone = self.user_input('Please enter y if you want to continue: ') if aone != 'y': raise exceptions.InvalidInputError - atwo = self.user_input('Please enter y again to confirm:' ) + atwo = self.user_input('Please enter y again to confirm: ') if atwo != 'y': raise exceptions.InvalidInputError else: From 9c7abb0e2d2fbabb3f8e6f34ee47af70ade4cc75 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 8 Sep 2020 11:31:02 +0200 Subject: [PATCH 011/318] Fixed wrong mapping for service_port states --- .../Base/Huawei_Base/baseCommandProcessor.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py index 4d32ec2..c7db4ff 100644 --- a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py @@ -25,15 +25,19 @@ def map_states(self, object, type): if object.admin_state == '0': if type == 'subrack': object.admin_state = 'lock' - elif type in ('card', 'port', 'ont_port', 'service_port'): + elif type in ('card', 'port', 'ont_port'): object.admin_state = 'deactivated' + elif type == 'service_port': + object.admin_state = 'disable' elif type in ('ont', 'ont_port', 'cpe'): object.admin_state = 'offline' elif object.admin_state == '1': if type == 'subrack': object.admin_state = 'unlock' - elif type in ('card', 'port', 'ont_port', 'service_port'): + elif type in ('card', 'port', 'ont_port'): object.admin_state = 'activated' + elif type == 'service_port': + object.admin_state = 'enable' elif type in ('ont', 'ont_port', 'cpe'): object.admin_state = 'online' elif object.admin_state == '2': @@ -43,15 +47,19 @@ def map_states(self, object, type): if object.operational_state == '0': if type in ('subrack', 'card'): object.operational_state = 'disabled' - elif type in ('port', 'service_port'): + elif type == 'port': object.operational_state = 'deactivated' + elif type == 'service_port': + object.operational_state = 'down' elif type in ('ont', 'ont_port'): object.operational_state = 'offline' elif object.operational_state == '1': if type in ('subrack', 'card'): object.operational_state = 'enabled' - elif type in ('port', 'service_port'): + elif type == 'port': object.operational_state = 'activated' + elif type == 'service_port': + object.operational_state = 'up' elif type in ('ont', 'ont_port'): object.operational_state = 'online' elif object.operational_state == '2': From 2836b5cf1cded1d336e4023dc68fb104fd7f4183 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Tue, 8 Sep 2020 11:38:36 +0200 Subject: [PATCH 012/318] Fixes involving Vlan interfaces for Huawei --- .../conf/bootstraps/create-huawei-5623_old.sh | 3 +-- .../schemas/huawei_vlan_interface_schemas.py | 3 ++- .../huawei/api/schemas/huawei_vlan_schemas.py | 4 ++-- nesi/huawei/huawei_resources/huawei_vlan.py | 3 --- .../huawei_resources/huawei_vlan_interface.py | 3 +++ .../api/models/vlan_interface_models.py | 3 +++ nesi/softbox/api/models/vlan_models.py | 4 ---- .../config/display_interface_vlanif_num.j2 | 16 +++++++++------ .../Huawei_Base/configCommandProcessor.py | 20 +++++++++++-------- 9 files changed, 33 insertions(+), 26 deletions(-) diff --git a/bootup/conf/bootstraps/create-huawei-5623_old.sh b/bootup/conf/bootstraps/create-huawei-5623_old.sh index d70f608..50f6fd0 100755 --- a/bootup/conf/bootstraps/create-huawei-5623_old.sh +++ b/bootup/conf/bootstraps/create-huawei-5623_old.sh @@ -91,7 +91,7 @@ req='{ "network_protocol": "telnet", "network_address": "127.0.0.1", "network_port": 9023, - "uuid": "5623" + "uuid": "2" }' box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 @@ -137,7 +137,6 @@ req='{ "bind_service_profile_id": '$port_profile_id', "bind_RAIO_profile_index": "-", "priority": "-", - "state": "up", "native_vlan" : "1" }' diff --git a/nesi/huawei/api/schemas/huawei_vlan_interface_schemas.py b/nesi/huawei/api/schemas/huawei_vlan_interface_schemas.py index d93c85d..b3c3b26 100644 --- a/nesi/huawei/api/schemas/huawei_vlan_interface_schemas.py +++ b/nesi/huawei/api/schemas/huawei_vlan_interface_schemas.py @@ -19,4 +19,5 @@ class Meta: fields = VlanInterfaceSchema.Meta.fields + ('admin_state', 'line_proto_state', 'input_packets', 'input_bytes', 'input_multicasts', 'output_packets', 'output_bytes', 'output_multicasts', 'internet_protocol', 'internet_address', - 'subnet_num', 'broadcast_address') + 'subnet_num', 'broadcast_address', 'sending_frames_format', + 'hardware_address', 'mtu') diff --git a/nesi/huawei/api/schemas/huawei_vlan_schemas.py b/nesi/huawei/api/schemas/huawei_vlan_schemas.py index 6af8758..0e715ea 100644 --- a/nesi/huawei/api/schemas/huawei_vlan_schemas.py +++ b/nesi/huawei/api/schemas/huawei_vlan_schemas.py @@ -18,7 +18,7 @@ class Meta: model = Vlan fields = VlanSchema.Meta.fields + \ ('type', 'attribute', 'bind_service_profile_id', - 'bind_RAIO_profile_index', 'priority', 'state', - 'native_vlan', 'sending_frames_format', 'hardware_address', 'vmac_ipoe', 'vmac_pppoe', 'vmac_pppoa', + 'bind_RAIO_profile_index', 'priority', + 'native_vlan', 'vmac_ipoe', 'vmac_pppoe', 'vmac_pppoa', 'vlan_mac', 'packet_policy_multicast', 'packet_policy_unicast', 'security_anti_ipspoofing', 'security_anti_macspoofing', 'igmp_mismatch', 'tag') diff --git a/nesi/huawei/huawei_resources/huawei_vlan.py b/nesi/huawei/huawei_resources/huawei_vlan.py index d243442..4597d59 100644 --- a/nesi/huawei/huawei_resources/huawei_vlan.py +++ b/nesi/huawei/huawei_resources/huawei_vlan.py @@ -23,10 +23,7 @@ class HuaweiVlan(Vlan): bind_service_profile_id = base.Field('bind_service_profile_id') bind_RAIO_profile_index = base.Field('bind_RAIO_profile_index') priority = base.Field('priority') - state = base.Field('state') native_vlan = base.Field('native_vlan') - sending_frames_format = base.Field('sending_frames_format') - hardware_address = base.Field('hardware_address') vmac_ipoe = base.Field('vmac_ipoe') vmac_pppoe = base.Field('vmac_pppoe') vmac_pppoa = base.Field('vmac_pppoa') diff --git a/nesi/huawei/huawei_resources/huawei_vlan_interface.py b/nesi/huawei/huawei_resources/huawei_vlan_interface.py index 1e72c09..0a2617e 100644 --- a/nesi/huawei/huawei_resources/huawei_vlan_interface.py +++ b/nesi/huawei/huawei_resources/huawei_vlan_interface.py @@ -30,6 +30,9 @@ class HuaweiVlanInterface(VlanInterface): internet_address = base.Field('internet_address') subnet_num = base.Field('subnet_num') broadcast_address = base.Field('broadcast_address') + sending_frames_format = base.Field('sending_frames_format') + hardware_address = base.Field('hardware_address') + mtu = base.Field('mtu') def set(self, field, value): mapping = {field: value} diff --git a/nesi/softbox/api/models/vlan_interface_models.py b/nesi/softbox/api/models/vlan_interface_models.py index a123228..1cd38a5 100644 --- a/nesi/softbox/api/models/vlan_interface_models.py +++ b/nesi/softbox/api/models/vlan_interface_models.py @@ -32,3 +32,6 @@ class VlanInterface(db.Model): internet_address = db.Column(db.String(), default=None, nullable=True) subnet_num = db.Column(db.String(), default=None, nullable=True) broadcast_address = db.Column(db.String(), default='0.0.0.0') + sending_frames_format = db.Column(db.String(), default='PKTFMT_ETHNT_2') + hardware_address = db.Column(db.String(), default='384c-4f1e-c1cc') + mtu = db.Column(db.Integer(), default=1500) diff --git a/nesi/softbox/api/models/vlan_models.py b/nesi/softbox/api/models/vlan_models.py index 0086e74..1fbff33 100644 --- a/nesi/softbox/api/models/vlan_models.py +++ b/nesi/softbox/api/models/vlan_models.py @@ -59,10 +59,7 @@ class Vlan(db.Model): bind_service_profile_id = db.Column(db.Integer()) bind_RAIO_profile_index = db.Column(db.String()) priority = db.Column(db.String()) - state = db.Column(db.Enum('up', 'down'), default='down') native_vlan = db.Column(db.Integer()) - sending_frames_format = db.Column(db.String(), default='PKTFMT_ETHNT_2') - hardware_address = db.Column(db.String(), default='384c-4f1e-c1cc') vmac_ipoe = db.Column(db.Enum('enable', 'disable'), default='disable') vmac_pppoe = db.Column(db.Enum('enable', 'disable'), default='disable') vmac_pppoa = db.Column(db.Enum('enable', 'disable'), default='disable') @@ -72,4 +69,3 @@ class Vlan(db.Model): security_anti_ipspoofing = db.Column(db.Enum('enable', 'disable'), default='disable') security_anti_macspoofing = db.Column(db.Enum('enable', 'disable'), default='disable') igmp_mismatch = db.Column(db.Enum('transparent'), default='transparent') - diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_interface_vlanif_num.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_interface_vlanif_num.j2 index 37ef273..cec9959 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_interface_vlanif_num.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_interface_vlanif_num.j2 @@ -1,7 +1,11 @@ -vlanif{{ context.vlan.number }} current state : {{ context.vlan.state }} -Line protocol current state : {{ context.vlan.state }} -Description : {{ model.vendor }}, SmartAX Series, vlanif{{ context.vlan_id }} Interface -The Maximum Transmit Unit is {{ context.vlan.mtu }} bytes -Internet Address is {{ model.mgmt_address }}/24 -IP Sending Frames' Format is {{ context.vlan.sending_frames_format }}, Hardware address is {{ context.vlan.hardware_address }} +{{ context.vlanif.name }} current state : {{ context.vlanif.admin_state }} +Line protocol current state : {{ context.vlanif.line_proto_state }} +Description : HUAWEI, SmartAX Series, {{ context.vlanif.name }} Interface +The Maximum Transmit Unit is {{ context.vlanif.mtu }} bytes +{% if context.vlanif.internet_protocol == 'enabled' %}Internet Address is {{ context.vlanif.internet_address }}/{{ context.vlanif.subnet_num }} +{% else %}Internet protocol processing : {{ context.vlanif.internet_protocol }} +{% endif %} +IP Sending Frames' Format is {{ context.vlanif.sending_frames_format }}, Hardware address is {{ context.vlanif.hardware_address }} + + diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index c00c3c3..5122a10 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -67,14 +67,20 @@ def do_interface(self, command, *args, context=None): if iftype == 'vlanif': vlan_if_name = 'vlanif' + interface_id try: - component = self._model.get_vlan_interface("name", vlan_if_name) - check = True - + vlan = self._model.get_vlan('number', int(interface_id)) except exceptions.SoftboxenError: text = self._render('vlan_does_not_exist', context=context) self._write(text) return + try: + component = self._model.get_vlan_interface("name", vlan_if_name) + check = True + except exceptions.SoftboxenError: + self._model.add_vlan_interface(name=vlan_if_name, vlan_id=vlan.id) + component = self._model.get_vlan_interface('name', vlan_if_name) + check = True + elif iftype == 'emu': try: component = self._model.get_emu("number", int(interface_id)) @@ -201,12 +207,13 @@ def generate_ont_info_summary(port): self._write(text) elif self._validate(args, 'interface', 'vlanif', str): vlan_number, = self._dissect(args, 'interface', 'vlanif', str) + name = 'vlanif' + vlan_number try: - vlan = self._model.get_vlan("number", int(vlan_number)) + vlanif = self._model.get_vlan_interface("name", name) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - text = self._render('display_interface_vlanif_num', context=dict(context, vlan=vlan)) + text = self._render('display_interface_vlanif_num', context=dict(context, vlanif=vlanif)) self._write(text) elif self._validate(args, 'vlan', 'all'): _ = self.user_input('{ |vlanattr|vlantype }:') @@ -566,9 +573,6 @@ def do_vlan(self, command, *args, context=None): self._model.add_vlan(number=int(trafficvlan), name='VLAN_' + trafficvlan) try: vlan = self._model.get_vlan("number", int(trafficvlan)) - interface_name = 'vlanif' + trafficvlan - self._model.add_vlan_interface(name=interface_name, vlan_id=vlan.id) - vlan_interface = self._model.get_vlan_interface('name', interface_name) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) return From c55b8cef8e9e5c11bfb22922bb11416b84813bbc Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 8 Sep 2020 11:49:19 +0200 Subject: [PATCH 013/318] Added further components to huawei setup script --- bootup/conf/bootstraps/create-huawei-5623.sh | 236 +++++++++++++++---- 1 file changed, 193 insertions(+), 43 deletions(-) diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 0d38caa..0cb7c64 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -21,51 +21,51 @@ path="`dirname \"$0\"`" #--------------------------------------------------------# # # -# Subrack 1/1 # -# |---> Card 1/1/1 (vdsl) # -# | |-> Port 1/1/1/1 # -# | | |-> Cpe 1/1/1/1/1 # -# | | |-> CpePort 1/1/1/1/1/1 # -# | |-> Port 1/1/1/2 # -# | | |-> Cpe 1/1/1/2/1 # -# | | |-> CpePort 1/1/1/2/1/1 # -# | |-> Port 1/1/1/3 # +# Subrack 0 # +# |---> Card 0/0 (vdsl) # +# | |-> Port 0/0/0 # +# | | |-> Cpe 0/0/0 1 # +# | | |-> CpePort 0/0/0 1/1 # +# | |-> Port 0/0/1 # +# | | |-> Cpe 0/0/1 1 # +# | | |-> CpePort 0/0/1 1/1 # +# | |-> Port 0/0/2 # # | # -# |---> Card 1/1/2 (adsl) # -# | |-> Port 1/1/2/1 # -# | | |-> Cpe 1/1/2/1/1 # -# | | |-> CpePort 1/1/2/1/1/1 # -# | |-> Port 1/1/2/2 # -# | | |-> Cpe 1/1/2/2/1 # -# | | |-> CpePort 1/1/2/2/1/1 # -# | |-> Port 1/1/2/3 # +# |---> Card 0/1 (adsl) # +# | |-> Port 0/1/0 # +# | | |-> Cpe 0/1/0 1 # +# | | |-> CpePort 0/1/0 1/1 # +# | |-> Port 0/1/1 # +# | | |-> Cpe 0/1/1 1 # +# | | |-> CpePort 0/1/1 1/1 # +# | |-> Port 0/1/2 # # | # -# |---> Card 1/1/4 (ftth) # -# | |-> Port 1/1/4/1 # -# | | |-> Ont 1/1/4/1/1 # -# | | |-> OntPort 1/1/4/1/1/1/1 # -# | | |-> Cpe 1/1/4/1/1/1/1/1 # -# | | |-> CpePort 1/1/4/1/1/1/1/1/1 # -# | |-> Port 1/1/4/2 # -# | | |-> Ont 1/1/4/2/1 # -# | | |-> OntPort 1/1/4/2/1/1/1 # -# | | |-> Cpe 1/1/4/2/1/1/1/1 # -# | | |-> CpePort 1/1/4/2/1/1/1/1/1 # -# | |-> Port 1/1/4/3 # +# |---> Card 0/2 (ftth) # +# | |-> Port 0/2/0 # +# | | |-> Ont # +# | | |-> OntPort # +# | | |-> Cpe # +# | | |-> CpePort # +# | |-> Port 0/2/1 # +# | | |-> Ont # +# | | |-> OntPort # +# | | |-> Cpe # +# | | |-> CpePort # +# | |-> Port 0/2/2 # # | # -# |---> Card 1/1/5 (ftth-pon) # -# |-> Port 1/1/5/1 # -# |-> Ont 1/1/5/1/1 # -# | |-> OntPort 1/1/5/1/1/1/1 # -# | |-> Cpe 1/1/5/1/1/1/1/1 # -# | |-> CpePort 1/1/5/1/1/1/1/1/1 # -# |-> Ont 1/1/5/1/2 # -# |-> OntPort 1/1/5/1/2/1/1 # -# | |-> Cpe 1/1/5/1/2/1/1/1 # -# | |-> CpePort 1/1/5/1/2/1/1/1/1 # -# |-> OntPort 1/1/5/1/2/1/2 # -# |-> Cpe 1/1/5/1/2/1/2/1 # -# |-> CpePort 1/1/5/1/2/1/2/1/1 # +# |---> Card 0/3 (ftth-pon) # +# |-> Port 0/3/0 # +# |-> Ont # +# | |-> OntPort # +# | |-> Cpe # +# | |-> CpePort # +# |-> Ont # +# |-> OntPort # +# | |-> Cpe # +# | |-> CpePort # +# |-> OntPort # +# |-> Cpe # +# |-> CpePort # # # #--------------------------------------------------------# @@ -147,6 +147,28 @@ req='{ port_0_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +### Cpe at port 0/0/0 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "port_id": '$port_0_0_0', + "description": "Cpe 0/0/0 1", + "mac": "03:ed:5d:a1:4d:5d", + "admin_state": "1" +}' + +cpe_0_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_0_0_1', + "description": "CpePort 0/0/0 1/1" +}' + +cpe_port_0_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + ### PORT 0/0/1 and deps ### # Create a physical port at the network device (admin operation) @@ -164,6 +186,28 @@ req='{ port_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +### Cpe at port 0/0/1 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "port_id": '$port_0_0_1', + "description": "Cpe 0/0/1 1", + "mac": "8e:1c:02:05:a3:dc", + "admin_state": "0" +}' + +cpe_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_0_1_1', + "description": "CpePort 0/0/1 1/1" +}' + +cpe_port_0_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + ### PORT 0/0/2 and deps ### # Create a physical port at the network device (admin operation) @@ -179,7 +223,7 @@ req='{ "operational_state": "0" }' -port_0_0_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_0_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) ### Card 0/1 ### @@ -210,6 +254,28 @@ req='{ port_0_1_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +### Cpe at port 0/1/0 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "port_id": '$port_0_1_0', + "description": "Cpe 0/1/0 1", + "mac": "61:26:5c:eb:8a:a6", + "admin_state": "1" +}' + +cpe_0_1_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_1_0_1', + "description": "CpePort 0/1/0 1/1" +}' + +cpe_port_0_1_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + ### PORT 0/1/1 and deps ### # Create a physical port at the network device (admin operation) @@ -227,6 +293,28 @@ req='{ port_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +### Cpe at port 0/1/1 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "port_id": '$port_0_1_1', + "description": "Cpe 0/1/1 1", + "mac": "49:a6:23:91:f4:7b", + "admin_state": "0" +}' + +cpe_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_1_1_1', + "description": "CpePort 0/1/1 1/1" +}' + +cpe_port_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + ### PORT 0/1/2 and deps ### # Create a physical port at the network device (admin operation) @@ -307,3 +395,65 @@ req='{ port_0_1_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +### Card 0/3 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_0', + "description": "Physical card 0/3", + "product": "ftth-pon", + "board_name": "H807GPBH" +}' + +card_0_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### PORT 0/3/0 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card_0_3', + "description": "Physical port 0/3/0", + "loopback": "disable", + "upstream": 10000, + "downstream": 25000, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "1", + "operational_state": "1" +}' + +port_0_3_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### PORT 0/3/1 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card_0_2', + "description": "Physical port 0/3/1", + "loopback": "disable", + "upstream": 0, + "downstream": 0, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "1", + "operational_state": "0" +}' + +port_0_3_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### PORT 0/3/2 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card_0_2', + "description": "Physical port 0/3/2", + "loopback": "disable", + "upstream": 0, + "downstream": 0, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "0", + "operational_state": "0" +}' + +port_0_3_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) From 680b24e4c30403c8a212911989e6bb6044023d4e Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 8 Sep 2020 12:03:35 +0200 Subject: [PATCH 014/318] Added more command functionality --- .../enable/config/display_vlan_all_bottom.j2 | 2 +- .../enable/config/display_vlan_all_mid.j2 | 2 +- .../enable/config/display_vlan_all_top.j2 | 6 +-- .../Huawei_Base/configCommandProcessor.py | 39 ++++++++----------- .../Huawei_Base/enableCommandProcessor.py | 10 ++++- .../Huawei_Base/interfaceCommandProcessor.py | 1 + 6 files changed, 32 insertions(+), 28 deletions(-) diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_bottom.j2 index 78c12c2..bd7f533 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_bottom.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_bottom.j2 @@ -1,4 +1,4 @@ - --------------------------------------------------------- + ----------------------------------------------------------------------- Total: {{ context.count }} Note : STND-Port--standard port, SERV-Port--service virtual port diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_mid.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_mid.j2 index dc702d4..ae27a66 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_mid.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_mid.j2 @@ -1,2 +1,2 @@ -{{ context.spacer1 }}{{ context.vlan.number }} {{ context.vlan.type }}{{ context.spacer2 }}{{ context.vlan.attribute }}{{ context.spacer3 }}2 {{ context.vlan.bind_service_profile_id }} +{{ context.spacer1 }}{{ context.vlan.number }} {{ context.vlan.type }}{{ context.spacer2 }}{{ context.vlan.attribute }}{{ context.spacer3 }}{{ context.portnum}}{{ context.spacer4 }}{{ context.servportnum }} - diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_top.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_top.j2 index 7373a94..08823af 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_top.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_top.j2 @@ -1,6 +1,6 @@ Command: display vlan all - --------------------------------------------------------- - VLAN Type Attribute STND-Port NUM SERV-Port NUM - --------------------------------------------------------- + ----------------------------------------------------------------------- + VLAN Type Attribute STND-Port NUM SERV-Port NUM VLAN-Con NUM + ----------------------------------------------------------------------- diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 5122a10..cc97bde 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -219,10 +219,22 @@ def generate_ont_info_summary(port): _ = self.user_input('{ |vlanattr|vlantype }:') text = self._render('display_vlan_all_top', context=context) count = 0 - for vlan in self._model.vlans: # TODO: STND_Port_NUM + SERV_Port_NUM hinzufügen + Service_Vlans? + for vlan in self._model.vlans: + portnum = 0 + servportnum = 0 + for port in self._model.ports: + if port.vlan_id == vlan.number: + portnum += 1 + for sport in self._model.service_vlans: + if sport.vlan_id == vlan.id: + servportnum += 1 + + context['portnum'] = portnum + context['servportnum'] = servportnum context['spacer1'] = self.create_spacers((6,), (vlan.number,))[0] * ' ' context['spacer2'] = self.create_spacers((10,), (vlan.type,))[0] * ' ' context['spacer3'] = self.create_spacers((23,), (vlan.attribute,))[0] * ' ' + context['spacer4'] = self.create_spacers((16,), (len(str(servportnum)),))[0] * ' ' text += self._render('display_vlan_all_mid', context=dict(context, vlan=vlan)) count += 1 @@ -272,7 +284,7 @@ def generate_ont_info_summary(port): text2 = '' for vlan in self._model.vlans: try: - if vlan.bind_service_profile_id != '-' and int(vlan.bind_service_profile_id) >= 0: + if vlan.bind_service_profile_id is not None and int(vlan.bind_service_profile_id) >= 0: profile = self._model.get_port_profile("id", int(vlan.bind_service_profile_id)) text += self._render('display_current_configuration_section_vlan_srvprof_mid', context=dict(context, vlan=vlan, profile=profile)) @@ -537,9 +549,10 @@ def do_timezone(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def do_time(self, command, *args, context=None): # TODO: Functionality + def do_time(self, command, *args, context=None): if self._validate(args, 'dst', 'start', '3', 'last', 'Sun', '02:00:00', 'end', '10', 'last', 'Sun', '03:00:00', 'adjust', '01:00'): + #we dont have some internal time to set return else: raise exceptions.CommandSyntaxError(command=command) @@ -959,25 +972,7 @@ def do_port(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - try: # Check if s_port exists - service_port = self._model.get_service_port("name", portident) - except exceptions.SoftboxenError: - self._model.add_service_port(name=portident, connected_id=port.id, connected_type='port', - bytes_us=port.total_bytes_us, packets_us=port.total_packets_us, - bytes_ds=port.total_bytes_ds, packets_ds=port.total_packets_ds) - try: - service_port = self._model.get_service_port("name", portident) - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError(command=command) - - params = dict(name=str(vlan.number), service_port_id=service_port.id) - service_vlan = self._model.get_service_vlan_by_values(params) - if service_vlan is None: - self._model.add_service_vlan(name=vlan.number, vlan_id=vlan.id, service_port_id=service_port.id) - try: - service_vlan = self._model.get_service_vlan_by_values(params) - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError(command=command) + port.set_vlan_id(vlan.number) else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py index ae4868d..0348aa8 100644 --- a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py @@ -209,8 +209,16 @@ def do_display(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def do_save(self, command, *args, context=None): # TODO: Functionality + def do_save(self, command, *args, context=None): if args == (): + # all data are stored directly into the database + return + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_reboot(self, command, *args, context=None): + if self._validate(args, 'system'): + # cant restart api return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index 91bd76d..d4b2802 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -509,6 +509,7 @@ def do_ont(self, command, *args, context=None): elif self._validate(args, 'delete', str, str): # delete all subcomponents + #TODO: delelte service_ports + service_vlans port_idx, ont_idx = self._dissect(args, 'delete', str, str) card = context['component'] try: From db1075b6d60adb434deb1778180f9bb05b3f8393 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 8 Sep 2020 14:01:22 +0200 Subject: [PATCH 015/318] added reboot command --- cli.py | 29 ++++++++++++------- nesi/softbox/cli/base.py | 2 +- .../Huawei_Base/enableCommandProcessor.py | 10 +++++-- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/cli.py b/cli.py index 937638e..0a8926d 100644 --- a/cli.py +++ b/cli.py @@ -197,17 +197,24 @@ def main(): stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0) stdout = os.fdopen(sys.stdout.fileno(), 'wb', 0) - command_processor = cli( - model, stdin, stdout, (), template_root=args.template_root, daemon=False) - - try: - context = dict() - context['login_banner'] = model.login_banner - command_processor.history_enabled = False - command_processor.loop(context=context) - except exceptions.TerminalExitError as exc: - if exc.return_to is not None and exc.return_to != 'sysexit': - raise exc + while True: + command_processor = cli( + model, stdin, stdout, (), template_root=args.template_root, daemon=False) + + try: + context = dict() + context['login_banner'] = model.login_banner + command_processor.history_enabled = False + command_processor.loop(context=context) + except exceptions.TerminalExitError as exc: + if exc.return_to is not None and exc.return_to == 'sysexit': + break + elif exc.return_to is not None and exc.return_to == 'sysreboot': + continue + elif exc.return_to is not None and exc.return_to != 'sysexit': + raise exc + else: + return finally: if args.standalone: p.terminate() diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 1c87f11..6f719a5 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -354,7 +354,7 @@ def loop(self, context=None, return_to=None, command=None): if not exc.return_to: exc.return_to = return_to - if not exc.return_to or exc.return_to == 'sysexit' or not isinstance(self, exc.return_to): + if not exc.return_to or exc.return_to == 'sysexit' or exc.return_to == 'sysreboot' or not isinstance(self, exc.return_to): raise exc # This is the first instance of the desired diff --git a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py index 0348aa8..34fe722 100644 --- a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py @@ -13,6 +13,7 @@ from nesi import exceptions from .huaweiBaseCommandProcessor import HuaweiBaseCommandProcessor +import time class EnableCommandProcessor(HuaweiBaseCommandProcessor): @@ -218,7 +219,12 @@ def do_save(self, command, *args, context=None): def do_reboot(self, command, *args, context=None): if self._validate(args, 'system'): - # cant restart api - return + time.sleep(10) + self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) + user = self._model.get_user('status', 'Online') + user.set_offline() + exc = exceptions.TerminalExitError() + exc.return_to = 'sysreboot' + raise exc else: raise exceptions.CommandSyntaxError(command=command) From f0b681c618ed608bc8fbb6fec52adffe564982be Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 8 Sep 2020 14:24:11 +0200 Subject: [PATCH 016/318] Completely reworked huawei setup script --- bootup/conf/bootstraps/create-huawei-5623.sh | 389 ++++++++++-- .../conf/bootstraps/create-huawei-5623_old.sh | 595 ------------------ 2 files changed, 345 insertions(+), 639 deletions(-) delete mode 100755 bootup/conf/bootstraps/create-huawei-5623_old.sh diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 0cb7c64..4f9a137 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -42,30 +42,32 @@ path="`dirname \"$0\"`" # | # # |---> Card 0/2 (ftth) # # | |-> Port 0/2/0 # -# | | |-> Ont # -# | | |-> OntPort # -# | | |-> Cpe # -# | | |-> CpePort # +# | | |-> Ont 0/2/0 0 # +# | | |-> OntPort 0/2/0 0/1 # +# | | |-> Cpe 0/2/0 0/1 1 # +# | | |-> CpePort 0/2/0 0/1 1/1 # # | |-> Port 0/2/1 # -# | | |-> Ont # -# | | |-> OntPort # -# | | |-> Cpe # -# | | |-> CpePort # +# | | |-> Ont 0/2/1 0 # +# | | |-> OntPort 0/2/1 0/1 # +# | | |-> Cpe 0/2/1 0/1 1 # +# | | |-> CpePort 0/2/1 0/1 1/1 # # | |-> Port 0/2/2 # +# | |-> Ont 0/2/2 0 # +# | |-> OntPort 0/2/2 0/1 # # | # # |---> Card 0/3 (ftth-pon) # # |-> Port 0/3/0 # -# |-> Ont # -# | |-> OntPort # -# | |-> Cpe # -# | |-> CpePort # -# |-> Ont # -# |-> OntPort # -# | |-> Cpe # -# | |-> CpePort # -# |-> OntPort # -# |-> Cpe # -# |-> CpePort # +# |-> Ont 0/3/0 0 # +# | |-> OntPort 0/3/0 0/1 # +# | |-> Cpe 0/3/0 0/1 1 # +# | |-> CpePort 0/3/0 0/1 1/1 # +# |-> Ont 0/3/0 1 # +# |-> OntPort 0/3/0 1/1 # +# | |-> Cpe 0/3/0 1/1 1 # +# | |-> CpePort 0/3/0 1/1 1/1 # +# |-> OntPort 0/3/0 1/2 # +# |-> Cpe 0/3/0 1/2 1 # +# |-> CpePort 0/3/0 1/2 1/1 # # # #--------------------------------------------------------# @@ -108,6 +110,70 @@ req='{ root_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) +# Service Profile +req='{ + "name": "PPPoE", + "type": "service", + "description": "Service Profile" +}' + +service_profile=$(create_resource "$req" $ENDPOINT/boxen/$box_id/port_profiles) + +# PPPoE Vlan +req='{ + "number": 2620, + "name": "PPPoE", + "description": "The standard PPPoE Vlan", + "type": "smart", + "attribute": "common", + "bind_service_profile_id": '$service_profile', + "bind_RAIO_profile_index": "-", + "priority": "-", + "native_vlan" : "1" +}' + +vlan_pppoe=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlans) + +### VlanInterface 1 ### + +# Create a vlan interface + +req='{ + "name": "vlanif2620", + "vlan_id": '$vlan_pppoe', + "admin_state": "UP", + "line_proto_state": "DOWN", + "internet_protocol": "enabled", + "internet_address": "127.0.0.1", + "subnet_num": "24" +}' + +vlan_interface_id1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlan_interfaces) + +# CPE Management Vlan +req='{ + "number": 3320, + "name": "CPE Management", + "description": "The standard CPE Management Vlan", + "type": "smart", + "attribute": "common", + "bind_service_profile_id": "-", + "bind_RAIO_profile_index": "-", + "priority": "-", + "native_vlan" : "1" +}' + +vlan_pppoe=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlans) + +### Fan Emu ### + +# Create a physical emu at the network device (admin operation) +req='{ + "type": "FAN", + "number": 0 +}' +emu_fan=$(create_resource "$req" $ENDPOINT/boxen/$box_id/emus) + ### Subrack 0 ### # Create a physical subrack at the network device (admin operation) @@ -319,7 +385,7 @@ cpe_port_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_0', + "card_id": '$card_0_1', "description": "Physical port 0/1/2", "loopback": "disable", "upstream": 0, @@ -361,6 +427,57 @@ req='{ port_0_2_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +### Ont at port 0/2/0 ### + +# Create a physical ont at the network device (admin operation) +req='{ + "port_id":'$port_0_2_0', + "description": "Ont 0/2/0 0", + "memory_occupation": "50%", + "cpu_occupation": "1%", + "operational_state": "1", + "admin_state": "1", + "index": 0 +}' + +ont_0_2_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### OntPort 0/2/0 0/1 ### + +# Create a physical ont-port at the ont (admin operation) +req='{ + "ont_id": '$ont_0_2_0_0', + "ont_port_index": 0, + "description": "0/2/0 0/1", + "operational_state": "1", + "admin_state": "1", + "ont_port_type": "ETH" +}' + +ont_port_0_2_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) + +### Cpe 0/2/0 0/1 1 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "ont_port_id": '$ont_port_0_2_0_0_1', + "description": "Cpe 0/2/0 0/1 1", + "admin_state": "1", + "mac": "a7:10:05:3f:57:96" +}' + +cpe_0_2_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 0/2/0 0/1 1/1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_2_0_0_1_1', + "description": "CpePort 0/2/0 0/1 1/1" +}' + +cpe_port_0_2_0_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + ### PORT 0/2/1 and deps ### # Create a physical port at the network device (admin operation) @@ -376,7 +493,58 @@ req='{ "operational_state": "0" }' -port_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Ont at port 0/2/1 ### + +# Create a physical ont at the network device (admin operation) +req='{ + "port_id":'$port_0_2_1', + "description": "Ont 0/2/1 0", + "memory_occupation": "50%", + "cpu_occupation": "1%", + "operational_state": "1", + "admin_state": "1", + "index": 0 +}' + +ont_0_2_1_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### OntPort 0/2/1 0/1 ### + +# Create a physical ont-port at the ont (admin operation) +req='{ + "ont_id": '$ont_0_2_1_0', + "ont_port_index": 0, + "description": "0/2/1 0/1", + "operational_state": "0", + "admin_state": "1", + "ont_port_type": "ETH" +}' + +ont_port_0_2_1_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) + +### Cpe 0/2/1 0/1 1 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "ont_port_id": '$ont_port_0_2_1_0_1', + "description": "Cpe 0/2/1 0/1 1", + "admin_state": "0", + "mac": "d4:3f:3d:ef:d9:9a" +}' + +cpe_0_2_1_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 0/2/1 0/1 1/1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_2_1_0_1_1', + "description": "CpePort 0/2/1 0/1 1/1" +}' + +cpe_port_0_2_1_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) ### PORT 0/2/2 and deps ### @@ -393,7 +561,36 @@ req='{ "operational_state": "0" }' -port_0_1_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_2_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Ont at port 0/2/2 ### + +# Create a physical ont at the network device (admin operation) +req='{ + "port_id":'$port_0_2_2', + "description": "Ont 0/2/2 0", + "memory_occupation": "50%", + "cpu_occupation": "1%", + "operational_state": "1", + "admin_state": "1", + "index": 0 +}' + +ont_0_2_2_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### OntPort 0/2/2 0/1 ### + +# Create a physical ont-port at the ont (admin operation) +req='{ + "ont_id": '$ont_0_2_2_0', + "ont_port_index": 0, + "description": "0/2/2 0/1", + "operational_state": "0", + "admin_state": "0", + "ont_port_type": "ETH" +}' + +ont_port_0_2_2_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) ### Card 0/3 ### @@ -424,36 +621,140 @@ req='{ port_0_3_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### PORT 0/3/1 and deps ### +### Ont at port 0/3/0 ### -# Create a physical port at the network device (admin operation) +# Create a physical ont at the network device (admin operation) req='{ - "card_id": '$card_0_2', - "description": "Physical port 0/3/1", - "loopback": "disable", - "upstream": 0, - "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "port_id":'$port_0_3_0', + "description": "Ont 0/3/0 0", + "memory_occupation": "50%", + "cpu_occupation": "1%", + "operational_state": "1", "admin_state": "1", - "operational_state": "0" + "index": 0 }' -port_0_3_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +ont_0_3_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) -### PORT 0/3/2 and deps ### +### OntPort 0/3/0 0/1 ### -# Create a physical port at the network device (admin operation) +# Create a physical ont-port at the ont (admin operation) req='{ - "card_id": '$card_0_2', - "description": "Physical port 0/3/2", - "loopback": "disable", - "upstream": 0, - "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "ont_id": '$ont_0_3_0_0', + "ont_port_index": 0, + "description": "0/3/0 0/1", + "operational_state": "0", + "admin_state": "1", + "ont_port_type": "ETH" +}' + +ont_port_0_3_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) + +### Cpe 0/3/0 0/1 1 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "ont_port_id": '$ont_port_0_3_0_0_1', + "description": "Cpe 0/3/0 0/1 1", "admin_state": "0", - "operational_state": "0" + "mac": "7b:80:95:99:65:90" +}' + +cpe_0_3_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 0/3/0 0/1 1/1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_3_0_0_1_1', + "description": "CpePort 0/3/0 0/1 1/1" +}' + +cpe_port_0_3_0_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + +### Ont at port 0/3/0 ### + +# Create a physical ont at the network device (admin operation) +req='{ + "port_id":'$port_0_3_0', + "description": "Ont 0/3/0 1", + "memory_occupation": "50%", + "cpu_occupation": "1%", + "operational_state": "0", + "admin_state": "1", + "index": 1 +}' + +ont_0_3_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### OntPort 0/3/0 1/1 ### + +# Create a physical ont-port at the ont (admin operation) +req='{ + "ont_id": '$ont_0_3_0_1', + "ont_port_index": 0, + "description": "0/3/0 1/1", + "operational_state": "1", + "admin_state": "1", + "ont_port_type": "ETH" +}' + +ont_port_0_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) + +### Cpe 0/3/0 1/1 1 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "ont_port_id": '$ont_port_0_3_0_1_1', + "description": "Cpe 0/3/0 1/1 1", + "admin_state": "1", + "mac": "26:1b:9d:83:54:5a" +}' + +cpe_0_3_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 0/3/0 1/1 1/1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_3_0_1_1_1', + "description": "CpePort 0/3/0 1/1 1/1" +}' + +cpe_port_0_3_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + +### OntPort 0/3/0 1/2 ### + +# Create a physical ont-port at the ont (admin operation) +req='{ + "ont_id": '$ont_0_3_0_1', + "ont_port_index": 0, + "description": "0/3/0 1/2", + "operational_state": "0", + "admin_state": "1", + "ont_port_type": "ETH" +}' + +ont_port_0_3_0_1_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) + +### Cpe 0/3/0 1/2 1 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "ont_port_id": '$ont_port_0_3_0_1_2', + "description": "Cpe 0/3/0 1/2 1", + "admin_state": "0", + "mac": "26:1b:9d:83:54:5a" +}' + +cpe_0_3_0_1_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 0/3/0 1/2 1/1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_3_0_1_2_1', + "description": "CpePort 0/3/0 1/2 1/1" }' -port_0_3_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +cpe_port_0_3_0_1_2_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) \ No newline at end of file diff --git a/bootup/conf/bootstraps/create-huawei-5623_old.sh b/bootup/conf/bootstraps/create-huawei-5623_old.sh deleted file mode 100755 index 50f6fd0..0000000 --- a/bootup/conf/bootstraps/create-huawei-5623_old.sh +++ /dev/null @@ -1,595 +0,0 @@ -#!/bin/bash -# This file is part of the NESi software. -# -# Copyright (c) 2020 -# Original Software Design by Ilya Etingof . -# -# Software adapted by inexio . -# - Janis Groß -# - Philip Konrath -# - Alexander Dincher -# -# License: https://github.com/inexio/NESi/LICENSE.rst -# -# Example NESi REST API server bootstrapping -# - -ENDPOINT=http://localhost:5000/nesi/v1 - -path="`dirname \"$0\"`" - -. $path/functions.sh - -#--------------------------------------------------------# -# # -# Subrack 1/1 # -# |---> Card 1/1/1 (xdsl) # -# | |-> Port 1/1/1/1 # -# | | |-> Cpe 1/1/1/1/1 # -# | | |-> CpePort 1/1/1/1/1/1 # -# | |-> Port 1/1/1/2 # -# | | |-> Cpe 1/1/1/2/1 # -# | | |-> CpePort 1/1/1/2/1/1 # -# | |-> Port 1/1/1/3 # -# | # -# |---> Card 1/1/2 (vdsl) # -# | |-> Port 1/1/2/1 # -# | | |-> Cpe 1/1/2/1/1 # -# | | |-> CpePort 1/1/2/1/1/1 # -# | |-> Port 1/1/2/2 # -# | | |-> Cpe 1/1/2/2/1 # -# | | |-> CpePort 1/1/2/2/1/1 # -# | |-> Port 1/1/2/3 # -# | # -# |---> Card 1/1/3 (adsl) # -# | |-> Port 1/1/3/1 # -# | | |-> Cpe 1/1/3/1/1 # -# | | |-> CpePort 1/1/3/1/1/1 # -# | |-> Port 1/1/3/2 # -# | | |-> Cpe 1/1/3/2/1 # -# | | |-> CpePort 1/1/3/2/1/1 # -# | |-> Port 1/1/3/3 # -# | # -# |---> Card 1/1/4 (ftth) # -# | |-> Port 1/1/4/1 # -# | | |-> Ont 1/1/4/1/1 # -# | | |-> OntPort 1/1/4/1/1/1/1 # -# | | |-> Cpe 1/1/4/1/1/1/1/1 # -# | | |-> CpePort 1/1/4/1/1/1/1/1/1 # -# | |-> Port 1/1/4/2 # -# | | |-> Ont 1/1/4/2/1 # -# | | |-> OntPort 1/1/4/2/1/1/1 # -# | | |-> Cpe 1/1/4/2/1/1/1/1 # -# | | |-> CpePort 1/1/4/2/1/1/1/1/1 # -# | |-> Port 1/1/4/3 # -# | # -# |---> Card 1/1/5 (ftth-pon) # -# |-> Port 1/1/5/1 # -# |-> Ont 1/1/5/1/1 # -# | |-> OntPort 1/1/5/1/1/1/1 # -# | |-> Cpe 1/1/5/1/1/1/1/1 # -# | |-> CpePort 1/1/5/1/1/1/1/1/1 # -# |-> Ont 1/1/5/1/2 # -# |-> OntPort 1/1/5/1/2/1/1 # -# | |-> Cpe 1/1/5/1/2/1/1/1 # -# | |-> CpePort 1/1/5/1/2/1/1/1/1 # -# |-> OntPort 1/1/5/1/2/1/2 # -# |-> Cpe 1/1/5/1/2/1/2/1 # -# |-> CpePort 1/1/5/1/2/1/2/1/1 # -# # -#--------------------------------------------------------# - -# Create a network device (admin operation) -req='{ - "vendor": "Huawei", - "model": "5623", - "version": "A", - "description": "Example Switch", - "hostname": "Huawei_5623A", - "mgmt_address": "10.0.0.12", - "software_version": "MA5623V800R016C00", - "network_protocol": "telnet", - "network_address": "127.0.0.1", - "network_port": 9023, - "uuid": "2" -}' - -box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 - -# Super Admin credentials -req='{ - "username": "root", - "password": "secret" -}' - -root_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) - -# Super Admin user -req='{ - "name": "root", - "credentials_id": '$root_credential_id', - "level": "Super", - "profile": "root", - "append_info": "Super Admin", - "reenter_num": 3, - "reenter_num_temp": 3, - "lock_status": "Unlocked" -}' - -root_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) - -# PortProfile 1 -req='{ - "name": "PPPoe", - "type": "service", - "description": "PortProfile #1" -}' - -port_profile_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/port_profiles) - -# VLAN 1 -req='{ - "number": 2602, - "name": "VLAN_2602", - "description": "VLAN #1", - "type": "smart", - "attribute": "common", - "bind_service_profile_id": '$port_profile_id', - "bind_RAIO_profile_index": "-", - "priority": "-", - "native_vlan" : "1" -}' - -vlan_id1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlans) - -### Emu 0 ### - -# Create a physical emu at the network device (admin operation) -req='{ - "type": "FAN", - "number": 0 -}' -emu_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/emus) - -req='{ - "number": 1 -}' -emu_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/emus) - -### Emu 0 ### - -# Create a physical emu at the network device (admin operation) -req='{ - "type": "H831PMU", - "number": 2 -}' -emu_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/emus) - -### Subrack 0 ### - -# Create a physical subrack at the network device (admin operation) -req='{ - "name": "0", - "description": "Physical subrack #1" -}' - -subrack_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks) - -### Card 1 ### - -# Create a physical card at the network device (admin operation) -req='{ - "subrack_id": '$subrack_id', - "description": "Physical card #1", - "product": "vdsl", - "board_name": "H83BVCMM" -}' - -card1_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - -### Card 2 ### - -# Create a physical card at the network device (admin operation) -req='{ - "subrack_id": '$subrack_id', - "description": "Physical card #2", - "product": "adsl", - "board_name": "H83BVCNN" -}' - -card2_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - -### Card 3 ### - -# Create a physical card at the network device (admin operation) -req='{ - "subrack_id": '$subrack_id', - "description": "Physical card #3", - "product": "ftth-pon", - "board_name": "H807GPBH" -}' - -card3_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - -### Card 4 ### - -# Create a physical card at the network device (admin operation) -req='{ - "subrack_id": '$subrack_id', - "description": "Physical card #4", - "product": "ftth", - "board_name": "H831EIUD" -}' - -card4_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - -### Card 5 ### - -# Create a physical card at the network device (admin operation) -req='{ - "subrack_id": '$subrack_id', - "description": "Physical card #5", - "product": "ftth", - "board_name": "H802OPGE" -}' - -card5_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - -### Card 6 ### - -# Create a physical card at the network device (admin operation) -req='{ - "subrack_id": '$subrack_id', - "description": "Physical card #6", - "product": "ftth-pon", - "board_name": "H807GPBH" -}' - -card6_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - -### Card 7 ### - -# Create a physical card at the network device (admin operation) -req='{ - "subrack_id": '$subrack_id', - "description": "Physical card #7", - "product": "ftth-pon", - "board_name": "H807GPBH" -}' - -card7_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - -### PORT 1 and deps ### - -# Create a physical port at the network device (admin operation) -req='{ - "card_id": '$card1_id', - "description": "Physical port #1 on this card", - "loopback": "disable", - "upstream": 1234, - "downstream": 4321, - "upstream_max": 100000, - "downstream_max": 100000, - "admin_state": "0" -}' - -port1_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) - -### PORT 0/0/0 and deps ### - -# Create a physical port at the network device (admin operation) -req='{ - "card_id": '$card2_id', - "description": "Physical port #1 on this card", - "loopback": "disable", - "upstream": 1234, - "downstream": 4321, - "upstream_max": 100000, - "downstream_max": 100000, - "admin_state": "0" -}' - -port2_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) - - -### PORT 3 and deps ### - -# Create a physical port at the network device (admin operation) -req='{ - "card_id": '$card3_id', - "description": "Physical port #1 on this card", - "upstream": 0, - "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, - "loopback": "disable", - "admin_state": "0" -}' - -port3_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) - -### PORT 4 and deps ### - -# Create a physical port at the network device (admin operation) -req='{ - "card_id": '$card4_id', - "description": "Physical port #1 on this card", - "loopback": "disable", - "upstream": 1234, - "downstream": 4321, - "upstream_max": 100000, - "downstream_max": 100000, - "admin_state": "0" -}' - -port4_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) - -### PORT 5 and deps ### - -# Create a physical port at the network device (admin operation) -req='{ - "card_id": '$card5_id', - "description": "Physical port #1 on this card", - "loopback": "disable", - "upstream": 1234, - "downstream": 4321, - "upstream_max": 100000, - "downstream_max": 100000, - "admin_state": "0" -}' - -port5_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) - - -### PORT 6 and deps ### - -# Create a physical port at the network device (admin operation) -req='{ - "card_id": '$card5_id', - "description": "Physical port #2 on this card", - "loopback": "disable", - "upstream": 1234, - "downstream": 4321, - "upstream_max": 100000, - "downstream_max": 100000, - "admin_state": "0", - "link": "failed" -}' - -port6_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) - -### PORT 7 and deps ### - -# Create a physical port at the network device (admin operation) -req='{ - "card_id": '$card6_id', - "description": "Physical port #7 on this card", - "loopback": "disable", - "upstream": 1234, - "downstream": 4321, - "upstream_max": 100000, - "downstream_max": 100000, - "admin_state": "0", - "link": "failed" -}' - -port7_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) - -### PORT 8 and deps ### - -# Create a physical port at the network device (admin operation) -req='{ - "card_id": '$card7_id', - "description": "Physical port #8 on this card", - "loopback": "disable", - "upstream": 1234, - "downstream": 4321, - "upstream_max": 100000, - "downstream_max": 100000, - "admin_state": "0", - "link": "failed" -}' - -port8_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) - -### PORT 9 and deps ### - -# Create a physical port at the network device (admin operation) -req='{ - "card_id": '$card7_id', - "description": "Physical port #9 on this card", - "loopback": "disable", - "upstream": 1234, - "downstream": 4321, - "upstream_max": 100000, - "downstream_max": 100000, - "admin_state": "0", - "link": "failed" -}' - -port9_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) - -### Ont 1 ### - -# Create a physical ont at the network device (admin operation) - -req='{ - "port_id":'$port3_id', - "description": "Ont #1", - "memory_occupation": "50%", - "cpu_occupation": "1%", - "index": 0 -}' - -ont_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) - -### Ont 2 ### - -# Create a physical ont at the network device (admin operation) - -req='{ - "port_id":'$port7_id', - "description": "Ont #2", - "index": 0 -}' - -ont2_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) - -### Ont 3 ### - -# Create a physical ont at the network device (admin operation) - -req='{ - "port_id":'$port7_id', - "description": "Ont #3", - "index": 1 -}' - -ont3_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) - -### Ont 4 ### - -# Create a physical ont at the network device (admin operation) - -req='{ - "port_id":'$port7_id', - "description": "Ont #4", - "index": 2 -}' - -ont4_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) - -### Ont 5 ### - -# Create a physical ont at the network device (admin operation) - -req='{ - "port_id":'$port8_id', - "description": "Ont #5", - "index": 0 -}' - -ont5_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) - -### Ont 6 ### - -# Create a physical ont at the network device (admin operation) - -req='{ - "port_id":'$port9_id', - "description": "Ont #6", - "index": 1 -}' - -ont7id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) - -### OntPort 1 ### - -# Create a physical ont-port at the ont (admin operation) - -req='{ - "ont_id": '$ont_id', - "ont_port_index": 0, - "description": "OntPort #1", - "ont_port_type": "ETH" -}' - -ont_port_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) - -### OntPort 1 ### - -# Create a physical ont-port at the ont (admin operation) - -req='{ - "ont_id": '$ont2_id', - "ont_port_index": 0, - "description": "OntPort #2", - "ont_port_type": "ETH" -}' - -ont_port2_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) - -### Cpe 1 ### - -# Create a physical cpe at the ont-port (admin operation) - -req='{ - "ont_port_id": '$ont_port_id', - "description": "Cpe #1", - "mac": "8f:db:82:ef:ea:17" -}' - -cpe_id1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) - -### Cpe 2 ### - -# Create a physical cpe at the vdsl-port (admin operation) - -req='{ - "port_id": '$port1_id', - "description": "Cpe #2", - "mac": "8f:db:82:ef:ea:17" -}' - -cpe_id2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) - -### Cpe 3 ### - -# Create a physical cpe at the adsl-port (admin operation) - -req='{ - "port_id": '$port2_id', - "description": "Cpe #3", - "mac": "8f:db:82:ef:ea:17" -}' - -cpe_id3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) - -### CpePort 1 ### - -# Create a physical cpe-port at the cpe (admin operation) - -req='{ - "cpe_id": '$cpe_id1', - "description": "CpePort #1" -}' - -cpe_port_id1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) - -### CpePort 2 ### - -# Create a physical cpe-port at the vdsl-cpe (admin operation) - -req='{ - "cpe_id": '$cpe_id2', - "description": "CpePort #2" -}' - -cpe_port_id2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) - -### CpePort 3 ### - -# Create a physical cpe-port at the vdsl-cpe (admin operation) - -req='{ - "cpe_id": '$cpe_id3', - "description": "CpePort #3" -}' - -cpe_port_id3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) - -### VlanInterface 1 ### - -# Create a vlan interface - -req='{ - "name": "vlanif2602", - "vlan_id": '$vlan_id1', - "admin_state": "UP", - "line_proto_state": "DOWN", - "internet_protocol": "enabled", - "internet_address": "127.0.0.1", - "subnet_num": "24" -}' - -vlan_interface_id1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlan_interfaces) From caf635275a195dac4a3fdffed848fa7761e33aff Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Tue, 8 Sep 2020 14:37:54 +0200 Subject: [PATCH 017/318] Fix for the 'display interface ' command --- .../schemas/huawei_service_port_schemas.py | 2 +- .../huawei_resources/huawei_service_port.py | 2 ++ .../softbox/api/models/service_port_models.py | 2 ++ .../enable/display_interface_product_port.j2 | 26 +++++++++---------- .../Huawei_Base/enableCommandProcessor.py | 14 +++++++++- 5 files changed, 31 insertions(+), 15 deletions(-) diff --git a/nesi/huawei/api/schemas/huawei_service_port_schemas.py b/nesi/huawei/api/schemas/huawei_service_port_schemas.py index b2542fb..264d2d7 100644 --- a/nesi/huawei/api/schemas/huawei_service_port_schemas.py +++ b/nesi/huawei/api/schemas/huawei_service_port_schemas.py @@ -16,7 +16,7 @@ class HuaweiServicePortSchema(ServicePortSchema): class Meta: model = ServicePort - fields = ServicePortSchema.Meta.fields + ('vpi', 'vci', 'flow_type', + fields = ServicePortSchema.Meta.fields + ('vpi', 'vci', 'flow_type', 'tx_cttr', 'rx_cttr', 'flow_para', 'tx', 'inbound_table_name', 'rx', 'outbound_table_name', 'label', 'priority', 'support_down_multicast_stream', 'support_igmp_packet', 'bytes_us', 'packets_us', 'bytes_ds', diff --git a/nesi/huawei/huawei_resources/huawei_service_port.py b/nesi/huawei/huawei_resources/huawei_service_port.py index 13a8b0f..fdc8792 100644 --- a/nesi/huawei/huawei_resources/huawei_service_port.py +++ b/nesi/huawei/huawei_resources/huawei_service_port.py @@ -12,6 +12,8 @@ class HuaweiServicePort(ServicePort): flow_para = base.Field('flow_para') rx = base.Field('rx') tx = base.Field('tx') + rx_cttr = base.Field('rx_cttr') + tx_cttr = base.Field('tx_cttr') support_down_multicast_stream = base.Field('support_down_multicast_stream') support_igmp_packet = base.Field('support_igmp_packet') bytes_us = base.Field('bytes_us') diff --git a/nesi/softbox/api/models/service_port_models.py b/nesi/softbox/api/models/service_port_models.py index 2e7ca0a..14d3dd7 100644 --- a/nesi/softbox/api/models/service_port_models.py +++ b/nesi/softbox/api/models/service_port_models.py @@ -23,6 +23,8 @@ class ServicePort(db.Model): flow_para = db.Column(db.Enum('untag', 'pppoe', '-'), default='untag') rx = db.Column(db.Integer(), default=560) tx = db.Column(db.Integer(), default=520) + rx_cttr = db.Column(db.String(), default='-') + tx_cttr = db.Column(db.String(), default='-') max_mac_count = db.Column(db.Integer(), default=600) support_down_multicast_stream = db.Column(db.String(), default='disable') support_igmp_packet = db.Column(db.String(), default='disable') diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_interface_product_port.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_interface_product_port.j2 index d6f4d34..8065dcc 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/display_interface_product_port.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_interface_product_port.j2 @@ -26,16 +26,16 @@ Packets num discarded downstream Due to congestion(packet) : {{ context.port.channel_packets_discarded_ds }} - Flow type : {{ context.port.flow_type }} - Flow para : {{ context.port.flow_para }} - Rx-cttr : {{ context.port.rx_cttr }} - Tx-cttr : {{ context.port.tx_cttr }} - VLAN : {{ context.port.vlan }} - Max mac-address learning count : {{ context.port.max_addr_learn_count }} - Support down multicast stream : {{ context.port.support_down_multicast_stream }} - Support IGMP packet : {{ context.port.support_igmp_packet }} - Bytes num upstream(byte) : {{ context.port.bytes_us }} - Packets num upstream(packet) : {{ context.port.packets_us }} - Bytes num downstream(byte) : {{ context.port.bytes_ds }} - Packets num downstream(packet) : {{ context.port.packets_ds }} - +{% if context.vlan_fields %} Flow type : {{ context.s_port.flow_type }} + Flow para : {{ context.s_port.flow_para }} + Rx-cttr : {{ context.s_port.rx_cttr }} + Tx-cttr : {{ context.s_port.tx_cttr }} + VLAN : {{ context.vlan.number }} + Max mac-address learning count : {{ context.s_port.max_mac_count }} + Support down multicast stream : {{ context.s_port.support_down_multicast_stream }} + Support IGMP packet : {{ context.s_port.support_igmp_packet }} + Bytes num upstream(byte) : {{ context.s_port.bytes_us }} + Packets num upstream(packet) : {{ context.s_port.packets_us }} + Bytes num downstream(byte) : {{ context.s_port.bytes_ds }} + Packets num downstream(packet) : {{ context.s_port.packets_ds }} +{% endif %} diff --git a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py index 34fe722..6c60fa6 100644 --- a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py @@ -78,7 +78,6 @@ def do_display(self, command, *args, context=None): port = self._model.get_port("name", port_identifier) self.map_states(port, 'port') card = self._model.get_card('id', port.card_id) - except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -88,6 +87,19 @@ def do_display(self, command, *args, context=None): context['spaced_out_name'] = self.space_out_port_name(port.name) context['spacer'] = self.create_spacers((7,), (port.dynamic_profile_index,))[0] * ' ' + try: + service_port = self._model.get_service_port('connected_id', port.id) + except exceptions.SoftboxenError: + context['vlan_fields'] = False + else: + context['vlan_fields'] = True + try: + service_vlan = self._model.get_service_vlan('service_port_id', service_port.id) + vlan = self._model.get_vlan('id', service_vlan.vlan_id) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + context['s_port'] = service_port + context['vlan'] = vlan text = self._render( 'display_interface_product_port', context=dict(context, port=port, card=card)) From 5381412fdc3081e08860acd7fe1f3e3613e6fe4c Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Tue, 8 Sep 2020 15:20:22 +0200 Subject: [PATCH 018/318] Additions and adjustments to the Huawei setup-script --- bootup/conf/bootstraps/create-huawei-5623.sh | 263 +++++++++++++++++-- 1 file changed, 247 insertions(+), 16 deletions(-) diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 4f9a137..60bc0d2 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -56,19 +56,33 @@ path="`dirname \"$0\"`" # | |-> OntPort 0/2/2 0/1 # # | # # |---> Card 0/3 (ftth-pon) # -# |-> Port 0/3/0 # -# |-> Ont 0/3/0 0 # -# | |-> OntPort 0/3/0 0/1 # -# | |-> Cpe 0/3/0 0/1 1 # -# | |-> CpePort 0/3/0 0/1 1/1 # -# |-> Ont 0/3/0 1 # -# |-> OntPort 0/3/0 1/1 # -# | |-> Cpe 0/3/0 1/1 1 # -# | |-> CpePort 0/3/0 1/1 1/1 # -# |-> OntPort 0/3/0 1/2 # -# |-> Cpe 0/3/0 1/2 1 # -# |-> CpePort 0/3/0 1/2 1/1 # -# # +# | |-> Port 0/3/0 # +# | |-> Ont 0/3/0 0 # +# | | |-> OntPort 0/3/0 0/1 # +# | | |-> Cpe 0/3/0 0/1 1 # +# | | |-> CpePort 0/3/0 0/1 1/1 # +# | |-> Ont 0/3/0 1 # +# | |-> OntPort 0/3/0 1/1 # +# | | |-> Cpe 0/3/0 1/1 1 # +# | | |-> CpePort 0/3/0 1/1 1/1 # +# | |-> OntPort 0/3/0 1/2 # +# | |-> Cpe 0/3/0 1/2 1 # +# | |-> CpePort 0/3/0 1/2 1/1 # +# | # +# |---> Card 0/4 (ftth) # +# | |-> Port 0/4/0 # +# | | |-> Ont 0/4/0 0 # +# | | |-> OntPort 0/4/0 0/1 # +# | | |-> Cpe 0/4/0 0/1 1 # +# | | |-> CpePort 0/4/0 0/1 1/1 # +# | |-> Port 0/4/1 # +# | | |-> Ont 0/4/1 0 # +# | | |-> OntPort 0/4/1 0/1 # +# | | |-> Cpe 0/4/1 0/1 1 # +# | | |-> CpePort 0/4/1 0/1 1/1 # +# | |-> Port 0/4/2 # +# | |-> Ont 0/4/2 0 # +# | |-> OntPort 0/4/2 0/1 # #--------------------------------------------------------# # Create a network device (admin operation) @@ -148,7 +162,7 @@ req='{ "subnet_num": "24" }' -vlan_interface_id1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlan_interfaces) +vlan_interface_pppoe=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlan_interfaces) # CPE Management Vlan req='{ @@ -163,7 +177,7 @@ req='{ "native_vlan" : "1" }' -vlan_pppoe=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlans) +vlan_cpem=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlans) ### Fan Emu ### @@ -213,6 +227,29 @@ req='{ port_0_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +### Serviceport 0/0/0 ### + +req='{ + "name": "0/0/0", + "connected_id": '$port_0_0_0', + "connected_type": "port", + "admin_state": "1", + "operational_state": "1" +}' + +service_port_0_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) + +### Service PPPoE Vlan at ServicePort 0/0/0 ### + +req='{ + "name": "2620", + "service_port_id": '$service_port_0_0_0', + "vlan_id": '$vlan_pppoe', + "card_id": '$card_0_0' +}' + +service_vlan_0_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlans) + ### Cpe at port 0/0/0 ### # Create a physical cpe at the ont-port (admin operation) @@ -757,4 +794,198 @@ req='{ "description": "CpePort 0/3/0 1/2 1/1" }' -cpe_port_0_3_0_1_2_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) \ No newline at end of file +cpe_port_0_3_0_1_2_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + +### Card 0/4 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_0', + "description": "Physical card 0/4", + "product": "ftth", + "board_name": "H807GPBH" +}' + +card_0_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### PORT 0/4/0 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card_0_4', + "description": "Physical port 0/4/0", + "loopback": "disable", + "upstream": 10000, + "downstream": 25000, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "1", + "operational_state": "1" +}' + +port_0_4_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Ont at port 0/4/0 ### + +# Create a physical ont at the network device (admin operation) +req='{ + "port_id":'$port_0_4_0', + "description": "Ont 0/4/0 0", + "memory_occupation": "50%", + "cpu_occupation": "1%", + "operational_state": "1", + "admin_state": "1", + "index": 0 +}' + +ont_0_4_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### OntPort 0/4/0 0/1 ### + +# Create a physical ont-port at the ont (admin operation) +req='{ + "ont_id": '$ont_0_4_0_0', + "ont_port_index": 0, + "description": "0/4/0 0/1", + "operational_state": "1", + "admin_state": "1", + "ont_port_type": "ETH" +}' + +ont_port_0_4_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) + +### Cpe 0/4/0 0/1 1 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "ont_port_id": '$ont_port_0_4_0_0_1', + "description": "Cpe 0/4/0 0/1 1", + "admin_state": "1", + "mac": "a7:10:05:3f:57:96" +}' + +cpe_0_4_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 0/4/0 0/1 1/1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_4_0_0_1_1', + "description": "CpePort 0/4/0 0/1 1/1" +}' + +cpe_port_0_4_0_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + +### PORT 0/4/1 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card_0_4', + "description": "Physical port 0/4/1", + "loopback": "disable", + "upstream": 0, + "downstream": 0, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "1", + "operational_state": "0" +}' + +port_0_4_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Ont at port 0/4/1 ### + +# Create a physical ont at the network device (admin operation) +req='{ + "port_id":'$port_0_4_1', + "description": "Ont 0/4/1 0", + "memory_occupation": "50%", + "cpu_occupation": "1%", + "operational_state": "1", + "admin_state": "1", + "index": 0 +}' + +ont_0_4_1_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### OntPort 0/4/1 0/1 ### + +# Create a physical ont-port at the ont (admin operation) +req='{ + "ont_id": '$ont_0_4_1_0', + "ont_port_index": 0, + "description": "0/4/1 0/1", + "operational_state": "0", + "admin_state": "1", + "ont_port_type": "ETH" +}' + +ont_port_0_4_1_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) + +### Cpe 0/4/1 0/1 1 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "ont_port_id": '$ont_port_0_4_1_0_1', + "description": "Cpe 0/4/1 0/1 1", + "admin_state": "0", + "mac": "d4:3f:3d:ef:d9:9a" +}' + +cpe_0_4_1_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 0/4/1 0/1 1/1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_4_1_0_1_1', + "description": "CpePort 0/4/1 0/1 1/1" +}' + +cpe_port_0_4_1_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + +### PORT 0/4/2 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card_0_4', + "description": "Physical port 0/4/2", + "loopback": "disable", + "upstream": 0, + "downstream": 0, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "0", + "operational_state": "0" +}' + +port_0_4_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Ont at port 0/4/2 ### + +# Create a physical ont at the network device (admin operation) +req='{ + "port_id":'$port_0_4_2', + "description": "Ont 0/4/2 0", + "memory_occupation": "50%", + "cpu_occupation": "1%", + "operational_state": "1", + "admin_state": "1", + "index": 0 +}' + +ont_0_4_2_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### OntPort 0/4/2 0/1 ### + +# Create a physical ont-port at the ont (admin operation) +req='{ + "ont_id": '$ont_0_4_2_0', + "ont_port_index": 0, + "description": "0/4/2 0/1", + "operational_state": "0", + "admin_state": "0", + "ont_port_type": "ETH" +}' + +ont_port_0_4_2_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) \ No newline at end of file From 23e9d4dc691602544847bebfa5c89d1221c2d2b8 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Tue, 8 Sep 2020 16:29:42 +0200 Subject: [PATCH 019/318] Small command functionality addition --- .../Base/Huawei_Base/diagnoseCommandProcessor.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py index 2b42b79..615c677 100644 --- a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py @@ -105,13 +105,23 @@ def on_unknown_command(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def do_switch(self, command, *args, context=None): # TODO: Functionality (that isn't how the switch command works) + def do_switch(self, command, *args, context=None): # TODO: Functionality if self._validate(args, 'vdsl', 'mode', 'to', str): + user = self._model.get_user('status', 'Online') + if user.level != 'Super': + raise exceptions.CommandSyntaxError(command=command) + + dsl_mode, = self._dissect(args, 'vdsl', 'mode', 'to', str) + if dsl_mode != 'timode' and dsl_mode != 'tr129' and dsl_mode != 'tr165': + raise exceptions.CommandSyntaxError(command=command) + aone = self.user_input('Please enter y if you want to continue: ') if aone != 'y': - raise exceptions.InvalidInputError + raise exceptions.CommandSyntaxError(command=command) atwo = self.user_input('Please enter y again to confirm: ') if atwo != 'y': - raise exceptions.InvalidInputError + raise exceptions.CommandSyntaxError(command=command) + + return else: raise exceptions.CommandSyntaxError(command=command) From 706af6a813fec381ea89bc4153fdf74ae233bc5f Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 8 Sep 2020 17:01:03 +0200 Subject: [PATCH 020/318] added unit tests for huawei --- .gitignore | 1 + bootup/conf/bootstraps/create-huawei-5623.sh | 4 +- nesi/huawei/huawei_resources/huawei_port.py | 16 -- .../huawei_resources/huawei_port_profile.py | 1 - .../api/models/vlan_interface_models.py | 2 +- .../huawei/displayEquipment1.txt | 5 + test_cases/unit_tests/alcatel/test_alcatel.py | 2 +- test_cases/unit_tests/huawei/test_huawei.py | 255 +++++++++++++++++- .../Base/Alcatel_Base/baseCommandProcessor.py | 4 + .../Huawei_Base/configCommandProcessor.py | 1 + 10 files changed, 264 insertions(+), 27 deletions(-) create mode 100644 test_cases/integration_tests/huawei/displayEquipment1.txt diff --git a/.gitignore b/.gitignore index b208db7..c38ccac 100644 --- a/.gitignore +++ b/.gitignore @@ -134,3 +134,4 @@ dmypy.json # Tests /test_cases/integration_tests/alcatel/output.txt +/test_cases/integration_tests/huawei/output.txt \ No newline at end of file diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 60bc0d2..2c1f029 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -155,8 +155,8 @@ vlan_pppoe=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlans) req='{ "name": "vlanif2620", "vlan_id": '$vlan_pppoe', - "admin_state": "UP", - "line_proto_state": "DOWN", + "admin_state": "1", + "line_proto_state": "1", "internet_protocol": "enabled", "internet_address": "127.0.0.1", "subnet_num": "24" diff --git a/nesi/huawei/huawei_resources/huawei_port.py b/nesi/huawei/huawei_resources/huawei_port.py index 9a4206f..4b2304a 100644 --- a/nesi/huawei/huawei_resources/huawei_port.py +++ b/nesi/huawei/huawei_resources/huawei_port.py @@ -207,22 +207,6 @@ class HuaweiPort(Port): rx_power_h = base.Field('rx_power_h') vlan_id = base.Field('vlan_id') - def admin_up(self): - """Set the admin port state to up""" - self.update(admin_state='1') - - def admin_down(self): - """Set the admin port state to down""" - self.update(admin_state='0') - - def port_up(self): - """Set the port status to 'UP'""" - self.update(operational_state='1') - - def port_down(self): - """Set the port status to 'DOWN'""" - self.update(operational_state='0') - def port_downstream_set(self, ds_rate): self.update(downstream_max=ds_rate) diff --git a/nesi/huawei/huawei_resources/huawei_port_profile.py b/nesi/huawei/huawei_resources/huawei_port_profile.py index 69d28cc..cac698f 100644 --- a/nesi/huawei/huawei_resources/huawei_port_profile.py +++ b/nesi/huawei/huawei_resources/huawei_port_profile.py @@ -76,7 +76,6 @@ class HuaweiPortProfile(PortProfile): us0_psd_mask = base.Field('us0_psd_mask') vdsltoneblackout = base.Field('vdsltoneblackout') - def set(self, field, value): mapping = {field: value} self.update(**mapping) diff --git a/nesi/softbox/api/models/vlan_interface_models.py b/nesi/softbox/api/models/vlan_interface_models.py index 1cd38a5..c2e7888 100644 --- a/nesi/softbox/api/models/vlan_interface_models.py +++ b/nesi/softbox/api/models/vlan_interface_models.py @@ -20,7 +20,7 @@ class VlanInterface(db.Model): name = db.Column(db.String()) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) vlan_id = db.Column(db.Integer, db.ForeignKey('vlan.id')) - admin_state = db.Column(db.Enum('UP', 'DOWN'), default='DOWN') + admin_state = db.Column(db.Enum('0', '1'), default='0') line_proto_state = db.Column(db.Enum('UP', 'DOWN'), default='DOWN') input_packets = db.Column(db.Integer(), default=0) input_bytes = db.Column(db.Integer(), default=0) diff --git a/test_cases/integration_tests/huawei/displayEquipment1.txt b/test_cases/integration_tests/huawei/displayEquipment1.txt new file mode 100644 index 0000000..48ff39a --- /dev/null +++ b/test_cases/integration_tests/huawei/displayEquipment1.txt @@ -0,0 +1,5 @@ +root +secret +enable +quit +y \ No newline at end of file diff --git a/test_cases/unit_tests/alcatel/test_alcatel.py b/test_cases/unit_tests/alcatel/test_alcatel.py index fa7e402..46d4dc7 100644 --- a/test_cases/unit_tests/alcatel/test_alcatel.py +++ b/test_cases/unit_tests/alcatel/test_alcatel.py @@ -296,7 +296,7 @@ def test_serviceport_fields(self): except exceptions.SoftboxenError: assert True - def test_serviceport_fields(self): + def test_servicevlan_fields(self): port = self.model.get_service_vlan("name", '2620') assert port.l2fwder_vlan is None port.set_l2fwder_vlan(1) diff --git a/test_cases/unit_tests/huawei/test_huawei.py b/test_cases/unit_tests/huawei/test_huawei.py index 6e99798..3911446 100644 --- a/test_cases/unit_tests/huawei/test_huawei.py +++ b/test_cases/unit_tests/huawei/test_huawei.py @@ -11,23 +11,266 @@ # License: https://github.com/inexio/NESi/LICENSE.rst from test_cases.unit_tests.test_core import TestCore +from nesi import exceptions +from os import listdir +from os.path import isfile, join +import pytest class TestHuawei(TestCore): + PATH = 'test_cases/integration_tests/huawei/' + DATA = [f for f in listdir('test_cases/integration_tests/huawei/') if + isfile(join('test_cases/integration_tests/huawei/', f)) and f != 'output.txt'] def test_portup_portdown(self): port = self.model.get_port("name", '0/0/0') + port.admin_down() assert(self.model.get_port("name", '0/0/0').admin_state == '0') port.admin_up() assert(self.model.get_port("name", '0/0/0').admin_state == '1') - port.admin_down() - assert(self.model.get_port("name", '0/0/0').admin_state == '0') + port.up() + assert port.operational_state == '1' + port.down() + assert port.operational_state == '0' + + def test_port_rest(self): + port = self.model.get_port("name", '0/0/0') + assert port.downstream_max == 100000 + port.port_downstream_set(1) + assert port.downstream_max == 1 + try: + port.port_downstream_set('failure') + assert False + except exceptions.SoftboxenError: + assert True + + assert port.upstream_max == 100000 + port.port_upstream_set(1) + assert port.upstream_max == 1 + try: + port.port_upstream_set('failure') + assert False + except exceptions.SoftboxenError: + assert True + + assert port.vlan_id is None + port.set_vlan_id(1) + assert port.vlan_id == 1 + try: + port.set_vlan_id('failure') + assert False + except exceptions.SoftboxenError: + assert True - def test_ontportup_portdown(self): + def test_ont_fields(self): + port = self.model.get_ont("name", '0/2/0/0') + assert port.ont_online_duration is None + port.set_online_duration('1') + assert (port.ont_online_duration == '1') + try: + port.set_online_duration(5) + assert False + except exceptions.SoftboxenError: + assert True + + def test_ont_ports(self): port = self.model.get_ont_port("name", '0/2/0/0/1') - assert(self.model.get_ont_port("name", '0/2/0/0/1').operational_state == '0') port.operational_state_up() - assert(self.model.get_ont_port("name", '0/2/0/0/1').operational_state == '1') + assert (port.operational_state == '1') port.operational_state_down() - assert(self.model.get_ont_port("name", '0/2/0/0/1').operational_state == '0') + assert (port.operational_state == '0') + + def test_port_profiles(self): + port = self.model.get_port_profile("name", "PPPoE") + assert port.type == 'service' + port.set('type', 'spectrum') + assert port.type == 'spectrum' + try: + port.set('FAIL', 'failure') + assert False + except exceptions.SoftboxenError: + assert True + + def test_service_port(self): + port = self.model.get_service_port("name", "0/0/0") + assert port.vpi == '-' + port.set_vpi('vpi') + assert port.vpi == 'vpi' + try: + port.set_vpi(1) + assert False + except exceptions.SoftboxenError: + assert True + + assert port.vci == '-' + port.set_vci('vci') + assert port.vci == 'vci' + try: + port.set_vci(1) + assert False + except exceptions.SoftboxenError: + assert True + + assert port.inbound_table_name == 'ip-traffic-table_520' + port.set_inbound_table_name('vci') + assert port.inbound_table_name == 'vci' + try: + port.set_inbound_table_name(1) + assert False + except exceptions.SoftboxenError: + assert True + + assert port.outbound_table_name == 'ip-traffic-table_560' + port.set_outbound_table_name('vci') + assert port.outbound_table_name == 'vci' + try: + port.set_outbound_table_name(1) + assert False + except exceptions.SoftboxenError: + assert True + + assert port.connected_id is not None + assert port.connected_type is not None + port.set_connected_id(20) + assert port.connected_id == 20 + port.set_connected_type('ont') + assert port.connected_type == 'ont' + try: + port.set_connected_type(1) + assert False + except exceptions.SoftboxenError: + assert True + try: + port.set_connected_id('failure') + assert False + except exceptions.SoftboxenError: + assert True + port.set_admin_state('0') + assert port.admin_state == '0' + port.set_admin_state('1') + assert port.admin_state == '1' + try: + port.set_connected_id(0) + assert False + except exceptions.SoftboxenError: + assert True + + def test_service_vlan(self): + port = self.model.get_service_vlan("name", "2620") + + assert port.mode == 'ptm' + port.set_mode('atm') + assert port.mode == 'atm' + try: + port.set_mode('fail') + assert False + except exceptions.SoftboxenError: + assert True + try: + port.set_mode(0) + assert False + except exceptions.SoftboxenError: + assert True + + assert port.tag == 'single-tagged' + port.set_tag('untagged') + assert port.tag == 'untagged' + try: + port.set_tag('fail') + assert False + except exceptions.SoftboxenError: + assert True + try: + port.set_tag(0) + assert False + except exceptions.SoftboxenError: + assert True + + def test_user(self): + user = self.model.get_user("name", 'root') + assert user.lock_status == 'Unlocked' + user.lock() + assert user.lock_status == 'Locked' + user.unlock() + assert user.lock_status == 'Unlocked' + + assert user.reenter_num_temp == 3 + user.set_reenter_num_temp(1) + assert user.reenter_num_temp == 1 + try: + user.set_reenter_num_temp('fail') + assert False + except exceptions.SoftboxenError: + assert True + + assert user.status == 'Offline' + user.set_online() + assert user.status == 'Online' + user.set_offline() + assert user.status == 'Offline' + + def test_vlan(self): + vlan = self.model.get_vlan('number', 2620) + + assert vlan.type == 'smart' + vlan.set_type_smart() + assert vlan.type == 'smart' + + assert vlan.tag == 'untagged' + vlan.set_tag('tagged') + assert vlan.tag == 'tagged' + try: + vlan.set_tag('fail') + assert False + except exceptions.SoftboxenError: + assert True + try: + vlan.set_tag(0) + assert False + except exceptions.SoftboxenError: + assert True + + assert vlan.bind_service_profile_id == 1 + vlan.set_service_profile_id(22) + assert vlan.bind_service_profile_id == 22 + try: + vlan.set_service_profile_id('fail') + assert False + except exceptions.SoftboxenError: + assert True + + def test_vlaninterface(self): + port = self.model.get_vlan_interface("name", "vlanif2620") + assert port.admin_state == '1' + port.set('admin_state', '0') + assert port.admin_state == '0' + try: + port.set('FAIL', 'failure') + assert False + except exceptions.SoftboxenError: + assert True + + def test_box_properties(self): + assert len(self.model.subracks) == 1 + assert len(self.model.cards) == 5 + assert len(self.model.get_cards()) == len(self.model.cards) + assert len(self.model.ports) == len(self.model.get_ports()) + assert len(self.model.onts) == len(self.model.get_onts()) + assert len(self.model.ont_ports) == len(self.model.get_ont_ports()) + assert len(self.model.cpes) == len(self.model.get_cpes()) + assert len(self.model.cpe_ports) == len(self.model.get_cpe_ports()) + assert len(self.model.vlans) == 2 + assert len(self.model.service_vlans) == 1 + assert len(self.model.service_ports) == 1 + assert len(self.model.credentials) == 1 + assert len(self.model.routes) == 0 + assert len(self.model.port_profiles) == 1 + assert len(self.model.qos_interfaces) == 0 + assert len(self.model.emus) == 1 + assert len(self.model.users) == 1 + assert len(self.model.vlan_interfaces) == 1 + assert self.model.get_user("name", 'root') == self.model.get_users("name", 'root').find_by_field_value("name", 'root') + @pytest.mark.parametrize("path", DATA) + def test_integration(self, path): + self.run(self.PATH + path, self.PATH + 'output.txt') diff --git a/vendors/Alcatel/Base/Alcatel_Base/baseCommandProcessor.py b/vendors/Alcatel/Base/Alcatel_Base/baseCommandProcessor.py index 56b8669..d87a9ff 100644 --- a/vendors/Alcatel/Base/Alcatel_Base/baseCommandProcessor.py +++ b/vendors/Alcatel/Base/Alcatel_Base/baseCommandProcessor.py @@ -33,11 +33,15 @@ def map_states(self, object, type): if object.admin_state == '0': if type == 'subrack': object.admin_state = 'lock' + elif type == 'vlan_interface': + object.admin_state = 'DOWN' elif type in ('card', 'port', 'ont', 'ont_port', 'cpe', 'service_port'): object.admin_state = 'down' elif object.admin_state == '1': if type == 'subrack': object.admin_state = 'unlock' + elif type == 'vlan_interface': + object.admin_state = 'UP' elif type in ('card', 'port', 'ont', 'ont_port', 'cpe', 'service_port'): object.admin_state = 'up' elif object.admin_state == '2': diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index cc97bde..a338936 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -210,6 +210,7 @@ def generate_ont_info_summary(port): name = 'vlanif' + vlan_number try: vlanif = self._model.get_vlan_interface("name", name) + self.map_states(vlanif, 'vlan_interface') except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) From 6d0264402f5028239ac413b5397be6355f2dbe6e Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 8 Sep 2020 17:00:58 +0200 Subject: [PATCH 021/318] Added functionality to display mac-address all command --- bootup/conf/bootstraps/create-huawei-5623.sh | 18 +-- .../enable/config/display_mac-address_all.j2 | 123 ------------------ .../config/display_mac-address_all_middle.j2 | 1 - ...m.j2 => display_mac_address_all_bottom.j2} | 0 .../config/display_mac_address_all_middle.j2 | 2 + ..._top.j2 => display_mac_address_all_top.j2} | 1 + .../Huawei_Base/configCommandProcessor.py | 58 ++++++++- 7 files changed, 68 insertions(+), 135 deletions(-) delete mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_mac-address_all.j2 delete mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_mac-address_all_middle.j2 rename templates/Huawei/Base/1/login/mainloop/enable/config/{display_mac-address_all_bottom.j2 => display_mac_address_all_bottom.j2} (100%) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_middle.j2 rename templates/Huawei/Base/1/login/mainloop/enable/config/{display_mac-address_all_top.j2 => display_mac_address_all_top.j2} (99%) diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 2c1f029..75f3460 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -256,7 +256,7 @@ service_vlan_0_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlan req='{ "port_id": '$port_0_0_0', "description": "Cpe 0/0/0 1", - "mac": "03:ed:5d:a1:4d:5d", + "mac": "03ed-5da1-4d5d", "admin_state": "1" }' @@ -295,7 +295,7 @@ port_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) req='{ "port_id": '$port_0_0_1', "description": "Cpe 0/0/1 1", - "mac": "8e:1c:02:05:a3:dc", + "mac": "8e1c-0205-a3dc", "admin_state": "0" }' @@ -363,7 +363,7 @@ port_0_1_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) req='{ "port_id": '$port_0_1_0', "description": "Cpe 0/1/0 1", - "mac": "61:26:5c:eb:8a:a6", + "mac": "6126-5ceb-8aa6", "admin_state": "1" }' @@ -402,7 +402,7 @@ port_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) req='{ "port_id": '$port_0_1_1', "description": "Cpe 0/1/1 1", - "mac": "49:a6:23:91:f4:7b", + "mac": "49a6-2391-f47b", "admin_state": "0" }' @@ -500,7 +500,7 @@ req='{ "ont_port_id": '$ont_port_0_2_0_0_1', "description": "Cpe 0/2/0 0/1 1", "admin_state": "1", - "mac": "a7:10:05:3f:57:96" + "mac": "a710-053f-5796" }' cpe_0_2_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) @@ -568,7 +568,7 @@ req='{ "ont_port_id": '$ont_port_0_2_1_0_1', "description": "Cpe 0/2/1 0/1 1", "admin_state": "0", - "mac": "d4:3f:3d:ef:d9:9a" + "mac": "d43f-3def-d99a" }' cpe_0_2_1_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) @@ -694,7 +694,7 @@ req='{ "ont_port_id": '$ont_port_0_3_0_0_1', "description": "Cpe 0/3/0 0/1 1", "admin_state": "0", - "mac": "7b:80:95:99:65:90" + "mac": "7b80-9599-6590" }' cpe_0_3_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) @@ -745,7 +745,7 @@ req='{ "ont_port_id": '$ont_port_0_3_0_1_1', "description": "Cpe 0/3/0 1/1 1", "admin_state": "1", - "mac": "26:1b:9d:83:54:5a" + "mac": "261b-9d83-545a" }' cpe_0_3_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) @@ -781,7 +781,7 @@ req='{ "ont_port_id": '$ont_port_0_3_0_1_2', "description": "Cpe 0/3/0 1/2 1", "admin_state": "0", - "mac": "26:1b:9d:83:54:5a" + "mac": "261b-9d83-545a" }' cpe_0_3_0_1_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac-address_all.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac-address_all.j2 deleted file mode 100644 index ae3c7de..0000000 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac-address_all.j2 +++ /dev/null @@ -1,123 +0,0 @@ - It will take some time, please wait... - ----------------------------------------------------------------------- - SRV-P BUNDLE TYPE MAC MAC TYPE F /S /P VPI VCI VLAN ID - INDEX INDEX - ----------------------------------------------------------------------- - - - eth 0014-2d4c-347f dynamic 0 /0 /0 - - 2302 - - - eth 34a2-a2b9-6a3b dynamic 0 /0 /0 - - 2302 - - - eth 80a2-357a-703f dynamic 0 /0 /0 - - 2302 - - - eth b86a-9704-ad75 dynamic 0 /0 /0 - - 2302 - - - eth 80a2-357a-82e3 dynamic 0 /0 /0 - - 1 - - - eth b86a-976f-864c dynamic 0 /0 /0 - - 2302 - - - eth 0020-d242-23ba dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f69-65f4 dynamic 0 /0 /0 - - 2302 - - - eth 80a2-357a-82df dynamic 0 /0 /0 - - 2323 - - - eth 0019-8f68-0a46 dynamic 0 /0 /0 - - 2302 - - - eth 748e-f878-ca60 dynamic 0 /0 /0 - - 2302 - - - eth 34a2-a2b9-69ab dynamic 0 /0 /0 - - 2302 - - - eth b86a-9704-b195 dynamic 0 /0 /0 - - 2302 - - - eth 0020-d24d-ace5 dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f68-0a28 dynamic 0 /0 /0 - - 2302 - - - eth 0020-d24e-2bae dynamic 0 /0 /0 - - 2302 - - - eth b86a-976f-92ac dynamic 0 /0 /0 - - 2302 - - - eth 0014-2d2c-cc2f dynamic 0 /0 /0 - - 2302 - - - eth 00e0-df63-42d9 dynamic 0 /0 /0 - - 2302 - - - eth b86a-9704-9ff5 dynamic 0 /0 /0 - - 2302 - - - eth 80a2-357a-82df dynamic 0 /0 /0 - - 1 - - - eth 0019-8f5f-9a9f dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f90-2c89 dynamic 0 /0 /0 - - 2302 - - - eth b86a-9742-0463 dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f90-1fca dynamic 0 /0 /0 - - 2302 - - - eth b86a-9742-03a3 dynamic 0 /0 /0 - - 2302 - - - eth e030-05c7-6128 dynamic 0 /0 /0 - - 2302 - - - eth fc33-4216-dab0 dynamic 0 /0 /0 - - 2302 - - - eth 0020-d231-d4bf dynamic 0 /0 /0 - - 2302 - - - eth 0020-d246-9b9c dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f69-ddb6 dynamic 0 /0 /0 - - 2302 - - - eth b86a-976f-80cc dynamic 0 /0 /0 - - 2302 - - - eth 0014-2d2c-cc28 dynamic 0 /0 /0 - - 2302 - - - eth e4a8-b6c5-02dc dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f67-06bd dynamic 0 /0 /0 - - 2302 - - - eth 000a-19c8-8462 dynamic 0 /0 /0 - - 2302 - - - eth 00e0-df71-6899 dynamic 0 /0 /0 - - 2302 - - - eth 0060-3519-3ee6 dynamic 0 /0 /0 - - 2302 - - - eth 00a2-eeb0-97ec dynamic 0 /0 /0 - - 2320 - - - eth 34a2-a2b9-6a73 dynamic 0 /0 /0 - - 2302 - - - eth 80a2-357a-6e9f dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f67-1736 dynamic 0 /0 /0 - - 2302 - - - eth 384c-4f1e-c114 dynamic 0 /0 /0 - - 2302 - - - eth 0020-d246-79e0 dynamic 0 /0 /0 - - 2302 - - - eth 000a-19ca-3af4 dynamic 0 /0 /0 - - 2302 - - - eth 609c-9fbb-9b9c dynamic 0 /0 /0 - - 2302 - - - eth 384c-4f1e-c23c dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f1f-8131 dynamic 0 /0 /0 - - 2302 - - - eth 0018-2317-dc33 dynamic 0 /0 /0 - - 2302 - - - eth 00e0-df30-829d dynamic 0 /0 /0 - - 2302 - - - eth 34a2-a2b9-695b dynamic 0 /0 /0 - - 2302 - - - eth 80a2-357a-82df dynamic 0 /0 /0 - - 2320 - - - eth 00e0-df70-7273 dynamic 0 /0 /0 - - 2302 - - - eth b86a-976f-8c0c dynamic 0 /0 /0 - - 2302 - - - eth 0014-2d4b-7fd4 dynamic 0 /0 /0 - - 2302 - - - eth 00e0-df70-7e73 dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f90-1c8f dynamic 0 /0 /0 - - 2302 - - - eth 80a2-357a-72bf dynamic 0 /0 /0 - - 2302 - - - eth 80a2-357a-647f dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f69-d6b4 dynamic 0 /0 /0 - - 2302 - - - eth 0020-d23b-c9a1 dynamic 0 /0 /0 - - 2302 - - - eth b86a-976f-830c dynamic 0 /0 /0 - - 2302 - 2 - vdl 3481-c403-3b3c dynamic 0 /1 /2 - - 2320 - - - eth 000a-19c5-9cd6 dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f69-cfef dynamic 0 /0 /0 - - 2302 - - - eth 80a2-357a-68ff dynamic 0 /0 /0 - - 2302 - - - eth 0014-2d4c-348b dynamic 0 /0 /0 - - 2302 - - - eth 0014-2d28-d377 dynamic 0 /0 /0 - - 2302 - - - eth 609c-9fbb-b45c dynamic 0 /0 /0 - - 2302 - - - eth 0020-d240-cd9c dynamic 0 /0 /0 - - 2302 - - - eth 000a-19ca-3558 dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f90-1fd4 dynamic 0 /0 /0 - - 2302 - - - eth 748e-f878-efa0 dynamic 0 /0 /0 - - 2302 - - - eth 000a-19ca-34b3 dynamic 0 /0 /0 - - 2302 - - - eth 384c-4f1e-c194 dynamic 0 /0 /0 - - 2302 - - - eth b86a-97a7-743c dynamic 0 /0 /0 - - 2302 - - - eth 748e-f877-56f0 dynamic 0 /0 /0 - - 2302 - - - eth 20d8-0bec-9047 dynamic 0 /0 /0 - - 2320 - - - eth 748e-f878-55b0 dynamic 0 /0 /0 - - 2302 - - - eth 80a2-357a-5cdf dynamic 0 /0 /0 - - 2302 - - - eth b86a-976f-9b6c dynamic 0 /0 /0 - - 2302 - - - eth 34a2-a2b9-6afb dynamic 0 /0 /0 - - 2302 - - - eth 20d8-0bec-9064 dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f67-1733 dynamic 0 /0 /0 - - 2302 - - - eth b86a-976f-904c dynamic 0 /0 /0 - - 2302 - - - eth b86a-976f-802c dynamic 0 /0 /0 - - 2302 - - - eth 80a2-357a-82df dynamic 0 /0 /0 - - 2302 - - - eth 000a-19ca-971c dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f67-fcca dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f90-2c8d dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f67-e400 dynamic 0 /0 /0 - - 2302 - - - eth 000a-19ca-3940 dynamic 0 /0 /0 - - 2302 - - - eth b86a-9741-ffe3 dynamic 0 /0 /0 - - 2302 - - - eth b86a-976f-886c dynamic 0 /0 /0 - - 2302 - - - eth 346a-c24d-5d6d dynamic 0 /0 /0 - - 2302 - - - eth b86a-976f-890c dynamic 0 /0 /0 - - 2302 - - - eth 0020-d246-131d dynamic 0 /0 /0 - - 2302 - - - eth 80a2-357a-657f dynamic 0 /0 /0 - - 2302 - - - eth 0019-8f67-079e dynamic 0 /0 /0 - - 2302 - - - eth 000a-19ca-96a3 dynamic 0 /0 /0 - - 2302 - - - eth 00e0-df4d-cc7d dynamic 0 /0 /0 - - 2302 - - - eth 34a2-a2b9-6943 dynamic 0 /0 /0 - - 2302 - - - eth 00e0-df63-6e4d dynamic 0 /0 /0 - - 2302 - - - eth b86a-976f-930c dynamic 0 /0 /0 - - 2302 - - - eth 0014-2d4b-cd0a dynamic 0 /0 /0 - - 2302 - - - eth 0000-5e00-0101 dynamic 0 /0 /0 - - 2302 - - - eth b86a-976f-8fec dynamic 0 /0 /0 - - 2302 - - - eth b86a-976f-9b4c dynamic 0 /0 /0 - - 2302 - - - eth 0020-d245-f909 dynamic 0 /0 /0 - - 2302 - - - eth b86a-97a7-853c dynamic 0 /0 /0 - - 2302 - ----------------------------------------------------------------------- - Total: 110 - Note: F--Frame, S--Slot, P--Port, - A--The MAC address is learned or configured on the aggregation port, - VPI indicates GEM Port ID for GPON, - v/e--vlan/encap, pritag--priority-tagged, - ppp--pppoe, ip--ipoe, ip4--ipv4oe, ip6--ipv6oe - diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac-address_all_middle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac-address_all_middle.j2 deleted file mode 100644 index 2d8a3be..0000000 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac-address_all_middle.j2 +++ /dev/null @@ -1 +0,0 @@ - - - eth {{ context.vlan.mac_address }} dynamic 0 /0 /0 - - {{ context.vlan.number }} \ No newline at end of file diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac-address_all_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_mac-address_all_bottom.j2 rename to templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_middle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_middle.j2 new file mode 100644 index 0000000..1f6da37 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_middle.j2 @@ -0,0 +1,2 @@ + - - {{ context.product }} {{ context.cpe_mac }} dynamic {{ context.subrack }} /{{ context.card }} /{{ context.port }} {{ context.ont }} {{ context.ont_port }} 2620 + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac-address_all_top.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_top.j2 similarity index 99% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_mac-address_all_top.j2 rename to templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_top.j2 index dccdc55..c89aee7 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac-address_all_top.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_top.j2 @@ -3,3 +3,4 @@ SRV-P BUNDLE TYPE MAC MAC TYPE F /S /P VPI VCI VLAN ID INDEX INDEX ----------------------------------------------------------------------- + diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index a338936..49018d5 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -273,9 +273,63 @@ def generate_ont_info_summary(port): elif self._validate(args, 'mac-address', 'all'): self.user_input('{ || }:') - text = self._render( - 'display_mac-address_all', + + text = self._render('display_mac_address_all_top', + context=context) + + for cpe in self._model.cpes: + port = None + ont_port = None + if cpe.port_id is not None: + port = self._model.get_port('id', cpe.port_id) + elif cpe.ont_port_id is not None: + ont_port = self._model.get_ont_port('id', cpe.ont_port_id) + else: + pass + #TODO: Raise exception: Floating CPE found + + ont = None + if port is None: + ont = self._model.get_ont('id', ont_port.ont_id) + port = self._model.get_port('id', ont.port_id) + + card = self._model.get_card('id', port.card_id) + + if card.product == 'adsl': + context['product'] = 'adl' + elif card.product == 'vdsl': + context['product'] = 'vdl' + elif card.product == 'ftth': + context['product'] = 'eth' + elif card.product == 'ftth-pon': + context['product'] = 'pon' + + ont_identifier = None + ont_port_identifier = None + + if ont_port is None: + subrack_identifier, card_identifier, port_identifier = port.name.split('/') + else: + subrack_identifier, card_identifier, port_identifier, ont_identifier, ont_port_identifier = ont_port.name.split('/') + + context['subrack'] = subrack_identifier + context['card'] = card_identifier + context['port'] = port_identifier + if ont is None: + context['ont'] = '-' + else: + context['ont'] = ont_identifier + if ont_port is None: + context['ont_port'] = '-' + else: + context['ont_port'] = ont_port_identifier + context['cpe_mac'] = cpe.mac + text += self._render('display_mac_address_all_middle', context=context) + + text += self._render('display_mac_address_all_bottom', + context=context) + self._write(text) elif self._validate(args, 'current-configuration', 'section', 'vlan-srvprof'): From e7fffc0593727633584d414a6c587bcd6fa66739 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 8 Sep 2020 17:15:59 +0200 Subject: [PATCH 022/318] Fixed line_proto_state --- nesi/softbox/api/models/vlan_interface_models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nesi/softbox/api/models/vlan_interface_models.py b/nesi/softbox/api/models/vlan_interface_models.py index c2e7888..5a53ae8 100644 --- a/nesi/softbox/api/models/vlan_interface_models.py +++ b/nesi/softbox/api/models/vlan_interface_models.py @@ -21,7 +21,7 @@ class VlanInterface(db.Model): box_id = db.Column(db.Integer, db.ForeignKey('box.id')) vlan_id = db.Column(db.Integer, db.ForeignKey('vlan.id')) admin_state = db.Column(db.Enum('0', '1'), default='0') - line_proto_state = db.Column(db.Enum('UP', 'DOWN'), default='DOWN') + line_proto_state = db.Column(db.Enum('0', '1'), default='0') # 0 => DOWN, 1 => UP input_packets = db.Column(db.Integer(), default=0) input_bytes = db.Column(db.Integer(), default=0) input_multicasts = db.Column(db.Integer(), default=0) From 00c28458443a1a7a1b9979d214f5a224ee11f1a8 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 9 Sep 2020 10:45:37 +0200 Subject: [PATCH 023/318] Now removing '\r' and '\n' from raw_line when retrieving username, removed 'Connection closed by foreign host' message from on_exit template --- templates/Huawei/5623/A/on_exit.j2 | 1 - vendors/Alcatel/7360/Alcatel_7360/main.py | 2 +- vendors/Huawei/5623/Huawei_5623/main.py | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/templates/Huawei/5623/A/on_exit.j2 b/templates/Huawei/5623/A/on_exit.j2 index 25b73e2..071fe94 100644 --- a/templates/Huawei/5623/A/on_exit.j2 +++ b/templates/Huawei/5623/A/on_exit.j2 @@ -1,3 +1,2 @@ Configuration console exit, please retry to log on -Connection closed by foreign host. diff --git a/vendors/Alcatel/7360/Alcatel_7360/main.py b/vendors/Alcatel/7360/Alcatel_7360/main.py index f2d11bb..3725989 100644 --- a/vendors/Alcatel/7360/Alcatel_7360/main.py +++ b/vendors/Alcatel/7360/Alcatel_7360/main.py @@ -30,7 +30,7 @@ def on_unknown_command(self, command, *args, context=None): subprocessor = self._create_subprocessor( LoginCommandProcessor, 'login') - context['username'] = context['raw_line'] + context['username'] = context['raw_line'].replace('\r', '').replace('\n', '') try: subprocessor.history_enabled = False diff --git a/vendors/Huawei/5623/Huawei_5623/main.py b/vendors/Huawei/5623/Huawei_5623/main.py index 3528735..e985903 100644 --- a/vendors/Huawei/5623/Huawei_5623/main.py +++ b/vendors/Huawei/5623/Huawei_5623/main.py @@ -30,7 +30,7 @@ def on_unknown_command(self, command, *args, context=None): subprocessor = self._create_subprocessor( LoginCommandProcessor, 'login') - context['username'] = context['raw_line'] + context['username'] = context['raw_line'].replace('\r', '').replace('\n', '') try: subprocessor.history_enabled = False From 88ca44b33dc1a63da2e598322cf98151eabd2021 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Wed, 9 Sep 2020 11:27:56 +0200 Subject: [PATCH 024/318] Small fix for the creation of port profiles and formatting changes --- .../Huawei_Base/configCommandProcessor.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 49018d5..9996dc8 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -19,9 +19,6 @@ from .baseMixIn import BaseMixIn -# TODO: Functionality of most functions - - class ConfigCommandProcessor(HuaweiBaseCommandProcessor, BaseMixIn): def do_disable(self, command, *args, context=None): @@ -274,8 +271,7 @@ def generate_ont_info_summary(port): elif self._validate(args, 'mac-address', 'all'): self.user_input('{ || }:') - text = self._render('display_mac_address_all_top', - context=context) + text = self._render('display_mac_address_all_top', context=context) for cpe in self._model.cpes: port = None @@ -310,7 +306,8 @@ def generate_ont_info_summary(port): if ont_port is None: subrack_identifier, card_identifier, port_identifier = port.name.split('/') else: - subrack_identifier, card_identifier, port_identifier, ont_identifier, ont_port_identifier = ont_port.name.split('/') + subrack_identifier, card_identifier, port_identifier, ont_identifier, ont_port_identifier = \ + ont_port.name.split('/') context['subrack'] = subrack_identifier context['card'] = card_identifier @@ -324,11 +321,9 @@ def generate_ont_info_summary(port): else: context['ont_port'] = ont_port_identifier context['cpe_mac'] = cpe.mac - text += self._render('display_mac_address_all_middle', - context=context) + text += self._render('display_mac_address_all_middle', context=context) - text += self._render('display_mac_address_all_bottom', - context=context) + text += self._render('display_mac_address_all_bottom', context=context) self._write(text) @@ -607,7 +602,7 @@ def do_timezone(self, command, *args, context=None): def do_time(self, command, *args, context=None): if self._validate(args, 'dst', 'start', '3', 'last', 'Sun', '02:00:00', 'end', '10', 'last', 'Sun', '03:00:00', 'adjust', '01:00'): - #we dont have some internal time to set + # we dont have some internal time to set return else: raise exceptions.CommandSyntaxError(command=command) @@ -1182,7 +1177,7 @@ def do_xdsl(self, command, *args, context=None): try: _ = self._model.get_port_profile('name', name) except exceptions.SoftboxenError: - self._model.add_port_profile(name=profile_num, type='inp-delay') + self._model.add_port_profile(name=name, type='inp-delay') try: port_profile = self._model.get_port_profile('name', name) except exceptions.SoftboxenError: From 8560874bc5734c89032d4fb944fc0ea21de39496 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 9 Sep 2020 11:55:54 +0200 Subject: [PATCH 025/318] Added newline between prompts for huawei devices, removing newlines from character count of prompt --- nesi/softbox/cli/base.py | 4 ++-- .../Base/1/login/mainloop/enable/config/interface/on_cycle.j2 | 1 + .../Huawei/Base/1/login/mainloop/enable/config/on_cycle.j2 | 1 + .../Base/1/login/mainloop/enable/config/test/on_cycle.j2 | 1 + .../Huawei/Base/1/login/mainloop/enable/diagnose/on_cycle.j2 | 1 + templates/Huawei/Base/1/login/mainloop/enable/on_cycle.j2 | 1 + templates/Huawei/Base/1/login/mainloop/on_cycle.j2 | 1 + 7 files changed, 8 insertions(+), 2 deletions(-) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 6f719a5..afb3ff3 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -365,7 +365,7 @@ def loop(self, context=None, return_to=None, command=None): self.on_exit(context) def get_prompt_len(self): - text = self._render('on_cycle', context=dict(), ignore_errors=True) + text = self._render('on_cycle', context=dict(), ignore_errors=True).replace('\n', '') if text is None or len(text) == 0: text = self._render('on_enter', context=dict(), ignore_errors=True) @@ -378,7 +378,7 @@ def get_prompt_len(self): return result def set_prompt_end_pos(self, context): - text = self._render('on_cycle', context=context, ignore_errors=True) + text = self._render('on_cycle', context=context, ignore_errors=True).replace('\n', '') if len(text) == 0: text = self._render('on_enter', context=context, ignore_errors=True) diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/on_cycle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/on_cycle.j2 index 467e833..ede133f 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/on_cycle.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/on_cycle.j2 @@ -1,3 +1,4 @@ + {% if context.iftype == 'vlanif' %}{{ model.hostname }}(config-if-{{ context.component.name }})#{% endif %} {% if context.iftype == 'emu' %}{{ model.hostname }}(config-if-{{ context.component.type| lower }}-{{ context.component.number }})#{% endif %} {% if context.iftype != 'vlanif' and context.iftype != 'emu' %}{{ model.hostname }}(config-if-{{ context.iftype }}-{{ context.component.name }})#{% endif %} diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/on_cycle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/on_cycle.j2 index 98fcba7..a5dd0fd 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/on_cycle.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/on_cycle.j2 @@ -1 +1,2 @@ + {{ model.hostname }}(config)# \ No newline at end of file diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/test/on_cycle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/test/on_cycle.j2 index 642a654..5538a40 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/test/on_cycle.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/test/on_cycle.j2 @@ -1 +1,2 @@ + {{ model.hostname }}(config-test)# \ No newline at end of file diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/on_cycle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/on_cycle.j2 index 013ebb1..85ce298 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/on_cycle.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/on_cycle.j2 @@ -1 +1,2 @@ + {{ model.hostname }}(diagnose)%% \ No newline at end of file diff --git a/templates/Huawei/Base/1/login/mainloop/enable/on_cycle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/on_cycle.j2 index d8fe528..1d41a30 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/on_cycle.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/on_cycle.j2 @@ -1 +1,2 @@ + {{ model.hostname }}# \ No newline at end of file diff --git a/templates/Huawei/Base/1/login/mainloop/on_cycle.j2 b/templates/Huawei/Base/1/login/mainloop/on_cycle.j2 index d9f093f..b6f8e0b 100644 --- a/templates/Huawei/Base/1/login/mainloop/on_cycle.j2 +++ b/templates/Huawei/Base/1/login/mainloop/on_cycle.j2 @@ -1 +1,2 @@ + {{ model.hostname }}> \ No newline at end of file From 4e9139d1c2caccec1e0f67379938eed563907ebf Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 9 Sep 2020 12:28:33 +0200 Subject: [PATCH 026/318] Fixed a problem with replacement of newline when getting prompt len --- nesi/softbox/cli/base.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index afb3ff3..e0070d6 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -365,7 +365,7 @@ def loop(self, context=None, return_to=None, command=None): self.on_exit(context) def get_prompt_len(self): - text = self._render('on_cycle', context=dict(), ignore_errors=True).replace('\n', '') + text = self._render('on_cycle', context=dict(), ignore_errors=True) if text is None or len(text) == 0: text = self._render('on_enter', context=dict(), ignore_errors=True) @@ -373,17 +373,17 @@ def get_prompt_len(self): if text is None: result = 0 else: - result = len(text) + result = len(text.replace('\n', '')) return result def set_prompt_end_pos(self, context): - text = self._render('on_cycle', context=context, ignore_errors=True).replace('\n', '') + text = self._render('on_cycle', context=context, ignore_errors=True) if len(text) == 0: text = self._render('on_enter', context=context, ignore_errors=True) - self.prompt_end_pos = len(text) - 1 + self.prompt_end_pos = len(text.replace('\n', '')) - 1 def on_cycle(self, context): text = self._render('on_cycle', context=context, ignore_errors=True) From 4ac82825eb896f00892770cc9e0bd082a3463e67 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 9 Sep 2020 13:38:36 +0200 Subject: [PATCH 027/318] Removed obsolete channel_current_us/ds fields from port --- nesi/huawei/api/schemas/huawei_port_schemas.py | 3 +-- nesi/huawei/huawei_resources/huawei_port.py | 2 -- nesi/softbox/api/models/port_models.py | 2 -- .../1/login/mainloop/enable/display_interface_product_port.j2 | 4 ++-- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/nesi/huawei/api/schemas/huawei_port_schemas.py b/nesi/huawei/api/schemas/huawei_port_schemas.py index 202c202..3e73125 100644 --- a/nesi/huawei/api/schemas/huawei_port_schemas.py +++ b/nesi/huawei/api/schemas/huawei_port_schemas.py @@ -23,8 +23,7 @@ class Meta: 'nte_power_status', 'current_operational_mode', 'cpes', 'description', 'total_count_of_line_training', 'result_last_initialization', 'total_bytes_us', 'total_packets_us', 'total_bytes_ds', 'total_packets_ds', - 'total_discarded_packets_ds', 'channel_current_ds', - 'channel_packets_discarded_ds', + 'total_discarded_packets_ds', 'channel_packets_discarded_ds', 'dynamic_profile', 'alarm_template_num', 'line_spectrum_profile', 'spectrum_profile_num', 'upbo_profile', 'upbo_profile_num', 'dpbo_profile', 'dpbo_profile_num', 'rfi_profile', 'rfi_profile_num', diff --git a/nesi/huawei/huawei_resources/huawei_port.py b/nesi/huawei/huawei_resources/huawei_port.py index 4b2304a..6ea0235 100644 --- a/nesi/huawei/huawei_resources/huawei_port.py +++ b/nesi/huawei/huawei_resources/huawei_port.py @@ -42,8 +42,6 @@ class HuaweiPort(Port): total_bytes_ds = base.Field('total_bytes_ds') total_packets_ds = base.Field('total_packets_ds') total_discarded_packets_ds = base.Field('total_discarded_packets_ds') - channel_current_ds = base.Field('channel_current_ds') - channel_current_us = base.Field('channel_current_us') channel_packets_discarded_ds = base.Field('channel_packets_discarded_ds') dynamic_profile = base.Field('dynamic_profile') diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index a502013..5127402 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -160,8 +160,6 @@ class Port(db.Model): total_bytes_ds = db.Column(db.Integer(), default=430667320) total_packets_ds = db.Column(db.Integer(), default=6493472) total_discarded_packets_ds = db.Column(db.Integer(), default=0) - channel_current_ds = db.Column(db.Integer(), default=30008) - channel_current_us = db.Column(db.Integer(), default=2008) channel_packets_discarded_ds = db.Column(db.Integer(), default=0) channel_ds_data_rate_profile = db.Column(db.Enum('No.1016 TEST_DSL_16000', ''), default='') diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_interface_product_port.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_interface_product_port.j2 index 8065dcc..6cd7b7b 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/display_interface_product_port.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_interface_product_port.j2 @@ -21,8 +21,8 @@ due to congestion(packet) : {{ context.port.total_discarded_packets_ds }} Channel 1 - Current rate downstream(kbps) : {{ context.port.channel_current_ds }} - Current rate upstream(kbps) : {{ context.port.channel_current_us }} + Current rate downstream(kbps) : {{ context.port.downstream }} + Current rate upstream(kbps) : {{ context.port.upstream }} Packets num discarded downstream Due to congestion(packet) : {{ context.port.channel_packets_discarded_ds }} From 56fe0a4346e5ede147c0f2d71524b325172f8ed4 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 9 Sep 2020 14:48:13 +0200 Subject: [PATCH 028/318] Corrected prompt behaviour when changing hostname on huawei device, moved set_hostname to base_resource box instead of vendor specific box --- nesi/alcatel/alcatel_resources/alcatel_box.py | 4 ---- nesi/huawei/huawei_resources/huawei_box.py | 4 ---- nesi/softbox/base_resources/box.py | 4 ++++ nesi/softbox/cli/base.py | 3 ++- .../Alcatel/Base/Alcatel_Base/configureCommandProcessor.py | 4 +--- vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py | 3 ++- 6 files changed, 9 insertions(+), 13 deletions(-) diff --git a/nesi/alcatel/alcatel_resources/alcatel_box.py b/nesi/alcatel/alcatel_resources/alcatel_box.py index 25facc8..c52d769 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_box.py +++ b/nesi/alcatel/alcatel_resources/alcatel_box.py @@ -330,10 +330,6 @@ def set_isam_location(self, isam_location): """Change isam location of a box.""" self.update(isam_location=isam_location) - def set_hostname(self, hostname): - """Change hostname of a box.""" - self.update(hostname=hostname) - def set_board_missing_reporting_logging(self, bool): """Change borad missing alarm value.""" self.update(board_missing_reporting_logging=bool) diff --git a/nesi/huawei/huawei_resources/huawei_box.py b/nesi/huawei/huawei_resources/huawei_box.py index d1d280c..9116c06 100644 --- a/nesi/huawei/huawei_resources/huawei_box.py +++ b/nesi/huawei/huawei_resources/huawei_box.py @@ -375,10 +375,6 @@ def add_port_profile(self, **fields): **fields ) - def change_hostname(self, name): - """Change the hostname of a box""" - self.update(hostname=name) - def set_network_address(self, addr): """Change the hostname of a box""" self.update(network_address=addr) diff --git a/nesi/softbox/base_resources/box.py b/nesi/softbox/base_resources/box.py index 8815617..88fbafa 100644 --- a/nesi/softbox/base_resources/box.py +++ b/nesi/softbox/base_resources/box.py @@ -71,6 +71,10 @@ class Box(base.Resource): timezone_offset = base.Field('timezone_offset') sntp_server_ip_address = base.Field('sntp_server_ip_address') + def set_hostname(self, name): + """Change the hostname value.""" + self.update(hostname=name) + def set_last_login(self, time): """Change last_login value.""" self.update(last_login=time) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index e0070d6..61723ea 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -356,12 +356,13 @@ def loop(self, context=None, return_to=None, command=None): if not exc.return_to or exc.return_to == 'sysexit' or exc.return_to == 'sysreboot' or not isinstance(self, exc.return_to): raise exc + # set prompt_len anew in case of prompt_len change in command-processor beneath + self.set_prompt_end_pos(context) # This is the first instance of the desired # CommandProcessor to unwind to, continuing self.on_cycle(context) - self.on_exit(context) def get_prompt_len(self): diff --git a/vendors/Alcatel/Base/Alcatel_Base/configureCommandProcessor.py b/vendors/Alcatel/Base/Alcatel_Base/configureCommandProcessor.py index 1c76be3..dbdd324 100644 --- a/vendors/Alcatel/Base/Alcatel_Base/configureCommandProcessor.py +++ b/vendors/Alcatel/Base/Alcatel_Base/configureCommandProcessor.py @@ -1468,9 +1468,7 @@ def do_operator(self, command, *args, context=None): if prompt.endswith('%d%c'): prompt = prompt[:-4] - box = self._model - box.set_hostname(prompt) - self._model.hostname = prompt + self._model.set_hostname(prompt) self.process(ConfigureSystemSecurityOperatorCommandProcessor, 'login', 'mainloop', 'configure', 'system', 'security', 'operator', 'user_name', args=(), return_to=ConfigureSystemSecuritySubProcessor, diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 9996dc8..ab61e6d 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -1313,7 +1313,8 @@ def do_sysname(self, command, *args, context=None): # TODO: Functionality name = '' for arg in args: name += arg - self._model.change_hostname(name) + self._model.set_hostname(name) + self.set_prompt_end_pos(context) else: raise exceptions.CommandSyntaxError(command=command) From 3b0d677bf2cac90d906caefbabfe1b765b135795 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Wed, 9 Sep 2020 14:53:17 +0200 Subject: [PATCH 029/318] Fix to make the Huawei specific 'display board str' command work in the userview-commandprocessor --- bootup/conf/bootstraps/create-huawei-5623.sh | 2 +- .../1/login/mainloop/display_board_0_bottom.j2 | 2 ++ .../1/login/mainloop/display_board_0_middle.j2 | 3 +++ .../Base/1/login/mainloop/display_board_0_top.j2 | 4 ++++ .../display_board_dsl_product_bottom_bottom.j2 | 5 +++++ .../display_board_dsl_product_bottom_middle.j2 | 2 ++ .../display_board_dsl_product_bottom_top.j2 | 6 ++++++ .../display_board_dsl_product_middle_bottom.j2 | 4 ++++ .../display_board_dsl_product_middle_middle.j2 | 2 ++ .../display_board_dsl_product_middle_top.j2 | 4 ++++ .../display_board_dsl_product_top_bottom.j2 | 5 +++++ .../display_board_dsl_product_top_middle.j2 | 2 ++ .../mainloop/display_board_dsl_product_top_top.j2 | 12 ++++++++++++ .../display_board_ftth_failed_link_bottom.j2 | 2 ++ .../display_board_ftth_failed_link_middle.j2 | 2 ++ .../display_board_ftth_failed_link_top.j2 | 4 ++++ .../display_board_ftth_normal_bottom_bottom.j2 | 4 ++++ .../display_board_ftth_normal_bottom_middle.j2 | 2 ++ .../display_board_ftth_normal_bottom_top.j2 | 5 +++++ .../mainloop/display_board_ftth_normal_header.j2 | 5 +++++ .../display_board_ftth_normal_top_bottom.j2 | 2 ++ .../display_board_ftth_normal_top_middle.j2 | 2 ++ .../mainloop/display_board_ftth_normal_top_top.j2 | 5 +++++ .../display_board_ftth_pon_bottom_bottom.j2 | 2 ++ .../display_board_ftth_pon_bottom_middle.j2 | 2 ++ .../mainloop/display_board_ftth_pon_bottom_top.j2 | 4 ++++ .../display_board_ftth_pon_middle_bottom.j2 | 2 ++ .../display_board_ftth_pon_middle_middle.j2 | 2 ++ .../mainloop/display_board_ftth_pon_middle_top.j2 | 5 +++++ .../display_board_ftth_pon_ont_summary.j2 | 2 ++ .../mainloop/display_board_ftth_pon_top_bottom.j2 | 2 ++ .../mainloop/display_board_ftth_pon_top_middle.j2 | 2 ++ .../mainloop/display_board_ftth_pon_top_top.j2 | 15 +++++++++++++++ .../display_board_ftth_special_bottom_bottom.j2 | 5 +++++ .../display_board_ftth_special_bottom_middle.j2 | 2 ++ .../display_board_ftth_special_bottom_top.j2 | 5 +++++ .../mainloop/display_board_ftth_special_header.j2 | 11 +++++++++++ .../display_board_ftth_special_middle_bottom.j2 | 2 ++ .../display_board_ftth_special_middle_middle.j2 | 2 ++ .../display_board_ftth_special_middle_top.j2 | 5 +++++ .../display_board_ftth_special_top_bottom.j2 | 2 ++ .../display_board_ftth_special_top_middle.j2 | 2 ++ .../display_board_ftth_special_top_top.j2 | 5 +++++ .../mainloop/enable/config/terminal_name_long.j2 | 2 -- .../mainloop/enable/config/terminal_pw_long.j2 | 2 -- .../Huawei_Base/huaweiBaseCommandProcessor.py | 2 +- .../Base/Huawei_Base/userViewCommandProcessor.py | 13 ++++++++++--- 47 files changed, 175 insertions(+), 9 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_0_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_0_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_0_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_header.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_ont_summary.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_header.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_middle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_top.j2 delete mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/terminal_name_long.j2 delete mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_long.j2 diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 75f3460..26c4f0e 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -803,7 +803,7 @@ req='{ "subrack_id": '$subrack_0', "description": "Physical card 0/4", "product": "ftth", - "board_name": "H807GPBH" + "board_name": "H802OPGE" }' card_0_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_0_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_0_bottom.j2 new file mode 100644 index 0000000..bfd4770 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_0_bottom.j2 @@ -0,0 +1,2 @@ + ------------------------------------------------------------------------- + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_0_middle.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_0_middle.j2 new file mode 100644 index 0000000..bdabcdc --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_0_middle.j2 @@ -0,0 +1,3 @@ + {{ context.cardname }}{{ context.spacer1 }}{{ context.card.board_name }}{{ context.spacer2 }}{{ context.card.board_status }}{{ context.spacer3 }}{{ context.card.sub_type_0 }}{{ context.spacer4 }}{{ context.card.sub_type_1 }}{{ context.spacer5 }}{% if context.card.board_status == 'Failed' %}Offline{% endif %}{% if context.card.board_status != 'Failed' %} {% endif %} + + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_0_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_0_top.j2 new file mode 100644 index 0000000..73d1484 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_0_top.j2 @@ -0,0 +1,4 @@ + ------------------------------------------------------------------------- + SlotID BoardName Status SubType0 SubType1 Online/Offline + ------------------------------------------------------------------------- + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_bottom.j2 new file mode 100644 index 0000000..19799ba --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_bottom.j2 @@ -0,0 +1,5 @@ + ------------------------------------------------------------------------------ + Note: + DDR: Downstream Data Rate UDR: Upstream Data Rate + DsRa:Downstream Rate Adaptation Ratio UsRa:Upstream Rate Adaptation Ratio + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_middle.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_middle.j2 new file mode 100644 index 0000000..d6589e7 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_middle.j2 @@ -0,0 +1,2 @@ +{{ context.spacer_beg3 }}{{ context.channelname }}{{ context.spacer12 }}{{ context.port.channel_ds_data_rate_profile_num }}{{ context.spacer13 }}{{ context.port.channel_us_data_rate_profile_num }}{{ context.spacer14 }}{{ context.port.channel_inp_data_rate_profile_num }}{{ context.spacer15 }}{{ context.port.channel_ds_rate_adapt_ratio }}{{ context.spacer16 }}{{ context.port.channel_us_rate_adapt_ratio }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_top.j2 new file mode 100644 index 0000000..3dd6528 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_top.j2 @@ -0,0 +1,6 @@ + + Channel info: + ------------------------------------------------------------------------------ + Channel DDR prof UDR prof INP prof DsRa ratio UsRa ratio + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_bottom.j2 new file mode 100644 index 0000000..992c565 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_bottom.j2 @@ -0,0 +1,4 @@ + ------------------------------------------------------------------------------ + Note: + NM: Noise Margin VN: Virtual Noise + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_middle.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_middle.j2 new file mode 100644 index 0000000..609018b --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_middle.j2 @@ -0,0 +1,2 @@ +{{ context.spacer_beg2 }}{{ context.portname }}{{ context.spacer6 }}{{ context.port.sos_profile_num }}{{ context.spacer7 }}{{ context.port.dpbo_profile_num }}{{ context.spacer8 }}{{ context.port.rfi_profile_num }}{{ context.spacer9 }}{{ context.port.noise_margin_profile_num }}{{ context.spacer10 }}{{ context.port.virtual_noise_profile_num }}{{ context.spacer11 }}{{ context.port.inm_profile_num }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_top.j2 new file mode 100644 index 0000000..09286ed --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_top.j2 @@ -0,0 +1,4 @@ + ------------------------------------------------------------------------------ + Port SOS prof DPBO prof RFI prof NM prof VN prof INM prof + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_bottom.j2 new file mode 100644 index 0000000..d8305d0 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_bottom.j2 @@ -0,0 +1,5 @@ + ------------------------------------------------------------------------------ + Total number of activated ports : {{ context.activated_count }} + Total number of unactivated ports: {{ context.port_counter }} + + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_middle.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_middle.j2 new file mode 100644 index 0000000..2e4d417 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_middle.j2 @@ -0,0 +1,2 @@ +{{ context.spacer_beg1 }}{{ context.portname }}{{ context.spacer1 }}{{ context.porttype }}{{ context.spacer2 }}{{ context.port.admin_state }}{{ context.spacer3 }}{{ context.port.alarm_template_num }}{{ context.spacer4 }}{{ context.port.spectrum_profile_num }}{{ context.spacer5 }}{{ context.port.upbo_profile_num }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_top.j2 new file mode 100644 index 0000000..679095c --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_top.j2 @@ -0,0 +1,12 @@ + --------------------------------------- + Board Name : {{ context.card.board_name }} + Board Status : {{ context.card.board_status }} + --------------------------------------- + + ------------------------------------------------------------------------------ + Line info: + ------------------------------------------------------------------------------ + Port Port Status Alarm Spec UPBO + Type Temp Prof Prof + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_bottom.j2 new file mode 100644 index 0000000..7c270bc --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_bottom.j2 @@ -0,0 +1,2 @@ + ------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_middle.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_middle.j2 new file mode 100644 index 0000000..012ceef --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_middle.j2 @@ -0,0 +1,2 @@ +{{ context.spacer_beg_f }}{{ context.portname }}{{ context.spacer_f }}{{ context.port.link }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_top.j2 new file mode 100644 index 0000000..58b8452 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_top.j2 @@ -0,0 +1,4 @@ + ------------------------------------------------------------ + Bits PortID Link Status + ------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_bottom.j2 new file mode 100644 index 0000000..608008f --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_bottom.j2 @@ -0,0 +1,4 @@ + ------------------------------------------------------------------------------ + Note: For a 1000 M, electrical port in the full-duplex mode, setting MDI to + any value is invalid + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_middle.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_middle.j2 new file mode 100644 index 0000000..d983f5c --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_middle.j2 @@ -0,0 +1,2 @@ +{{ context.spacer_beg2 }}{{ context.portname }}{{ context.spacer10 }}{{ context.port.alm_prof_15_min }}{{ context.spacer11 }}{{ context.port.warn_prof_15_min }}{{ context.spacer12 }}{{ context.port.alm_prof_24_hour }}{{ context.spacer13 }}{{ context.port.warn_prof_24_hour }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_top.j2 new file mode 100644 index 0000000..1be72b8 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_top.j2 @@ -0,0 +1,5 @@ + ------------------------------------------------------------------------------ + Port 15Min 15Min 24Hour 24Hour + AlmProf WarnProf AlmProf WarnProf + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_header.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_header.j2 new file mode 100644 index 0000000..53692be --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_header.j2 @@ -0,0 +1,5 @@ + --------------------------------------- + Board Name : {{ context.card.board_name }} + Board Status : {{ context.card.board_status }} + --------------------------------------- + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_bottom.j2 new file mode 100644 index 0000000..26647c9 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_bottom.j2 @@ -0,0 +1,2 @@ + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_middle.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_middle.j2 new file mode 100644 index 0000000..54d6e0e --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_middle.j2 @@ -0,0 +1,2 @@ +{{ context.spacer_beg1 }}{{ context.portname }}{{ context.spacer1 }}{{ context.porttype }}{{ context.spacer2 }}{{ context.port.combo_status }}{{ context.spacer3 }}{{ context.port.optic_status }}{{ context.spacer4 }}{{ context.port.mdi }}{{ context.spacer5 }}{{ context.port.speed_h }}{{ context.spacer6 }}{{ context.port.duplex }}{{ context.spacer7 }}{{ context.port.flow_ctrl }}{{ context.spacer8 }}{{ context.port.active_state }}{{ context.spacer9 }}{{ context.port.link }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_top.j2 new file mode 100644 index 0000000..8f37485 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_top.j2 @@ -0,0 +1,5 @@ + ------------------------------------------------------------------------------ + Port Port COMBO Optic MDI Speed Duplex Flow- Active Link + Type Mode Status (Mbps) Ctrl State + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_bottom.j2 new file mode 100644 index 0000000..1bb4b80 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_bottom.j2 @@ -0,0 +1,2 @@ + ----------------------------------------------------------------------------- + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_middle.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_middle.j2 new file mode 100644 index 0000000..5708e36 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_middle.j2 @@ -0,0 +1,2 @@ +{{ context.spacer_beg3 }}{{ context.subrackname }}{{ context.spacer15 }}{{ context.cardportname }}{{ context.spacer16 }}{{ context.ont_id }}{{ context.spacer17 }}{{ context.ont.description }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_top.j2 new file mode 100644 index 0000000..6cf25e2 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_top.j2 @@ -0,0 +1,4 @@ + ----------------------------------------------------------------------------- + F/S/P ONT-ID Description + ----------------------------------------------------------------------------- + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_bottom.j2 new file mode 100644 index 0000000..1bb4b80 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_bottom.j2 @@ -0,0 +1,2 @@ + ----------------------------------------------------------------------------- + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_middle.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_middle.j2 new file mode 100644 index 0000000..ca33557 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_middle.j2 @@ -0,0 +1,2 @@ +{{ context.spacer_beg2 }}{{ context.subrackname }}{{ context.spacer7 }}{{ context.cardportname }}{{ context.spacer8 }}{{ context.ont_id }}{{ context.spacer9 }}{{ context.ont.serial_number }}{{ context.spacer10 }}{{ context.ont.control_flag}}{{ context.spacer11 }}{{ context.ont.run_state }}{{ context.spacer12 }}{{ context.ont.config_state }}{{ context.spacer13 }}{{ context.ont.match_state }}{{ context.spacer14 }}{{ context.ont.protect_side }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_top.j2 new file mode 100644 index 0000000..409b7d3 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_top.j2 @@ -0,0 +1,5 @@ + ----------------------------------------------------------------------------- + F/S/P ONT SN Control Run Config Match Protect + ID flag state state state side + ----------------------------------------------------------------------------- + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_ont_summary.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_ont_summary.j2 new file mode 100644 index 0000000..2a0c6de --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_ont_summary.j2 @@ -0,0 +1,2 @@ + In port {{ context.subrackname }} {{ context.cardportname }} , the total of ONTs are: {{ context.ontcounter }}, online: {{ context.onlinecounter }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_bottom.j2 new file mode 100644 index 0000000..3b67bf6 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_bottom.j2 @@ -0,0 +1,2 @@ + ------------------------------------------------------------- + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_middle.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_middle.j2 new file mode 100644 index 0000000..63e10b1 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_middle.j2 @@ -0,0 +1,2 @@ +{{ context.spacer_beg1 }}{{ context.portname }}{{ context.spacer3 }}{{ context.porttype }}{{ context.spacer4 }}{{ context.port.min_distance }}{{ context.spacer5 }}{{ context.port.max_distance }}{{ context.spacer6 }}{{ context.port.optical_module_status }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_top.j2 new file mode 100644 index 0000000..45cc4d9 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_top.j2 @@ -0,0 +1,15 @@ + --------------------------------------- + Board Name : {{ context.card.board_name }} + Board Status : {{ context.card.board_status }} + --------------------------------------- + + ------------------------------------------------------------------------------ + Power Status Power-off cause Power-off Time + ------------------------------------------------------------------------------ + {{ context.card.power_status }}{{ context.spacer1 }}{{ context.card.power_off_cause }}{{ context.spacer2 }}{{ context.card.power_off_time }} + ------------------------------------------------------------------------------ + ------------------------------------------------------------- + Port Port min-distance max-distance Optical-module + type (km) (km) status + ------------------------------------------------------------- + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_bottom.j2 new file mode 100644 index 0000000..e031a08 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_bottom.j2 @@ -0,0 +1,5 @@ + ------------------------------------------------------------------------------ + Note: For any port, setting MDI to auto-negotiation is invalid, For a 1000 M + Electrical port in the full-duplex mode, setting MDI to any value is + invalid + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_middle.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_middle.j2 new file mode 100644 index 0000000..12c22e9 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_middle.j2 @@ -0,0 +1,2 @@ +{{ context.spacer_beg3 }}{{ context.portname }}{{ context.spacer18 }}{{ context.port.alm_prof_15_min }}{{ context.spacer19 }}{{ context.port.warn_prof_15_min }}{{ context.spacer20 }}{{ context.port.alm_prof_24_hour }}{{ context.spacer21 }}{{ context.port.warn_prof_24_hour }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_top.j2 new file mode 100644 index 0000000..1be72b8 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_top.j2 @@ -0,0 +1,5 @@ + ------------------------------------------------------------------------------ + Port 15Min 15Min 24Hour 24Hour + AlmProf WarnProf AlmProf WarnProf + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_header.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_header.j2 new file mode 100644 index 0000000..592df0d --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_header.j2 @@ -0,0 +1,11 @@ + --------------------------------------- + Board Name : {{ context.card.board_name }} + Board Status : {{ context.card.board_status }} + --------------------------------------- + + ------------------------------------------------------------------------------ + Power Status Power-off cause Power-off Time + ------------------------------------------------------------------------------ + {{ context.card.power_status }}{{ context.spacer1 }}{{ context.card.power_off_cause }}{{ context.spacer2 }}{{ context.card.power_off_time }} + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_bottom.j2 new file mode 100644 index 0000000..26647c9 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_bottom.j2 @@ -0,0 +1,2 @@ + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_middle.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_middle.j2 new file mode 100644 index 0000000..d0eba19 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_middle.j2 @@ -0,0 +1,2 @@ +{{ context.spacer_beg2 }}{{ context.portname }}{{ context.spacer12 }}{{ context.port.detecting_time }}{{ context.spacer13 }}{{ context.port.tx_state }}{{ context.spacer14 }}{{ context.port.resume_detect }}{{ context.spacer15 }}{{ context.port.detect_interval }}{{ context.spacer16 }}{{ context.port.resume_duration }}{{ context.spacer17 }}{{ context.port.auto_sensing }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_top.j2 new file mode 100644 index 0000000..6c72263 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_top.j2 @@ -0,0 +1,5 @@ + ------------------------------------------------------------------------------ + Port Detecting Time(Min) TX State Resume Detect Resume Auto-sensing + Detect Interval Duration + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_bottom.j2 new file mode 100644 index 0000000..26647c9 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_bottom.j2 @@ -0,0 +1,2 @@ + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_middle.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_middle.j2 new file mode 100644 index 0000000..af570c9 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_middle.j2 @@ -0,0 +1,2 @@ +{{ context.spacer_beg1 }}{{ context.portname }}{{ context.spacer3 }}{{ context.porttype }}{{ context.spacer4 }}{{ context.port.optic_status }}{{ context.spacer5 }}{{ context.port.native_vlan }}{{ context.spacer6 }}{{ context.port.mdi }}{{ context.spacer7 }}{{ context.port.speed_h }}{{ context.spacer8 }}{{ context.port.duplex }}{{ context.spacer9 }}{{ context.port.flow_ctrl }}{{ context.spacer10 }}{{ context.port.active_state }}{{ context.spacer11 }}{{ context.port.link }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_top.j2 new file mode 100644 index 0000000..52e5eda --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_top.j2 @@ -0,0 +1,5 @@ + ------------------------------------------------------------------------------ + Port Port Optic Native MDI Speed Duplex Flow- Active Link + Type Status VLAN (Mbps) Ctrl State + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_name_long.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_name_long.j2 deleted file mode 100644 index ee98b4b..0000000 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_name_long.j2 +++ /dev/null @@ -1,2 +0,0 @@ - Failure: The user name must be equal to or less than 15 characters - diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_long.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_long.j2 deleted file mode 100644 index ee98b4b..0000000 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_long.j2 +++ /dev/null @@ -1,2 +0,0 @@ - Failure: The user name must be equal to or less than 15 characters - diff --git a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py index 227994d..5bb84e8 100644 --- a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py @@ -107,7 +107,7 @@ def display_board(self, command, args, context=None): port=port)) context['activated_count'] = activated_count - context['port_counter'] = port_counter + context['port_counter'] = port_counter - activated_count text1 += self._render('display_board_dsl_product_top_bottom', context=context) text2 += self._render('display_board_dsl_product_middle_bottom', context=context) text3 += self._render('display_board_dsl_product_bottom_bottom', context=context) diff --git a/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py index 16dd980..6ff0b2e 100644 --- a/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py @@ -12,10 +12,10 @@ from datetime import datetime from nesi import exceptions -from .baseCommandProcessor import BaseCommandProcessor +from .huaweiBaseCommandProcessor import HuaweiBaseCommandProcessor -class UserViewCommandProcessor(BaseCommandProcessor): +class UserViewCommandProcessor(HuaweiBaseCommandProcessor): def do_enable(self, command, *args, context=None): @@ -47,7 +47,7 @@ def do_quit(self, command, *args, context=None): raise exc return - def on_help(self, command, args, context=None): + def on_help(self, command, *args, context=None): if self._validate(command, 'help'): text = self._render( 'help', @@ -56,3 +56,10 @@ def on_help(self, command, args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_display(self, command, *args, context=None): + if self._validate(args, 'board', str): + self.display_board(command, args, context) + + else: + raise exceptions.CommandSyntaxError(command=command) + From 9009721060591c00095c7526eb755ce7b05e94ed Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Wed, 9 Sep 2020 15:39:43 +0200 Subject: [PATCH 030/318] Small field adjustments --- bootup/conf/bootstraps/create-huawei-5623.sh | 3 --- nesi/softbox/api/models/vlan_models.py | 4 ++-- vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 26c4f0e..4def75d 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -141,7 +141,6 @@ req='{ "type": "smart", "attribute": "common", "bind_service_profile_id": '$service_profile', - "bind_RAIO_profile_index": "-", "priority": "-", "native_vlan" : "1" }' @@ -171,8 +170,6 @@ req='{ "description": "The standard CPE Management Vlan", "type": "smart", "attribute": "common", - "bind_service_profile_id": "-", - "bind_RAIO_profile_index": "-", "priority": "-", "native_vlan" : "1" }' diff --git a/nesi/softbox/api/models/vlan_models.py b/nesi/softbox/api/models/vlan_models.py index 1fbff33..37f7f46 100644 --- a/nesi/softbox/api/models/vlan_models.py +++ b/nesi/softbox/api/models/vlan_models.py @@ -56,8 +56,8 @@ class Vlan(db.Model): # Huawei Data type = db.Column(db.Enum('smart'), default='smart') attribute = db.Column(db.Enum('common', 'uncommon'), default='common') - bind_service_profile_id = db.Column(db.Integer()) - bind_RAIO_profile_index = db.Column(db.String()) + bind_service_profile_id = db.Column(db.Integer(), default=None) + bind_RAIO_profile_index = db.Column(db.String(), default='-') priority = db.Column(db.String()) native_vlan = db.Column(db.Integer()) vmac_ipoe = db.Column(db.Enum('enable', 'disable'), default='disable') diff --git a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py index c7db4ff..050d637 100644 --- a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py @@ -28,7 +28,7 @@ def map_states(self, object, type): elif type in ('card', 'port', 'ont_port'): object.admin_state = 'deactivated' elif type == 'service_port': - object.admin_state = 'disable' + object.admin_state = 'down' elif type in ('ont', 'ont_port', 'cpe'): object.admin_state = 'offline' elif object.admin_state == '1': @@ -37,7 +37,7 @@ def map_states(self, object, type): elif type in ('card', 'port', 'ont_port'): object.admin_state = 'activated' elif type == 'service_port': - object.admin_state = 'enable' + object.admin_state = 'up' elif type in ('ont', 'ont_port', 'cpe'): object.admin_state = 'online' elif object.admin_state == '2': From def12eb86a212e016b43b096e0ba6552e99d43c4 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 9 Sep 2020 16:46:45 +0200 Subject: [PATCH 031/318] added integration tests and fixed small issues --- bootup/conf/bootstraps/create-huawei-5623.sh | 9 +++ nesi/huawei/api/schemas/huawei_box_schemas.py | 3 +- nesi/huawei/huawei_resources/huawei_box.py | 9 +++ nesi/softbox/api/models/box_models.py | 2 + .../enable/config/terminal_pw_short.j2 | 2 +- .../integration_tests/huawei/backup.txt | 8 ++ .../huawei/backupRestart.txt | 9 +++ .../integration_tests/huawei/backupTest.txt | 10 +++ .../huawei/changeAllPorts16.txt | 19 +++++ .../integration_tests/huawei/changeDSL2.txt | 5 ++ .../integration_tests/huawei/changeDSLAM9.txt | 18 +++++ .../huawei/changeDSLProfile18.txt | 74 +++++++++++++++++++ .../integration_tests/huawei/changeIp7.txt | 25 +++++++ .../integration_tests/huawei/changeMode17.txt | 11 +++ .../integration_tests/huawei/changeONT13.txt | 11 +++ .../huawei/changeOntPorts1.txt | 11 +++ .../huawei/changePPPoE12.txt | 26 +++++++ .../integration_tests/huawei/changePort5.txt | 13 ++++ .../huawei/changeSPort20.txt | 16 ++++ .../huawei/changeTerminalUser15.txt | 16 ++++ .../integration_tests/huawei/changeTime11.txt | 10 +++ .../integration_tests/huawei/changeVlan10.txt | 10 +++ .../huawei/displayBoard7.txt | 10 +++ .../huawei/displayDSLAM3.txt | 9 +++ .../huawei/displayEquipment1.txt | 10 +++ .../huawei/displayFreeSPort6.txt | 9 +++ .../huawei/displayMacInfo4.txt | 10 +++ .../huawei/displayMonitor2.txt | 19 +++++ .../integration_tests/huawei/displayOnt5.txt | 14 ++++ .../huawei/displayState9.txt | 28 +++++++ .../integration_tests/huawei/unchangeDSL4.txt | 19 +++++ .../huawei/unchangeONT14.txt | 11 +++ .../huawei/unchangePort6.txt | 17 +++++ test_cases/unit_tests/huawei/test_huawei.py | 23 +++--- test_cases/unit_tests/test_core.py | 23 ++++-- .../Base/Huawei_Base/baseCommandProcessor.py | 2 +- .../Huawei_Base/configCommandProcessor.py | 34 +++++---- 37 files changed, 518 insertions(+), 37 deletions(-) create mode 100644 test_cases/integration_tests/huawei/backup.txt create mode 100644 test_cases/integration_tests/huawei/backupRestart.txt create mode 100644 test_cases/integration_tests/huawei/backupTest.txt create mode 100644 test_cases/integration_tests/huawei/changeAllPorts16.txt create mode 100644 test_cases/integration_tests/huawei/changeDSL2.txt create mode 100644 test_cases/integration_tests/huawei/changeDSLAM9.txt create mode 100644 test_cases/integration_tests/huawei/changeDSLProfile18.txt create mode 100644 test_cases/integration_tests/huawei/changeIp7.txt create mode 100644 test_cases/integration_tests/huawei/changeMode17.txt create mode 100644 test_cases/integration_tests/huawei/changeONT13.txt create mode 100644 test_cases/integration_tests/huawei/changeOntPorts1.txt create mode 100644 test_cases/integration_tests/huawei/changePPPoE12.txt create mode 100644 test_cases/integration_tests/huawei/changePort5.txt create mode 100644 test_cases/integration_tests/huawei/changeSPort20.txt create mode 100644 test_cases/integration_tests/huawei/changeTerminalUser15.txt create mode 100644 test_cases/integration_tests/huawei/changeTime11.txt create mode 100644 test_cases/integration_tests/huawei/changeVlan10.txt create mode 100644 test_cases/integration_tests/huawei/displayBoard7.txt create mode 100644 test_cases/integration_tests/huawei/displayDSLAM3.txt create mode 100644 test_cases/integration_tests/huawei/displayFreeSPort6.txt create mode 100644 test_cases/integration_tests/huawei/displayMacInfo4.txt create mode 100644 test_cases/integration_tests/huawei/displayMonitor2.txt create mode 100644 test_cases/integration_tests/huawei/displayOnt5.txt create mode 100644 test_cases/integration_tests/huawei/displayState9.txt create mode 100644 test_cases/integration_tests/huawei/unchangeDSL4.txt create mode 100644 test_cases/integration_tests/huawei/unchangeONT14.txt create mode 100644 test_cases/integration_tests/huawei/unchangePort6.txt diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 4def75d..456bac0 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -185,6 +185,15 @@ req='{ }' emu_fan=$(create_resource "$req" $ENDPOINT/boxen/$box_id/emus) +### Emu 2 ### + +# Create a physical emu at the network device (admin operation) +req='{ + "type": "H831PMU", + "number": 2 +}' +emu2_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/emus) + ### Subrack 0 ### # Create a physical subrack at the network device (admin operation) diff --git a/nesi/huawei/api/schemas/huawei_box_schemas.py b/nesi/huawei/api/schemas/huawei_box_schemas.py index dbb3d48..d5c6b67 100644 --- a/nesi/huawei/api/schemas/huawei_box_schemas.py +++ b/nesi/huawei/api/schemas/huawei_box_schemas.py @@ -16,7 +16,8 @@ class HuaweiBoxSchema(BoxSchema): class Meta: model = Box - fields = BoxSchema.Meta.fields + ('cpu_occupancy', 'vlan_interfaces', 'raio_anid') + fields = BoxSchema.Meta.fields + ('cpu_occupancy', 'vlan_interfaces', 'raio_anid', 'handshake_mode', + 'handshake_interval') vlan_interfaces = ma.Hyperlinks( {'_links': { diff --git a/nesi/huawei/huawei_resources/huawei_box.py b/nesi/huawei/huawei_resources/huawei_box.py index 9116c06..f1fea48 100644 --- a/nesi/huawei/huawei_resources/huawei_box.py +++ b/nesi/huawei/huawei_resources/huawei_box.py @@ -27,6 +27,8 @@ class HuaweiBox(Box): """ cpu_occupancy = base.Field('cpu_occupancy') raio_anid = base.Field('raio_anid') + handshake_mode = base.Field('handshake_mode') + handshake_interval = base.Field('handshake_interval') @property def credentials(self): @@ -383,6 +385,13 @@ def set_raio_anid(self, addr): """Change the raio anid of a box""" self.update(raio_anid=addr) + def set_handshake_mode(self, mode): + """Change the handshake mode of a box""" + self.update(handshake_mode=mode) + + def set_handshake_interval(self, interval): + """Change the handshake interval of a box""" + self.update(handshake_interval=interval) class HuaweiBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 2ed16e5..3438039 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -101,3 +101,5 @@ class Box(db.Model): cpu_occupancy = db.Column(db.String(), default='20%') raio_anid = db.Column(db.String(), default='127.0.0.1') + handshake_mode = db.Column(db.Enum('enable', 'disable'), default='disable') + handshake_interval = db.Column(db.Integer(), default=None) diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_short.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_short.j2 index 470dcef..57fc638 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_short.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_short.j2 @@ -1,2 +1,2 @@ - Failure: The user name must be equal to or more than 6 characters + Failure: The user password must be equal to or more than 6 characters diff --git a/test_cases/integration_tests/huawei/backup.txt b/test_cases/integration_tests/huawei/backup.txt new file mode 100644 index 0000000..e0b90c9 --- /dev/null +++ b/test_cases/integration_tests/huawei/backup.txt @@ -0,0 +1,8 @@ +root +secret +enable +config +backup configuration tftp 1.1.1.1 /test/huawei/testfile +quit +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/backupRestart.txt b/test_cases/integration_tests/huawei/backupRestart.txt new file mode 100644 index 0000000..4dfb8cc --- /dev/null +++ b/test_cases/integration_tests/huawei/backupRestart.txt @@ -0,0 +1,9 @@ +root +secret +enable +reboot system +root +secret +enable +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/backupTest.txt b/test_cases/integration_tests/huawei/backupTest.txt new file mode 100644 index 0000000..2cb9524 --- /dev/null +++ b/test_cases/integration_tests/huawei/backupTest.txt @@ -0,0 +1,10 @@ +root +secret +enable +config +test +xdsl melt 0/0/0 measured-frequency 25Hz busy force + +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changeAllPorts16.txt b/test_cases/integration_tests/huawei/changeAllPorts16.txt new file mode 100644 index 0000000..12ae3fc --- /dev/null +++ b/test_cases/integration_tests/huawei/changeAllPorts16.txt @@ -0,0 +1,19 @@ +root +secret +enable +config +interface vdsl 0/0 +deactivate all +shutdown all +quit +interface eth 0/2 +deactivate all +shutdown all +quit +interface gpon 0/3 +deactivate all +shutdown all +quit +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changeDSL2.txt b/test_cases/integration_tests/huawei/changeDSL2.txt new file mode 100644 index 0000000..48ff39a --- /dev/null +++ b/test_cases/integration_tests/huawei/changeDSL2.txt @@ -0,0 +1,5 @@ +root +secret +enable +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changeDSLAM9.txt b/test_cases/integration_tests/huawei/changeDSLAM9.txt new file mode 100644 index 0000000..51d4ed0 --- /dev/null +++ b/test_cases/integration_tests/huawei/changeDSLAM9.txt @@ -0,0 +1,18 @@ +root +secret +enable +config +undo smart +undo system snmp-user password security +sysname test +snmp-agent community read blablablub +snmp-agent community write blubblabla +snmp-agent target-host trap-hostname test_U2000 address 1.1.1.1 udp-port 1 trap-paramsname test_U2000 +snmp-agent target-host trap-paramsname test_U2000 v1 securityname secret +snmp-agent trap enable standard +system handshake interval 400 +system handshake enable +save +quit +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changeDSLProfile18.txt b/test_cases/integration_tests/huawei/changeDSLProfile18.txt new file mode 100644 index 0000000..4d38689 --- /dev/null +++ b/test_cases/integration_tests/huawei/changeDSLProfile18.txt @@ -0,0 +1,74 @@ +root +secret +enable +config +xdsl data-rate-profile quickadd 1003 maximum-bit-error-ratio 2 path-mode 3 rate 32 32 3456 32 0 0 g.998.4-rtx etr-min 32 etr-max 200000 ndr-max 200000 desc TEST_DSL_3000 +xdsl data-rate-profile quickadd 1006 maximum-bit-error-ratio 2 path-mode 3 rate 32 32 6656 32 0 0 g.998.4-rtx etr-min 32 etr-max 200000 ndr-max 200000 desc TEST_DSL_6000 +xdsl data-rate-profile quickadd 1016 maximum-bit-error-ratio 2 path-mode 3 rate 32 32 17280 32 0 0 g.998.4-rtx etr-min 32 etr-max 200000 ndr-max 200000 desc TEST_DSL_16000 +xdsl data-rate-profile quickadd 1025 maximum-bit-error-ratio 2 path-mode 3 rate 32 32 26368 32 0 0 g.998.4-rtx etr-min 32 etr-max 200000 ndr-max 200000 desc TEST_DSL_25000 +xdsl data-rate-profile quickadd 1050 maximum-bit-error-ratio 2 path-mode 3 rate 32 32 52544 32 0 0 g.998.4-rtx etr-min 32 etr-max 200000 ndr-max 200000 desc TEST_DSL_50000 +xdsl data-rate-profile quickadd 1100 maximum-bit-error-ratio 2 path-mode 3 rate 32 32 115200 32 0 0 g.998.4-rtx etr-min 32 etr-max 200000 ndr-max 200000 desc TEST_DSL_100000 +xdsl data-rate-profile quickadd 2001 maximum-bit-error-ratio 2 path-mode 3 rate 32 32 1152 32 0 0 g.998.4-rtx etr-min 32 etr-max 200000 ndr-max 200000 desc UP_1000 +xdsl data-rate-profile quickadd 2002 maximum-bit-error-ratio 2 path-mode 3 rate 32 32 2304 32 0 0 g.998.4-rtx etr-min 32 etr-max 200000 ndr-max 200000 desc UP_2000 +xdsl data-rate-profile quickadd 2005 maximum-bit-error-ratio 2 path-mode 3 rate 32 32 5248 32 0 0 g.998.4-rtx etr-min 32 etr-max 200000 ndr-max 200000 desc UP_5000 +xdsl data-rate-profile quickadd 2010 maximum-bit-error-ratio 2 path-mode 3 rate 32 32 11520 32 0 0 g.998.4-rtx etr-min 32 etr-max 200000 ndr-max 200000 desc UP_10000 +xdsl data-rate-profile quickadd 2256 maximum-bit-error-ratio 2 path-mode 3 rate 32 32 256 32 0 0 g.998.4-rtx etr-min 32 etr-max 200000 ndr-max 200000 desc UP_256 +xdsl data-rate-profile quickadd 2512 maximum-bit-error-ratio 2 path-mode 3 rate 32 32 512 32 0 0 g.998.4-rtx etr-min 32 etr-max 200000 ndr-max 200000 desc UP_512 +xdsl data-rate-profile quickadd 3010 maximum-bit-error-ratio 2 path-mode 3 rate 32 32 11520 32 0 0 g.998.4-rtx etr-min 32 etr-max 200000 ndr-max 200000 desc TEST_DSL_10000 +xdsl data-rate-profile quickadd 2015 desc UP_15000 +xdsl data-rate-profile quickmodify 2015 path-mode 3 rate 32 32 15750 32 0 0 maximum-bit-error-ratio 2 +xdsl data-rate-profile quickadd 2020 desc UP_20000 +xdsl data-rate-profile quickmodify 2020 path-mode 3 rate 32 32 23040 32 0 0 maximum-bit-error-ratio 2 +xdsl data-rate-profile quickadd 1060 desc TEST_DSL_60000 +xdsl data-rate-profile quickmodify 1060 path-mode 3 rate 32 32 63000 32 0 0 maximum-bit-error-ratio 2 +xdsl data-rate-profile quickadd 1030 desc TEST_DSL_30000 +xdsl data-rate-profile quickmodify 1030 path-mode 3 rate 32 32 31500 32 0 0 maximum-bit-error-ratio 2 +xdsl dpbo-profile quickadd 1020 working-mode 7 eside-electrical-length 40 40 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 1 desc DPBO_20 +xdsl dpbo-profile quickadd 1030 working-mode 7 eside-electrical-length 60 60 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_30 +xdsl dpbo-profile quickadd 1040 working-mode 7 eside-electrical-length 80 80 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_40 +xdsl dpbo-profile quickadd 1050 working-mode 7 eside-electrical-length 100 100 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_50 +xdsl dpbo-profile quickadd 1060 working-mode 7 eside-electrical-length 120 120 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_60 +xdsl dpbo-profile quickadd 1070 working-mode 7 eside-electrical-length 140 140 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_70 +xdsl dpbo-profile quickadd 1075 working-mode 7 eside-electrical-length 150 150 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_75 +xdsl dpbo-profile quickadd 1080 working-mode 7 eside-electrical-length 160 160 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_80 +xdsl dpbo-profile quickadd 1085 working-mode 7 eside-electrical-length 170 170 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_85 +xdsl dpbo-profile quickadd 1090 working-mode 7 eside-electrical-length 180 180 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_90 +xdsl dpbo-profile quickadd 1095 working-mode 7 eside-electrical-length 190 190 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_95 +xdsl dpbo-profile quickadd 1100 working-mode 7 eside-electrical-length 200 200 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_100 +xdsl dpbo-profile quickadd 1105 working-mode 7 eside-electrical-length 210 210 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_105 +xdsl dpbo-profile quickadd 1110 working-mode 7 eside-electrical-length 220 220 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_110 +xdsl dpbo-profile quickadd 1115 working-mode 7 eside-electrical-length 230 230 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_115 +xdsl dpbo-profile quickadd 1120 working-mode 7 eside-electrical-length 240 240 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_120 +xdsl dpbo-profile quickadd 1122 working-mode 7 eside-electrical-length 244 244 assumed-exchange-psd enable 63:73,256:73,314:84,376:93,511:96 eside-cable-model 270 490 264 min-usable-signal 224 span-frequency 64 511 dpbo-calculation 2 desc DPBO_122 +xdsl noise-margin-profile quickadd 1000 snr-margin 60 40 310 60 40 310 rate-adapt 2 2 snr-mode disable disable desc ADSL_6dB +xdsl noise-margin-profile quickadd 2001 snr-margin 60 40 310 60 40 310 rate-adapt 2 2 snr-mode disable disable desc VDSL_6dB +xdsl noise-margin-profile quickadd 1090 snr-margin 60 40 310 90 40 310 rate-adapt 2 2 snr-mode disable disable desc ADSL_9dB +xdsl noise-margin-profile quickadd 2091 snr-margin 60 40 310 90 40 310 rate-adapt 2 2 snr-mode disable disable desc VDSL_9dB +xdsl inp-delay-profile quickadd 1000 inp-4.3125khz 4 4 inp-8.625khz 3 3 interleaved-delay 8 8 delay-variation 255 channel-policy 0 desc ADSL +xdsl inp-delay-profile quickadd 1001 inp-4.3125khz 4 4 inp-8.625khz 3 3 interleaved-delay 8 8 delay-variation 255 channel-policy 0 desc VDSL +xdsl inp-delay-profile quickadd 2000 inp-4.3125khz 1 1 inp-8.625khz 1 1 interleaved-delay 0 0 delay-variation 255 channel-policy 0 desc ADSL_FAST +xdsl inp-delay-profile quickadd 2001 inp-4.3125khz 1 1 inp-8.625khz 1 1 interleaved-delay 0 0 delay-variation 255 channel-policy 0 desc VDSL_FAST +xdsl mode-specific-psd-profile quickadd 1000 nominal-transmit-PSD-ds 400 nominal-transmit-PSD-us 380 aggregate-transmit-power-ds 198 aggregate-transmit-power-us 133 aggregate-receive-power-us 255 +xdsl mode-specific-psd-profile quickmodify 1000 upstream-psd-mask-selection 8 description ADSL2plus +xdsl mode-specific-psd-profile quickmodify 1000 psd-class-mask 6 psd-limit-mask 34 +xdsl mode-specific-psd-profile quickadd 1001 nominal-transmit-PSD-ds 400 nominal-transmit-PSD-us 380 aggregate-transmit-power-ds 145 aggregate-transmit-power-us 145 aggregate-receive-power-us 255 +xdsl mode-specific-psd-profile quickmodify 1001 upstream-psd-mask-selection 9 description VDSL +xdsl mode-specific-psd-profile quickmodify 1001 psd-class-mask 6 psd-limit-mask 34 +xdsl line-spectrum-profile quickadd 1000 l0-time 255 l2-time 30 l3-time 255 max-transmite-power-reduction 3 total-max-power-reduction 31 bit-swap-ds 1 bit-swap-us 1 overhead-datarate-us 4000 overhead-datarate-ds 4000 +xdsl line-spectrum-profile quickmodify 1000 allow-transitions-to-idle 2 allow-transitions-to-lowpower 2 reference-clock freeRun cyclic-extension-flag 1 force-inp-ds 1 force-inp-us 1 desc ADSL2plus +xdsl line-spectrum-profile quickmodify 1000 g.993.2-profile 7 mode-specific enable 1 1000 +xdsl line-spectrum-profile quickmodify 1000 transmode custom T1.413 disable G.992.1 disable G.992.2 disable G.992.3 disable G.992.4 disable G.992.5 enable AnnexB G.993.2 disable ETSI disable +xdsl line-spectrum-profile quickadd 1001 l0-time 255 l2-time 30 l3-time 255 max-transmite-power-reduction 3 total-max-power-reduction 31 bit-swap-ds 1 bit-swap-us 1 overhead-datarate-us 4000 overhead-datarate-ds 4000 +xdsl line-spectrum-profile quickmodify 1001 allow-transitions-to-idle 2 allow-transitions-to-lowpower 2 reference-clock freeRun cyclic-extension-flag 1 force-inp-ds 1 force-inp-us 1 desc VDSL +xdsl line-spectrum-profile quickmodify 1001 g.993.2-profile 7 mode-specific enable 1 1001 +xdsl line-spectrum-profile quickmodify 1001 g.993.2-profile 7 us0-psd-mask 19 +xdsl line-spectrum-profile quickmodify 1001 transmode 6 +xdsl line-spectrum-profile quickadd 1002 l0-time 255 l2-time 30 l3-time 255 max-transmite-power-reduction 3 total-max-power-reduction 31 bit-swap-ds 1 bit-swap-us 1 overhead-datarate-us 4000 overhead-datarate-ds 4000 +xdsl line-spectrum-profile quickmodify 1002 allow-transitions-to-idle 2 allow-transitions-to-lowpower 2 reference-clock freeRun cyclic-extension-flag 1 force-inp-ds 1 force-inp-us 1 desc VDSL_NO_ADSL +xdsl line-spectrum-profile quickmodify 1002 g.993.2-profile 7 mode-specific enable 1 1001 +xdsl line-spectrum-profile quickmodify 1002 g.993.2-profile 7 us0-psd-mask 19 +xdsl line-spectrum-profile quickmodify 1002 transmode 6 +xdsl line-spectrum-profile quickmodify 1002 vdsltoneblackout enable 0-511 +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changeIp7.txt b/test_cases/integration_tests/huawei/changeIp7.txt new file mode 100644 index 0000000..47180cf --- /dev/null +++ b/test_cases/integration_tests/huawei/changeIp7.txt @@ -0,0 +1,25 @@ +root +secret +enable +config +undo smart +undo interactive +load script tftp 1.1.1.1 testfile +vlan 11 smart +port vlan 11 0/0 0 +interface vlanif 11 +ip address 1.1.1.1 255.255.255.0 +quit +undo ip route-static all +Y +ip route-static 0.0.0.0 0 1.1.1.1 +interface vlanif 2620 +undo ip address 1.1.1.1 24 +quit +undo interface vlanif 2620 +undo port vlan 2620 0/0 0 +undo vlan 2620 +raio-anid 1.1.1.1 +quit +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changeMode17.txt b/test_cases/integration_tests/huawei/changeMode17.txt new file mode 100644 index 0000000..ec20156 --- /dev/null +++ b/test_cases/integration_tests/huawei/changeMode17.txt @@ -0,0 +1,11 @@ +root +secret +enable +config +diagnose +switch vdsl mode to timode +y +y +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changeONT13.txt b/test_cases/integration_tests/huawei/changeONT13.txt new file mode 100644 index 0000000..f0ff075 --- /dev/null +++ b/test_cases/integration_tests/huawei/changeONT13.txt @@ -0,0 +1,11 @@ +root +secret +enable +config +interface gpon 0/3 +ont add 0 2 sn-auth 1 omci ont-lineprofile-id 0 ont-srvprofile-id 0 desc "This is a new ont" +quit +save +quit +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changeOntPorts1.txt b/test_cases/integration_tests/huawei/changeOntPorts1.txt new file mode 100644 index 0000000..255b9fc --- /dev/null +++ b/test_cases/integration_tests/huawei/changeOntPorts1.txt @@ -0,0 +1,11 @@ +root +secret +enable +config +interface gpon 0/3 +ont port attribute 0 0 eth 1 operational-state on +quit +save +quit +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changePPPoE12.txt b/test_cases/integration_tests/huawei/changePPPoE12.txt new file mode 100644 index 0000000..bc62e31 --- /dev/null +++ b/test_cases/integration_tests/huawei/changePPPoE12.txt @@ -0,0 +1,26 @@ +root +secret +enable +config +raio-anid 1.1.1.1 +raio-format pitp-pmode cid eth "anid eth slot/port+1" +raio-format pitp-pmode cid atm "anid atm slot/port+1:vpi:vci" +raio-format pitp-pmode rid plabel +raio sub-option 0x81 pitp-pmode enable +raio sub-option 0x82 pitp-pmode enable +pitp enable pmode +vlan service-profile profile-name "PPPoE" profile-id 10 +forwarding vlan-mac +packet-policy multicast forward +packet-policy unicast discard +security anti-macspoofing disable +security anti-ipspoofing disable +pitp enable +vmac disable +igmp mismatch transparent +commit +quit +raio-mode user-defined pitp-pmode +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changePort5.txt b/test_cases/integration_tests/huawei/changePort5.txt new file mode 100644 index 0000000..374b218 --- /dev/null +++ b/test_cases/integration_tests/huawei/changePort5.txt @@ -0,0 +1,13 @@ +root +secret +enable +config +interface vdsl 0/0 +activate 0 +return +config +interface opg 0/4 +undo shutdown 0 +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changeSPort20.txt b/test_cases/integration_tests/huawei/changeSPort20.txt new file mode 100644 index 0000000..adc498b --- /dev/null +++ b/test_cases/integration_tests/huawei/changeSPort20.txt @@ -0,0 +1,16 @@ +root +secret +enable +config +display service-port 0/0/0 +undo service-port 0/0/0 +service-port 1 vlan 2620 adsl 0/1/0 vpi 1 vci 32 multi-service user-encap pppoe inbound traffic-table index 10 outbound traffic-table index 10 +service-port 2 vlan 2620 vdsl mode atm 0/0/0 vpi 1 vci 32 multi-service user-encap pppoe inbound traffic-table index 10 outbound traffic-table index 10 +service-port 3 vlan 2620 vdsl mode ptm 0/0/1 multi-service user-encap pppoe inbound traffic-table index 10 outbound traffic-table index 1 +service-port 4 vlan 2620 eth 0/2/0 multi-service user-vlan 2620 user-encap pppoe inbound traffic-table index intable outbound traffic-table index outtable +service-port 5 vlan 2620 vdsl mode ptm 0/0/2 multi-service user-vlan untagged +service-port 6 vlan 2620 vdsl mode atm 0/1/1 vpi 1 vci 32 multi-service user-vlan untagged +service-port 7 vlan 2620 eth 0/2/1 multi-service user-vlan 2620 user-encap pppoe inbound traffic-table index intable outbound traffic-table index outtable +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changeTerminalUser15.txt b/test_cases/integration_tests/huawei/changeTerminalUser15.txt new file mode 100644 index 0000000..154c578 --- /dev/null +++ b/test_cases/integration_tests/huawei/changeTerminalUser15.txt @@ -0,0 +1,16 @@ +root +secret +enable +config +terminal user name +testuser +123456 +123456 +root +3 +4 +\r\n +n +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changeTime11.txt b/test_cases/integration_tests/huawei/changeTime11.txt new file mode 100644 index 0000000..0dd9916 --- /dev/null +++ b/test_cases/integration_tests/huawei/changeTime11.txt @@ -0,0 +1,10 @@ +root +secret +enable +config +ntp-service unicast-server 1.1.1.1 +timezone GMT+ 02:00 +time dst start 3 last Sun 03:00:00 end 10 last Sun 04:00:00 adjust 01:00 +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changeVlan10.txt b/test_cases/integration_tests/huawei/changeVlan10.txt new file mode 100644 index 0000000..e082f05 --- /dev/null +++ b/test_cases/integration_tests/huawei/changeVlan10.txt @@ -0,0 +1,10 @@ +root +secret +enable +config +vlan 11 smart +port vlan 11 0/0 0 +vlan bind service-profile 11 profile-id 1 +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/displayBoard7.txt b/test_cases/integration_tests/huawei/displayBoard7.txt new file mode 100644 index 0000000..d9dc698 --- /dev/null +++ b/test_cases/integration_tests/huawei/displayBoard7.txt @@ -0,0 +1,10 @@ +root +secret +display board 0/0 +enable +display board 0/0 +config +display board 0/0 +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/displayDSLAM3.txt b/test_cases/integration_tests/huawei/displayDSLAM3.txt new file mode 100644 index 0000000..5d367c0 --- /dev/null +++ b/test_cases/integration_tests/huawei/displayDSLAM3.txt @@ -0,0 +1,9 @@ +root +secret +enable +config +display version + +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/displayEquipment1.txt b/test_cases/integration_tests/huawei/displayEquipment1.txt index 48ff39a..a7486b4 100644 --- a/test_cases/integration_tests/huawei/displayEquipment1.txt +++ b/test_cases/integration_tests/huawei/displayEquipment1.txt @@ -1,5 +1,15 @@ root secret enable +config +display board 0 +display board 0/0 +display vlan all + +display interface vlanif 2620 +display current-configuration section vlan-srvprof + +display vdsl line-profile 1 +return quit y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/displayFreeSPort6.txt b/test_cases/integration_tests/huawei/displayFreeSPort6.txt new file mode 100644 index 0000000..5a71df5 --- /dev/null +++ b/test_cases/integration_tests/huawei/displayFreeSPort6.txt @@ -0,0 +1,9 @@ +root +secret +enable +config +display service-port all + +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/displayMacInfo4.txt b/test_cases/integration_tests/huawei/displayMacInfo4.txt new file mode 100644 index 0000000..d323800 --- /dev/null +++ b/test_cases/integration_tests/huawei/displayMacInfo4.txt @@ -0,0 +1,10 @@ +root +secret +enable +config +display max-address all +display ont autofind all +display ont info summary 0 +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/displayMonitor2.txt b/test_cases/integration_tests/huawei/displayMonitor2.txt new file mode 100644 index 0000000..f64407c --- /dev/null +++ b/test_cases/integration_tests/huawei/displayMonitor2.txt @@ -0,0 +1,19 @@ +root +secret +enable +diagnose +system status collect all +display system status collection +quit +display temperature 0/0 +display temperature 0/1 +config +display version + +display alarm active alarmtype environment detail +display pitp config +interface emu 2 +display power run info +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/displayOnt5.txt b/test_cases/integration_tests/huawei/displayOnt5.txt new file mode 100644 index 0000000..0b8a6fb --- /dev/null +++ b/test_cases/integration_tests/huawei/displayOnt5.txt @@ -0,0 +1,14 @@ +root +secret +enable +config +display service-port 0/0/0 +interface gpon 0/3 +display port state 0 +display ont port state 0 0 eth-port 1 +display ont info 0 0 +display ont optical-info 0 0 +display traffic table ip index testtest +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/displayState9.txt b/test_cases/integration_tests/huawei/displayState9.txt new file mode 100644 index 0000000..5f7cb0c --- /dev/null +++ b/test_cases/integration_tests/huawei/displayState9.txt @@ -0,0 +1,28 @@ +root +secret +enable +display interface vdsl 0/0/0 +display vdsl port state 0/0/0 +display vdsl line operation port 0/0/0 +config +interface vdsl 0/0 +display inventory cpe 0 +return +display interface adsl 0/1/0 +display adsl port state 0/1/0 +display adsl line operation port 0/1/0 +config +interface adsl 0/1 +display inventory cpe 0 +return +config +interface gpon 0/3 +display port state 0 +return +config +interface eth 0/2 +display port ddm-info 0 + +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/unchangeDSL4.txt b/test_cases/integration_tests/huawei/unchangeDSL4.txt new file mode 100644 index 0000000..510b0dd --- /dev/null +++ b/test_cases/integration_tests/huawei/unchangeDSL4.txt @@ -0,0 +1,19 @@ +root +secret +enable +config +interface vdsl 0/0 +deactivate 1 +quit +interface adsl 0/1 +deactivate 2 +quit +interface opg 0/4 +shutdown 1 +quit +interface eth 0/2 +shutdown 1 +quit +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/unchangeONT14.txt b/test_cases/integration_tests/huawei/unchangeONT14.txt new file mode 100644 index 0000000..8af312c --- /dev/null +++ b/test_cases/integration_tests/huawei/unchangeONT14.txt @@ -0,0 +1,11 @@ +root +secret +enable +config +interface gpon 0/3 +ont delete 0 0 +quit +save +return +quit +y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/unchangePort6.txt b/test_cases/integration_tests/huawei/unchangePort6.txt new file mode 100644 index 0000000..28a3fe9 --- /dev/null +++ b/test_cases/integration_tests/huawei/unchangePort6.txt @@ -0,0 +1,17 @@ +root +secret +enable +config +interface vdsl 0/0 +deactivate 1 +return +config +interface opg 0/4 +shutdown 0 +return +config +interface eth 0/2 +shutdown 0 +return +quit +y \ No newline at end of file diff --git a/test_cases/unit_tests/huawei/test_huawei.py b/test_cases/unit_tests/huawei/test_huawei.py index 3911446..7cf2dfb 100644 --- a/test_cases/unit_tests/huawei/test_huawei.py +++ b/test_cases/unit_tests/huawei/test_huawei.py @@ -90,6 +90,7 @@ def test_port_profiles(self): assert False except exceptions.SoftboxenError: assert True + port.set('type', 'service') def test_service_port(self): port = self.model.get_service_port("name", "0/0/0") @@ -131,6 +132,8 @@ def test_service_port(self): assert port.connected_id is not None assert port.connected_type is not None + id = port.connected_id + type =port.connected_type port.set_connected_id(20) assert port.connected_id == 20 port.set_connected_type('ont') @@ -145,12 +148,14 @@ def test_service_port(self): assert False except exceptions.SoftboxenError: assert True + port.set_connected_id(id) + port.set_connected_type(type) port.set_admin_state('0') assert port.admin_state == '0' port.set_admin_state('1') assert port.admin_state == '1' try: - port.set_connected_id(0) + port.set_admin_state(0) assert False except exceptions.SoftboxenError: assert True @@ -238,6 +243,7 @@ def test_vlan(self): assert False except exceptions.SoftboxenError: assert True + vlan.set_service_profile_id(1) def test_vlaninterface(self): port = self.model.get_vlan_interface("name", "vlanif2620") @@ -253,23 +259,20 @@ def test_vlaninterface(self): def test_box_properties(self): assert len(self.model.subracks) == 1 assert len(self.model.cards) == 5 - assert len(self.model.get_cards()) == len(self.model.cards) - assert len(self.model.ports) == len(self.model.get_ports()) - assert len(self.model.onts) == len(self.model.get_onts()) - assert len(self.model.ont_ports) == len(self.model.get_ont_ports()) - assert len(self.model.cpes) == len(self.model.get_cpes()) - assert len(self.model.cpe_ports) == len(self.model.get_cpe_ports()) + assert len(self.model.ports) == 13 + assert len(self.model.onts) == 8 + assert len(self.model.ont_ports) == 9 + assert len(self.model.cpes) == 11 + assert len(self.model.cpe_ports) == 11 assert len(self.model.vlans) == 2 assert len(self.model.service_vlans) == 1 assert len(self.model.service_ports) == 1 assert len(self.model.credentials) == 1 assert len(self.model.routes) == 0 assert len(self.model.port_profiles) == 1 - assert len(self.model.qos_interfaces) == 0 - assert len(self.model.emus) == 1 + assert len(self.model.emus) == 2 assert len(self.model.users) == 1 assert len(self.model.vlan_interfaces) == 1 - assert self.model.get_user("name", 'root') == self.model.get_users("name", 'root').find_by_field_value("name", 'root') @pytest.mark.parametrize("path", DATA) def test_integration(self, path): diff --git a/test_cases/unit_tests/test_core.py b/test_cases/unit_tests/test_core.py index c5fb7c2..7040105 100644 --- a/test_cases/unit_tests/test_core.py +++ b/test_cases/unit_tests/test_core.py @@ -67,14 +67,21 @@ def run(self, inpath, outpath): fd1 = os.open(inpath, os.O_RDONLY) stdin1 = os.fdopen(fd1, 'rb', 0) - command_processor = self.cli(self.model, stdin1, stdout1, (), template_root='templates/', daemon=True) - try: - context = dict() - context['login_banner'] = self.model.login_banner - command_processor.loop(context=context) - except exceptions.TerminalExitError as exc: - if exc.return_to is not None and exc.return_to != 'sysexit': - pass + while True: + command_processor = self.cli(self.model, stdin1, stdout1, (), template_root='templates/', daemon=True) + try: + context = dict() + context['login_banner'] = self.model.login_banner + command_processor.history_enabled = False + command_processor.loop(context=context) + except exceptions.TerminalExitError as exc: + if exc.return_to is not None and exc.return_to == 'sysexit': + break + elif exc.return_to is not None and exc.return_to == 'sysreboot': + continue + else: + pass + stdin1.close() stdout1.close() del stdin1 diff --git a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py index 050d637..4a3fc33 100644 --- a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py @@ -59,7 +59,7 @@ def map_states(self, object, type): elif type == 'port': object.operational_state = 'activated' elif type == 'service_port': - object.operational_state = 'up' + object.operational_state = 'disable' elif type in ('ont', 'ont_port'): object.operational_state = 'online' elif object.operational_state == '2': diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index ab61e6d..0d469e7 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -207,7 +207,6 @@ def generate_ont_info_summary(port): name = 'vlanif' + vlan_number try: vlanif = self._model.get_vlan_interface("name", name) - self.map_states(vlanif, 'vlan_interface') except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -600,9 +599,9 @@ def do_timezone(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_time(self, command, *args, context=None): - if self._validate(args, 'dst', 'start', '3', 'last', 'Sun', '02:00:00', 'end', '10', 'last', 'Sun', '03:00:00', - 'adjust', '01:00'): - # we dont have some internal time to set + if self._validate(args, 'dst', 'start', str, 'last', 'Sun', str, 'end', str, 'last', 'Sun', str, + 'adjust', str): + #we dont have some internal time to set return else: raise exceptions.CommandSyntaxError(command=command) @@ -880,26 +879,29 @@ def do_undo(self, command, *args, context=None): # TODO: Functionality raise exceptions.CommandSyntaxError(command=command) def do_snmp_agent(self, command, *args, context=None): # TODO: Functionality - if self._validate(args, 'community', 'read', '%S0O&R^7OW*+Xa9W4YQ.U=1!!B#A8&)VAB\']]F;U$19\'2_1!!%"'): + if self._validate(args, 'community', 'read', str): return - elif self._validate(args, 'community', 'write', '%0;OY:ZN9E3#]`FQ^XRO$#A!!B#A8&)VAB\']]F;U$19\'2_1!!%"'): + elif self._validate(args, 'community', 'write', str): return - elif self._validate(args, 'target-host', 'trap-hostname', 'test_U2000', 'address', str, - 'udp-port', '162', 'trap-paramsname', 'test_U2000"'): + elif self._validate(args, 'target-host', 'trap-hostname', str, 'address', str, + 'udp-port', str , 'trap-paramsname', str): return - elif self._validate(args, 'target-host', 'trap-paramsname', 'test_U2000', 'v1', 'securityname', - '%S0O&R^7OW*+Xa9W4YQ.U=1!!B#A8&)VAB\']]F;U$19\'2_1!!%"'): + elif self._validate(args, 'target-host', 'trap-paramsname', str, 'v1', 'securityname', + str): return elif self._validate(args, 'trap', 'enable', 'standard'): return else: raise exceptions.CommandSyntaxError(command=command) - def do_system(self, command, *args, context=None): # TODO: Functionality - if self._validate(args, 'handshake', 'interval', '300'): - return - elif self._validate(args, 'handshake', 'enable'): - return + def do_system(self, command, *args, context=None): + if self._validate(args, 'handshake', 'interval', str): + interval, = self._dissect(args, 'handshake', 'interval', str) + self._model.set_handshake_interval(interval) + elif self._validate(args, 'handshake', str): + mode, = self._dissect(args, 'handshake', str) + if mode == 'enable' or mode == 'disable': + self._model.set_handshake_mode(mode) else: raise exceptions.CommandSyntaxError(command=command) @@ -1308,7 +1310,7 @@ def do_load(self, command, *args, context=None): # TODO: Read in file else: raise exceptions.CommandSyntaxError(command=command) - def do_sysname(self, command, *args, context=None): # TODO: Functionality + def do_sysname(self, command, *args, context=None): if args != (): name = '' for arg in args: From b984fc7926b2de5efdcf4dc63011e49ec4308af6 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 10 Sep 2020 10:48:59 +0200 Subject: [PATCH 032/318] Added functionality for command 'display ont autofind all' --- bootup/conf/bootstraps/create-huawei-5623.sh | 16 ++++++++++++---- nesi/huawei/api/schemas/huawei_ont_schemas.py | 3 ++- nesi/huawei/huawei_resources/huawei_ont.py | 4 ++++ nesi/softbox/api/models/ont_models.py | 6 ++++-- .../enable/config/display_ont_autofind_all.j2 | 14 -------------- .../config/display_ont_autofind_all_body.j2 | 15 +++++++++++++++ .../config/display_ont_autofind_all_footer.j2 | 2 ++ .../Base/Huawei_Base/configCommandProcessor.py | 15 +++++++++++++++ 8 files changed, 54 insertions(+), 21 deletions(-) delete mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all_body.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all_footer.j2 diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 456bac0..321b438 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -480,7 +480,11 @@ req='{ "cpu_occupation": "1%", "operational_state": "1", "admin_state": "1", - "index": 0 + "index": 0, + "autofind": true, + "vendor_id": "HWTC", + "version": "535.B", + "software_version": "V3R025C29D195" }' ont_0_2_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) @@ -616,7 +620,11 @@ req='{ "cpu_occupation": "1%", "operational_state": "1", "admin_state": "1", - "index": 0 + "index": 0, + "autofind": true, + "vendor_id": "HWTC", + "version": "535.B", + "software_version": "V3R025C29D195" }' ont_0_2_2_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) @@ -867,7 +875,7 @@ req='{ "ont_port_id": '$ont_port_0_4_0_0_1', "description": "Cpe 0/4/0 0/1 1", "admin_state": "1", - "mac": "a7:10:05:3f:57:96" + "mac": "0cdb-be79-2528" }' cpe_0_4_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) @@ -935,7 +943,7 @@ req='{ "ont_port_id": '$ont_port_0_4_1_0_1', "description": "Cpe 0/4/1 0/1 1", "admin_state": "0", - "mac": "d4:3f:3d:ef:d9:9a" + "mac": "c8cd-656b-7110" }' cpe_0_4_1_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) diff --git a/nesi/huawei/api/schemas/huawei_ont_schemas.py b/nesi/huawei/api/schemas/huawei_ont_schemas.py index 0b37921..57e880e 100644 --- a/nesi/huawei/api/schemas/huawei_ont_schemas.py +++ b/nesi/huawei/api/schemas/huawei_ont_schemas.py @@ -25,4 +25,5 @@ class Meta: 'interoperability_mode', 'power_reduction_status', 'fec_upstream_state', 'port_number_pots', 'max_adaptive_num_pots', 'port_number_eth', 'max_adaptive_num_eth', 'port_number_vdsl', 'max_adaptive_num_vdsl', - 'lineprofile_id', 'srvprofile_id', 'index') + 'lineprofile_id', 'srvprofile_id', 'index', 'autofind', 'version', + 'software_version', 'vendor_id') diff --git a/nesi/huawei/huawei_resources/huawei_ont.py b/nesi/huawei/huawei_resources/huawei_ont.py index ec0382b..634cf0a 100644 --- a/nesi/huawei/huawei_resources/huawei_ont.py +++ b/nesi/huawei/huawei_resources/huawei_ont.py @@ -52,6 +52,10 @@ class HuaweiOnt(Ont): max_adaptive_num_vdsl = base.Field('max_adaptive_num_vdsl') lineprofile_id = base.Field('lineprofile_id') srvprofile_id = base.Field('srvprofile_id') + autofind = base.Field('autofind') + version = base.Field('version') + vendor_id = base.Field('vendor_id') + software_version = base.Field('software_version') def set_online_duration(self, duration): """Set the ont online duration""" diff --git a/nesi/softbox/api/models/ont_models.py b/nesi/softbox/api/models/ont_models.py index add3395..d7ad897 100644 --- a/nesi/softbox/api/models/ont_models.py +++ b/nesi/softbox/api/models/ont_models.py @@ -20,6 +20,8 @@ class Ont(db.Model): description = db.Column(db.String()) admin_state = db.Column(db.Enum('0', '1'), default='0') # Alcatel: 0 => down, 1 => up; Huawei: 0 => offline, 1 => online operational_state = db.Column(db.Enum('0', '1'), default='0') # Alcatel: 0 => down, 1 => up; Huawei: 0 => offline, 1 => online + vendor_id = db.Column(db.String(), default=None) + version = db.Column(db.String(), default=None) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) port_id = db.Column(db.Integer, db.ForeignKey('port.id')) @@ -89,10 +91,8 @@ class Ont(db.Model): eqpt_ver_num = db.Column(db.String(), default='3FE56389AEBA01') sw_ver_act = db.Column(db.String(), default='3FE56065AFGB89') sw_ver_psv = db.Column(db.String(), default='3FE56065AFBB48') - vendor_id = db.Column(db.Enum('ALCL'), default='ALCL') equip_id = db.Column(db.String(), default='3FE56389AEBA01') actual_num_slots = db.Column(db.Integer(), default=1) - version_number = db.Column(db.String(), default='3FE56389AEBA01') num_tconts = db.Column(db.Integer(), default=32) num_trf_sched = db.Column(db.Integer(), default=32) num_prio_queues = db.Column(db.Integer(), default=124) @@ -151,4 +151,6 @@ class Ont(db.Model): max_adaptive_num_vdsl = db.Column(db.String(), default='-') lineprofile_id = db.Column(db.Integer(), nullable=True) srvprofile_id = db.Column(db.Integer(), nullable=True) + autofind = db.Column(db.Boolean(), default=False) + software_version = db.Column(db.String(), default=None) diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all.j2 deleted file mode 100644 index 1229ab1..0000000 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all.j2 +++ /dev/null @@ -1,14 +0,0 @@ ----------------------------------------------------------------------------- - Number : 1 - F/S/P : 0/1/6 - Ont SN : 4857544346DAD39A (HWTC-46DAD39A) - Password : 0x00000000000000000000 - Loid : - Checkcode : - VendorID : HWTC - Ont Version : 635.A - Ont SoftwareVersion : V3R015C10S106 - Ont EquipmentID : 010H - Ont autofind time : 2020-07-08 09:11:12+01:00 - ---------------------------------------------------------------------------- - The number of GPON autofind ONT is 1 \ No newline at end of file diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all_body.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all_body.j2 new file mode 100644 index 0000000..00e8843 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all_body.j2 @@ -0,0 +1,15 @@ + ---------------------------------------------------------------------------- + Number : {{ context.ont.index }} + F/S/P : {{ context.port_identifier }} + Ont SN : {{ context.ont.serial_number }} + Password : 0x00000000000000000000 + Loid : + Checkcode : + VendorID : {{ context.ont.vendor_id }} + Ont Version : {{ context.ont.version }} + Ont SoftwareVersion : {{ context.ont.software_version }} + Ont EquipmentID : 010H + Ont Customized Info : - + Ont autofind time : 2020-08-20 12:19:59+01:00 + ---------------------------------------------------------------------------- + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all_footer.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all_footer.j2 new file mode 100644 index 0000000..aa8657a --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all_footer.j2 @@ -0,0 +1,2 @@ + The number of GPON autofind ONT is {{ context.autofind_count }} + diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 0d469e7..811b6e8 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -121,6 +121,21 @@ def do_interface(self, command, *args, context=None): def do_display(self, command, *args, context=None): if self._validate(args, 'board', str): self.display_board(command, args, context) + elif self._validate(args, 'ont', 'autofind', 'all'): + autofind_onts = [] + + for ont in self._model.onts: + if ont.autofind: + autofind_onts.append(ont) + + for autofind_ont in autofind_onts: + port = self._model.get_port('id', autofind_ont.port_id) + context['port_identifier'] = port.name + context['ont'] = autofind_ont + self._write(self._render('display_ont_autofind_all_body', context=context)) + + context['autofind_count'] = len(autofind_onts) + self._write(self._render('display_ont_autofind_all_footer', context=context)) elif self._validate(args, 'ont', 'info', 'summary', str): def generate_ont_info_summary(port): text = '' From 78736fe9b40350d416bd15a64e7a28688e204ce3 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 10 Sep 2020 10:51:55 +0200 Subject: [PATCH 033/318] Removed pycache file from git --- bootup/sockets/__pycache__/telnet.cpython-38.pyc | Bin 2303 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 bootup/sockets/__pycache__/telnet.cpython-38.pyc diff --git a/bootup/sockets/__pycache__/telnet.cpython-38.pyc b/bootup/sockets/__pycache__/telnet.cpython-38.pyc deleted file mode 100644 index 678e8f43c2163a8eb29ede6ea2c9301b344c5dd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2303 zcmZuyOK%)S5bmD0*Sn4%Bqkw%6(vF=kQZ`5A_~YMG6(@132y|fkcP>0C!Wph%%-Ou zlGWzqNSyK?*2nx8P8|EnDSsgc#8*9DVmsTTuBm=iRabpgeYewTF*NtjJIVDW#{Qwf z$>w6PgI;fg2qt*J2F;%jIL1!ljNF0C*|$u%!h6nycjyc}!S`6~zrq>Ti@9mZCz%}U zyejLA=1w*bgB^6MK{Ap$a0D05b2f0_NR{5uKXeCy@I`=?P=wGBnRZ_mrPO;>_E739 zI3bvLl6{+G{|++srYvDoACylys55my-Kh)eX@BNxe;A;LM>HQz*)W-Ma3MBIvCu*T`VB8Blev%Fu`Iu%06x;EapQrfs#ksE(h30atqmZNcz zYMH32(k7^_^(MUaP4ZoDw{MpB?%e)9+3Wwbd+SHTA>m$L3KJB0tz~IKNRp+l&63_% zG8K9Gz<57Egz*Z{I51uO6k0zv$krrK-E*{k+J>535q8 zdcQkK&(FMt00+l+(Cbe?&LW^e6%f_L-4~&V5dT0d!Q-vT#wiuYFrX;R8}S5U3xg|Q zG#m060&GJ{FmNplJPQM#0{N2n;y|rouL=6r#cC4+MVVs4d02zS9kHkA{&rDaBJMpR zNunrhM1|7rcOk zpIO=Wm|hv4d)QKcacHpGS7&R-+QKv1;AvX1dfeIi+ZO)HO6M086iVjaWc6Bo<66Cy zRb?qNEycEVVLx^(giRn)IjTz2E~*E4ncPdUO`*JmIH2VdJ=ti^i@bg#BHm~svH`Cl zdfB6cTuHS`qaYoRB{C~ivXE&ljXzd-shcpKP9NimJk#oZI)*f>#)?pD*7{P7@-i)U zpX7R1sY*2{@w1|WygheKBd^<@V9i&CG(xiP1k?Lb2 z^ah?#Yu!QVZGxuodGxOw From c736990ed4ccfc43ed4087d33043eeaa4f3ff464 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 10 Sep 2020 11:57:38 +0200 Subject: [PATCH 034/318] Added functionality for command 'display ont info summary 0' and swapped obsolete field run_state of ont with admin_state --- bootup/conf/bootstraps/create-huawei-5623.sh | 4 ++-- nesi/huawei/api/schemas/huawei_ont_schemas.py | 2 +- nesi/huawei/huawei_resources/huawei_ont.py | 1 - nesi/softbox/api/models/ont_models.py | 1 - .../display_board_ftth_pon_middle_middle.j2 | 2 +- .../display_board_ftth_pon_middle_middle.j2 | 2 +- .../display_ont_info_summary_0_bottom.j2 | 1 + .../display_ont_info_summary_0_middle.j2 | 2 +- .../display_ont_info_port_ont_header.j2 | 2 +- ...peration_not_supported_by_board_failure.j2 | 2 ++ ...operation_not_supported_by_port_failure.j2 | 2 ++ .../display_board_ftth_pon_middle_middle.j2 | 2 +- .../Huawei_Base/configCommandProcessor.py | 20 +++++++++++-------- .../Huawei_Base/huaweiBaseCommandProcessor.py | 5 +++-- .../Huawei_Base/interfaceCommandProcessor.py | 1 + 15 files changed, 29 insertions(+), 20 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_board_failure.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_port_failure.j2 diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 321b438..4daea4a 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -983,8 +983,8 @@ req='{ "description": "Ont 0/4/2 0", "memory_occupation": "50%", "cpu_occupation": "1%", - "operational_state": "1", - "admin_state": "1", + "operational_state": "0", + "admin_state": "0", "index": 0 }' diff --git a/nesi/huawei/api/schemas/huawei_ont_schemas.py b/nesi/huawei/api/schemas/huawei_ont_schemas.py index 57e880e..a74af69 100644 --- a/nesi/huawei/api/schemas/huawei_ont_schemas.py +++ b/nesi/huawei/api/schemas/huawei_ont_schemas.py @@ -16,7 +16,7 @@ class HuaweiOntSchema(OntSchema): class Meta: model = Ont - fields = OntSchema.Meta.fields + ('run_state', 'serial_number', 'control_flag', 'config_state', 'match_state', + fields = OntSchema.Meta.fields + ('serial_number', 'control_flag', 'config_state', 'match_state', 'protect_side', 'dba_type', 'ont_distance', 'ont_last_distance', 'ont_battery_state', 'memory_occupation', 'cpu_occupation', 'temperature', 'authentic_type', 'management_mode', 'software_work_mode', 'isolation_state', diff --git a/nesi/huawei/huawei_resources/huawei_ont.py b/nesi/huawei/huawei_resources/huawei_ont.py index 634cf0a..3e91322 100644 --- a/nesi/huawei/huawei_resources/huawei_ont.py +++ b/nesi/huawei/huawei_resources/huawei_ont.py @@ -16,7 +16,6 @@ class HuaweiOnt(Ont): """Represent physical shelf resource.""" - run_state = base.Field('run_state') serial_number = base.Field('serial_number') control_flag = base.Field('control_flag') config_state = base.Field('config_state') diff --git a/nesi/softbox/api/models/ont_models.py b/nesi/softbox/api/models/ont_models.py index d7ad897..3cf8afb 100644 --- a/nesi/softbox/api/models/ont_models.py +++ b/nesi/softbox/api/models/ont_models.py @@ -115,7 +115,6 @@ class Ont(db.Model): olt_rx_sig_level = db.Column(db.Float(), default=-18.8) # Huawei data - run_state = db.Column(db.Enum('online', 'offline'), default='online') serial_number = db.Column(db.String(), default='485754433AD3209C') control_flag = db.Column(db.Enum('active'), default='active') config_state = db.Column(db.Enum('normal'), default='normal') diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_middle.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_middle.j2 index ca33557..b8a4fa4 100644 --- a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_middle.j2 +++ b/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_middle.j2 @@ -1,2 +1,2 @@ -{{ context.spacer_beg2 }}{{ context.subrackname }}{{ context.spacer7 }}{{ context.cardportname }}{{ context.spacer8 }}{{ context.ont_id }}{{ context.spacer9 }}{{ context.ont.serial_number }}{{ context.spacer10 }}{{ context.ont.control_flag}}{{ context.spacer11 }}{{ context.ont.run_state }}{{ context.spacer12 }}{{ context.ont.config_state }}{{ context.spacer13 }}{{ context.ont.match_state }}{{ context.spacer14 }}{{ context.ont.protect_side }} +{{ context.spacer_beg2 }}{{ context.subrackname }}{{ context.spacer7 }}{{ context.cardportname }}{{ context.spacer8 }}{{ context.ont_id }}{{ context.spacer9 }}{{ context.ont.serial_number }}{{ context.spacer10 }}{{ context.ont.control_flag}}{{ context.spacer11 }}{{ context.ont.admin_state }}{{ context.spacer12 }}{{ context.ont.config_state }}{{ context.spacer13 }}{{ context.ont.match_state }}{{ context.spacer14 }}{{ context.ont.protect_side }} diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_middle_middle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_middle_middle.j2 index ca33557..b8a4fa4 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_middle_middle.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_middle_middle.j2 @@ -1,2 +1,2 @@ -{{ context.spacer_beg2 }}{{ context.subrackname }}{{ context.spacer7 }}{{ context.cardportname }}{{ context.spacer8 }}{{ context.ont_id }}{{ context.spacer9 }}{{ context.ont.serial_number }}{{ context.spacer10 }}{{ context.ont.control_flag}}{{ context.spacer11 }}{{ context.ont.run_state }}{{ context.spacer12 }}{{ context.ont.config_state }}{{ context.spacer13 }}{{ context.ont.match_state }}{{ context.spacer14 }}{{ context.ont.protect_side }} +{{ context.spacer_beg2 }}{{ context.subrackname }}{{ context.spacer7 }}{{ context.cardportname }}{{ context.spacer8 }}{{ context.ont_id }}{{ context.spacer9 }}{{ context.ont.serial_number }}{{ context.spacer10 }}{{ context.ont.control_flag}}{{ context.spacer11 }}{{ context.ont.admin_state }}{{ context.spacer12 }}{{ context.ont.config_state }}{{ context.spacer13 }}{{ context.ont.match_state }}{{ context.spacer14 }}{{ context.ont.protect_side }} diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_bottom.j2 index 26647c9..3de2c01 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_bottom.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_bottom.j2 @@ -1,2 +1,3 @@ ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_middle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_middle.j2 index 36da20a..457f72f 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_middle.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_middle.j2 @@ -1,2 +1,2 @@ - {{ context.ont_idx }} {{ context.ont_run_state }} {{ context.last_uptime }} {{ context.last_downtime }} dying-gasp + {{ context.ont_idx }} {{ context.ont_admin_state }} {{ context.last_uptime }} {{ context.last_downtime }} dying-gasp diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_header.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_header.j2 index 7b71c80..30548df 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_header.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_header.j2 @@ -2,7 +2,7 @@ F/S/P : {{ context.port.name }} ONT-ID : {{ context.ont_idx }} Control flag : {{ context.ont.control_flag }} - Run state : {{ context.ont.run_state }} + Run state : {{ context.ont.admin_state }} Config state : {{ context.ont.config_state }} Match state : {{ context.ont.match_state }} DBA type : {{ context.ont.dba_type }} diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_board_failure.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_board_failure.j2 new file mode 100644 index 0000000..c1acca6 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_board_failure.j2 @@ -0,0 +1,2 @@ + Failure: The board does not support this operation + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_port_failure.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_port_failure.j2 new file mode 100644 index 0000000..fe32796 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_port_failure.j2 @@ -0,0 +1,2 @@ + Failure: The port of this type does not support this operation + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_middle_middle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_middle_middle.j2 index ca33557..b8a4fa4 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_middle_middle.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_middle_middle.j2 @@ -1,2 +1,2 @@ -{{ context.spacer_beg2 }}{{ context.subrackname }}{{ context.spacer7 }}{{ context.cardportname }}{{ context.spacer8 }}{{ context.ont_id }}{{ context.spacer9 }}{{ context.ont.serial_number }}{{ context.spacer10 }}{{ context.ont.control_flag}}{{ context.spacer11 }}{{ context.ont.run_state }}{{ context.spacer12 }}{{ context.ont.config_state }}{{ context.spacer13 }}{{ context.ont.match_state }}{{ context.spacer14 }}{{ context.ont.protect_side }} +{{ context.spacer_beg2 }}{{ context.subrackname }}{{ context.spacer7 }}{{ context.cardportname }}{{ context.spacer8 }}{{ context.ont_id }}{{ context.spacer9 }}{{ context.ont.serial_number }}{{ context.spacer10 }}{{ context.ont.control_flag}}{{ context.spacer11 }}{{ context.ont.admin_state }}{{ context.spacer12 }}{{ context.ont.config_state }}{{ context.spacer13 }}{{ context.ont.match_state }}{{ context.spacer14 }}{{ context.ont.protect_side }} diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 811b6e8..8092b13 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -147,8 +147,9 @@ def generate_ont_info_summary(port): onts = self._model.get_onts('port_id', port.id) distance = random.randint(0, 7) * 1000 for ont in onts: + self.map_states(ont, 'ont') context['ont_count'] += 1 - if ont.run_state == 'online': + if ont.admin_state == 'online': context['ont_online_count'] += 1 context['ont_idx'] = ont.name.split("/")[-1] context['ont_serial_number'] = ont.serial_number @@ -156,9 +157,9 @@ def generate_ont_info_summary(port): context['ont_distance'] = random.randint(distance, distance + 1000) context['rx_power'] = round(random.uniform(15, 25), 2) context['tx_power'] = round(random.uniform(1, 3), 2) - context['ont_run_state'] = ont.run_state + context['ont_admin_state'] = ont.admin_state date = datetime.date.today() - datetime.timedelta(days=random.randint(7, 28)) - if ont.run_state == 'online': + if ont.admin_state == 'online': context['last_uptime'] = date.strftime('%Y-%m-%d %H:%M:%S') context['last_downtime'] = (date - datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S') else: @@ -178,6 +179,7 @@ def generate_ont_info_summary(port): identifier, = self._dissect(args, 'ont', 'info', 'summary', str) components = identifier.split("/") + self._write(' Command is being executed. Please wait\n') text = '' if len(components) == 1: try: @@ -187,7 +189,7 @@ def generate_ont_info_summary(port): return cards = self._model.get_cards('subrack_id', subrack.id) for card in cards: - if card.product != 'ftth-pon': + if card.product not in ('ftth-pon', 'ftth'): continue ports = self._model.get_ports('card_id', card.id) for port in ports: @@ -198,8 +200,9 @@ def generate_ont_info_summary(port): except exceptions.InvalidInputError: self.on_error(context=context) return - if card.product != 'ftth-pon': - self.on_error(context=context) + if card.product not in ('ftth-pon', 'ftth'): + self._write(self._render('operation_not_supported_by_board_failure', context=context)) + return ports = self._model.get_ports('card_id', card.id) for port in ports: text += generate_ont_info_summary(port) @@ -210,8 +213,9 @@ def generate_ont_info_summary(port): self.on_error(context=context) return card = self._model.get_card('id', port.card_id) - if card.product != 'ftth-pon': - self.on_error(context=context) + if card.product not in ('ftth-pon', 'ftth'): + self._write(self._render('operation_not_supported_by_port_failure', context=context)) + return text += generate_ont_info_summary(port) else: raise exceptions.CommandSyntaxError diff --git a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py index 5bb84e8..0925102 100644 --- a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py @@ -148,7 +148,7 @@ def display_board(self, command, args, context=None): for ont in onts: if ont.port_id == port.id: ontcounter += 1 - if ont.run_state == 'online': + if ont.admin_state == '1': onlinecounter += 1 subrackname, cardportname = port.name.split('/', maxsplit=1) @@ -164,13 +164,14 @@ def display_board(self, command, args, context=None): else: text2 += self._render('display_board_ftth_pon_middle_top', context=context) for ont in onts: + self.map_states(ont, 'ont') context['ont_id'] = ont.index context['spacer_beg2'] = self.create_spacers((4,), (subrackname,))[0] * ' ' context['spacer7'] = self.create_spacers((4,), (cardportname,))[0] * ' ' context['spacer8'] = self.create_spacers((5,), (ont.index,))[0] * ' ' context['spacer9'] = self.create_spacers((18,), (ont.serial_number,))[0] * ' ' context['spacer10'] = self.create_spacers((8,), (ont.control_flag,))[0] * ' ' - context['spacer11'] = self.create_spacers((12,), (ont.run_state,))[0] * ' ' + context['spacer11'] = self.create_spacers((12,), (ont.admin_state,))[0] * ' ' context['spacer12'] = self.create_spacers((9,), (ont.config_state,))[0] * ' ' context['spacer13'] = self.create_spacers((8,), (ont.match_state,))[0] * ' ' context['spacer14'] = self.create_spacers((4,), ('',))[0] * ' ' diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index d4b2802..c6513c6 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -144,6 +144,7 @@ def do_display(self, command, *args, context=None): online_duration = time_now - last_up ont.set_online_duration(str(online_duration)) ont = self._model.get_ont("name", ontname) + self.map_states(ont, 'ont') context['ont_idx'] = ont.index From 9bc94a68d069908a88049d90a76903e9d498ff8d Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 10 Sep 2020 13:56:50 +0200 Subject: [PATCH 035/318] Corrected 'display mac-address all' template and added mac_address count --- .../enable/config/display_mac_address_all_bottom.j2 | 2 +- .../enable/config/display_mac_address_all_middle.j2 | 2 +- .../enable/config/display_mac_address_all_top.j2 | 1 - .../Base/Huawei_Base/configCommandProcessor.py | 13 +++++++++---- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_bottom.j2 index f3e9611..be9b35a 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_bottom.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_bottom.j2 @@ -1,5 +1,5 @@ ----------------------------------------------------------------------- - Total: 110 + Total: {{ context.mac_address_count }} Note: F--Frame, S--Slot, P--Port, A--The MAC address is learned or configured on the aggregation port, VPI indicates GEM Port ID for GPON, diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_middle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_middle.j2 index 1f6da37..be039a4 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_middle.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_middle.j2 @@ -1,2 +1,2 @@ - - - {{ context.product }} {{ context.cpe_mac }} dynamic {{ context.subrack }} /{{ context.card }} /{{ context.port }} {{ context.ont }} {{ context.ont_port }} 2620 + - - {{ context.product }} {{ context.cpe_mac }} dynamic {{ context.subrack }} /{{ context.card }} /{{ context.port }} {{ context.ont }} {{ context.ont_port }} 2620 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_top.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_top.j2 index c89aee7..8dba082 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_top.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_top.j2 @@ -1,4 +1,3 @@ - It will take some time, please wait... ----------------------------------------------------------------------- SRV-P BUNDLE TYPE MAC MAC TYPE F /S /P VPI VCI VLAN ID INDEX INDEX diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 8092b13..ffa5d3d 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -289,8 +289,11 @@ def generate_ont_info_summary(port): elif self._validate(args, 'mac-address', 'all'): self.user_input('{ || }:') + self._write(' It will take some time, please wait...\n') + text = self._render('display_mac_address_all_top', context=context) + mac_address_count = 0 for cpe in self._model.cpes: port = None ont_port = None @@ -310,13 +313,13 @@ def generate_ont_info_summary(port): card = self._model.get_card('id', port.card_id) if card.product == 'adsl': - context['product'] = 'adl' + context['product'] = 'adl ' elif card.product == 'vdsl': - context['product'] = 'vdl' + context['product'] = 'vdl ' elif card.product == 'ftth': - context['product'] = 'eth' + context['product'] = 'eth ' elif card.product == 'ftth-pon': - context['product'] = 'pon' + context['product'] = 'gpon' ont_identifier = None ont_port_identifier = None @@ -340,7 +343,9 @@ def generate_ont_info_summary(port): context['ont_port'] = ont_port_identifier context['cpe_mac'] = cpe.mac text += self._render('display_mac_address_all_middle', context=context) + mac_address_count += 1 + context['mac_address_count'] = mac_address_count text += self._render('display_mac_address_all_bottom', context=context) self._write(text) From 1a85c748704539b830f0db80a74c8be1a89dda29 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 10 Sep 2020 14:18:09 +0200 Subject: [PATCH 036/318] Added functionality for 'undo smart' and 'smart' commands --- nesi/huawei/api/schemas/huawei_box_schemas.py | 2 +- nesi/huawei/huawei_resources/huawei_box.py | 10 ++++++++++ nesi/softbox/api/models/box_models.py | 1 + .../Base/Huawei_Base/baseCommandProcessor.py | 3 ++- .../Base/Huawei_Base/configCommandProcessor.py | 12 ++++++++---- .../Base/Huawei_Base/enableCommandProcessor.py | 14 ++++++++++++++ .../Base/Huawei_Base/huaweiBaseCommandProcessor.py | 3 ++- .../Base/Huawei_Base/interfaceCommandProcessor.py | 3 ++- .../Base/Huawei_Base/testCommandProcessor.py | 3 ++- 9 files changed, 42 insertions(+), 9 deletions(-) diff --git a/nesi/huawei/api/schemas/huawei_box_schemas.py b/nesi/huawei/api/schemas/huawei_box_schemas.py index d5c6b67..7954f3e 100644 --- a/nesi/huawei/api/schemas/huawei_box_schemas.py +++ b/nesi/huawei/api/schemas/huawei_box_schemas.py @@ -17,7 +17,7 @@ class HuaweiBoxSchema(BoxSchema): class Meta: model = Box fields = BoxSchema.Meta.fields + ('cpu_occupancy', 'vlan_interfaces', 'raio_anid', 'handshake_mode', - 'handshake_interval') + 'handshake_interval', 'interactive_mode') vlan_interfaces = ma.Hyperlinks( {'_links': { diff --git a/nesi/huawei/huawei_resources/huawei_box.py b/nesi/huawei/huawei_resources/huawei_box.py index f1fea48..e04494f 100644 --- a/nesi/huawei/huawei_resources/huawei_box.py +++ b/nesi/huawei/huawei_resources/huawei_box.py @@ -29,6 +29,7 @@ class HuaweiBox(Box): raio_anid = base.Field('raio_anid') handshake_mode = base.Field('handshake_mode') handshake_interval = base.Field('handshake_interval') + interactive_mode = base.Field('interactive_mode') @property def credentials(self): @@ -393,6 +394,15 @@ def set_handshake_interval(self, interval): """Change the handshake interval of a box""" self.update(handshake_interval=interval) + def disable_interactive(self): + """Disable Interactive function.""" + self.update(interactive_mode=False) + + def enable_interactive(self): + """Enable Interactive function.""" + self.update(interactive_mode=True) + + class HuaweiBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 3438039..103888a 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -103,3 +103,4 @@ class Box(db.Model): raio_anid = db.Column(db.String(), default='127.0.0.1') handshake_mode = db.Column(db.Enum('enable', 'disable'), default='disable') handshake_interval = db.Column(db.Integer(), default=None) + interactive_mode = db.Column(db.Boolean(), default=True) diff --git a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py index 4a3fc33..3a60b5a 100644 --- a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py @@ -98,7 +98,8 @@ def on_unknown_command(self, command, *args, context=None): def do_scroll(self, command, *args, context=None): if args == (): - _ = self.user_input('{ |number<10,512> }:') + if self._model.interactive_mode: + self.user_input('{ |number<10,512> }:') return elif self._validate(args, str): return diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index ffa5d3d..42dc3ed 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -232,7 +232,8 @@ def generate_ont_info_summary(port): text = self._render('display_interface_vlanif_num', context=dict(context, vlanif=vlanif)) self._write(text) elif self._validate(args, 'vlan', 'all'): - _ = self.user_input('{ |vlanattr|vlantype }:') + if self._model.interactive_mode: + self.user_input('{ |vlanattr|vlantype }:') text = self._render('display_vlan_all_top', context=context) count = 0 for vlan in self._model.vlans: @@ -270,7 +271,8 @@ def generate_ont_info_summary(port): self._write(text) elif self._validate(args, 'version'): - self.user_input('{ |backplane|frameid/slotid }:') + if self._model.interactive_mode: + self.user_input('{ |backplane|frameid/slotid }:') text = self._render('display_version', context=dict(context, box=self._model)) self._write(text) @@ -287,7 +289,8 @@ def generate_ont_info_summary(port): self._write(text) elif self._validate(args, 'mac-address', 'all'): - self.user_input('{ || }:') + if self._model.interactive_mode: + self.user_input('{ || }:') self._write(' It will take some time, please wait...\n') @@ -351,7 +354,8 @@ def generate_ont_info_summary(port): self._write(text) elif self._validate(args, 'current-configuration', 'section', 'vlan-srvprof'): - self.user_input('{ || }:') + if self._model.interactive_mode: + self.user_input('{ || }:') text = self._render('display_current_configuration_section_vlan_srvprof_top', context=dict(context, box=self._model)) text2 = '' diff --git a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py index 6c60fa6..a76538d 100644 --- a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py @@ -18,6 +18,20 @@ class EnableCommandProcessor(HuaweiBaseCommandProcessor): + def do_undo(self, command, *args, context=None): + if self._validate(args, 'smart'): + self._write(" Interactive function is disabled\n") + self._model.disable_interactive() + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_smart(self, command, *args, context=None): + if self._validate(args,): + self._write(" Interactive function is enabled\n") + self._model.enable_interactive() + else: + raise exceptions.CommandSyntaxError(command=command) + def do_disable(self, command, *args, context=None): from .userViewCommandProcessor import UserViewCommandProcessor diff --git a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py index 0925102..6d23d0c 100644 --- a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py @@ -381,7 +381,8 @@ def display_service_port(self, command, args, context): s_port_idx, = self._dissect(args, 'service-port', str) if s_port_idx == 'all': - self.user_input('{ |sort-by|| }:') + if self._model.interactive_mode: + self.user_input('{ |sort-by|| }:') text = self._render('display_service_port_all_top', context=context) s_ports = self._model.service_ports diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index c6513c6..47b9ed6 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -261,7 +261,8 @@ def do_display(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - self.user_input('{ |sort-by|| }:') + if self._model.interactive_mode: + self.user_input('{ |sort-by|| }:') text = self._render( 'display_port_ddm-info', context=dict(context, port=port)) diff --git a/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py index fdbdb41..8fff27c 100644 --- a/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py @@ -44,7 +44,8 @@ def do_xdsl(self, command, *args, context=None): except (exceptions.SoftboxenError, AssertionError): raise exceptions.CommandSyntaxError(command=command) - _ = self.user_input('{ |discharge|fault-force-test }:') + if self._model.interactive_mode: + self.user_input('{ |discharge|fault-force-test }:') text = self._render('melt_failure', context=context) self._write(text) From 76367dcdce63fec1da543c26ccbaa99fc85441d5 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Thu, 10 Sep 2020 16:49:46 +0200 Subject: [PATCH 037/318] Fixed melt test template --- .../enable/config/test/melt_failure.j2 | 8 -- .../mainloop/enable/config/test/melt_test.j2 | 78 +++++++++++++++++++ .../enable/config/test/melt_test_wait.j2 | 6 ++ .../Base/Huawei_Base/testCommandProcessor.py | 17 +++- 4 files changed, 100 insertions(+), 9 deletions(-) delete mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_failure.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test_wait.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_failure.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_failure.j2 deleted file mode 100644 index 3c13ce8..0000000 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_failure.j2 +++ /dev/null @@ -1,8 +0,0 @@ - - - Command: - xdsl melt 0/0/0 measured-frequency 25Hz busy force - Failure: No License is left for MELT test. Please apply License - - - diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test.j2 new file mode 100644 index 0000000..854406f --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test.j2 @@ -0,0 +1,78 @@ + Tested port: {{ context.port_name }} + Start time of the test: {{ context.time_beg }} + End time of the test: {{ context.time_end }} + I--Invalid V--Valid + ------------------------------------------------------------------------------ + Test Item Flag Result + ------------------------------------------------------------------------------ + Conclusion: + Does PPA exist? I no + Does signature exist? V no + Does hazardous voltage (AC) exist? V no + Does hazardous voltage (DC) exist? V no + Line open V yes + Line short V no + Is the phone in the off-hook state? V no + Significant terminal device capacitance detected? V no + + Main measurement results: + a->ground AC voltage(V) V 0.010 + b->ground AC voltage(V) V 0.013 + a->b AC voltage(V) V 0.012 + Frequency of a->ground foreign AC voltage(Hz) I 0 + Frequency of b->ground foreign AC voltage(Hz) I 0 + Frequency of a->b foreign AC voltage(Hz) I 0 + a->ground DC voltage(V) V -0.191 + b->ground DC voltage(V) V -0.141 + a->b DC voltage(V) V -0.051 + a->ground resistance(Ohm) V 10000000 + b->ground resistance(Ohm) V 10000000 + a->b resistance(Ohm) V 10000000 + b->a resistance(Ohm) V 10000000 + a->ground capacitance(nF) V 0 + b->ground capacitance(nF) V 0 + a->b capacitance(nF) V 1 + Capacitance of signature or ringer(nF) I 0 + Resistance of signature or ringer(Ohm) I 0 + Vzener(V) I -31.144 + Rzener(Ohm) I 10000000 + Rbat_a(Ohm) I 10000000 + Rbat_b(Ohm) I 10000000 + + Measurement results for reference: + Aggregate a->ground conductance(uS) V 0.0 + Aggregate a->ground susceptance(uS) V 0.0 + Aggregate b->ground conductance(uS) V 0.0 + Aggregate b->ground susceptance(uS) V 0.0 + Aggregate a->b conductance(uS) V 0.0 + Aggregate a->b susceptance(uS) V 0.0 + AC foreign current on a wire(uA) V 0 + AC foreign current on b wire(uA) V 1 + DC foreign current on a wire(uA) V -8 + DC foreign current on b wire(uA) V -6 + CtrLV(nF) V 23 + CtrHV(nF) V 27 + CtrAc(nF) V 26 + RtgSer(Ohm) V 10000000 + RrgSer(Ohm) V 7034829 + RtrSer(Ohm) V 0 + + Applied measurement parameters: + AC measurement frequency(Hz) 25 + a->ground highest measurement DC voltage(V) V -3.622 + a->ground lowest measurement DC voltage(V) V -53.032 + b->ground highest measurement DC voltage(V) V -3.680 + b->ground lowest measurement DC voltage(V) V -53.718 + a->b measurement DC voltage(V) V 46.790 + b->a measurement DC voltage(V) V -46.626 + Current mapping the a-wire highest voltage for test(uA) V -49 + Current mapping the a-wire lowest voltage for test(uA) V -83 + Current mapping the b-wire highest voltage for test(uA) V 80 + Current mapping the b-wire lowest voltage for test(uA) V 116 + Current mapping the a->b voltage for test(uA) I 32 + Current mapping the b->a voltage for test(uA) I 0 + UtgAcAdmit(V) V 7 + UrgAcAdmit(V) V 7 + UtrAcAdmit(V) V 6 + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test_wait.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test_wait.j2 new file mode 100644 index 0000000..1057c74 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test_wait.j2 @@ -0,0 +1,6 @@ + Command: + xdsl melt {{ context.port_name }} measured-frequency 25Hz busy force + Frame: {{ context.subrack_num }} Slot: {{ context.card_num }} Port: {{ context.port_num }} under testing, Please wait...... + + + diff --git a/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py index 8fff27c..8c48f67 100644 --- a/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py @@ -10,6 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst +from datetime import datetime +from time import sleep from nesi import exceptions from .baseCommandProcessor import BaseCommandProcessor @@ -47,7 +49,20 @@ def do_xdsl(self, command, *args, context=None): if self._model.interactive_mode: self.user_input('{ |discharge|fault-force-test }:') - text = self._render('melt_failure', context=context) + context['port_name'] = port.name + s_num, card_num, port_num = port.name.split('/') + context['subrack_num'] = s_num + context['card_num'] = card_num + context['port_num'] = port_num + + context['time_beg'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + text = self._render('melt_test_wait', context=context) + self._write(text) + sleep(2) + + context['time_end'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + text = self._render('melt_test', context=context) self._write(text) else: From 20bf310912ea4ab377ef8ef213c5d67e72beda99 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 10 Sep 2020 16:53:13 +0200 Subject: [PATCH 038/318] added unknown commands and fixed small issues --- nesi/huawei/api/schemas/huawei_box_schemas.py | 2 +- .../schemas/huawei_port_profile_schemas.py | 6 +- .../huawei/api/schemas/huawei_vlan_schemas.py | 4 +- nesi/huawei/huawei_resources/huawei_box.py | 10 + .../huawei_resources/huawei_port_profile.py | 11 ++ nesi/huawei/huawei_resources/huawei_vlan.py | 9 - nesi/softbox/api/models/box_models.py | 2 + nesi/softbox/api/models/portprofile_models.py | 11 ++ nesi/softbox/api/models/vlan_models.py | 10 +- .../config/backup_configuration_tftp.j2 | 4 + ..._configuration_section_vlan_srvprof_mid.j2 | 37 ++-- .../enable/config/display_pitp_config.j2 | 4 +- .../enable/config/display_vlan_all_bottom.j2 | 2 +- .../enable/config/display_vlan_all_mid.j2 | 2 +- .../enable/config/display_vlan_all_top.j2 | 6 +- .../login/mainloop/enable/config/srvprof/?.j2 | 31 ++++ .../enable/config/srvprof/on_cycle.j2 | 2 + .../enable/config/srvprof/on_error.j2 | 2 + .../config/srvprof/please_wait_commit.j2 | 2 + .../Huawei_Base/configCommandProcessor.py | 172 ++++++------------ .../Huawei_Base/diagnoseCommandProcessor.py | 2 +- .../vlanSrvprofCommandProcessor.py | 157 ++++++++++++++++ 22 files changed, 322 insertions(+), 166 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/backup_configuration_tftp.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/?.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_cycle.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_error.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/please_wait_commit.j2 create mode 100644 vendors/Huawei/Base/Huawei_Base/vlanSrvprofCommandProcessor.py diff --git a/nesi/huawei/api/schemas/huawei_box_schemas.py b/nesi/huawei/api/schemas/huawei_box_schemas.py index 7954f3e..06cddcd 100644 --- a/nesi/huawei/api/schemas/huawei_box_schemas.py +++ b/nesi/huawei/api/schemas/huawei_box_schemas.py @@ -17,7 +17,7 @@ class HuaweiBoxSchema(BoxSchema): class Meta: model = Box fields = BoxSchema.Meta.fields + ('cpu_occupancy', 'vlan_interfaces', 'raio_anid', 'handshake_mode', - 'handshake_interval', 'interactive_mode') + 'handshake_interval', 'interactive_mode', 'pitp', 'pitp_mode') vlan_interfaces = ma.Hyperlinks( {'_links': { diff --git a/nesi/huawei/api/schemas/huawei_port_profile_schemas.py b/nesi/huawei/api/schemas/huawei_port_profile_schemas.py index 25138ec..0279aa5 100644 --- a/nesi/huawei/api/schemas/huawei_port_profile_schemas.py +++ b/nesi/huawei/api/schemas/huawei_port_profile_schemas.py @@ -32,4 +32,8 @@ class Meta: 'reference_clock', 'cyclic_extension_flag', 'force_inp_ds', 'force_inp_us', 'g_993_2_profile', 'mode_specific', 'transmode', 'T1_413', 'G_992_1', 'G_992_2', 'G_992_3', 'G_992_4', 'G_992_5', - 'AnnexB_G_993_2', 'ETSI', 'us0_psd_mask', 'vdsltoneblackout') + 'AnnexB_G_993_2', 'ETSI', 'us0_psd_mask', 'vdsltoneblackout', + 'vmac_ipoe', 'vmac_pppoe', 'vmac_pppoa', + 'vlan_mac', 'packet_policy_multicast', 'packet_policy_unicast', + 'security_anti_ipspoofing', + 'security_anti_macspoofing', 'igmp_mismatch', 'commit') diff --git a/nesi/huawei/api/schemas/huawei_vlan_schemas.py b/nesi/huawei/api/schemas/huawei_vlan_schemas.py index 0e715ea..acb4e74 100644 --- a/nesi/huawei/api/schemas/huawei_vlan_schemas.py +++ b/nesi/huawei/api/schemas/huawei_vlan_schemas.py @@ -19,6 +19,4 @@ class Meta: fields = VlanSchema.Meta.fields + \ ('type', 'attribute', 'bind_service_profile_id', 'bind_RAIO_profile_index', 'priority', - 'native_vlan', 'vmac_ipoe', 'vmac_pppoe', 'vmac_pppoa', - 'vlan_mac', 'packet_policy_multicast', 'packet_policy_unicast', 'security_anti_ipspoofing', - 'security_anti_macspoofing', 'igmp_mismatch', 'tag') + 'native_vlan', 'tag') diff --git a/nesi/huawei/huawei_resources/huawei_box.py b/nesi/huawei/huawei_resources/huawei_box.py index e04494f..5069322 100644 --- a/nesi/huawei/huawei_resources/huawei_box.py +++ b/nesi/huawei/huawei_resources/huawei_box.py @@ -30,6 +30,8 @@ class HuaweiBox(Box): handshake_mode = base.Field('handshake_mode') handshake_interval = base.Field('handshake_interval') interactive_mode = base.Field('interactive_mode') + pitp = base.Field('pitp') + pitp_mode = base.Field('pitp_mode') @property def credentials(self): @@ -403,6 +405,14 @@ def enable_interactive(self): self.update(interactive_mode=True) + def set_pitp(self, state): + """Change the pitp of a box""" + self.update(pitp=state) + + def set_pitp_mode(self, mode): + """Change the pitp mode of a box""" + self.update(pitp_mode=mode) + class HuaweiBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/huawei/huawei_resources/huawei_port_profile.py b/nesi/huawei/huawei_resources/huawei_port_profile.py index cac698f..a61a2b1 100644 --- a/nesi/huawei/huawei_resources/huawei_port_profile.py +++ b/nesi/huawei/huawei_resources/huawei_port_profile.py @@ -76,6 +76,17 @@ class HuaweiPortProfile(PortProfile): us0_psd_mask = base.Field('us0_psd_mask') vdsltoneblackout = base.Field('vdsltoneblackout') + vmac_ipoe = base.Field('vmac_ipoe') + vmac_pppoe = base.Field('vmac_pppoe') + vmac_pppoa = base.Field('vmac_pppoa') + vlan_mac = base.Field('vlan_mac') + packet_policy_multicast = base.Field('packet_policy_multicast') + packet_policy_unicast = base.Field('packet_policy_unicast') + security_anti_ipspoofing = base.Field('security_anti_ipspoofing') + security_anti_macspoofing = base.Field('security_anti_macspoofing') + igmp_mismatch = base.Field('igmp_mismatch') + commit = base.Field('commit') + def set(self, field, value): mapping = {field: value} self.update(**mapping) diff --git a/nesi/huawei/huawei_resources/huawei_vlan.py b/nesi/huawei/huawei_resources/huawei_vlan.py index 4597d59..12210a6 100644 --- a/nesi/huawei/huawei_resources/huawei_vlan.py +++ b/nesi/huawei/huawei_resources/huawei_vlan.py @@ -24,15 +24,6 @@ class HuaweiVlan(Vlan): bind_RAIO_profile_index = base.Field('bind_RAIO_profile_index') priority = base.Field('priority') native_vlan = base.Field('native_vlan') - vmac_ipoe = base.Field('vmac_ipoe') - vmac_pppoe = base.Field('vmac_pppoe') - vmac_pppoa = base.Field('vmac_pppoa') - vlan_mac = base.Field('vlan_mac') - packet_policy_multicast = base.Field('packet_policy_multicast') - packet_policy_unicast = base.Field('packet_policy_unicast') - security_anti_ipspoofing = base.Field('security_anti_ipspoofing') - security_anti_macspoofing = base.Field('security_anti_macspoofing') - igmp_mismatch = base.Field('igmp_mismatch') tag = base.Field('tag') def set_tag(self, tag): diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 103888a..5bfe4f5 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -104,3 +104,5 @@ class Box(db.Model): handshake_mode = db.Column(db.Enum('enable', 'disable'), default='disable') handshake_interval = db.Column(db.Integer(), default=None) interactive_mode = db.Column(db.Boolean(), default=True) + pitp = db.Column(db.Enum('enable', 'disable'), default='disable') + pitp_mode = db.Column(db.String(), default='') diff --git a/nesi/softbox/api/models/portprofile_models.py b/nesi/softbox/api/models/portprofile_models.py index 6092ade..a912476 100644 --- a/nesi/softbox/api/models/portprofile_models.py +++ b/nesi/softbox/api/models/portprofile_models.py @@ -87,3 +87,14 @@ class PortProfile(db.Model): ETSI = db.Column(db.String(), default=None) us0_psd_mask = db.Column(db.Integer(), default=None) vdsltoneblackout = db.Column(db.String(), default=None) + + vmac_ipoe = db.Column(db.Enum('enable', 'disable'), default=None) + vmac_pppoe = db.Column(db.Enum('enable', 'disable'), default=None) + vmac_pppoa = db.Column(db.Enum('enable', 'disable'), default=None) + vlan_mac = db.Column(db.Enum('forwarding', 'discard'), default=None) + packet_policy_multicast = db.Column(db.Enum('forward', 'discard'), default=None) + packet_policy_unicast = db.Column(db.Enum('forward', 'discard'), default=None) + security_anti_ipspoofing = db.Column(db.Enum('enable', 'disable'), default=None) + security_anti_macspoofing = db.Column(db.Enum('enable', 'disable'), default=None) + igmp_mismatch = db.Column(db.Enum('transparent'), default=None) + commit = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/models/vlan_models.py b/nesi/softbox/api/models/vlan_models.py index 37f7f46..13a4bc9 100644 --- a/nesi/softbox/api/models/vlan_models.py +++ b/nesi/softbox/api/models/vlan_models.py @@ -60,12 +60,4 @@ class Vlan(db.Model): bind_RAIO_profile_index = db.Column(db.String(), default='-') priority = db.Column(db.String()) native_vlan = db.Column(db.Integer()) - vmac_ipoe = db.Column(db.Enum('enable', 'disable'), default='disable') - vmac_pppoe = db.Column(db.Enum('enable', 'disable'), default='disable') - vmac_pppoa = db.Column(db.Enum('enable', 'disable'), default='disable') - vlan_mac = db.Column(db.Enum('forwarding', 'discard'), default='forwarding') - packet_policy_multicast = db.Column(db.Enum('forward', 'discard'), default='forward') - packet_policy_unicast = db.Column(db.Enum('forward', 'discard'), default='discard') - security_anti_ipspoofing = db.Column(db.Enum('enable', 'disable'), default='disable') - security_anti_macspoofing = db.Column(db.Enum('enable', 'disable'), default='disable') - igmp_mismatch = db.Column(db.Enum('transparent'), default='transparent') + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/backup_configuration_tftp.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/backup_configuration_tftp.j2 new file mode 100644 index 0000000..f33bbd3 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/backup_configuration_tftp.j2 @@ -0,0 +1,4 @@ + Backing up files is succesful from the host to the maintenance terminal + PARAMETERS :FrameID: 0, SlotID: 0, Position: -1, Backup type: Configuration + file, Backup Object: Active control board + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_mid.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_mid.j2 index b64153a..9bbfe92 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_mid.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_mid.j2 @@ -1,17 +1,22 @@ - vlan service-profile profile-id {{ context.vlan.bind_service_profile_id}} profile-name "{{ context.profile.name}}" - vmac {{ context.vlan.vmac_ipoe}} ipoe - vmac {{ context.vlan.vmac_pppoe}} pppoe - vmac {{ context.vlan.vmac_ppoa}} pppoa - {% if 'forwarding' == context.vlan.vlan_mac %} forwarding vlan-mac{% endif %} - - {% if 'forward' == context.vlan.packet_policy_multicast %} packet-policy multicast forward{% endif %} - - {% if 'discard' == context.vlan.packet_policy_unicast %} packet-policy unicast discard{% endif %} - - {% if 'disable' == context.vlan.security_anti_ipspoofing %} security anti-ipspoofing disable{% endif %} - - {% if 'disable' == context.vlan.security_anti_macspoofing %} security anti-macspoofing disable{% endif %} - - igmp mismatch {{ context.vlan.igmp_mismatch}} - commit + vlan service-profile profile-id {{ context.profile.id}} profile-name {{ context.profile.name}} + {% if context.profile.vmac_ipoe != None %} vmac {{ context.profile.vmac_ipoe}} ipoe +{% endif %} + {% if context.profile.vmac_pppoe != None %} vmac {{ context.profile.vmac_pppoe}} pppoe +{% endif %} + {% if context.profile.vmac_pppoa != None %} vmac {{ context.profile.vmac_pppoa}} pppoa +{% endif %} + {% if None != context.profile.vlan_mac %} {{ context.profile.vlan_mac}} vlan-mac +{% endif %} + {% if context.profile.packet_policy_multicast != None %} packet-policy multicast {{ context.profile.packet_policy_multicast}} +{% endif %} + {% if context.profile.packet_policy_unicast != None %} packet-policy unicast {{ context.profile.packet_policy_unicast}} +{% endif %} + {% if context.profile.security_anti_ipspoofing != None %} security anti-ipspoofing {{ context.profile.security_anti_ipspoofing}} +{% endif %} + {% if context.profile.security_anti_macspoofing != None %} security anti-macspoofing {{ context.profile.security_anti_macspoofing}} +{% endif %} + {% if context.profile.igmp_mismatch != None %} igmp mismatch {{ context.profile.igmp_mismatch}} +{% endif %} + {% if context.profile.commit == True %} commit +{% endif %} diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_pitp_config.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_pitp_config.j2 index f9905d1..597b967 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_pitp_config.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_pitp_config.j2 @@ -1,3 +1,3 @@ - PITP is enabled. Current mode:pmode - PITP transparent pmode user-vlan: - + PITP is {{ context.box.pitp }}. Current mode:{{ context.box.pitp_mode }} + {% if context.box.pitp == 'enable' %} PITP transparent pmode user-vlan: -{% endif %} diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_bottom.j2 index bd7f533..03f4629 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_bottom.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_bottom.j2 @@ -1,4 +1,4 @@ - ----------------------------------------------------------------------- + ----------------------------------------------------------- Total: {{ context.count }} Note : STND-Port--standard port, SERV-Port--service virtual port diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_mid.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_mid.j2 index ae27a66..83efa36 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_mid.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_mid.j2 @@ -1,2 +1,2 @@ -{{ context.spacer1 }}{{ context.vlan.number }} {{ context.vlan.type }}{{ context.spacer2 }}{{ context.vlan.attribute }}{{ context.spacer3 }}{{ context.portnum}}{{ context.spacer4 }}{{ context.servportnum }} - +{{ context.spacer1 }}{{ context.vlan.number }} {{ context.vlan.type }}{{ context.spacer2 }}{{ context.vlan.attribute }}{{ context.spacer3 }}{{ context.portnum}}{{ context.spacer4 }}{{ context.servportnum }} diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_top.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_top.j2 index 08823af..f50a42a 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_top.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_top.j2 @@ -1,6 +1,6 @@ Command: display vlan all - ----------------------------------------------------------------------- - VLAN Type Attribute STND-Port NUM SERV-Port NUM VLAN-Con NUM - ----------------------------------------------------------------------- + ----------------------------------------------------------- + VLAN Type Attribute STND-Port NUM SERV-Port NUM + ----------------------------------------------------------- diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/?.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/?.j2 new file mode 100644 index 0000000..913f00e --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/?.j2 @@ -0,0 +1,31 @@ +--------------------------------------------- + Command of (config-vlan-srvprof-10)# Mode: +--------------------------------------------- +bpdu BPDU +commit Commit VLAN service profile +dhcp DHCP command group +dhcpv6 DHCPv6 command group +display Display information +forwarding VLAN service-profile forwarding +igmp IGMP +ipv6 IPv6 command group +l3-protocol Layer-3 protocol +mac-address MAC address table +mac-authen MAC authentication +ospf OSPF +packet-policy Packet policy +pitp PITP +pppoa PPPoA +pppoe PPPoE +quit Exit from current mode and enter prior mode +return Enter the privileged mode +rip RIP +ripng RIPng +router-redirect Router-Redirect +security security command group +switch Switch language mode +undo Negate a command or set its defaults +user-bridging Configure user-bridging +vmac Configure VMAC +vtp-cdp VTP-CDP + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_cycle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_cycle.j2 new file mode 100644 index 0000000..73bcb7e --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_cycle.j2 @@ -0,0 +1,2 @@ + +{{ model.hostname }}(config-vlan-srvprof-{{ context.srvprof.id }})# \ No newline at end of file diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_error.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_error.j2 new file mode 100644 index 0000000..19f5c1d --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_error.j2 @@ -0,0 +1,2 @@ + % Unknown command, the error locates at '^' + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/please_wait_commit.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/please_wait_commit.j2 new file mode 100644 index 0000000..96d4296 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/please_wait_commit.j2 @@ -0,0 +1,2 @@ + Info: Please use the commit command to make modifications take effect + diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 42dc3ed..008aa3d 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -17,6 +17,7 @@ from nesi import exceptions from .huaweiBaseCommandProcessor import HuaweiBaseCommandProcessor from .baseMixIn import BaseMixIn +from .vlanSrvprofCommandProcessor import VlanSrvprofCommandProcessor class ConfigCommandProcessor(HuaweiBaseCommandProcessor, BaseMixIn): @@ -50,6 +51,8 @@ def do_backup(self, command, *args, context=None): if self._validate(args, 'configuration', 'tftp', str, str): ip, path = self._dissect(args, 'configuration', 'tftp', str, str) time.sleep(5) + text = self._render('backup_configuration_tftp', context=context) + self._write(text) return else: raise exceptions.CommandSyntaxError(command=command) @@ -277,15 +280,13 @@ def generate_ont_info_summary(port): self._write(text) elif self._validate(args, 'alarm', 'active', 'alarmtype', 'environment', 'detail'): - text = self._render( - 'display_alarm_active_alarmtype_environment_detail', - context=context) + text = self._render('display_alarm_active_alarmtype_environment_detail', context=context) self._write(text) elif self._validate(args, 'pitp', 'config'): text = self._render( 'display_pitp_config', - context=context) + context=dict(context, box=self._model)) self._write(text) elif self._validate(args, 'mac-address', 'all'): @@ -362,14 +363,16 @@ def generate_ont_info_summary(port): for vlan in self._model.vlans: try: if vlan.bind_service_profile_id is not None and int(vlan.bind_service_profile_id) >= 0: - profile = self._model.get_port_profile("id", int(vlan.bind_service_profile_id)) - text += self._render('display_current_configuration_section_vlan_srvprof_mid', - context=dict(context, vlan=vlan, profile=profile)) text2 += self._render('display_current_configuration_section_vlan_srvprof_bot', - context=dict(context, vlan=vlan, profile=profile)) - + context=dict(context, vlan=vlan)) except ValueError: raise exceptions.CommandSyntaxError(command=command) + + for profile in self._model.port_profiles: + if profile.type == 'service': + text += self._render('display_current_configuration_section_vlan_srvprof_mid', + context=dict(context, profile=profile)) + text += text2 text += self._render('display_current_configuration_section_vlan_srvprof_bot2', context=context) @@ -629,7 +632,7 @@ def do_timezone(self, command, *args, context=None): def do_time(self, command, *args, context=None): if self._validate(args, 'dst', 'start', str, 'last', 'Sun', str, 'end', str, 'last', 'Sun', str, 'adjust', str): - #we dont have some internal time to set + # we dont have some internal time to set return else: raise exceptions.CommandSyntaxError(command=command) @@ -651,9 +654,28 @@ def do_vlan(self, command, *args, context=None): context=context) self._write(text) - elif self._validate(args, 'service-profile', 'profile-name', str, 'profile-id', str): # TODO: Functionality + elif self._validate(args, 'service-profile', 'profile-name', str, 'profile-id', str): name, id = self._dissect(args, 'service-profile', 'profile-name', str, 'profile-id', str) - return + try: + profile = self._model.get_port_profile('id', int(id)) + assert profile.type == "service" + except exceptions.SoftboxenError: + try: + self._model.add_port_profile(name=name, type='service', id=id) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + except AssertionError: + raise exceptions.CommandSyntaxError(command=command) + try: + profile = self._model.get_port_profile('id', int(id)) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + context['srvprof'] = profile + subprocessor = self._create_subprocessor( + VlanSrvprofCommandProcessor, 'login', 'mainloop', 'enable', 'config', 'srvprof') + + subprocessor.loop(context=context, return_to=ConfigCommandProcessor) elif self._validate(args, str, 'smart'): trafficvlan, = self._dissect(args, str, 'smart') @@ -674,7 +696,8 @@ def do_vlan(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def do_raio_format(self, command, *args, context=None): # TODO: Functionality + def do_raio_format(self, command, *args, context=None): + # not needed in simulation if self._validate(args, 'pitp-pmode', 'cid', 'eth', '"anid', 'eth', 'slot/port+1"'): return @@ -687,7 +710,8 @@ def do_raio_format(self, command, *args, context=None): # TODO: Functionality else: raise exceptions.CommandSyntaxError(command=command) - def do_raio(self, command, *args, context=None): # TODO: Functionality + def do_raio(self, command, *args, context=None): + # not needed in simulation if self._validate(args, 'sub-option', '0x81', 'pitp-pmode', 'enable'): return @@ -703,30 +727,20 @@ def do_raio(self, command, *args, context=None): # TODO: Functionality else: raise exceptions.CommandSyntaxError(command=command) - def do_pitp(self, command, *args, context=None): # TODO: Functionality - if self._validate(args, 'enable', 'pmode'): - text = self._render( - 'pitp_enable_pmode', - context=context) - self._write(text) - - elif self._validate(args, 'enable'): - text = self._render( - 'please_wait_commit', - context=context) - self._write(text) - - elif self._validate(args, 'disable'): - text = self._render( - 'please_wait_commit', - context=context) - self._write(text) - + def do_pitp(self, command, *args, context=None): + if self._validate(args, str, str): + pitp, mode = self._dissect(args, str, str) + if pitp == 'enable' or pitp == 'disable': + self._model.set_pitp(pitp) + self._model.set_pitp_mode(mode) + text = self._render('pitp_enable_pmode', context=context) + self._write(text) else: raise exceptions.CommandSyntaxError(command=command) - def do_raio_mode(self, command, *args, context=None): # TODO: Functionality + def do_raio_mode(self, command, *args, context=None): if self._validate(args, 'user-defined', 'pitp-pmode'): + # not needed in simulation return else: raise exceptions.CommandSyntaxError(command=command) @@ -748,90 +762,9 @@ def do_raio_anid(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def do_forwarding(self, command, *args, context=None): # TODO: Functionality - if self._validate(args, 'vlan-mac'): - text = self._render( - 'please_wait_commit', - context=context) - self._write(text) - else: - raise exceptions.CommandSyntaxError(command=command) - - def do_packet_policy(self, command, *args, context=None): # TODO: Functionality - if self._validate(args, 'multicast', 'forward'): - text = self._render( - 'please_wait_commit', - context=context) - self._write(text) - - elif self._validate(args, 'unicast', 'discard'): - text = self._render( - 'please_wait_commit', - context=context) - self._write(text) - - else: - raise exceptions.CommandSyntaxError(command=command) - - def do_security(self, command, *args, context=None): # TODO: Functionality - if self._validate(args, 'anti-macspoofing', 'disable'): - text = self._render( - 'please_wait_commit', - context=context) - self._write(text) - - elif self._validate(args, 'anti-macspoofing', 'enable'): - text = self._render( - 'please_wait_commit', - context=context) - self._write(text) - - elif self._validate(args, 'anti-ipspoofing', 'disable'): - text = self._render( - 'please_wait_commit', - context=context) - self._write(text) - - elif self._validate(args, 'anti-ipspoofing', 'enable'): - text = self._render( - 'please_wait_commit', - context=context) - self._write(text) - - else: - raise exceptions.CommandSyntaxError(command=command) - - def do_vmac(self, command, *args, context=None): # TODO: Functionality - if self._validate(args, 'disable'): - text = self._render( - 'please_wait_commit', - context=context) - self._write(text) - - elif self._validate(args, 'enable'): - text = self._render( - 'please_wait_commit', - context=context) - self._write(text) - - else: - raise exceptions.CommandSyntaxError(command=command) - - def do_igmp(self, command, *args, context=None): # TODO: Functionality - if self._validate(args, 'mismatch', 'transparent'): - text = self._render( - 'please_wait_commit', - context=context) - self._write(text) - - else: - raise exceptions.CommandSyntaxError(command=command) - - def do_commit(self, command, *args, context=None): # TODO: Functionality - return - - def do_undo(self, command, *args, context=None): # TODO: Functionality + def do_undo(self, command, *args, context=None): if self._validate(args, 'system', 'snmp-user', 'password', 'security'): + # importend for future snmp interactions return elif self._validate(args, 'service-port', str): s_port_idx, = self._dissect(args, 'service-port', str) @@ -906,7 +839,8 @@ def do_undo(self, command, *args, context=None): # TODO: Functionality else: raise exceptions.CommandSyntaxError(command=command) - def do_snmp_agent(self, command, *args, context=None): # TODO: Functionality + def do_snmp_agent(self, command, *args, context=None): + # importend for future snmp interactions if self._validate(args, 'community', 'read', str): return elif self._validate(args, 'community', 'write', str): @@ -1314,7 +1248,7 @@ def do_test(self, command, *args, context=None): def do_save(self, command, *args, context=None): if args == (): - # Saves the config that was entered + # command would save config but other commands do that automatically return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py index 615c677..8831ca0 100644 --- a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py @@ -74,7 +74,7 @@ def do_system(self, command, *args, context=None): context=dict(context, emu=emu, result=result)) text += self._render('display_system_status_collection_7', context=context) for port in self._model.ports: - result = ['Abnormal', 'Normal'][port.admin_state == 'activated'] + result = ['Abnormal', 'Normal'][port.admin_state == '1'] context['spacer'] = self.create_spacers((9,), (result,))[0] * ' ' text += self._render('display_system_status_collection_8', context=dict(context, port=port, result=result)) diff --git a/vendors/Huawei/Base/Huawei_Base/vlanSrvprofCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/vlanSrvprofCommandProcessor.py new file mode 100644 index 0000000..0677d3d --- /dev/null +++ b/vendors/Huawei/Base/Huawei_Base/vlanSrvprofCommandProcessor.py @@ -0,0 +1,157 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from .baseCommandProcessor import BaseCommandProcessor + + +class VlanSrvprofCommandProcessor(BaseCommandProcessor): + + def do_return(self, command, *args, context=None): + + from .enableCommandProcessor import EnableCommandProcessor + + context.pop('srvprof') + exc = exceptions.TerminalExitError() + exc.return_to = EnableCommandProcessor + raise exc + + def do_quit(self, command, *args, context=None): + context.pop('srvprof') + raise exceptions.TerminalExitError() + + def on_unknown_command(self, command, *args, context=None): + if self._validate(command, '?'): + text = self._render( + '?', + context=context) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) + + def get_profile(self, command, context): + srvprofid = context['srvprof'].id + try: + profile = self._model.get_port_profile('id', int(srvprofid)) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + return profile + + def do_security(self, command, *args, context=None): + if self._validate(args, 'anti-macspoofing', 'disable'): + context['srvprof'].security_anti_macspoofing = 'disable' + text = self._render('please_wait_commit', context=context) + self._write(text) + + elif self._validate(args, 'anti-macspoofing', 'enable'): + context['srvprof'].security_anti_macspoofing = 'enable' + text = self._render('please_wait_commit', context=context) + self._write(text) + + elif self._validate(args, 'anti-ipspoofing', 'disable'): + context['srvprof'].security_anti_ipspoofing = 'disable' + text = self._render('please_wait_commit', context=context) + self._write(text) + + elif self._validate(args, 'anti-ipspoofing', 'enable'): + context['srvprof'].security_anti_ipspoofing = 'enable' + text = self._render('please_wait_commit', context=context) + self._write(text) + + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_vmac(self, command, *args, context=None): + if self._validate(args, 'disable'): + context['srvprof'].vmac_ipoe = 'disable' + context['srvprof'].vmac_pppoa = 'disable' + context['srvprof'].vmac_pppoe = 'disable' + text = self._render('please_wait_commit', context=context) + self._write(text) + + elif self._validate(args, 'enable'): + context['srvprof'].vmac_ipoe = 'enable' + context['srvprof'].vmac_pppoa = 'enable' + context['srvprof'].vmac_pppoe = 'enable' + text = self._render('please_wait_commit', context=context) + self._write(text) + + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_igmp(self, command, *args, context=None): + if self._validate(args, 'mismatch', 'transparent'): + context['srvprof'].igmp_mismatch = 'transparent' + text = self._render('please_wait_commit', context=context) + self._write(text) + + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_pitp(self, command, *args, context=None): + if self._validate(args, 'enable'): + self._model.set_pitp('enable') + print(context['srvprof'].vlan_mac) + text = self._render('please_wait_commit', context=context) + self._write(text) + + elif self._validate(args, 'disable'): + self._model.set_pitp('disable') + text = self._render('please_wait_commit', context=context) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_forwarding(self, command, *args, context=None): + if self._validate(args, 'vlan-mac'): + context['srvprof'].vlan_mac = 'forwarding' + text = self._render('please_wait_commit', context=context) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_packet_policy(self, command, *args, context=None): + if self._validate(args, 'multicast', 'forward'): + context['srvprof'].packet_policy_multicast = 'forward' + text = self._render( + 'please_wait_commit', + context=context) + self._write(text) + + elif self._validate(args, 'unicast', 'discard'): + context['srvprof'].packet_policy_unicast = 'discard' + text = self._render( + 'please_wait_commit', + context=context) + self._write(text) + + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_commit(self, command, *args, context=None): + profile = self.get_profile(command, context) + if len(args) == 0: + virtprof = context['srvprof'] + profile.set('vlan_mac', virtprof.vlan_mac) + profile.set('vmac_ipoe', virtprof.vmac_ipoe) + profile.set('vmac_pppoa', virtprof.vmac_pppoa) + profile.set('vmac_pppoe', virtprof.vmac_pppoe) + profile.set('security_anti_macspoofing', virtprof.security_anti_macspoofing) + profile.set('security_anti_ipspoofing', virtprof.security_anti_ipspoofing) + profile.set('packet_policy_unicast', virtprof.packet_policy_unicast) + profile.set('packet_policy_multicast', virtprof.packet_policy_multicast) + profile.set('igmp_mismatch', virtprof.igmp_mismatch) + profile.set('commit', True) + else: + raise exceptions.CommandSyntaxError(command=command) + + From c1b9e112b9887cf00c56e8188d6d0fdc2a4b0012 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 11 Sep 2020 15:52:39 +0200 Subject: [PATCH 039/318] Added functionalities for activating/deactivating ports --- nesi/huawei/huawei_resources/huawei_port.py | 6 ++ .../enable/config/board_type_error.j2 | 2 + .../Huawei_Base/configCommandProcessor.py | 3 +- .../Huawei_Base/interfaceCommandProcessor.py | 80 ++++++++++++++----- 4 files changed, 69 insertions(+), 22 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/board_type_error.j2 diff --git a/nesi/huawei/huawei_resources/huawei_port.py b/nesi/huawei/huawei_resources/huawei_port.py index 6ea0235..8923b4b 100644 --- a/nesi/huawei/huawei_resources/huawei_port.py +++ b/nesi/huawei/huawei_resources/huawei_port.py @@ -205,6 +205,12 @@ class HuaweiPort(Port): rx_power_h = base.Field('rx_power_h') vlan_id = base.Field('vlan_id') + def admin_up(self): + self.update(admin_state='2') + + def admin_down(self): + self.update(admin_state='0') + def port_downstream_set(self, ds_rate): self.update(downstream_max=ds_rate) diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/board_type_error.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/board_type_error.j2 new file mode 100644 index 0000000..bfa89db --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/board_type_error.j2 @@ -0,0 +1,2 @@ + Failure: Board type error + diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 008aa3d..2dfd7a1 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -117,7 +117,8 @@ def do_interface(self, command, *args, context=None): subprocessor.loop(context=dict(context, component=component, iftype=iftype), return_to=ConfigCommandProcessor) else: - raise exceptions.CommandSyntaxError(command=command) + self._write(self._render('board_type_error', context=context)) + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index 47b9ed6..0bfd9e1 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -406,7 +406,10 @@ def do_activate(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - + elif self._validate(args, 'all'): + if context['iftype'] == 'vlanif': + raise exceptions.CommandSyntaxError(command=command) + self.card_ports_up(card) elif self._validate(args, str): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) @@ -426,8 +429,21 @@ def do_activate(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_deactivate(self, command, *args, context=None): - if self._validate(args, str): - self.card_ports_down(args, context, command) + if context['iftype'] == 'vlanif': + raise exceptions.CommandSyntaxError(command=command) + card = context['component'] + if self._validate(args, 'all'): + self.card_ports_down(card) + elif self._validate(args, str): + port_identifier, = self._dissect(args, str) + try: + portname = card.name + '/' + port_identifier + port = self._model.get_port("name", portname) + + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + port.admin_down() else: raise exceptions.CommandSyntaxError(command=command) @@ -476,8 +492,21 @@ def do_vectoring_config(self, command, *args, context=None): # TODO: Functional raise exceptions.CommandSyntaxError(command=command) def do_shutdown(self, command, *args, context=None): - if self._validate(args, str): - self.card_ports_down(args, context, command) + if context['iftype'] == 'vlanif': + raise exceptions.CommandSyntaxError(command=command) + card = context['component'] + if self._validate(args, 'all'): + self.card_ports_down(card) + elif self._validate(args, str): + port_identifier, = self._dissect(args, str) + try: + portname = card.name + '/' + port_identifier + port = self._model.get_port("name", portname) + + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + port.admin_down() else: raise exceptions.CommandSyntaxError(command=command) @@ -610,24 +639,19 @@ def do_undo(self, command, *args, context=None): vlan_if.set('subnet_num', None) else: raise exceptions.CommandSyntaxError(command=command) - else: - raise exceptions.CommandSyntaxError(command=command) - - def card_ports_down(self, args, context, command): - card = context['component'] - if context['iftype'] == 'vlanif': - raise exceptions.CommandSyntaxError(command=command) - port_identifier, = self._dissect( - args, str) + elif self._validate(args, 'shutdown', 'all'): + if context['iftype'] == 'vlanif': + raise exceptions.CommandSyntaxError(command=command) - if port_identifier == 'all': - ports = self._model.get_ports('card_id', card.id) - if not ports: + card = context['component'] + self.card_ports_up(card) + elif self._validate(args, 'shutdown', str): + if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) - for port in ports: - port.admin_down() - else: + port_identifier, = self._dissect(args, 'shutdown', str) + card = context['component'] + try: portname = card.name + '/' + port_identifier port = self._model.get_port("name", portname) @@ -635,6 +659,20 @@ def card_ports_down(self, args, context, command): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - port.admin_down() + port.admin_up() + else: + raise exceptions.CommandSyntaxError(command=command) + def card_ports_down(self, card): + ports = self._model.get_ports('card_id', card.id) + if not ports: + raise exceptions.CommandSyntaxError() + for port in ports: + port.admin_down() + def card_ports_up(self, card): + ports = self._model.get_ports('card_id', card.id) + if not ports: + raise exceptions.CommandSyntaxError() + for port in ports: + port.admin_up() From b4b0afd80fe9333e733514f72a09939722cd6975 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Mon, 14 Sep 2020 11:34:56 +0200 Subject: [PATCH 040/318] various adjustments --- bootup/conf/bootstraps/create-huawei-5623.sh | 1 + nesi/huawei/api/schemas/huawei_box_schemas.py | 2 +- nesi/huawei/huawei_resources/huawei_box.py | 5 ++++ .../huawei_resources/huawei_ont_port.py | 12 ++++---- nesi/softbox/api/models/box_models.py | 2 ++ .../softbox/api/models/service_port_models.py | 4 +-- .../diagnose/switch_dsl_mode_failure.j2 | 2 ++ .../enable/diagnose/switch_dsl_mode_temp_1.j2 | 5 ++++ .../Base/Huawei_Base/baseCommandProcessor.py | 2 +- .../Huawei_Base/diagnoseCommandProcessor.py | 29 ++++++++++++++----- .../Huawei_Base/interfaceCommandProcessor.py | 10 +++---- 11 files changed, 51 insertions(+), 23 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_failure.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_1.j2 diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 4daea4a..4f3153e 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -97,6 +97,7 @@ req='{ "network_protocol": "telnet", "network_address": "127.0.0.1", "network_port": 9023, + "dsl_mode": "tr165", "uuid": "5623" }' diff --git a/nesi/huawei/api/schemas/huawei_box_schemas.py b/nesi/huawei/api/schemas/huawei_box_schemas.py index 06cddcd..057504b 100644 --- a/nesi/huawei/api/schemas/huawei_box_schemas.py +++ b/nesi/huawei/api/schemas/huawei_box_schemas.py @@ -17,7 +17,7 @@ class HuaweiBoxSchema(BoxSchema): class Meta: model = Box fields = BoxSchema.Meta.fields + ('cpu_occupancy', 'vlan_interfaces', 'raio_anid', 'handshake_mode', - 'handshake_interval', 'interactive_mode', 'pitp', 'pitp_mode') + 'handshake_interval', 'interactive_mode', 'pitp', 'pitp_mode', 'dsl_mode') vlan_interfaces = ma.Hyperlinks( {'_links': { diff --git a/nesi/huawei/huawei_resources/huawei_box.py b/nesi/huawei/huawei_resources/huawei_box.py index 5069322..4e0e097 100644 --- a/nesi/huawei/huawei_resources/huawei_box.py +++ b/nesi/huawei/huawei_resources/huawei_box.py @@ -32,6 +32,7 @@ class HuaweiBox(Box): interactive_mode = base.Field('interactive_mode') pitp = base.Field('pitp') pitp_mode = base.Field('pitp_mode') + dsl_mode = base.Field('dsl_mode') @property def credentials(self): @@ -404,6 +405,10 @@ def enable_interactive(self): """Enable Interactive function.""" self.update(interactive_mode=True) + def set_dsl_mode(self, mode): + """Change the dsl mode of a box""" + self.update(dsl_mode=mode) + def set_pitp(self, state): """Change the pitp of a box""" diff --git a/nesi/huawei/huawei_resources/huawei_ont_port.py b/nesi/huawei/huawei_resources/huawei_ont_port.py index bd26ea7..fb55c4c 100644 --- a/nesi/huawei/huawei_resources/huawei_ont_port.py +++ b/nesi/huawei/huawei_resources/huawei_ont_port.py @@ -47,13 +47,13 @@ class HuaweiOntPort(OntPort): max_mac_count = base.Field('max_mac_count') vlan_id = base.Field('vlan_id') - def operational_state_down(self): - """Change ont port operational state to down.""" - self.update(operational_state='0') + def down(self): + """Change ont port admin state to down.""" + self.update(admin_state='0') - def operational_state_up(self): - """Change ont port operational state to up.""" - self.update(operational_state='1') + def up(self): + """Change ont port admin state to up.""" + self.update(admin_state='1') class HuaweiOntPortCollection(OntPortCollection): diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 5bfe4f5..1a796f5 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -106,3 +106,5 @@ class Box(db.Model): interactive_mode = db.Column(db.Boolean(), default=True) pitp = db.Column(db.Enum('enable', 'disable'), default='disable') pitp_mode = db.Column(db.String(), default='') + dsl_mode = db.Column(db.Enum('tr165', 'tr129'), default='tr165') + diff --git a/nesi/softbox/api/models/service_port_models.py b/nesi/softbox/api/models/service_port_models.py index 14d3dd7..328dac7 100644 --- a/nesi/softbox/api/models/service_port_models.py +++ b/nesi/softbox/api/models/service_port_models.py @@ -5,8 +5,8 @@ class ServicePort(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) - admin_state = db.Column(db.Enum('0', '1', '2'), default='0') # Alcatel: 0 => down, 1 => up, 2 => not-appl; Huawei: 0 => disable, 1 => enable - operational_state = db.Column(db.Enum('0', '1'), default='0') # Alcatel: 0 => down, 1 => up; Huawei: 0 => disable, 1 => enable + admin_state = db.Column(db.Enum('0', '1', '2'), default='0') # Alcatel: 0 => down, 1 => up, 2 => not-appl; Huawei: 0 => down, 1 => up + operational_state = db.Column(db.Enum('0', '1'), default='0') # Alcatel: 0 => down, 1 => up; Huawei: 0 => down, 1 => up connected_id = db.Column(db.Integer(), nullable=False) connected_type = db.Column(db.Enum('port', 'ont', 'cpe'), nullable=False) diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_failure.j2 b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_failure.j2 new file mode 100644 index 0000000..74b9212 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_failure.j2 @@ -0,0 +1,2 @@ + Failure: The current mode is already the configured mode + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_1.j2 b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_1.j2 new file mode 100644 index 0000000..4f3b895 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_1.j2 @@ -0,0 +1,5 @@ + + + Command: + switch vdsl mode to {{ context.dsl_mode }} + diff --git a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py index 3a60b5a..ef6ab82 100644 --- a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py @@ -59,7 +59,7 @@ def map_states(self, object, type): elif type == 'port': object.operational_state = 'activated' elif type == 'service_port': - object.operational_state = 'disable' + object.operational_state = 'up' elif type in ('ont', 'ont_port'): object.operational_state = 'online' elif object.operational_state == '2': diff --git a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py index 8831ca0..cc117ef 100644 --- a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py @@ -112,16 +112,29 @@ def do_switch(self, command, *args, context=None): # TODO: Functionality raise exceptions.CommandSyntaxError(command=command) dsl_mode, = self._dissect(args, 'vdsl', 'mode', 'to', str) - if dsl_mode != 'timode' and dsl_mode != 'tr129' and dsl_mode != 'tr165': + context['dsl_mode'] = dsl_mode + if dsl_mode != 'tr129' and dsl_mode != 'tr165': raise exceptions.CommandSyntaxError(command=command) - aone = self.user_input('Please enter y if you want to continue: ') - if aone != 'y': - raise exceptions.CommandSyntaxError(command=command) - atwo = self.user_input('Please enter y again to confirm: ') - if atwo != 'y': - raise exceptions.CommandSyntaxError(command=command) + self.user_input('{ |adsl }:', False) + + text = self._render('switch_dsl_mode_temp_1', context=context) + self._write(text) + + if self._model.dsl_mode == dsl_mode: + text = self._render('switch_dsl_mode_failure', context=context) + self._write(text) + return + + answer_one = self.user_input('Warning: The operation will result in loss of all VDSL configuration. ' + 'Are you sure to proceed? (y/n)[n]:', False) + if answer_one != 'y': + return + answer_two = self.user_input('Please enter y again to confirm:', False) + if answer_two != 'y': + return + + self._model.set_dsl_mode(dsl_mode) - return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index 0bfd9e1..7cdc6d4 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -518,7 +518,7 @@ def do_ont(self, command, *args, context=None): 'ont-srvprofile-id', str, 'desc', str) card = context['component'] # create ont - '''port = self._model.get_port('name', card.name + '/' + port_idx) + port = self._model.get_port('name', card.name + '/' + port_idx) try: self._model.get_ont('name', card.name + '/' + port_idx + '/' + ont_idx) raise exceptions.CommandSyntaxError(command=command) @@ -536,11 +536,11 @@ def do_ont(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) ont_port = self._model.add_ont_port(ont_id=ont.id) if ont_port is None: - raise exceptions.CommandSyntaxError(command=command)''' + raise exceptions.CommandSyntaxError(command=command) elif self._validate(args, 'delete', str, str): # delete all subcomponents - #TODO: delelte service_ports + service_vlans + # TODO: delete service_ports + service_vlans port_idx, ont_idx = self._dissect(args, 'delete', str, str) card = context['component'] try: @@ -586,9 +586,9 @@ def do_ont(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) if state == 'on': - ont_port.operational_state_up() + ont_port.up() elif state == 'off': - ont_port.operational_state_down() + ont_port.down() else: raise exceptions.CommandSyntaxError(command=command) From 1afea714cec93a9e5f995a6d8c082dcde6174b3a Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Mon, 14 Sep 2020 14:12:41 +0200 Subject: [PATCH 041/318] Finished implementing the possibility to switch btwenn two dsl modes --- .../enable/diagnose/switch_dsl_mode_temp_2.j2 | 4 +++ .../Huawei_Base/diagnoseCommandProcessor.py | 17 ++++++++-- .../Huawei_Base/interfaceCommandProcessor.py | 34 ++++++++++++++----- 3 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_2.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_2.j2 b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_2.j2 new file mode 100644 index 0000000..2c43fa1 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_2.j2 @@ -0,0 +1,4 @@ + It will take several minutes, please wait... + The data is being saved, please wait a moment... + + diff --git a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py index cc117ef..2098f8e 100644 --- a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py @@ -10,11 +10,12 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst from datetime import datetime - from nesi import exceptions from .baseCommandProcessor import BaseCommandProcessor from .baseMixIn import BaseMixIn +import time + class DiagnoseCommandProcessor(BaseCommandProcessor, BaseMixIn): @@ -126,15 +127,25 @@ def do_switch(self, command, *args, context=None): # TODO: Functionality self._write(text) return - answer_one = self.user_input('Warning: The operation will result in loss of all VDSL configuration. ' + answer_one = self.user_input(' Warning: The operation will result in loss of all VDSL configuration. ' 'Are you sure to proceed? (y/n)[n]:', False) if answer_one != 'y': return - answer_two = self.user_input('Please enter y again to confirm:', False) + answer_two = self.user_input(' Warning: The operation will automatically save and reboot system. ' + 'Are you sure you want to proceed? (y/n)[n]:', False) if answer_two != 'y': return + text = self._render('switch_dsl_mode_temp_2', context=context) + self._write(text) self._model.set_dsl_mode(dsl_mode) + time.sleep(10) + self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) + user = self._model.get_user('status', 'Online') + user.set_offline() + exc = exceptions.TerminalExitError() + exc.return_to = 'sysreboot' + raise exc else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index 7cdc6d4..ffbf060 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -296,16 +296,19 @@ def do_activate(self, command, *args, context=None): if self._validate(args, str, 'prof-desc', 'ds-rate', str, 'us-rate', str): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) + if self._model.dsl_mode == 'tr129': + raise exceptions.CommandSyntaxError(command=command) if card.product == 'vdsl': port_idx, ds_rate, us_rate, = self._dissect( args, str, 'prof-desc', 'ds-rate', str, 'us-rate', str) try: - port = self._model.get_port("name", port_idx) - port.port_downstream_set(ds_rate) - port.port_upstream_set(us_rate) + port_name = card.name + '/' + port_idx + port = self._model.get_port("name", port_name) + port.port_downstream_set(int(ds_rate)) + port.port_upstream_set(int(us_rate)) - except exceptions.SoftboxenError: + except (exceptions.SoftboxenError, ValueError): raise exceptions.CommandSyntaxError(command=command) if port.downstream_max != int(ds_rate) and port.upstream_max != int(us_rate): @@ -319,13 +322,16 @@ def do_activate(self, command, *args, context=None): # TODO: Brackets mean optional parameters, so make them optional... if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) + if self._model.dsl_mode == 'tr129': + raise exceptions.CommandSyntaxError(command=command) if card.product == 'vdsl': port_idx, ds_rate, us_rate = self._dissect(args, str, 'prof.desc', 'ds-rate', str, 'us-rate', str, 'noise-margin', 'VDSL_6db', 'inp-delay', 'VDSL_(FAST)', '(spectrum str)', '(dpbo DPBO:str)') try: - _ = self._model.get_port("name", port_idx) + port_name = card.name + '/' + port_idx + port = self._model.get_port("name", port_name) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -340,13 +346,16 @@ def do_activate(self, command, *args, context=None): # TODO: Brackets mean optional parameters, so make them optional... if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) + if self._model.dsl_mode == 'tr129': + raise exceptions.CommandSyntaxError(command=command) if card.product == 'vdsl': port_idx, ds_rate, us_rate = self._dissect(args, str, 'prof.desc', 'ds-rate', str, 'us-rate', str, 'noise-margin', 'ADSL_6db', 'inp-delay', 'ADSL_(FAST)', '(spectrum str)', '(dpbo DPBO:str)') try: - _ = self._model.get_port("name", port_idx) + port_name = card.name + '/' + port_idx + port = self._model.get_port("name", port_name) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -361,13 +370,16 @@ def do_activate(self, command, *args, context=None): # TODO: Brackets mean optional parameters, so make them optional... if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) + if self._model.dsl_mode == 'tr129': + raise exceptions.CommandSyntaxError(command=command) if card.product == 'vdsl': port_idx, ds_rate, us_rate = self._dissect(args, str, 'prof.desc', 'ds-rate', str, 'us-rate', str, 'noise-margin', 'ADSL_6db', 'inp-delay', 'ADSL', '(spectrum str)', '(dpbo DPBO:str)') try: - _ = self._model.get_port("name", port_idx) + port_name = card.name + '/' + port_idx + port = self._model.get_port("name", port_name) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -380,12 +392,15 @@ def do_activate(self, command, *args, context=None): elif self._validate(args, str, 'template-name', str): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) + if self._model.dsl_mode == 'tr165': + raise exceptions.CommandSyntaxError(command=command) if card.product == 'adsl': # TODO: Template looks like this: {huawei_downstream}_{huawei_downstream}_ADSL port_idx, template_name = self._dissect(args, str, 'template-name', str) try: - _ = self._model.get_port("name", port_idx) + port_name = card.name + '/' + port_idx + port = self._model.get_port("name", port_name) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -397,7 +412,8 @@ def do_activate(self, command, *args, context=None): port_idx, template_name = self._dissect(args, str, 'template-name', str) try: - _ = self._model.get_port("name", port_idx) + port_name = card.name + '/' + port_idx + port = self._model.get_port("name", port_name) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) From e83960f3ba50f236d71ab60331eefb8f1962afb8 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Mon, 14 Sep 2020 15:56:37 +0200 Subject: [PATCH 042/318] Additions to include Service ports/vlans when deleting ONTs --- .../Huawei_Base/interfaceCommandProcessor.py | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index ffbf060..c19b6c4 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -556,7 +556,6 @@ def do_ont(self, command, *args, context=None): elif self._validate(args, 'delete', str, str): # delete all subcomponents - # TODO: delete service_ports + service_vlans port_idx, ont_idx = self._dissect(args, 'delete', str, str) card = context['component'] try: @@ -574,11 +573,37 @@ def do_ont(self, command, *args, context=None): if len(cpe_ports) != 0: for cpe_port_coll in cpe_ports: for cpe_port in cpe_port_coll: + while True: + params = dict(connected_type='cpe', connected_id=cpe_port.id) + service_port = self._model.get_service_port_by_values(params) + if service_port is None: + break + try: + service_vlan = self._model.get_service_vlan('service_port_id', + service_port.id) + except exceptions.SoftboxenError: + pass + else: + service_vlan.delete() + service_port.delete() cpe_port.delete() for cpe_coll in cpes: for cpe in cpe_coll: cpe.delete() for ont_port in ont_ports: + while True: + params = dict(connected_type='ont', connected_id=ont_port.id) + service_port = self._model.get_service_port_by_values(params) + if service_port is None: + break + else: + try: + service_vlan = self._model.get_service_vlan('service_port_id', service_port.id) + except exceptions.SoftboxenError: + pass + else: + service_vlan.delete() + service_port.delete() ont_port.delete() ont.delete() except exceptions.SoftboxenError: From d8bab039a0923526b23fc279b34e621d2ad272a7 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 15 Sep 2020 11:28:53 +0200 Subject: [PATCH 043/318] added new configure DSL commands and fixed small issues --- .../api/schemas/huawei_ontport_schemas.py | 2 +- nesi/huawei/api/schemas/huawei_port_schemas.py | 4 ++-- nesi/huawei/huawei_resources/huawei_ont_port.py | 2 +- nesi/huawei/huawei_resources/huawei_port.py | 5 ++++- nesi/softbox/api/models/port_models.py | 2 +- ...duct_port_state_num_card_port_deactivated.j2 | 3 ++- test_cases/unit_tests/huawei/test_huawei.py | 10 +++++----- .../Base/Huawei_Base/configCommandProcessor.py | 17 ++++++++++------- .../Base/Huawei_Base/enableCommandProcessor.py | 2 +- 9 files changed, 27 insertions(+), 20 deletions(-) diff --git a/nesi/huawei/api/schemas/huawei_ontport_schemas.py b/nesi/huawei/api/schemas/huawei_ontport_schemas.py index 4b8de6b..8bb884b 100644 --- a/nesi/huawei/api/schemas/huawei_ontport_schemas.py +++ b/nesi/huawei/api/schemas/huawei_ontport_schemas.py @@ -21,4 +21,4 @@ class Meta: 'outbound', 'downstream_mode', 'mismatch_policy', 'dscp_mapping_table_index', 'service_type', 'service_index', 's_vlan', 's_pri', 'c_vlan', 'c_pri', 'encap', 's_pri_policy', 'igmp_mode', - 'igmp_vlan', 'igmp_pri', 'max_mac_count', 'vlan_id', 'operational_state') + 'igmp_vlan', 'igmp_pri', 'max_mac_count', 'vlan_id', 'admin_state') diff --git a/nesi/huawei/api/schemas/huawei_port_schemas.py b/nesi/huawei/api/schemas/huawei_port_schemas.py index 3e73125..77a70cc 100644 --- a/nesi/huawei/api/schemas/huawei_port_schemas.py +++ b/nesi/huawei/api/schemas/huawei_port_schemas.py @@ -33,7 +33,7 @@ class Meta: 'channel_ds_data_rate_profile', 'channel_ds_data_rate_profile_num', 'channel_us_data_rate_profile', 'channel_us_data_rate_profile_num', 'channel_inp_delay_profile', 'channel_inp_data_rate_profile_num', - 'channel_ds_rate_adapt_ratio', 'channel_us_rate_adapt_ratio', 'group_id', + 'channel_ds_rate_adapt_ratio', 'channel_us_rate_adapt_ratio', 'current_power_management_state', 'retransmission_used_us', 'retransmission_used_ds', 'signal_attenuation_ds_1', 'signal_attenuation_us_1', 'line_attenuation_ds_1', @@ -74,4 +74,4 @@ class Meta: 'auto_sensing', 'alm_prof_15_min', 'warn_prof_15_min', 'alm_prof_24_hour', 'warn_prof_24_hour', 'optic_status', 'combo_status', 'temperature_h_exact', 'supply_voltage_h_exact', 'tx_bias_current_h_exact', 'tx_power_h_exact', - 'rx_power_h_exact', 'vlan_id', 'rx_power_h') + 'rx_power_h_exact', 'vlan_id', 'rx_power_h', 'vectoring_group') diff --git a/nesi/huawei/huawei_resources/huawei_ont_port.py b/nesi/huawei/huawei_resources/huawei_ont_port.py index fb55c4c..0c362d7 100644 --- a/nesi/huawei/huawei_resources/huawei_ont_port.py +++ b/nesi/huawei/huawei_resources/huawei_ont_port.py @@ -18,7 +18,7 @@ class HuaweiOntPort(OntPort): """Represent physical ONT port resource.""" - operational_state = base.Field('operational_state') + admin_state = base.Field('admin_state') ont_port_index = base.Field('ont_port_index') ont_port_type = base.Field('ont_port_type') speed = base.Field('speed') diff --git a/nesi/huawei/huawei_resources/huawei_port.py b/nesi/huawei/huawei_resources/huawei_port.py index 8923b4b..a98153c 100644 --- a/nesi/huawei/huawei_resources/huawei_port.py +++ b/nesi/huawei/huawei_resources/huawei_port.py @@ -71,7 +71,6 @@ class HuaweiPort(Port): channel_inp_data_rate_profile_num = base.Field('channel_inp_data_rate_profile_num') channel_ds_rate_adapt_ratio = base.Field('channel_ds_rate_adapt_ratio') channel_us_rate_adapt_ratio = base.Field('channel_us_rate_adapt_ratio') - group_id = base.Field('group_id') standard_port_in_training = base.Field('standard_port_in_training') current_power_management_state = base.Field('current_power_management_state') retransmission_used_us = base.Field('retransmission_used_us') @@ -204,6 +203,7 @@ class HuaweiPort(Port): rx_power_h_exact = base.Field('rx_power_h_exact') rx_power_h = base.Field('rx_power_h') vlan_id = base.Field('vlan_id') + vectoring_group = base.Field('vectoring_group') def admin_up(self): self.update(admin_state='2') @@ -220,6 +220,9 @@ def port_upstream_set(self, us_rate): def set_vlan_id(self, id): self.update(vlan_id=id) + def set_vectoring_group(self, group): + self.update(vectoring_group=group) + class HuaweiPortCollection(PortCollection): """Represent a collection of ports.""" diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 5127402..4df3ec7 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -170,7 +170,6 @@ class Port(db.Model): channel_inp_data_rate_profile_num = db.Column(db.Integer(), nullable=True, default=None) channel_ds_rate_adapt_ratio = db.Column(db.Integer(), nullable=True, default=None) channel_us_rate_adapt_ratio = db.Column(db.Integer(), nullable=True, default=None) - group_id = db.Column(db.String(), default='-') standard_port_in_training = db.Column(db.String(), default='G.993.2-Annex B') current_power_management_state = db.Column(db.String(), default='Full-on state') retransmission_used_us = db.Column(db.String(), default='Unused, retransmission mode is forbidden') @@ -302,3 +301,4 @@ class Port(db.Model): warn_prof_24_hour = db.Column(db.String(), default='-') combo_status = db.Column(db.Enum('-', 'optic', 'electric'), default='optic') vlan_id = db.Column(db.Integer()) + vectoring_group = db.Column(db.Integer(), default=None) diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_product_port_state_num_card_port_deactivated.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_product_port_state_num_card_port_deactivated.j2 index ba3d2d2..dc5fd19 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/display_product_port_state_num_card_port_deactivated.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_product_port_state_num_card_port_deactivated.j2 @@ -1,6 +1,7 @@ ------------------------------------------------------------------------------ Port Status Loopback Line Template Alarm Template Group ID ------------------------------------------------------------------------------ - {{ context.portname}}{{ context.spacer1 }}{{ context.port.admin_state }}{{ context.spacer2 }}{{ context.port.loopback }}{{ context.spacer3 }}{{ context.port.line_template_num }}{{ context.spacer4 }}{{ context.port.alarm_template_num }}{{ context.spacer5 }}{{ context.port.group_id }} + {{ context.portname}}{{ context.spacer1 }}{{ context.port.admin_state }}{{ context.spacer2 }}{{ context.port.loopback }}{{ context.spacer3 }}{{ context.port.line_template_num }}{{ context.spacer4 }}{{ context.port.alarm_template_num }}{{ context.spacer5 }}{% if context.port.vectoring_group != None %}{{ context.port.vectoring_group }}{% else %}-{% endif %} + ------------------------------------------------------------------------------ diff --git a/test_cases/unit_tests/huawei/test_huawei.py b/test_cases/unit_tests/huawei/test_huawei.py index 7cf2dfb..0789401 100644 --- a/test_cases/unit_tests/huawei/test_huawei.py +++ b/test_cases/unit_tests/huawei/test_huawei.py @@ -27,7 +27,7 @@ def test_portup_portdown(self): port.admin_down() assert(self.model.get_port("name", '0/0/0').admin_state == '0') port.admin_up() - assert(self.model.get_port("name", '0/0/0').admin_state == '1') + assert(self.model.get_port("name", '0/0/0').admin_state == '2') port.up() assert port.operational_state == '1' port.down() @@ -75,10 +75,10 @@ def test_ont_fields(self): def test_ont_ports(self): port = self.model.get_ont_port("name", '0/2/0/0/1') - port.operational_state_up() - assert (port.operational_state == '1') - port.operational_state_down() - assert (port.operational_state == '0') + port.up() + assert (port.admin_state == '1') + port.down() + assert (port.admin_state == '0') def test_port_profiles(self): port = self.model.get_port_profile("name", "PPPoE") diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 2dfd7a1..eb5a1b9 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -999,26 +999,29 @@ def do_deactivate(self, command, *args, context=None): # TODO: Functionality raise exceptions.CommandSyntaxError(command=command) def do_xdsl(self, command, *args, context=None): - if self._validate(args, 'vectoring-group', 'link', 'add', str, str): # TODO: Functionality + if self._validate(args, 'vectoring-group', 'link', 'add', str, str): profile_idx, port_idx = self._dissect(args, 'vectoring-group', 'link', 'add', str, str) + print(port_idx) portname = port_idx[0:3] + '/' + port_idx[4] try: - _ = self._model.get_port("name", portname) + port = self._model.get_port("name", portname) + port.set_vectoring_group(int(profile_idx)) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) return - elif self._validate(args, 'vectoring-group', 'link', 'delete', str, str): # TODO: Functionality + elif self._validate(args, 'vectoring-group', 'link', 'delete', str, str): profile_idx, port_idx = self._dissect(args, 'vectoring-group', 'link', 'delete', str, str) - portname = port_idx[0:3] + '/' + port_idx[4] - + portname = str(port_idx[0:3] + '/' + port_idx[4]) try: - _ = self._model.get_port("name", portname) + port = self._model.get_port("name", portname) + assert int(port.vectoring_group) == int(profile_idx) + port.set_vectoring_group(None) - except exceptions.SoftboxenError: + except (exceptions.SoftboxenError, AssertionError): raise exceptions.CommandSyntaxError(command=command) return diff --git a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py index a76538d..08cfc1d 100644 --- a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py @@ -148,7 +148,7 @@ def do_display(self, command, *args, context=None): context['channelname'] = channelname text = '' - if port.admin_state == '1': + if port.admin_state == 'activated': context['spacer1'] = self.create_spacers((7,), (portname,))[0] * ' ' context['spacer2'] = self.create_spacers((15,), (port.admin_state,))[0] * ' ' context['spacer3'] = self.create_spacers((25,), (port.loopback,))[0] * ' ' From a92f99a92017d4f09bb6928379d63a3978776a4e Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 15 Sep 2020 13:47:49 +0200 Subject: [PATCH 044/318] Added functionality for 'port ont-auto-find enable/disable' command and corrected behaviour of 'display ont autofind all' command --- bootup/conf/bootstraps/create-huawei-5623.sh | 2 -- nesi/huawei/api/schemas/huawei_ont_schemas.py | 2 +- .../huawei/api/schemas/huawei_port_schemas.py | 2 +- nesi/huawei/huawei_resources/huawei_ont.py | 1 - nesi/huawei/huawei_resources/huawei_port.py | 7 +++++++ nesi/softbox/api/models/ont_models.py | 1 - nesi/softbox/api/models/port_models.py | 1 + ...operation_not_supported_by_port_failure.j2 | 2 ++ .../Huawei_Base/configCommandProcessor.py | 12 ++++++++--- .../Huawei_Base/interfaceCommandProcessor.py | 21 +++++++++++++++++++ 10 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/interface/operation_not_supported_by_port_failure.j2 diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 4f3153e..1861e6f 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -482,7 +482,6 @@ req='{ "operational_state": "1", "admin_state": "1", "index": 0, - "autofind": true, "vendor_id": "HWTC", "version": "535.B", "software_version": "V3R025C29D195" @@ -622,7 +621,6 @@ req='{ "operational_state": "1", "admin_state": "1", "index": 0, - "autofind": true, "vendor_id": "HWTC", "version": "535.B", "software_version": "V3R025C29D195" diff --git a/nesi/huawei/api/schemas/huawei_ont_schemas.py b/nesi/huawei/api/schemas/huawei_ont_schemas.py index a74af69..ddc671e 100644 --- a/nesi/huawei/api/schemas/huawei_ont_schemas.py +++ b/nesi/huawei/api/schemas/huawei_ont_schemas.py @@ -25,5 +25,5 @@ class Meta: 'interoperability_mode', 'power_reduction_status', 'fec_upstream_state', 'port_number_pots', 'max_adaptive_num_pots', 'port_number_eth', 'max_adaptive_num_eth', 'port_number_vdsl', 'max_adaptive_num_vdsl', - 'lineprofile_id', 'srvprofile_id', 'index', 'autofind', 'version', + 'lineprofile_id', 'srvprofile_id', 'index', 'version', 'software_version', 'vendor_id') diff --git a/nesi/huawei/api/schemas/huawei_port_schemas.py b/nesi/huawei/api/schemas/huawei_port_schemas.py index 77a70cc..3e24fd4 100644 --- a/nesi/huawei/api/schemas/huawei_port_schemas.py +++ b/nesi/huawei/api/schemas/huawei_port_schemas.py @@ -74,4 +74,4 @@ class Meta: 'auto_sensing', 'alm_prof_15_min', 'warn_prof_15_min', 'alm_prof_24_hour', 'warn_prof_24_hour', 'optic_status', 'combo_status', 'temperature_h_exact', 'supply_voltage_h_exact', 'tx_bias_current_h_exact', 'tx_power_h_exact', - 'rx_power_h_exact', 'vlan_id', 'rx_power_h', 'vectoring_group') + 'rx_power_h_exact', 'vlan_id', 'rx_power_h', 'vectoring_group', 'ont_autofind') diff --git a/nesi/huawei/huawei_resources/huawei_ont.py b/nesi/huawei/huawei_resources/huawei_ont.py index 3e91322..880dba2 100644 --- a/nesi/huawei/huawei_resources/huawei_ont.py +++ b/nesi/huawei/huawei_resources/huawei_ont.py @@ -51,7 +51,6 @@ class HuaweiOnt(Ont): max_adaptive_num_vdsl = base.Field('max_adaptive_num_vdsl') lineprofile_id = base.Field('lineprofile_id') srvprofile_id = base.Field('srvprofile_id') - autofind = base.Field('autofind') version = base.Field('version') vendor_id = base.Field('vendor_id') software_version = base.Field('software_version') diff --git a/nesi/huawei/huawei_resources/huawei_port.py b/nesi/huawei/huawei_resources/huawei_port.py index a98153c..b26efc5 100644 --- a/nesi/huawei/huawei_resources/huawei_port.py +++ b/nesi/huawei/huawei_resources/huawei_port.py @@ -204,6 +204,7 @@ class HuaweiPort(Port): rx_power_h = base.Field('rx_power_h') vlan_id = base.Field('vlan_id') vectoring_group = base.Field('vectoring_group') + ont_autofind = base.Field('ont_autofind') def admin_up(self): self.update(admin_state='2') @@ -223,6 +224,12 @@ def set_vlan_id(self, id): def set_vectoring_group(self, group): self.update(vectoring_group=group) + def enable_ont_autofind(self): + self.update(ont_autofind=True) + + def disable_ont_autofind(self): + self.update(ont_autofind=False) + class HuaweiPortCollection(PortCollection): """Represent a collection of ports.""" diff --git a/nesi/softbox/api/models/ont_models.py b/nesi/softbox/api/models/ont_models.py index 3cf8afb..523137b 100644 --- a/nesi/softbox/api/models/ont_models.py +++ b/nesi/softbox/api/models/ont_models.py @@ -150,6 +150,5 @@ class Ont(db.Model): max_adaptive_num_vdsl = db.Column(db.String(), default='-') lineprofile_id = db.Column(db.Integer(), nullable=True) srvprofile_id = db.Column(db.Integer(), nullable=True) - autofind = db.Column(db.Boolean(), default=False) software_version = db.Column(db.String(), default=None) diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 4df3ec7..a3c46de 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -122,6 +122,7 @@ class Port(db.Model): egress_port = db.Column(db.Boolean(), default=False) # Huawei data + ont_autofind = db.Column(db.Boolean(), default=False) loopback = db.Column(db.Enum('enable', 'disable'), default='disable') dynamic_profile = db.Column(db.Enum('Bind no dynamic-profile', ''), default='') dynamic_profile_index = db.Column(db.String(), default='-') diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/operation_not_supported_by_port_failure.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/operation_not_supported_by_port_failure.j2 new file mode 100644 index 0000000..fe32796 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/operation_not_supported_by_port_failure.j2 @@ -0,0 +1,2 @@ + Failure: The port of this type does not support this operation + diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index eb5a1b9..c6b45d2 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -128,9 +128,11 @@ def do_display(self, command, *args, context=None): elif self._validate(args, 'ont', 'autofind', 'all'): autofind_onts = [] - for ont in self._model.onts: - if ont.autofind: - autofind_onts.append(ont) + for port in self._model.ports: + if port.ont_autofind: + onts = self._model.get_onts('port_id', port.id) + for ont in onts: + autofind_onts.append(ont) for autofind_ont in autofind_onts: port = self._model.get_port('id', autofind_ont.port_id) @@ -138,6 +140,10 @@ def do_display(self, command, *args, context=None): context['ont'] = autofind_ont self._write(self._render('display_ont_autofind_all_body', context=context)) + if len(autofind_onts) == 0: + self._write(self._render('display_ont_autofind_all_failure', context=context)) + return + context['autofind_count'] = len(autofind_onts) self._write(self._render('display_ont_autofind_all_footer', context=context)) elif self._validate(args, 'ont', 'info', 'summary', str): diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index c19b6c4..945222a 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -636,6 +636,27 @@ def do_ont(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_port(self, command, *args, context=None): + if context['iftype'] == 'vlanif': + raise exceptions.CommandSyntaxError(command=command) + card = context['component'] + if card.product != 'ftth-pon': + self._write(self._render('operation_not_supported_by_port_failure', context=context)) + return + if self._validate(args, str, 'ont-auto-find', str): + port_identifier, mode = self._dissect(args, str, 'ont-auto-find', str) + + port = self._model.get_port('name', card.name + "/" + port_identifier) + + if mode == 'enable': + port.enable_ont_autofind() + elif mode == 'disable': + port.disable_ont_autofind() + else: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def do_ip(self, command, *args, context=None): if self._validate(args, 'address', str, str): ip, subnet_mask = self._dissect(args, 'address', str, str) From ae93d7b98375ef3805caab79a2bc121dbe6382eb Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Tue, 15 Sep 2020 16:10:48 +0200 Subject: [PATCH 045/318] Introduced the concept of management cards to Huawei --- bootup/conf/bootstraps/create-alcatel-7360.sh | 3 +- bootup/conf/bootstraps/create-huawei-5623.sh | 120 +++++++- nesi/softbox/api/models/card_models.py | 2 +- nesi/softbox/api/models/port_models.py | 2 +- .../display_board_mgnt_bottom_bottom.j2 | 4 + .../enable/display_board_mgnt_bottom_mid.j2 | 2 + .../enable/display_board_mgnt_bottom_top.j2 | 5 + .../display_board_mgnt_failed_bottom.j2 | 2 + .../enable/display_board_mgnt_failed_mid.j2 | 2 + .../enable/display_board_mgnt_failed_top.j2 | 4 + .../enable/display_board_mgnt_header.j2 | 6 + .../enable/display_board_mgnt_top_bottom.j2 | 2 + .../enable/display_board_mgnt_top_mid.j2 | 2 + .../enable/display_board_mgnt_top_top.j2 | 5 + .../Huawei_Base/configCommandProcessor.py | 3 + .../Huawei_Base/huaweiBaseCommandProcessor.py | 278 +++++++++++------- 16 files changed, 333 insertions(+), 109 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_mid.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_mid.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_header.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_mid.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_top.j2 diff --git a/bootup/conf/bootstraps/create-alcatel-7360.sh b/bootup/conf/bootstraps/create-alcatel-7360.sh index e01beac..04f9320 100755 --- a/bootup/conf/bootstraps/create-alcatel-7360.sh +++ b/bootup/conf/bootstraps/create-alcatel-7360.sh @@ -380,7 +380,8 @@ req='{ "mgnt_entity_oamipaddr": "0.0.0.0", "mgnt_entity_pairnum": 0, "dual_host_ip": "0.0.0.0", - "dual_host_loc": "none" + "dual_host_loc": "none", + "product": "mgnt" }' card_nt_a=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 1861e6f..b30657f 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -751,6 +751,29 @@ req='{ ont_port_0_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +### Serviceport 0/3/0/1/1 ### + +req='{ + "name": "0/3/0/1/1", + "connected_id": '$ont_port_0_3_0_1_1', + "connected_type": "ont", + "admin_state": "1", + "operational_state": "1" +}' + +service_port_0_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) + +### Service PPPoE Vlan at ServicePort 0/3/0/1/1 ### + +req='{ + "name": "2620", + "service_port_id": '$service_port_0_3_0_1_1', + "vlan_id": '$vlan_pppoe', + "card_id": '$card_0_3' +}' + +service_vlan_0_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlans) + ### Cpe 0/3/0 1/1 1 ### # Create a physical cpe at the ont-port (admin operation) @@ -773,6 +796,29 @@ req='{ cpe_port_0_3_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +### Serviceport 0/3/0/1/1/1/1 ### + +req='{ + "name": "0/3/0/1/1/1/1", + "connected_id": '$cpe_port_0_3_0_1_1_1_1', + "connected_type": "cpe", + "admin_state": "1", + "operational_state": "1" +}' + +service_port_0_3_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) + +### Service PPPoE Vlan at ServicePort 0/3/0/1/1/1/1 ### + +req='{ + "name": "2620", + "service_port_id": '$service_port_0_3_0_1_1_1_1', + "vlan_id": '$vlan_pppoe', + "card_id": '$card_0_3' +}' + +service_vlan_0_3_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlans) + ### OntPort 0/3/0 1/2 ### # Create a physical ont-port at the ont (admin operation) @@ -1001,4 +1047,76 @@ req='{ "ont_port_type": "ETH" }' -ont_port_0_4_2_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) \ No newline at end of file +ont_port_0_4_2_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) + +### Management Card 0/6 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_0', + "name": "0/6", + "description": "Physical card 0/6", + "product": "mgnt", + "board_name": "HS22CCVW", + "board_status": "Active_normal" +}' + +card_0_6=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### PORT 0/6/0 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card_0_6', + "description": "Physical port 0/6/0", + "loopback": "disable", + "upstream": 10000, + "downstream": 25000, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "1", + "operational_state": "1", + "combo_status": "-", + "optic_status": "normal", + "mdi": "-", + "speed_h": "auto_1000", + "duplex": "auto_full", + "flow_ctrl": "off", + "active_state": "active", + "link": "online", + "alm_prof_15_min" : "-", + "warn_prof_15_min": "-", + "alm_prof_24_hour": "-", + "warn_prof_24_hour": "-" +}' + +port_0_6_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### PORT 0/6/1 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card_0_6', + "description": "Physical port 0/6/1", + "loopback": "disable", + "upstream": 10000, + "downstream": 25000, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "1", + "operational_state": "1", + "combo_status": "-", + "optic_status": "normal", + "mdi": "-", + "speed_h": "auto_1000", + "duplex": "auto_full", + "flow_ctrl": "off", + "active_state": "active", + "link": "online", + "alm_prof_15_min" : "-", + "warn_prof_15_min": "-", + "alm_prof_24_hour": "-", + "warn_prof_24_hour": "-" +}' + +port_0_6_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index a7d2188..c132fb4 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -22,7 +22,7 @@ class Card(db.Model): subrack_id = db.Column(db.Integer, db.ForeignKey('subrack.id')) ports = db.relationship('Port', backref='Card', lazy='dynamic') ppc = db.Column(db.Enum('8', '16', '32', '48', '64'), default='32') - product = db.Column(db.Enum('xdsl', 'vdsl', 'adsl', 'sdsl', 'ftth-pon', 'ftth'), + product = db.Column(db.Enum('xdsl', 'vdsl', 'adsl', 'sdsl', 'ftth-pon', 'ftth', 'mgnt'), nullable=False, default='vdsl') # Alcatel specific data diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index a3c46de..51a34f2 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -285,7 +285,7 @@ class Port(db.Model): optic_status = db.Column(db.Enum('normal', 'absence'), default='normal') native_vlan = db.Column(db.String(), default='-') mdi = db.Column(db.String(), default='-') - speed_h = db.Column(db.Enum('100', '1000', '10000', '100000', 'auto_1000'), default='1000') + speed_h = db.Column(db.Enum('100', '1000', '10000', '100000', 'auto_1000', 'auto'), default='1000') duplex = db.Column(db.Enum('full', 'auto_full', 'auto'), default='full') flow_ctrl = db.Column(db.Enum('on', 'off'), default='off') active_state = db.Column(db.Enum('active', 'deactive'), default='deactive') diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_bottom.j2 new file mode 100644 index 0000000..608008f --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_bottom.j2 @@ -0,0 +1,4 @@ + ------------------------------------------------------------------------------ + Note: For a 1000 M, electrical port in the full-duplex mode, setting MDI to + any value is invalid + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_mid.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_mid.j2 new file mode 100644 index 0000000..78ed071 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_mid.j2 @@ -0,0 +1,2 @@ +{{ context.spacer1 }}{{ context.port_num }}{{ context.spacer2 }}{{ context.port.alm_prof_15_min }}{{ context.spacer3 }}{{ context.port.warn_prof_15_min }}{{ context.spacer4 }}{{ context.port.alm_prof_24_hour }}{{ context.spacer5 }}{{ context.port.warn_prof_24_hour }} + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_top.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_top.j2 new file mode 100644 index 0000000..1be72b8 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_top.j2 @@ -0,0 +1,5 @@ + ------------------------------------------------------------------------------ + Port 15Min 15Min 24Hour 24Hour + AlmProf WarnProf AlmProf WarnProf + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_bottom.j2 new file mode 100644 index 0000000..26647c9 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_bottom.j2 @@ -0,0 +1,2 @@ + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_mid.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_mid.j2 new file mode 100644 index 0000000..53807c2 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_mid.j2 @@ -0,0 +1,2 @@ +{{ context.spacer1 }}{{ context.port_num }}{{ context.spacer2 }}{{ context.port_type }}{{ context.spacer3 }}{{ context.link_down }} + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_top.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_top.j2 new file mode 100644 index 0000000..6a7f30a --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_top.j2 @@ -0,0 +1,4 @@ + ------------------------------------------------------------------------------ + Port Port Type Link State + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_header.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_header.j2 new file mode 100644 index 0000000..091e699 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_header.j2 @@ -0,0 +1,6 @@ + --------------------------------------- + Board Name : {{ context.card.board_name }} + Board Status : {{ context.card.board_status }} + --------------------------------------- + + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_bottom.j2 new file mode 100644 index 0000000..26647c9 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_bottom.j2 @@ -0,0 +1,2 @@ + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_mid.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_mid.j2 new file mode 100644 index 0000000..655cda8 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_mid.j2 @@ -0,0 +1,2 @@ +{{ context.spacer1 }}{{ context.port_num }}{{ context.spacer2 }}{{ context.port_type }}{{ context.spacer3 }}{{ context.port.combo_status }}{{ context.spacer4 }}{{ context.port.optic_status }}{{ context.spacer5 }}{{ context.port.mdi }}{{ context.spacer6 }}{{ context.port.speed_h }}{{ context.spacer7 }}{{ context.port.duplex }}{{ context.spacer8 }}{{ context.port.flow_ctrl }}{{ context.spacer9 }}{{ context.port.active_state }}{{ context.spacer10 }}{{ context.port.link }} + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_top.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_top.j2 new file mode 100644 index 0000000..8f37485 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_top.j2 @@ -0,0 +1,5 @@ + ------------------------------------------------------------------------------ + Port Port COMBO Optic MDI Speed Duplex Flow- Active Link + Type Mode Status (Mbps) Ctrl State + ------------------------------------------------------------------------------ + diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index c6b45d2..a67a41f 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -988,6 +988,9 @@ def do_port(self, command, *args, context=None): trafficvlan, cardident, portid = self._dissect(args, 'vlan', str, str, str) portident = cardident + '/' + portid try: + card = self._model.get_card('name', cardident) + if card.product != 'mgnt': + raise exceptions.CommandSyntaxError(command=command) port = self._model.get_port("name", portident) vlan = self._model.get_vlan("number", int(trafficvlan)) except exceptions.SoftboxenError: diff --git a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py index 6d23d0c..4e63e48 100644 --- a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py @@ -61,50 +61,49 @@ def display_board(self, command, args, context=None): for port in ports: self.map_states(port, 'port') - if card.id == port.card_id: - if port.admin_state == 'activated': - activated_count += 1 - _, _, portname = port.name.split('/') - context['portname'] = portname - if card.product == 'vdsl': - porttype = 'VDSL' - else: - porttype = 'ADSL' - context['porttype'] = porttype - context['spacer_beg1'] = self.create_spacers((6,), (portname,))[0] * ' ' - context['spacer1'] = self.create_spacers((7,), (porttype,))[0] * ' ' - context['spacer2'] = self.create_spacers((3,), ('',))[0] * ' ' - context['spacer3'] = self.create_spacers( - (25,), (port.admin_state + str(port.alarm_template_num),))[0] * ' ' - context['spacer4'] = self.create_spacers((13,), (port.spectrum_profile_num,))[0] * ' ' - context['spacer5'] = self.create_spacers((13,), (port.upbo_profile_num,))[0] * ' ' - text1 += self._render('display_board_dsl_product_top_middle', - context=dict(context, port=port)) - port_counter += 1 - - context['spacer_beg2'] = self.create_spacers((6,), (portname,))[0] * ' ' - context['spacer6'] = self.create_spacers((11,), (port.sos_profile_num,))[0] * ' ' - context['spacer7'] = self.create_spacers((11,), (port.dpbo_profile_num,))[0] * ' ' - context['spacer8'] = self.create_spacers((13,), (port.rfi_profile_num,))[0] * ' ' - context['spacer9'] = self.create_spacers((13,), (port.noise_margin_profile_num,))[0] * ' ' - context['spacer10'] = self.create_spacers((13,), (port.virtual_noise_profile_num,))[0] * ' ' - context['spacer11'] = self.create_spacers((13,), (port.inm_profile_num,))[0] * ' ' - text2 += self._render('display_board_dsl_product_middle_middle', context=dict(context, - port=port)) - - channelname = portname + '.1' - context['channelname'] = channelname - context['spacer_beg3'] = self.create_spacers((7,), (channelname,))[0] * ' ' - context['spacer12'] = self.create_spacers((21,), - (port.channel_ds_data_rate_profile_num,))[0] * ' ' - context['spacer13'] = self.create_spacers((13,), - (port.channel_us_data_rate_profile_num,))[0] * ' ' - context['spacer14'] = self.create_spacers((13,), - (port.channel_inp_data_rate_profile_num,))[0] * ' ' - context['spacer15'] = self.create_spacers((13,), (port.channel_ds_rate_adapt_ratio,))[0] * ' ' - context['spacer16'] = self.create_spacers((13,), (port.channel_us_rate_adapt_ratio,))[0] * ' ' - text3 += self._render('display_board_dsl_product_bottom_middle', context=dict(context, - port=port)) + if port.admin_state == 'activated': + activated_count += 1 + _, _, portname = port.name.split('/') + context['portname'] = portname + if card.product == 'vdsl': + porttype = 'VDSL' + else: + porttype = 'ADSL' + context['porttype'] = porttype + context['spacer_beg1'] = self.create_spacers((6,), (portname,))[0] * ' ' + context['spacer1'] = self.create_spacers((7,), (porttype,))[0] * ' ' + context['spacer2'] = self.create_spacers((3,), ('',))[0] * ' ' + context['spacer3'] = self.create_spacers( + (25,), (port.admin_state + str(port.alarm_template_num),))[0] * ' ' + context['spacer4'] = self.create_spacers((13,), (port.spectrum_profile_num,))[0] * ' ' + context['spacer5'] = self.create_spacers((13,), (port.upbo_profile_num,))[0] * ' ' + text1 += self._render('display_board_dsl_product_top_middle', + context=dict(context, port=port)) + port_counter += 1 + + context['spacer_beg2'] = self.create_spacers((6,), (portname,))[0] * ' ' + context['spacer6'] = self.create_spacers((11,), (port.sos_profile_num,))[0] * ' ' + context['spacer7'] = self.create_spacers((11,), (port.dpbo_profile_num,))[0] * ' ' + context['spacer8'] = self.create_spacers((13,), (port.rfi_profile_num,))[0] * ' ' + context['spacer9'] = self.create_spacers((13,), (port.noise_margin_profile_num,))[0] * ' ' + context['spacer10'] = self.create_spacers((13,), (port.virtual_noise_profile_num,))[0] * ' ' + context['spacer11'] = self.create_spacers((13,), (port.inm_profile_num,))[0] * ' ' + text2 += self._render('display_board_dsl_product_middle_middle', context=dict(context, + port=port)) + + channelname = portname + '.1' + context['channelname'] = channelname + context['spacer_beg3'] = self.create_spacers((7,), (channelname,))[0] * ' ' + context['spacer12'] = self.create_spacers((21,), + (port.channel_ds_data_rate_profile_num,))[0] * ' ' + context['spacer13'] = self.create_spacers((13,), + (port.channel_us_data_rate_profile_num,))[0] * ' ' + context['spacer14'] = self.create_spacers((13,), + (port.channel_inp_data_rate_profile_num,))[0] * ' ' + context['spacer15'] = self.create_spacers((13,), (port.channel_ds_rate_adapt_ratio,))[0] * ' ' + context['spacer16'] = self.create_spacers((13,), (port.channel_us_rate_adapt_ratio,))[0] * ' ' + text3 += self._render('display_board_dsl_product_bottom_middle', context=dict(context, + port=port)) context['activated_count'] = activated_count context['port_counter'] = port_counter - activated_count @@ -129,68 +128,67 @@ def display_board(self, command, args, context=None): ports = self._model.get_ports('card_id', card.id) for port in ports: - if card.id == port.card_id: - _, _, portname = port.name.split('/') - context['portname'] = portname - porttype = 'GPON' - context['porttype'] = porttype - context['spacer_beg1'] = self.create_spacers((5,), (portname,))[0] * ' ' - context['spacer3'] = self.create_spacers((9,), (porttype,))[0] * ' ' - context['spacer4'] = self.create_spacers((9,), (port.min_distance,))[0] * ' ' - context['spacer5'] = self.create_spacers((16,), (port.max_distance,))[0] * ' ' - context['spacer6'] = self.create_spacers((19,), (port.optical_module_status,))[0] * ' ' - text1 += self._render('display_board_ftth_pon_top_middle', context=dict(context, port=port)) - - onts = self._model.get_onts('port_id', port.id) - - ontcounter = 0 - onlinecounter = 0 + _, _, portname = port.name.split('/') + context['portname'] = portname + porttype = 'GPON' + context['porttype'] = porttype + context['spacer_beg1'] = self.create_spacers((5,), (portname,))[0] * ' ' + context['spacer3'] = self.create_spacers((9,), (porttype,))[0] * ' ' + context['spacer4'] = self.create_spacers((9,), (port.min_distance,))[0] * ' ' + context['spacer5'] = self.create_spacers((16,), (port.max_distance,))[0] * ' ' + context['spacer6'] = self.create_spacers((19,), (port.optical_module_status,))[0] * ' ' + text1 += self._render('display_board_ftth_pon_top_middle', context=dict(context, port=port)) + + onts = self._model.get_onts('port_id', port.id) + + ontcounter = 0 + onlinecounter = 0 + for ont in onts: + if ont.port_id == port.id: + ontcounter += 1 + if ont.admin_state == '1': + onlinecounter += 1 + + subrackname, cardportname = port.name.split('/', maxsplit=1) + subrackname = subrackname + '/' + context['subrackname'] = subrackname + context['cardportname'] = cardportname + context['ontcounter'] = ontcounter + context['onlinecounter'] = onlinecounter + + if not onts: + text2 += self._render('display_board_ftth_pon_ont_summary', context=context) + + else: + text2 += self._render('display_board_ftth_pon_middle_top', context=context) for ont in onts: - if ont.port_id == port.id: - ontcounter += 1 - if ont.admin_state == '1': - onlinecounter += 1 - - subrackname, cardportname = port.name.split('/', maxsplit=1) - subrackname = subrackname + '/' - context['subrackname'] = subrackname - context['cardportname'] = cardportname - context['ontcounter'] = ontcounter - context['onlinecounter'] = onlinecounter - - if not onts: + self.map_states(ont, 'ont') + context['ont_id'] = ont.index + context['spacer_beg2'] = self.create_spacers((4,), (subrackname,))[0] * ' ' + context['spacer7'] = self.create_spacers((4,), (cardportname,))[0] * ' ' + context['spacer8'] = self.create_spacers((5,), (ont.index,))[0] * ' ' + context['spacer9'] = self.create_spacers((18,), (ont.serial_number,))[0] * ' ' + context['spacer10'] = self.create_spacers((8,), (ont.control_flag,))[0] * ' ' + context['spacer11'] = self.create_spacers((12,), (ont.admin_state,))[0] * ' ' + context['spacer12'] = self.create_spacers((9,), (ont.config_state,))[0] * ' ' + context['spacer13'] = self.create_spacers((8,), (ont.match_state,))[0] * ' ' + context['spacer14'] = self.create_spacers((4,), ('',))[0] * ' ' + + text2 += self._render('display_board_ftth_pon_middle_middle', + context=dict(context, ont=ont)) + + text2 += self._render('display_board_ftth_pon_bottom_top', context=context) + context['ont_id'] = ont.index + context['spacer_beg3'] = self.create_spacers((4,), (subrackname,))[0] * ' ' + context['spacer15'] = self.create_spacers((4,), (cardportname,))[0] * ' ' + context['spacer16'] = self.create_spacers((8,), (ont.index,))[0] * ' ' + context['spacer17'] = self.create_spacers((3,), ('',))[0] * ' ' + text2 += self._render('display_board_ftth_pon_bottom_middle', + context=dict(context, ont=ont)) + + text2 += self._render('display_board_ftth_pon_bottom_bottom', context=context) text2 += self._render('display_board_ftth_pon_ont_summary', context=context) - else: - text2 += self._render('display_board_ftth_pon_middle_top', context=context) - for ont in onts: - self.map_states(ont, 'ont') - context['ont_id'] = ont.index - context['spacer_beg2'] = self.create_spacers((4,), (subrackname,))[0] * ' ' - context['spacer7'] = self.create_spacers((4,), (cardportname,))[0] * ' ' - context['spacer8'] = self.create_spacers((5,), (ont.index,))[0] * ' ' - context['spacer9'] = self.create_spacers((18,), (ont.serial_number,))[0] * ' ' - context['spacer10'] = self.create_spacers((8,), (ont.control_flag,))[0] * ' ' - context['spacer11'] = self.create_spacers((12,), (ont.admin_state,))[0] * ' ' - context['spacer12'] = self.create_spacers((9,), (ont.config_state,))[0] * ' ' - context['spacer13'] = self.create_spacers((8,), (ont.match_state,))[0] * ' ' - context['spacer14'] = self.create_spacers((4,), ('',))[0] * ' ' - - text2 += self._render('display_board_ftth_pon_middle_middle', - context=dict(context, ont=ont)) - - text2 += self._render('display_board_ftth_pon_bottom_top', context=context) - context['ont_id'] = ont.index - context['spacer_beg3'] = self.create_spacers((4,), (subrackname,))[0] * ' ' - context['spacer15'] = self.create_spacers((4,), (cardportname,))[0] * ' ' - context['spacer16'] = self.create_spacers((8,), (ont.index,))[0] * ' ' - context['spacer17'] = self.create_spacers((3,), ('',))[0] * ' ' - text2 += self._render('display_board_ftth_pon_bottom_middle', - context=dict(context, ont=ont)) - - text2 += self._render('display_board_ftth_pon_bottom_bottom', context=context) - text2 += self._render('display_board_ftth_pon_ont_summary', context=context) - text1 += self._render('display_board_ftth_pon_top_bottom', context=context) text1 += text2 @@ -218,7 +216,7 @@ def display_board(self, command, args, context=None): ports = self._model.get_ports('card_id', card.id) for port in ports: - if port.card_id == card.id and port.link != 'failed': + if port.link != 'failed': _, _, portname = port.name.split('/') context['portname'] = portname porttype = '' @@ -309,7 +307,7 @@ def display_board(self, command, args, context=None): ports = self._model.get_ports('card_id', card.id) for port in ports: - if port.card_id == card.id and port.link != 'failed': + if port.link != 'failed': _, _, portname = port.name.split('/') porttype = '' if port.speed_h == '1000': @@ -373,6 +371,76 @@ def display_board(self, command, args, context=None): self._write(text_header) + elif card.product == 'mgnt': + text_header = self._render('display_board_mgnt_header', context=dict(context, card=card)) + text_top = '' + text_bottom = '' + text_failed = '' + + text_top += self._render('display_board_mgnt_top_top', context=context) + text_bottom += self._render('display_board_mgnt_bottom_top', context=context) + ports = self._model.get_ports('card_id', card.id) + for port in ports: + if port.link == 'failed': + text_failed += self._render('display_board_mgnt_failed_top', context=context) + + _, _, port_num = port.name.split('/') + context['port_num'] = port_num + port_type = 'AUTO' + context['port_type'] = port_type + link_down = 'DOWN' + context['link_down'] = link_down + + context['spacer1'] = self.create_spacers((6,), (port_num,))[0] * ' ' + context['spacer2'] = self.create_spacers((2,), ('',))[0] * ' ' + context['spacer3'] = self.create_spacers((17,), (port_type,))[0] * ' ' + text_failed += self._render('display_board_mgnt_failed_mid', context=dict(context, port=port)) + + text_failed += self._render('display_board_mgnt_failed_bottom', context=context) + + else: + port_type = 'GE' + _, _, port_num = port.name.split('/') + context['port_num'] = port_num + context['port_type'] = port_type + + context['spacer1'] = self.create_spacers((5,), ('',))[0] * ' ' + context['spacer2'] = self.create_spacers((2,), (port_num,))[0] * ' ' + context['spacer3'] = self.create_spacers((5,), (port_type,))[0] * ' ' + context['spacer4'] = self.create_spacers((9,), (port.combo_status,))[0] * ' ' + context['spacer5'] = self.create_spacers((9,), (port.optic_status,))[0] * ' ' + context['spacer6'] = self.create_spacers((7,), (port.mdi,))[0] * ' ' + context['spacer7'] = self.create_spacers((11,), (port.speed_h,))[0] * ' ' + context['spacer8'] = self.create_spacers((10,), (port.duplex,))[0] * ' ' + context['spacer9'] = self.create_spacers((6,), (port.flow_ctrl,))[0] * ' ' + context['spacer10'] = self.create_spacers((9,), (port.active_state,))[0] * ' ' + text_top += self._render('display_board_mgnt_top_mid', context=dict(context, port=port)) + + context['spacer1'] = self.create_spacers((6,), (port_num,))[0] * ' ' + context['spacer2'] = self.create_spacers((9,), (port.alm_prof_15_min,))[0] * ' ' + context['spacer3'] = self.create_spacers((9,), (port.warn_prof_15_min,))[0] * ' ' + context['spacer4'] = self.create_spacers((8,), (port.alm_prof_24_hour,))[0] * ' ' + context['spacer5'] = self.create_spacers((9,), (port.warn_prof_24_hour,))[0] * ' ' + text_bottom += self._render('display_board_mgnt_bottom_mid', context=dict(context, port=port)) + + text_top += self._render('display_board_mgnt_top_bottom', context=context) + text_bottom += self._render('display_board_mgnt_bottom_bottom', context=context) + + try: + port_name_0 = card.name + '/0' + port_0 = self._model.get_port('name', port_name_0) + port_name_1 = card.name + '/1' + port_1 = self._model.get_port('name', port_name_1) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + if port_0.link == 'failed': + text = text_header + text_failed + text_top + text_bottom + elif port_1.link == 'failed': + text = text_header + text_top + text_bottom + text_failed + else: + text = text_header + text_top + text_bottom + self._write(text) else: raise exceptions.CommandSyntaxError(command=command) return From 49b4b0d5cfd0fcbf2320e6d1a1626c8a01ea966f Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 16 Sep 2020 07:48:07 +0200 Subject: [PATCH 046/318] added new configure DSL commands and added new badge --- README.md | 6 +- .../huawei/api/schemas/huawei_port_schemas.py | 3 +- nesi/huawei/huawei_resources/huawei_port.py | 12 +++ nesi/softbox/api/models/port_models.py | 54 +++++----- .../Huawei_Base/interfaceCommandProcessor.py | 102 ++++++++++++------ 5 files changed, 117 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index 1d40107..094d204 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ [![GitHub license](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/inexio/NESi/master/LICENSE.rst) [![GitHub build](https://img.shields.io/github/workflow/status/inexio/NESi/api_build/master?label=build)]() +[![GitHub build](https://img.shields.io/github/v/tag/inexio/NESi?label=Release)](https://github.com/inexio/NESi) + The `NESi` project which originated from [`softboxen`](https://github.com/etingof/softboxen), a project originally created by our @@ -31,9 +33,9 @@ For more information on `softboxen` or `NESi` please refer to our local [documen ### Supported Vendors - Alcatel (nearly feature complete) - - Huawei (work in progress) + - Huawei (nearly feature complete)(work in progress) - Edgecore (not implemented yet) - - Keymile (not implemented yet) + - Keymile (work in progress) - Pbn (not implemented yet) - Zhone (not implemented yet) diff --git a/nesi/huawei/api/schemas/huawei_port_schemas.py b/nesi/huawei/api/schemas/huawei_port_schemas.py index 3e24fd4..c56dbb4 100644 --- a/nesi/huawei/api/schemas/huawei_port_schemas.py +++ b/nesi/huawei/api/schemas/huawei_port_schemas.py @@ -74,4 +74,5 @@ class Meta: 'auto_sensing', 'alm_prof_15_min', 'warn_prof_15_min', 'alm_prof_24_hour', 'warn_prof_24_hour', 'optic_status', 'combo_status', 'temperature_h_exact', 'supply_voltage_h_exact', 'tx_bias_current_h_exact', 'tx_power_h_exact', - 'rx_power_h_exact', 'vlan_id', 'rx_power_h', 'vectoring_group', 'ont_autofind') + 'rx_power_h_exact', 'vlan_id', 'rx_power_h', 'vectoring_group', + 'vectoring_profile_id', 'template_name', 'ont_autofind') diff --git a/nesi/huawei/huawei_resources/huawei_port.py b/nesi/huawei/huawei_resources/huawei_port.py index b26efc5..5cc3db1 100644 --- a/nesi/huawei/huawei_resources/huawei_port.py +++ b/nesi/huawei/huawei_resources/huawei_port.py @@ -204,7 +204,9 @@ class HuaweiPort(Port): rx_power_h = base.Field('rx_power_h') vlan_id = base.Field('vlan_id') vectoring_group = base.Field('vectoring_group') + vectoring_profile_id = base.Field('vectoring_profile_id') ont_autofind = base.Field('ont_autofind') + template_name = base.Field('template_name') def admin_up(self): self.update(admin_state='2') @@ -230,6 +232,16 @@ def enable_ont_autofind(self): def disable_ont_autofind(self): self.update(ont_autofind=False) + def set_template_name(self, template): + self.update(template_name=template) + + def set_vectoring_profile_id(self, id): + self.update(vectoring_profile_id=id) + + def set(self, field, value): + mapping = {field: value} + self.update(**mapping) + class HuaweiPortCollection(PortCollection): """Represent a collection of ports.""" diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 51a34f2..0aa33bd 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -127,26 +127,26 @@ class Port(db.Model): dynamic_profile = db.Column(db.Enum('Bind no dynamic-profile', ''), default='') dynamic_profile_index = db.Column(db.String(), default='-') dynamic_profile_name = db.Column(db.String(), default='-') - line_template = db.Column(db.Enum('No.72 SMART_5000_UP_1000_1', ''), default='') - line_template_num = db.Column(db.Integer(), nullable=True, default=82) + line_template = db.Column(db.String(), default='') + line_template_num = db.Column(db.String(), nullable=True, default='-') alarm_template = db.Column(db.String(), default='No.1 DEFVAL') alarm_template_num = db.Column(db.Integer(), nullable=False, default=1) - line_spectrum_profile = db.Column(db.Enum('No.1000 ADSL2plus', 'No.1001 VDSL', ''), default='') - spectrum_profile_num = db.Column(db.Integer(), nullable=True, default=None) - upbo_profile = db.Column(db.Enum('No.1 DEFVAL', ''), default='') - upbo_profile_num = db.Column(db.Integer(), nullable=True, default=None) - dpbo_profile = db.Column(db.Enum('No.1080 DPBO_80', ''), default='') - dpbo_profile_num = db.Column(db.Integer(), nullable=True, default=None) - rfi_profile = db.Column(db.Enum('No.1 DEFVAL', ''), default='') - rfi_profile_num = db.Column(db.Integer(), nullable=True, default=None) - noise_margin_profile = db.Column(db.Enum('No.1000 ADSL_6dB', ''), default='') - noise_margin_profile_num = db.Column(db.Integer(), nullable=True, default=None) - virtual_noise_profile = db.Column(db.Enum('No.1 DEFVAL', ''), default='') - virtual_noise_profile_num = db.Column(db.Integer(), nullable=True, default=None) - inm_profile = db.Column(db.Enum('No.1 DEFVAL', ''), default='') - inm_profile_num = db.Column(db.Integer(), nullable=True, default=None) - sos_profile = db.Column(db.Enum('No.1 DEFVAL', ''), default='No.1 DEFVAL') - sos_profile_num = db.Column(db.Integer(), nullable=True, default=1) + line_spectrum_profile = db.Column(db.String(), default='') + spectrum_profile_num = db.Column(db.String(), nullable=True, default='-') + upbo_profile = db.Column(db.String(), default='') + upbo_profile_num = db.Column(db.String(), nullable=True, default='-') + dpbo_profile = db.Column(db.String(), default='') + dpbo_profile_num = db.Column(db.String(), nullable=True, default='-') + rfi_profile = db.Column(db.String(), default='') + rfi_profile_num = db.Column(db.String(), nullable=True, default='-') + noise_margin_profile = db.Column(db.String(), default='') + noise_margin_profile_num = db.Column(db.String(), nullable=True, default='-') + virtual_noise_profile = db.Column(db.String(), default='') + virtual_noise_profile_num = db.Column(db.String(), nullable=True, default='-') + inm_profile = db.Column(db.String(), default='') + inm_profile_num = db.Column(db.String(), nullable=True, default='-') + sos_profile = db.Column(db.String(), default='') + sos_profile_num = db.Column(db.String(), nullable=True, default='-') hardware = db.Column(db.Enum('XTU-C', 'ATU-C'), default='XTU-C') last_up_time = db.Column(db.String(), default='2019-09-17 11:46:10+01:00') last_down_time = db.Column(db.String(), default='2019-09-17 11:45:24+01:00') @@ -163,14 +163,14 @@ class Port(db.Model): total_discarded_packets_ds = db.Column(db.Integer(), default=0) channel_packets_discarded_ds = db.Column(db.Integer(), default=0) - channel_ds_data_rate_profile = db.Column(db.Enum('No.1016 TEST_DSL_16000', ''), default='') - channel_ds_data_rate_profile_num = db.Column(db.Integer(), nullable=True, default=None) - channel_us_data_rate_profile = db.Column(db.Enum('No.2001 UP_1000', ''), default='') - channel_us_data_rate_profile_num = db.Column(db.Integer(), nullable=True, default=None) - channel_inp_delay_profile = db.Column(db.Enum('No.1000 ADSL', ''), default='') - channel_inp_data_rate_profile_num = db.Column(db.Integer(), nullable=True, default=None) - channel_ds_rate_adapt_ratio = db.Column(db.Integer(), nullable=True, default=None) - channel_us_rate_adapt_ratio = db.Column(db.Integer(), nullable=True, default=None) + channel_ds_data_rate_profile = db.Column(db.String(), default='') + channel_ds_data_rate_profile_num = db.Column(db.String(), nullable=True, default='-') + channel_us_data_rate_profile = db.Column(db.String(), default='') + channel_us_data_rate_profile_num = db.Column(db.String(), nullable=True, default='-') + channel_inp_delay_profile = db.Column(db.String(), default='') + channel_inp_data_rate_profile_num = db.Column(db.String(), nullable=True, default='-') + channel_ds_rate_adapt_ratio = db.Column(db.String(), nullable=True, default='-') + channel_us_rate_adapt_ratio = db.Column(db.String(), nullable=True, default='-') standard_port_in_training = db.Column(db.String(), default='G.993.2-Annex B') current_power_management_state = db.Column(db.String(), default='Full-on state') retransmission_used_us = db.Column(db.String(), default='Unused, retransmission mode is forbidden') @@ -303,3 +303,5 @@ class Port(db.Model): combo_status = db.Column(db.Enum('-', 'optic', 'electric'), default='optic') vlan_id = db.Column(db.Integer()) vectoring_group = db.Column(db.Integer(), default=None) + vectoring_profile_id = db.Column(db.Integer(), default=None) + template_name = db.Column(db.String(), default=None) diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index 945222a..f00e295 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -364,27 +364,78 @@ def do_activate(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - - elif self._validate(args, str, 'prof.desc', 'ds-rate', str, 'us-rate', str, 'noise-margin', 'ADSL_6db', - 'inp-delay', 'ADSL', '(spectrum str)', '(dpbo DPBO:str)'): - # TODO: Brackets mean optional parameters, so make them optional... + elif self._validate(args[:6], str, 'prof-desc', 'ds-rate', str, 'us-rate', str): + #elif self._validate(args, str, 'prof.desc', 'ds-rate', str, 'us-rate', str, '(spectrum str)', 'noise-margin', 'ADSL_6db', 'inp-delay', 'ADSL','(dpbo DPBO:str)'): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) if self._model.dsl_mode == 'tr129': raise exceptions.CommandSyntaxError(command=command) if card.product == 'vdsl': - port_idx, ds_rate, us_rate = self._dissect(args, str, 'prof.desc', 'ds-rate', str, 'us-rate', str, - 'noise-margin', 'ADSL_6db', 'inp-delay', 'ADSL', - '(spectrum str)', '(dpbo DPBO:str)') + port_idx, ds_rate, us_rate = self._dissect(args[:6], str, 'prof-desc', 'ds-rate', str, 'us-rate', str) try: port_name = card.name + '/' + port_idx port = self._model.get_port("name", port_name) - except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - return + i = 6 + while i < len(args): + if args[i] == 'spectrum': + spectrum = args[i+1] + i += 2 + try: + profile = self._model.get_port_profile('description', spectrum) + spectrum_profile = 'No. ' + profile.id + ' ' + spectrum + spectrum_id = profile.id + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + elif args[i] == 'noise-margin': + noise = args[i+1] + i += 2 + try: + profile = self._model.get_port_profile('description', noise) + noise_profile = 'No. ' + profile.id + ' ' + noise + noise_id = profile.id + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + elif args[i] == 'inp-delay': + inp = args[i+1] + i += 2 + try: + profile = self._model.get_port_profile('description', inp) + inp_profile = 'No. ' + profile.id + ' ' + inp + inp_id = profile.id + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + elif args[i] == 'dpbo': + dpbo = args[i+1] + i += 2 + try: + profile = self._model.get_port_profile('description', dpbo) + dpbo_profile = 'No. ' + profile.id + ' ' + dpbo + dpbo_id = profile.id + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + else: + raise exceptions.CommandSyntaxError(command=command) + + try: + port.admin_up() + port.set('downstream_max', int(ds_rate)) + port.set('upstream_max', int(us_rate)) + port.set('line_spectrum_profile', spectrum_profile) + port.set('spectrum_profile_num', int(spectrum_id)) + port.set('noise_margin_profile', noise_profile) + port.set('noise_margin_profile_num', int(noise_id)) + port.set('line_spectrum_profile', inp_profile) + port.set('spectrum_profile_num', int(inp_id)) + port.set('line_spectrum_profile', dpbo_profile) + port.set('spectrum_profile_num', int(dpbo_id)) + + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) else: raise exceptions.CommandSyntaxError(command=command) @@ -394,32 +445,20 @@ def do_activate(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) if self._model.dsl_mode == 'tr165': raise exceptions.CommandSyntaxError(command=command) - if card.product == 'adsl': - # TODO: Template looks like this: {huawei_downstream}_{huawei_downstream}_ADSL + if card.product == 'adsl' or card.product == 'vdsl': + #Template looks like this: {huawei_downstream}_{huawei_downstream}_ADSL + #Template looks like this: {huawei_downstream}_{huawei_downstream}_{summary} vdsl port_idx, template_name = self._dissect(args, str, 'template-name', str) try: port_name = card.name + '/' + port_idx port = self._model.get_port("name", port_name) + port.admin_up() + port.set_template_name(template_name) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - return - - elif card.product == 'vdsl': - # TODO: Template looks like this: {huawei_downstream}_{huawei_downstream}_{summary} - port_idx, template_name = self._dissect(args, str, 'template-name', str) - - try: - port_name = card.name + '/' + port_idx - port = self._model.get_port("name", port_name) - - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError(command=command) - - return - else: raise exceptions.CommandSyntaxError(command=command) elif self._validate(args, 'all'): @@ -490,20 +529,21 @@ def on_unknown_command(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def do_vectoring_config(self, command, *args, context=None): # TODO: Functionality + def do_vectoring_config(self, command, *args, context=None): card = context['component'] if self._validate(args, str, 'profile-index', str): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) - port_idx, profile_idx = self._dissect(args, str, 'profile-index', str) + port_identifier, profile_idx = self._dissect(args, str, 'profile-index', str) try: - _ = self._model.get_port("name", port_idx) + portname = card.name + '/' + port_identifier + port = self._model.get_port("name", portname) + self._model.get_port_profile('id', int(profile_idx)) + port.set_vectoring_profile_id(int(profile_idx)) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - return - else: raise exceptions.CommandSyntaxError(command=command) From 5e0794a725897665558e9f83200ec4b14b230079 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Wed, 16 Sep 2020 08:15:05 +0200 Subject: [PATCH 047/318] Added missing templates --- .../1/login/mainloop/display_board_mgnt_bottom_bottom.j2 | 4 ++++ .../Base/1/login/mainloop/display_board_mgnt_bottom_mid.j2 | 2 ++ .../Base/1/login/mainloop/display_board_mgnt_bottom_top.j2 | 5 +++++ .../1/login/mainloop/display_board_mgnt_failed_bottom.j2 | 2 ++ .../Base/1/login/mainloop/display_board_mgnt_failed_mid.j2 | 2 ++ .../Base/1/login/mainloop/display_board_mgnt_failed_top.j2 | 4 ++++ .../Base/1/login/mainloop/display_board_mgnt_header.j2 | 6 ++++++ .../Base/1/login/mainloop/display_board_mgnt_top_bottom.j2 | 2 ++ .../Base/1/login/mainloop/display_board_mgnt_top_mid.j2 | 2 ++ .../Base/1/login/mainloop/display_board_mgnt_top_top.j2 | 5 +++++ .../enable/config/display_board_mgnt_bottom_bottom.j2 | 4 ++++ .../mainloop/enable/config/display_board_mgnt_bottom_mid.j2 | 2 ++ .../mainloop/enable/config/display_board_mgnt_bottom_top.j2 | 5 +++++ .../enable/config/display_board_mgnt_failed_bottom.j2 | 2 ++ .../mainloop/enable/config/display_board_mgnt_failed_mid.j2 | 2 ++ .../mainloop/enable/config/display_board_mgnt_failed_top.j2 | 4 ++++ .../mainloop/enable/config/display_board_mgnt_header.j2 | 6 ++++++ .../mainloop/enable/config/display_board_mgnt_top_bottom.j2 | 2 ++ .../mainloop/enable/config/display_board_mgnt_top_mid.j2 | 2 ++ .../mainloop/enable/config/display_board_mgnt_top_top.j2 | 5 +++++ 20 files changed, 68 insertions(+) create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_mid.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_mid.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_mgnt_header.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_mid.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_mid.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_mid.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_top.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_header.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_bottom.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_mid.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_bottom.j2 new file mode 100644 index 0000000..608008f --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_bottom.j2 @@ -0,0 +1,4 @@ + ------------------------------------------------------------------------------ + Note: For a 1000 M, electrical port in the full-duplex mode, setting MDI to + any value is invalid + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_mid.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_mid.j2 new file mode 100644 index 0000000..78ed071 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_mid.j2 @@ -0,0 +1,2 @@ +{{ context.spacer1 }}{{ context.port_num }}{{ context.spacer2 }}{{ context.port.alm_prof_15_min }}{{ context.spacer3 }}{{ context.port.warn_prof_15_min }}{{ context.spacer4 }}{{ context.port.alm_prof_24_hour }}{{ context.spacer5 }}{{ context.port.warn_prof_24_hour }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_top.j2 new file mode 100644 index 0000000..1be72b8 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_top.j2 @@ -0,0 +1,5 @@ + ------------------------------------------------------------------------------ + Port 15Min 15Min 24Hour 24Hour + AlmProf WarnProf AlmProf WarnProf + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_bottom.j2 new file mode 100644 index 0000000..26647c9 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_bottom.j2 @@ -0,0 +1,2 @@ + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_mid.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_mid.j2 new file mode 100644 index 0000000..53807c2 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_mid.j2 @@ -0,0 +1,2 @@ +{{ context.spacer1 }}{{ context.port_num }}{{ context.spacer2 }}{{ context.port_type }}{{ context.spacer3 }}{{ context.link_down }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_top.j2 new file mode 100644 index 0000000..6a7f30a --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_top.j2 @@ -0,0 +1,4 @@ + ------------------------------------------------------------------------------ + Port Port Type Link State + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_header.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_header.j2 new file mode 100644 index 0000000..091e699 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_header.j2 @@ -0,0 +1,6 @@ + --------------------------------------- + Board Name : {{ context.card.board_name }} + Board Status : {{ context.card.board_status }} + --------------------------------------- + + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_bottom.j2 new file mode 100644 index 0000000..26647c9 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_bottom.j2 @@ -0,0 +1,2 @@ + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_mid.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_mid.j2 new file mode 100644 index 0000000..655cda8 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_mid.j2 @@ -0,0 +1,2 @@ +{{ context.spacer1 }}{{ context.port_num }}{{ context.spacer2 }}{{ context.port_type }}{{ context.spacer3 }}{{ context.port.combo_status }}{{ context.spacer4 }}{{ context.port.optic_status }}{{ context.spacer5 }}{{ context.port.mdi }}{{ context.spacer6 }}{{ context.port.speed_h }}{{ context.spacer7 }}{{ context.port.duplex }}{{ context.spacer8 }}{{ context.port.flow_ctrl }}{{ context.spacer9 }}{{ context.port.active_state }}{{ context.spacer10 }}{{ context.port.link }} + diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_top.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_top.j2 new file mode 100644 index 0000000..8f37485 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_top.j2 @@ -0,0 +1,5 @@ + ------------------------------------------------------------------------------ + Port Port COMBO Optic MDI Speed Duplex Flow- Active Link + Type Mode Status (Mbps) Ctrl State + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_bottom.j2 new file mode 100644 index 0000000..608008f --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_bottom.j2 @@ -0,0 +1,4 @@ + ------------------------------------------------------------------------------ + Note: For a 1000 M, electrical port in the full-duplex mode, setting MDI to + any value is invalid + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_mid.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_mid.j2 new file mode 100644 index 0000000..78ed071 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_mid.j2 @@ -0,0 +1,2 @@ +{{ context.spacer1 }}{{ context.port_num }}{{ context.spacer2 }}{{ context.port.alm_prof_15_min }}{{ context.spacer3 }}{{ context.port.warn_prof_15_min }}{{ context.spacer4 }}{{ context.port.alm_prof_24_hour }}{{ context.spacer5 }}{{ context.port.warn_prof_24_hour }} + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_top.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_top.j2 new file mode 100644 index 0000000..1be72b8 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_top.j2 @@ -0,0 +1,5 @@ + ------------------------------------------------------------------------------ + Port 15Min 15Min 24Hour 24Hour + AlmProf WarnProf AlmProf WarnProf + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_bottom.j2 new file mode 100644 index 0000000..26647c9 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_bottom.j2 @@ -0,0 +1,2 @@ + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_mid.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_mid.j2 new file mode 100644 index 0000000..53807c2 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_mid.j2 @@ -0,0 +1,2 @@ +{{ context.spacer1 }}{{ context.port_num }}{{ context.spacer2 }}{{ context.port_type }}{{ context.spacer3 }}{{ context.link_down }} + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_top.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_top.j2 new file mode 100644 index 0000000..6a7f30a --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_top.j2 @@ -0,0 +1,4 @@ + ------------------------------------------------------------------------------ + Port Port Type Link State + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_header.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_header.j2 new file mode 100644 index 0000000..091e699 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_header.j2 @@ -0,0 +1,6 @@ + --------------------------------------- + Board Name : {{ context.card.board_name }} + Board Status : {{ context.card.board_status }} + --------------------------------------- + + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_bottom.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_bottom.j2 new file mode 100644 index 0000000..26647c9 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_bottom.j2 @@ -0,0 +1,2 @@ + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_mid.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_mid.j2 new file mode 100644 index 0000000..655cda8 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_mid.j2 @@ -0,0 +1,2 @@ +{{ context.spacer1 }}{{ context.port_num }}{{ context.spacer2 }}{{ context.port_type }}{{ context.spacer3 }}{{ context.port.combo_status }}{{ context.spacer4 }}{{ context.port.optic_status }}{{ context.spacer5 }}{{ context.port.mdi }}{{ context.spacer6 }}{{ context.port.speed_h }}{{ context.spacer7 }}{{ context.port.duplex }}{{ context.spacer8 }}{{ context.port.flow_ctrl }}{{ context.spacer9 }}{{ context.port.active_state }}{{ context.spacer10 }}{{ context.port.link }} + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_top.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_top.j2 new file mode 100644 index 0000000..8f37485 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_top.j2 @@ -0,0 +1,5 @@ + ------------------------------------------------------------------------------ + Port Port COMBO Optic MDI Speed Duplex Flow- Active Link + Type Mode Status (Mbps) Ctrl State + ------------------------------------------------------------------------------ + From 98e3c3a78c1cfc33388eee4d15918d01292a799e Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 16 Sep 2020 11:20:56 +0200 Subject: [PATCH 048/318] added functionality for display line-profile --- bootup/conf/bootstraps/create-huawei-5623.sh | 31 ++++++ .../huawei_resources/huawei_port_profile.py | 1 + .../display_adsl_line-profile_num.j2 | 33 ++++++ .../display_vdsl_line-profile_num.j2 | 101 ++++++++++++++++++ .../Huawei_Base/configCommandProcessor.py | 12 --- .../Huawei_Base/interfaceCommandProcessor.py | 51 +++++++++ 6 files changed, 217 insertions(+), 12 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_adsl_line-profile_num.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_vdsl_line-profile_num.j2 diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index b30657f..e71ffc6 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -125,6 +125,37 @@ req='{ root_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) +# Service Profile +req='{ + "name": "line_spectrum_1", + "type": "service", + "description": "Service Profile", + "l0_time": 255, + "l2_time": 30, + "l3_time": 255, + "max_transmite_power_reduction": 3, + "total_max_power_reduction": 9, + "bit_swap_ds": 1, + "bit_swap_us": 1, + "allow_transitions_to_idle": 2, + "allow_transitions_to_lowpower": 2, + "reference_clock": "FreeRun", + "force_inp_ds": 1, + "force_inp_us": 1, + "g_993_2_profile": 12, + "mode_specific": "enable", + "T1_413": "enable", + "G_992_1": "enable", + "G_992_2": "enable", + "G_992_3": "enable", + "G_992_4": "enable", + "G_992_5": "enable", + "AnnexB_G_993_2": "enable", + "us0_psd_mask": 32 +}' + +line_profile=$(create_resource "$req" $ENDPOINT/boxen/$box_id/port_profiles) + # Service Profile req='{ "name": "PPPoE", diff --git a/nesi/huawei/huawei_resources/huawei_port_profile.py b/nesi/huawei/huawei_resources/huawei_port_profile.py index a61a2b1..a283243 100644 --- a/nesi/huawei/huawei_resources/huawei_port_profile.py +++ b/nesi/huawei/huawei_resources/huawei_port_profile.py @@ -47,6 +47,7 @@ class HuaweiPortProfile(PortProfile): upstream_psd_mask_selection = base.Field('upstream_psd_mask_selection') psd_class_mask = base.Field('psd_class_mask') psd_limit_mask = base.Field('psd_limit_mask') + l0_time = base.Field('l0_time') l2_time = base.Field('l2_time') l3_time = base.Field('l3_time') diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_adsl_line-profile_num.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_adsl_line-profile_num.j2 new file mode 100644 index 0000000..beb56ac --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_adsl_line-profile_num.j2 @@ -0,0 +1,33 @@ +------------------------------------------------------------------------------ + Profile index :{{ context.profile.id }} Name: ADSL LINE PROFILE {{ context.profile.id }} + ADSL transmission mode : {{ context.trmode }} + Trellis mode : Enable + Upstream channel bit swap :{% if context.profile.bit_swap_us == 1 %} Enable {% else %} Disable {% endif %} + + Downstream channel bit swap :{% if context.profile.bit_swap_ds == 1 %} Enable {% else %} Disable {% endif %} + + Channel mode :{% if context.profile.mode_specific == 'enable' %} Interleaved {% else %} Disable {% endif %} + + Maximum downstream interleaved delay(ms) : 16 + Maximum upstream interleaved delay(ms) : 6 + Target downstream SNR margin(dB) : 6 + Maximum acceptable downstream SNR margin(dB) : 16 + Minimum acceptable downstream SNR margin(dB) : 0 + Target upstream SNR margin(dB) : 6 + Maximum acceptable upstream SNR margin(dB) : 16 + Minimum acceptable upstream SNR margin(dB) : 0 + Downstream SNR margin for rate downshift(dB) : 0 + Downstream SNR margin for rate upshift(dB) : 0 + Upstream SNR margin for rate downshift(dB) : 0 + Upstream SNR margin for rate upshift(dB) : 0 + Minimum upshift time in downstream(seconds) : 0 + Minimum downshift time in downstream(seconds) : 0 + Minimum upshift time in upstream(seconds) : 0 + Minimum downshift time in upstream(seconds) : 0 + Downstream form of transmit rate adaptation : Adapting at startup + Minimum transmit rate downstream(Kbps) : 32 + Maximum transmit rate downstream(Kbps) : 24544 + Minimum transmit rate upstream(Kbps) : 32 + Maximum transmit rate upstream(Kbps) : 1024 + ------------------------------------------------------------------------------ + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_vdsl_line-profile_num.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_vdsl_line-profile_num.j2 new file mode 100644 index 0000000..5b6ef29 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_vdsl_line-profile_num.j2 @@ -0,0 +1,101 @@ + ------------------------------------------------------------------------------ + Profile index: {{ context.profile.id }} Name: {{ context.profile.name }} + Transmission mode: + {% if context.profile.T1_413 == 'enable' %} T1.413 + {% endif %} + {% if context.profile.G_992_1 == 'enable' %} G.992.1(Annex A/B/C) + {% endif %} + {% if context.profile.G_992_2 == 'enable' %} G.992.2(Annex A/C) + {% endif %} + {% if context.profile.G_992_3 == 'enable' %} G.992.3(Annex A/B/I/J/L/M) + {% endif %} + {% if context.profile.G_992_4 == 'enable' %} G.992.4(Annex A/I) + {% endif %} + {% if context.profile.G_992_5 == 'enable' %} G.992.5(Annex A/B/I/J/M) + {% endif %} + {% if context.profile.AnnexB_G_993_2 == 'enable' %} G.993.2(Annex A/B/C) + {% endif %} + Bit swap downstream :{% if context.profile.bit_swap_ds == 1 %} Enable {% else %} Disable {% endif %} + + Bit swap upstream :{% if context.profile.bit_swap_us == 1 %} Enable {% else %} Disable {% endif %} + + Form of transmit rate adaptation downstream : AdaptAtStartup + Form of transmit rate adaptation upstream : AdaptAtStartup + Target SNR margin downstream(0.1dB) : 60 + Minimum SNR margin downstream(0.1dB) : 0 + Maximum SNR margin downstream(0.1dB) : 300 + Target SNR margin upstream(0.1dB) : 60 + Minimum SNR margin upstream(0.1dB) : 0 + Maximum SNR margin upstream(0.1dB) : 300 + UPBO US1 band reference PSD parameters[a, b] : 1650,1020 + UPBO US2 band reference PSD parameters[a, b] : 1650,615 + UPBO US3 band reference PSD parameters[a, b] : 0,0 + UPBO US4 band reference PSD parameters[a, b] : 0,0 + UPBO Boost Mode : Enable + UPBO US1 band reference electrical length : 0 + UPBO US2 band reference electrical length : 0 + UPBO US3 band reference electrical length : 0 + UPBO US4 band reference electrical length : 0 + UPBO use of electrical length to compute UPBO : Auto + Kl0 selection : max(kl0_CO,kl0_CPE) + UPBO electrical length estimation mode : ELE_M0 + UPBO electrical length threshold percentile : 10 + Allow transition to idle :{% if context.profile.allow_transitions_to_idle == 2 %} not allowed {% else %} allowed {% endif %} + + Allow transition to low power :{% if context.profile.allow_transitions_to_lowpower == 2 %} not allowed {% else %} allowed {% endif %} + + L0 time(second) : {{ context.profile.l0_time }} + L2 time(second) : {{ context.profile.l2_time }} + L3 time(second) : {{ context.profile.l3_time }} + Maximum aggregate transmit power reduction(dB) : {{ context.profile.max_transmite_power_reduction }} + Total maximum aggregate transmit power reduction + (dB) : {{ context.profile.total_max_power_reduction }} + + G.993.2 profile : Profile{{ context.profile.g_993_2_profile }}a + VDSL2 PSD class mask : AnnexB998-M2x-B(B8-6) + VDSL2 link use of U0 : Unused + Maximum nominal aggregate transmit power + downstream(0.1dBm) : 145 + Maximum nominal aggregate transmit power + upstream(0.1dBm) : 145 + Upstream PSD mask selection : ADLU-{{ context.profile.us0_psd_mask }}/EU-{{ context.profile.us0_psd_mask }} + Virtual noise mode downstream : Disable + Virtual noise mode upstream : Disable + G.993.2 profile autosensing : Disable + Network timing reference clock mode : {{ context.profile.reference_clock }} + INM inter arrival time offset downstream + (DMT symbol) : 3 + INM inter arrival time step downstream : 0 + INM cluster continuation value downstream + (DMT symbol) : 0 + INM equivalent INP mode downstream : 0 + INM inter arrival time offset upstream + (DMT symbol) : 3 + INM inter arrival time step upstream : 0 + INM cluster continuation value upstream + (DMT symbol) : 0 + INM equivalent INP mode upstream : 0 + SOS time window downstream(64ms) : 0 + Minimum percentage of degraded tones downstream : 0 + Minimum number of normalized CRC anomalies + downstream(0.02) : 65535 + Maximum number of SOS downstream : 0 + SNR margin offset of ROC downstream(0.1dB) : 0 + Minimum impulse noise protection of ROC + downstream : 0 + SOS time window upstream(64ms) : 0 + Minimum percentage of degraded tones upstream : 0 + Minimum number of normalized CRC anomalies + upstream(0.02) : 65535 + Maximum number of SOS upstream : 0 + SNR margin offset of ROC upstream(0.1dB) : 0 + Minimum impulse noise protection of ROC + upstream : 0 + G.998.4 retransmission control in downstream : RTX_FORBIDDEN + G.998.4 retransmission control in upstream : RTX_FORBIDDEN + Force framer setting for inp downstream :{% if context.profile.force_inp_ds == 1 %} False {% else %} True {% endif %} + + Force framer setting for inp upstream :{% if context.profile.force_inp_us == 1 %} False {% else %} True {% endif %} + + ------------------------------------------------------------------------------ + diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index a67a41f..4350d91 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -268,18 +268,6 @@ def generate_ont_info_summary(port): text += self._render('display_vlan_all_bottom', context=dict(context, count=count)) self._write(text) - elif self._validate(args, 'vdsl', 'line-profile', str): # TODO: Check if line-profile exists - vdsl_id, = self._dissect(args, 'vdsl', 'line-profile', str) - context['vdsl_id'] = vdsl_id - text = self._render('display_vdsl_line-profile_num', context=context) - self._write(text) - - elif self._validate(args, 'adsl', 'line-profile', str): # TODO: Check if line-profile exists - adsl_id, = self._dissect(args, 'adsl', 'line-profile', str) - context['adsl_id'] = adsl_id - text = self._render('display_adsl_line-profile_num', context=context) - self._write(text) - elif self._validate(args, 'version'): if self._model.interactive_mode: self.user_input('{ |backplane|frameid/slotid }:') diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index f00e295..5908aaa 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -50,6 +50,57 @@ def do_display(self, command, *args, context=None): 'display_inventory_cpe', context=dict(context, cpe=cpe)) self._write(text) + + elif self._validate(args, 'vdsl', 'line-profile', str): + if context['iftype'] == 'vlanif': + raise exceptions.CommandSyntaxError(command=command) + if self._model.dsl_mode == 'tr129': + raise exceptions.CommandSyntaxError(command=command) + if card.product == 'vdsl': + vdsl_id, = self._dissect(args, 'vdsl', 'line-profile', str) + try: + profile = self._model.get_port_profile('name', 'line_spectrum_' + str(vdsl_id)) + + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + text = self._render('display_vdsl_line-profile_num', context=dict(context, profile=profile)) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) + + elif self._validate(args, 'adsl', 'line-profile', str): + if context['iftype'] == 'vlanif': + raise exceptions.CommandSyntaxError(command=command) + if self._model.dsl_mode == 'tr129': + raise exceptions.CommandSyntaxError(command=command) + if card.product == 'adsl': + adsl_id, = self._dissect(args, 'adsl', 'line-profile', str) + try: + profile = self._model.get_port_profile('name', 'line_spectrum_' + str(adsl_id)) + txt = '' + if profile.G_992_1 == 'enable': + txt += 'G_992_1' + if profile.G_992_2 == 'enable': + txt += ', G_992_2' + if profile.G_992_3 == 'enable': + txt += ', G_992_3' + if profile.G_992_4 == 'enable': + txt += ', G_992_4' + if profile.G_992_5 == 'enable': + txt += ', G_992_5' + if profile.T1_413 == 'enable': + txt += ', T1.413' + if len(txt.split(',')) == 6: + context['trmode'] = 'All(G.992.1~5,T1.413)' + else: + context['trmode'] = txt + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + text = self._render('display_adsl_line-profile_num', context=dict(context, profile=profile)) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args, 'power', 'run', 'info'): emu = context['component'] if context['iftype'] == 'emu' and emu.type == 'H831PMU': From d349d700bbcf9a79caac9acda443e00e5c0b0fe6 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 16 Sep 2020 12:02:08 +0200 Subject: [PATCH 049/318] added template for vlan_help + removed todos --- nesi/softbox/api/models/cpe_models.py | 2 +- nesi/softbox/api/models/port_models.py | 2 +- nesi/softbox/base_resources/cpe.py | 8 ++ nesi/softbox/base_resources/ont.py | 8 ++ .../config/display_adsl_line-profile_num.j2 | 30 ------- .../config/display_vdsl_line-profile_num.j2 | 85 ------------------- .../enable/config/interface/vlan_help.j2 | 16 ++++ .../Base/Huawei_Base/baseCommandProcessor.py | 6 +- .../Huawei_Base/configCommandProcessor.py | 17 +++- .../Huawei_Base/diagnoseCommandProcessor.py | 2 +- .../Huawei_Base/interfaceCommandProcessor.py | 78 ++--------------- 11 files changed, 58 insertions(+), 196 deletions(-) delete mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_adsl_line-profile_num.j2 delete mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_vdsl_line-profile_num.j2 diff --git a/nesi/softbox/api/models/cpe_models.py b/nesi/softbox/api/models/cpe_models.py index c16758e..6a59b2d 100644 --- a/nesi/softbox/api/models/cpe_models.py +++ b/nesi/softbox/api/models/cpe_models.py @@ -39,4 +39,4 @@ class Cpe(db.Model): version_number = db.Column(db.String(), default='1.180.129.93 AB') version_number_oct = db.Column(db.String(), default='0x312E3138302E3132392E393320414200') vendor_serial_number = db.Column(db.String(), default='444E6DCD4770 F!Box7530 164.07.14') - self_test_result = db.Column(db.Enum('PASS'), default='PASS') # TODO: find corresponding value(s) + self_test_result = db.Column(db.Enum('PASS'), default='PASS') # find corresponding value(s) diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 0aa33bd..ed6a5fb 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -155,7 +155,7 @@ class Port(db.Model): current_operational_mode = db.Column(db.String(), default='No Protocol Selected') total_count_of_line_training = db.Column(db.Integer(), nullable=False, default=0) result_last_initialization = db.Column(db.Enum('No failure'), - default='No failure') # TODO: Find corresponding value(s) + default='No failure') # Find corresponding value(s) total_bytes_us = db.Column(db.Integer(), default=448203129) total_packets_us = db.Column(db.Integer(), default=6386689) total_bytes_ds = db.Column(db.Integer(), default=430667320) diff --git a/nesi/softbox/base_resources/cpe.py b/nesi/softbox/base_resources/cpe.py index 66dcc30..513a9f1 100644 --- a/nesi/softbox/base_resources/cpe.py +++ b/nesi/softbox/base_resources/cpe.py @@ -29,6 +29,14 @@ class Cpe(base.Resource): admin_state = base.Field('admin_state') mac = base.Field('mac') + def down(self): + """Change ont port admin state to down.""" + self.update(admin_state='0') + + def up(self): + """Change ont port admin state to up.""" + self.update(admin_state='1') + class CpeCollection(base.ResourceCollection): """Represent a collection of cpes.""" diff --git a/nesi/softbox/base_resources/ont.py b/nesi/softbox/base_resources/ont.py index 6590c49..5ea1f7e 100644 --- a/nesi/softbox/base_resources/ont.py +++ b/nesi/softbox/base_resources/ont.py @@ -24,6 +24,14 @@ class Ont(base.Resource): admin_state = base.Field('admin_state') operational_state = base.Field('operational_state') + def down(self): + """Change ont port admin state to down.""" + self.update(admin_state='0') + + def up(self): + """Change ont port admin state to up.""" + self.update(admin_state='1') + class OntCollection(base.ResourceCollection): """Represent a collection of ONTs.""" diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_adsl_line-profile_num.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_adsl_line-profile_num.j2 deleted file mode 100644 index 8e69a3e..0000000 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_adsl_line-profile_num.j2 +++ /dev/null @@ -1,30 +0,0 @@ ------------------------------------------------------------------------------- - Profile index :{{ context.adsl_id }} Name: ADSL LINE PROFILE {{ context.adsl_id }} - ADSL transmission mode : All(G.992.1~5,T1.413) - Trellis mode : Enable - Upstream channel bit swap : Enable - Downstream channel bit swap : Enable - Channel mode : Interleaved - Maximum downstream interleaved delay(ms) : 16 - Maximum upstream interleaved delay(ms) : 6 - Target downstream SNR margin(dB) : 6 - Maximum acceptable downstream SNR margin(dB) : 16 - Minimum acceptable downstream SNR margin(dB) : 0 - Target upstream SNR margin(dB) : 6 - Maximum acceptable upstream SNR margin(dB) : 16 - Minimum acceptable upstream SNR margin(dB) : 0 - Downstream SNR margin for rate downshift(dB) : 0 - Downstream SNR margin for rate upshift(dB) : 0 - Upstream SNR margin for rate downshift(dB) : 0 - Upstream SNR margin for rate upshift(dB) : 0 - Minimum upshift time in downstream(seconds) : 0 - Minimum downshift time in downstream(seconds) : 0 - Minimum upshift time in upstream(seconds) : 0 - Minimum downshift time in upstream(seconds) : 0 - Downstream form of transmit rate adaptation : Adapting at startup - Minimum transmit rate downstream(Kbps) : 32 - Maximum transmit rate downstream(Kbps) : 24544 - Minimum transmit rate upstream(Kbps) : 32 - Maximum transmit rate upstream(Kbps) : 1024 - ------------------------------------------------------------------------------ - diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vdsl_line-profile_num.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vdsl_line-profile_num.j2 deleted file mode 100644 index 498dfd2..0000000 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vdsl_line-profile_num.j2 +++ /dev/null @@ -1,85 +0,0 @@ - ------------------------------------------------------------------------------ - Profile index: {{ context.vdsl_id }} Name: DEFVAL - Transmission mode: - T1.413 G.992.1(Annex A/B/C) - G.992.2(Annex A/C) G.992.3(Annex A/B/I/J/L/M) - G.992.4(Annex A/I) G.992.5(Annex A/B/I/J/M) - G.993.2(Annex A/B/C) - Bit swap downstream : Enable - Bit swap upstream : Enable - Form of transmit rate adaptation downstream : AdaptAtStartup - Form of transmit rate adaptation upstream : AdaptAtStartup - Target SNR margin downstream(0.1dB) : 60 - Minimum SNR margin downstream(0.1dB) : 0 - Maximum SNR margin downstream(0.1dB) : 300 - Target SNR margin upstream(0.1dB) : 60 - Minimum SNR margin upstream(0.1dB) : 0 - Maximum SNR margin upstream(0.1dB) : 300 - UPBO US1 band reference PSD parameters[a, b] : 1650,1020 - UPBO US2 band reference PSD parameters[a, b] : 1650,615 - UPBO US3 band reference PSD parameters[a, b] : 0,0 - UPBO US4 band reference PSD parameters[a, b] : 0,0 - UPBO Boost Mode : Enable - UPBO US1 band reference electrical length : 0 - UPBO US2 band reference electrical length : 0 - UPBO US3 band reference electrical length : 0 - UPBO US4 band reference electrical length : 0 - UPBO use of electrical length to compute UPBO : Auto - Kl0 selection : max(kl0_CO,kl0_CPE) - UPBO electrical length estimation mode : ELE_M0 - UPBO electrical length threshold percentile : 10 - Allow transition to idle : not allowed - Allow transition to low power : not allowed - L0 time(second) : 255 - L2 time(second) : 30 - L3 time(second) : 255 - Maximum aggregate transmit power reduction(dB) : 3 - Total maximum aggregate transmit power reduction - (dB) : 9 - - G.993.2 profile : Profile12a - VDSL2 PSD class mask : AnnexB998-M2x-B(B8-6) - VDSL2 link use of U0 : Unused - Maximum nominal aggregate transmit power - downstream(0.1dBm) : 145 - Maximum nominal aggregate transmit power - upstream(0.1dBm) : 145 - Upstream PSD mask selection : ADLU-32/EU-32 - Virtual noise mode downstream : Disable - Virtual noise mode upstream : Disable - G.993.2 profile autosensing : Disable - Network timing reference clock mode : FreeRun - INM inter arrival time offset downstream - (DMT symbol) : 3 - INM inter arrival time step downstream : 0 - INM cluster continuation value downstream - (DMT symbol) : 0 - INM equivalent INP mode downstream : 0 - INM inter arrival time offset upstream - (DMT symbol) : 3 - INM inter arrival time step upstream : 0 - INM cluster continuation value upstream - (DMT symbol) : 0 - INM equivalent INP mode upstream : 0 - SOS time window downstream(64ms) : 0 - Minimum percentage of degraded tones downstream : 0 - Minimum number of normalized CRC anomalies - downstream(0.02) : 65535 - Maximum number of SOS downstream : 0 - SNR margin offset of ROC downstream(0.1dB) : 0 - Minimum impulse noise protection of ROC - downstream : 0 - SOS time window upstream(64ms) : 0 - Minimum percentage of degraded tones upstream : 0 - Minimum number of normalized CRC anomalies - upstream(0.02) : 65535 - Maximum number of SOS upstream : 0 - SNR margin offset of ROC upstream(0.1dB) : 0 - Minimum impulse noise protection of ROC - upstream : 0 - G.998.4 retransmission control in downstream : RTX_FORBIDDEN - G.998.4 retransmission control in upstream : RTX_FORBIDDEN - Force framer setting for inp downstream : False - Force framer setting for inp upstream : False - ------------------------------------------------------------------------------ - diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/vlan_help.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/vlan_help.j2 index 043dbcf..930205e 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/vlan_help.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/vlan_help.j2 @@ -1,17 +1,33 @@ --------------------------------------------- Command of vlanif{{ context.component.number }} Mode: --------------------------------------------- +arp arp command group description Specify interface description +dhcp DHCP command group dhcp-client DHCP client configuration command +dhcp-server Configure DHCP server group of this interface +dhcpv6-server Configure DHCPv6 server group of this interface display Display information firewall Specify firewall configuration +igmp Specify parameters for IGMP ip ip command group ipv6 ipv6 command group +isis Configure interface parameters for ISIS +mpls mpls command group +mtu MTU command group ntp-service Specify NTP (Network Time Protocol) configuration information +ospf ospf command group +ospfv3 ospfv3 command group +pim Specify interface parameters for PIM +priority-mark The priority of the packet send from the interface quit Exit from current mode and enter prior mode return Enter the privileged mode +rip rip command group +ripng RIPng (Routing Information Protocol next generation) shutdown Shutdown the specified interface +static-route IPv4 static routes switch Switch language mode undo Negate a command or set its defaults +vlan Configure the encapsulation mode of the VLAN interface diff --git a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py index ef6ab82..af044a1 100644 --- a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py @@ -81,13 +81,15 @@ def user_input(self, prompt, allow_history=True, tmp_boundary=None): def do_quit(self, command, *args, context=None): raise exceptions.TerminalExitError() - def do_undo(self, command, *args, context=None): # TODO: Functionality + def do_undo(self, command, *args, context=None): if self._validate(args, 'alarm', 'output', 'all'): + # importend for future snmp interactions return elif self._validate(args, 'event', 'output', 'all'): return elif self._validate(args, 'smart'): - return + self._write(" Interactive function is disabled\n") + self._model.disable_interactive() elif self._validate(args, 'system', 'snmp-user', 'password', 'security'): return else: diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 4350d91..c5a3742 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -774,7 +774,8 @@ def do_undo(self, command, *args, context=None): s_vlan.delete() elif self._validate(args, 'smart'): - return + self._write(" Interactive function is disabled\n") + self._model.disable_interactive() elif self._validate(args, 'interactive'): return @@ -989,8 +990,18 @@ def do_port(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def do_deactivate(self, command, *args, context=None): # TODO: Functionality + def do_deactivate(self, command, *args, context=None): if self._validate(args, 'all'): + for component in self._model.cpes: + component.down() + for component in self._model.ont_ports: + component.down() + for component in self._model.onts: + component.down() + for component in self._model.ports: + component.admin_down() + for component in self._model.service_ports: + component.set_admin_state(0) return else: raise exceptions.CommandSyntaxError(command=command) @@ -1254,7 +1265,7 @@ def do_save(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def do_load(self, command, *args, context=None): # TODO: Read in file + def do_load(self, command, *args, context=None): # Read in file if self._validate(args, 'script', 'tftp', str, str): ip, file_name = self._dissect(args, 'script', 'tftp', str, str) diff --git a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py index 2098f8e..b373524 100644 --- a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py @@ -106,7 +106,7 @@ def on_unknown_command(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def do_switch(self, command, *args, context=None): # TODO: Functionality + def do_switch(self, command, *args, context=None): if self._validate(args, 'vdsl', 'mode', 'to', str): user = self._model.get_user('status', 'Online') if user.level != 'Super': diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index 5908aaa..b37877a 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -344,78 +344,7 @@ def do_display(self, command, *args, context=None): def do_activate(self, command, *args, context=None): card = context['component'] - if self._validate(args, str, 'prof-desc', 'ds-rate', str, 'us-rate', str): - if context['iftype'] == 'vlanif': - raise exceptions.CommandSyntaxError(command=command) - if self._model.dsl_mode == 'tr129': - raise exceptions.CommandSyntaxError(command=command) - if card.product == 'vdsl': - port_idx, ds_rate, us_rate, = self._dissect( - args, str, 'prof-desc', 'ds-rate', str, 'us-rate', str) - - try: - port_name = card.name + '/' + port_idx - port = self._model.get_port("name", port_name) - port.port_downstream_set(int(ds_rate)) - port.port_upstream_set(int(us_rate)) - - except (exceptions.SoftboxenError, ValueError): - raise exceptions.CommandSyntaxError(command=command) - - if port.downstream_max != int(ds_rate) and port.upstream_max != int(us_rate): - raise exceptions.CommandSyntaxError(command=command) - - else: - raise exceptions.CommandSyntaxError(command=command) - - elif self._validate(args, str, 'prof.desc', 'ds-rate', str, 'us-rate', str, 'noise-margin', 'VDSL_6db', - 'inp-delay', 'VDSL_(FAST)', '(spectrum str)', '(dpbo DPBO:str)'): - # TODO: Brackets mean optional parameters, so make them optional... - if context['iftype'] == 'vlanif': - raise exceptions.CommandSyntaxError(command=command) - if self._model.dsl_mode == 'tr129': - raise exceptions.CommandSyntaxError(command=command) - if card.product == 'vdsl': - port_idx, ds_rate, us_rate = self._dissect(args, str, 'prof.desc', 'ds-rate', str, 'us-rate', str, - 'noise-margin', 'VDSL_6db', 'inp-delay', 'VDSL_(FAST)', - '(spectrum str)', '(dpbo DPBO:str)') - - try: - port_name = card.name + '/' + port_idx - port = self._model.get_port("name", port_name) - - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError(command=command) - - return - - else: - raise exceptions.CommandSyntaxError(command=command) - - elif self._validate(args, str, 'prof.desc', 'ds-rate', str, 'us-rate', str, 'noise-margin', 'ADSL_6db', - 'inp-delay', 'ADSL_(FAST)', '(spectrum str)', '(dpbo DPBO:str)'): - # TODO: Brackets mean optional parameters, so make them optional... - if context['iftype'] == 'vlanif': - raise exceptions.CommandSyntaxError(command=command) - if self._model.dsl_mode == 'tr129': - raise exceptions.CommandSyntaxError(command=command) - if card.product == 'vdsl': - port_idx, ds_rate, us_rate = self._dissect(args, str, 'prof.desc', 'ds-rate', str, 'us-rate', str, - 'noise-margin', 'ADSL_6db', 'inp-delay', 'ADSL_(FAST)', - '(spectrum str)', '(dpbo DPBO:str)') - - try: - port_name = card.name + '/' + port_idx - port = self._model.get_port("name", port_name) - - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError(command=command) - - return - - else: - raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args[:6], str, 'prof-desc', 'ds-rate', str, 'us-rate', str): + if self._validate(args[:6], str, 'prof-desc', 'ds-rate', str, 'us-rate', str): #elif self._validate(args, str, 'prof.desc', 'ds-rate', str, 'us-rate', str, '(spectrum str)', 'noise-margin', 'ADSL_6db', 'inp-delay', 'ADSL','(dpbo DPBO:str)'): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) @@ -575,7 +504,10 @@ def on_unknown_command(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) else: - # TODO: print VLAN help + text = self._render( + 'vlan_help', + context=context) + self._write(text) raise exceptions.CommandSyntaxError(command=command) else: raise exceptions.CommandSyntaxError(command=command) From b99978dc6f0f618794dc93da2399c84dbcf1150b Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 16 Sep 2020 13:01:44 +0200 Subject: [PATCH 050/318] updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 094d204..53f7a13 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ For more information on `softboxen` or `NESi` please refer to our local [documen ### Supported Vendors - Alcatel (nearly feature complete) - - Huawei (nearly feature complete)(work in progress) + - Huawei (nearly feature complete) - Edgecore (not implemented yet) - Keymile (work in progress) - Pbn (not implemented yet) From 05b41ead08789864675635e368b9b8b53b8fa59c Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Wed, 16 Sep 2020 13:20:47 +0200 Subject: [PATCH 051/318] =?UTF-8?q?When=20a=20card=20doesn't=20exist,=20it?= =?UTF-8?q?=20now=20shows=20up=20as=20a=20blank=20line=20in=20the=20Versio?= =?UTF-8?q?n:=20ImageMagick=207.0.10-11=20Q16=20x86=5F64=202020-05-09=20ht?= =?UTF-8?q?tps://imagemagick.org=20Copyright:=20=C2=A9=201999-2020=20Image?= =?UTF-8?q?Magick=20Studio=20LLC=20License:=20https://imagemagick.org/scri?= =?UTF-8?q?pt/license.php=20Features:=20Cipher=20DPC=20HDRI=20Modules=20Op?= =?UTF-8?q?enMP(3.1)=20Delegates=20(built-in):=20bzlib=20freetype=20gslib?= =?UTF-8?q?=20heic=20jng=20jp2=20jpeg=20lcms=20ltdl=20lzma=20openexr=20png?= =?UTF-8?q?=20ps=20tiff=20webp=20xml=20zlib=20Usage:=20display=20[options?= =?UTF-8?q?=20...]=20file=20[=20[options=20...]=20file=20...]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Image Settings: -alpha option on, activate, off, deactivate, set, opaque, copy transparent, extract, background, or shape -antialias remove pixel-aliasing -authenticate password decipher image with this password -backdrop display image centered on a backdrop -channel type apply option to select image channels -colormap type Shared or Private -colorspace type alternate image colorspace -comment string annotate image with comment -compress type type of pixel compression when writing the image -define format:option define one or more image format options -delay value display the next image after pausing -density geometry horizontal and vertical density of the image -depth value image depth -display server display image to this X server -dispose method layer disposal method -dither method apply error diffusion to image -endian type endianness (MSB or LSB) of the image -filter type use this filter when resizing an image -format string output formatted image characteristics -geometry geometry preferred size and location of the Image window -gravity type horizontal and vertical backdrop placement -identify identify the format and characteristics of the image -immutable displayed image cannot be modified -interlace type type of image interlacing scheme -interpolate method pixel color interpolation method -label string assign a label to an image -limit type value pixel cache resource limit -loop iterations loop images then exit -map type display image using this Standard Colormap -matte store matte channel if the image has one -monitor monitor progress -nostdin do not try to open stdin -page geometry size and location of an image canvas -profile filename add, delete, or apply an image profile -quality value JPEG/MIFF/PNG compression level -quantize colorspace reduce colors in this colorspace -quiet suppress all warning messages -regard-warnings pay attention to warning messages -remote command execute a command in an remote display process -repage geometry size and location of an image canvas (operator) -respect-parentheses settings remain in effect until parenthesis boundary -sampling-factor geometry horizontal and vertical sampling factor -scenes range image scene range -seed value seed a new sequence of pseudo-random numbers -set property value set an image property -size geometry width and height of image -support factor resize support: > 1.0 is blurry, < 1.0 is sharp -texture filename name of texture to tile onto the image background -transparent-color color transparent color -treedepth value color tree depth -update seconds detect when image file is modified and redisplay -verbose print detailed information about the image -visual type display image using this visual type -virtual-pixel method virtual pixel access method -window id display image to background of this window -window-group id exit program when this window id is destroyed -write filename write image to a file Image Operators: -auto-orient automagically orient image -border geometry surround image with a border of color -clip clip along the first path from the 8BIM profile -clip-path id clip along a named path from the 8BIM profile -colors value preferred number of colors in the image -contrast enhance or reduce the image contrast -crop geometry preferred size and location of the cropped image -decipher filename convert cipher pixels to plain pixels -deskew threshold straighten an image -despeckle reduce the speckles within an image -edge factor apply a filter to detect edges in the image -enhance apply a digital filter to enhance a noisy image -equalize perform histogram equalization to an image -extract geometry extract area from image -flip flip image in the vertical direction -flop flop image in the horizontal direction -frame geometry surround image with an ornamental border -fuzz distance colors within this distance are considered equal -gamma value level of gamma correction -monochrome transform image to black and white -negate replace every pixel with its complementary color -normalize transform image to span the full range of colors -raise value lighten/darken image edges to create a 3-D effect -resample geometry change the resolution of an image -resize geometry resize the image -roll geometry roll an image vertically or horizontally -rotate degrees apply Paeth rotation to the image -sample geometry scale image with pixel sampling -segment value segment an image -sharpen geometry sharpen the image -strip strip image of all profiles and comments -threshold value threshold the image -thumbnail geometry create a thumbnail of the image -trim trim image edges Image Sequence Operators: -coalesce merge a sequence of images -flatten flatten a sequence of images Miscellaneous Options: -debug events display copious debugging information -help print program options -list type print a list of supported option arguments -log format format of debugging information -version print version information In addition to those listed above, you can specify these standard X resources as command line options: -background, -bordercolor, -mattecolor, -borderwidth, -font, -foreground, -iconGeometry, -iconic, -name, -shared-memory, -usePixmap, or -title. By default, the image format of 'file' is determined by its magic number. To specify a particular image format, precede the filename with an image format name and a colon (i.e. ps:image) or specify the image type as the filename suffix (i.e. image.ps). Specify 'file' as '-' for standard input or output. Buttons: 1 press to map or unmap the Command widget 2 press and drag to magnify a region of an image 3 press to load an image from a visual image directory output --- .../1/login/mainloop/display_board_0_empty.j2 | 2 + .../enable/config/display_board_0_empty.j2 | 2 + .../mainloop/enable/display_board_0_empty.j2 | 2 + .../Huawei_Base/huaweiBaseCommandProcessor.py | 39 +++++++++++++------ 4 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/display_board_0_empty.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/display_board_0_empty.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/display_board_0_empty.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_0_empty.j2 b/templates/Huawei/Base/1/login/mainloop/display_board_0_empty.j2 new file mode 100644 index 0000000..b7785f8 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/display_board_0_empty.j2 @@ -0,0 +1,2 @@ + {{ context.cardname }} + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_0_empty.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_0_empty.j2 new file mode 100644 index 0000000..b7785f8 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_0_empty.j2 @@ -0,0 +1,2 @@ + {{ context.cardname }} + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_0_empty.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_board_0_empty.j2 new file mode 100644 index 0000000..b7785f8 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_board_0_empty.j2 @@ -0,0 +1,2 @@ + {{ context.cardname }} + diff --git a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py index 4e63e48..c7bc641 100644 --- a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py @@ -22,18 +22,33 @@ def display_board(self, command, args, context=None): if identifier == '0': text = self._render('display_board_0_top', context=context) - cards = self._model.cards - for card in cards: - _, cardname = card.name.split('/') - context['cardname'] = cardname - - context['spacer1'] = self.create_spacers((8,), (cardname,))[0] * ' ' - context['spacer2'] = self.create_spacers((11,), (card.board_name,))[0] * ' ' - context['spacer3'] = self.create_spacers((17,), (card.board_status,))[0] * ' ' - context['spacer4'] = self.create_spacers((9,), (card.sub_type_0,))[0] * ' ' - context['spacer5'] = self.create_spacers((12,), (card.sub_type_1,))[0] * ' ' - - text += self._render('display_board_0_middle', context=dict(context, card=card)) + sorted_cards = [] + for card in self._model.cards: + card_id = int(card.name[2:]) + sorted_cards.append(card_id) + + sorted_cards = sorted(sorted_cards) + + for i in range(0, sorted_cards[-1]+1): + if i not in sorted_cards: + context['cardname'] = i + text += self._render('display_board_0_empty', context=context) + + else: + try: + cardname = '0/' + str(i) + card = self._model.get_card('name', cardname) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + context['cardname'] = i + + context['spacer1'] = self.create_spacers((8,), (cardname,))[0] * ' ' + context['spacer2'] = self.create_spacers((11,), (card.board_name,))[0] * ' ' + context['spacer3'] = self.create_spacers((17,), (card.board_status,))[0] * ' ' + context['spacer4'] = self.create_spacers((9,), (card.sub_type_0,))[0] * ' ' + context['spacer5'] = self.create_spacers((12,), (card.sub_type_1,))[0] * ' ' + + text += self._render('display_board_0_middle', context=dict(context, card=card)) text += self._render('display_board_0_bottom', context=context) self._write(text) From 70baa5054d6f8453fc71073f4bb7f90ee4877a27 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Thu, 17 Sep 2020 11:19:37 +0200 Subject: [PATCH 052/318] Various small fixes --- bootup/conf/bootstraps/create-huawei-5623.sh | 2 +- .../config/interface/display_port_ddm-info.j2 | 2 - .../config/interface/display_port_state.j2 | 2 +- .../interface/display_port_state_offline.j2 | 12 +++++ .../enable/display_interface_product_port.j2 | 2 +- ...duct_port_state_num_card_port_activated.j2 | 6 +-- .../Huawei_Base/enableCommandProcessor.py | 44 ++++++++++++------- .../Huawei_Base/interfaceCommandProcessor.py | 15 ++++--- 8 files changed, 56 insertions(+), 29 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state_offline.j2 diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index e71ffc6..6e9b047 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -243,7 +243,7 @@ req='{ "subrack_id": '$subrack_0', "description": "Physical card 0/0", "product": "vdsl", - "board_name": "H83BVCMM" + "board_name": "H80DSDPM" }' card_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_ddm-info.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_ddm-info.j2 index 69a3d79..49b7f95 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_ddm-info.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_ddm-info.j2 @@ -1,5 +1,3 @@ - Command: - display port ddm-info 1 Temperature(C) : {{ context.port.temperature_h_exact }} Supply voltage(V) : {{ context.port.supply_voltage_h_exact }} TX bias current(mA) : {{ context.port.tx_bias_current_h_exact }} diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state.j2 index 5d96efe..cbee89e 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state.j2 @@ -2,7 +2,7 @@ Port Information ---------------------------------------------------------------------------- F/S/P {{ context.port.name }} - Port state {% if context.port.operational_state == '0' %}Offline{% endif %}{% if context.port.operational_state == '1' %}Online{% endif %} + Port state {% if context.port.operational_state == 'activated' %}Online{% else %}Offline{% endif %} Last down cause {{ context.port.last_down_cause }} Last up time {{ context.port.last_up_time }} diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state_offline.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state_offline.j2 new file mode 100644 index 0000000..2ced469 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state_offline.j2 @@ -0,0 +1,12 @@ + ---------------------------------------------------------------------------- + F/S/P {{ context.port.name }} + Optical Module status {{ context.port.optical_module_status }} + Port state {% if context.port.operational_state == 'activated' %}Online{% else %}Offline{% endif %} + + Port energy-saving flag {{ context.port.port_energy_saving_flag }} + xPON MAC chipset state {{ context.port.xpon_mac_chipset_state }} + Last down cause - + Last up time - + Last down time - + ---------------------------------------------------------------------------- + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_interface_product_port.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_interface_product_port.j2 index 6cd7b7b..85d26c1 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/display_interface_product_port.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_interface_product_port.j2 @@ -1,4 +1,4 @@ - {% if context.card.product == 'vdsl'%} VDSL {% endif %}{% if context.card.product == 'adsl'%}ADSL {% endif %}{{ context.spaced_out_name }} is {{ context.port.operational_state }} + {% if context.card.product == 'vdsl'%} VDSL {% endif %}{% if context.card.product == 'adsl'%}ADSL {% endif %}{{ context.spaced_out_name }} is {{ context.port_o_state }} The {% if context.card.product == 'vdsl'%}VDSL {% endif %}{% if context.card.product == 'adsl'%}ADSL {% endif %}port state is {{ context.port.admin_state }} The {% if context.card.product == 'vdsl'%}VDSL {% endif %}{% if context.card.product == 'adsl'%}ADSL {% endif %}port loopback state is {{ context.port.loopback }} Description : {{ context.port.description }} diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_product_port_state_num_card_port_activated.j2 b/templates/Huawei/Base/1/login/mainloop/enable/display_product_port_state_num_card_port_activated.j2 index c35d17f..ef07002 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/display_product_port_state_num_card_port_activated.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/display_product_port_state_num_card_port_activated.j2 @@ -4,13 +4,13 @@ Port Status Loopback Alarm Spec UPBO Temp Prof Prof ------------------------------------------------------------------------------ - {{ context.portname }}{{ context.spacer1 }}{{ context.port.admin_state }}{{ context.spacer2 }}{{ context.port.loopback }}{{ context.spacer3 }}{{ context.port.alarm_template_num }}{{ context.spacer4 }}{{ context.port.spectrum_profile_num }}{{ context.spacer5 }}{{ context.port.upbo_profile_num }} +{{ context.spacer_beg1 }}{{ context.portname }}{{ context.spacer1 }}{{ context.port_a_state }}{{ context.spacer2 }}{{ context.port_loopback }}{{ context.spacer3 }}{{ context.port.alarm_template_num }}{{ context.spacer4 }}{{ context.port.spectrum_profile_num }}{{ context.spacer5 }}{{ context.port.upbo_profile_num }} ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ Port DPBO prof RFI prof NM prof VN prof INM prof ------------------------------------------------------------------------------ - {{ context.portname }}{{ context.spacer6 }}{{ context.port.dpbo_profile_num }}{{ context.spacer7 }}{{ context.port.rfi_profile_num }}{{ context.spacer8 }}{{ context.port.noise_margin_profile_num }}{{ context.spacer9 }}{{ context.port.virtual_noise_profile_num }}{{ context.spacer10 }}{{ context.port.inm_profile_num }} +{{ context.spacer_beg2 }}{{ context.portname }}{{ context.spacer6 }}{{ context.port.dpbo_profile_num }}{{ context.spacer7 }}{{ context.port.rfi_profile_num }}{{ context.spacer8 }}{{ context.port.noise_margin_profile_num }}{{ context.spacer9 }}{{ context.port.virtual_noise_profile_num }}{{ context.spacer10 }}{{ context.port.inm_profile_num }} ------------------------------------------------------------------------------ Note: NM: Noise Margin VN: Virtual Noise @@ -20,7 +20,7 @@ ------------------------------------------------------------------------------ Channel DDR prof UDR prof INP prof DsRa ratio UsRa ratio ------------------------------------------------------------------------------ - {{ context.channelname }}{{ context.spacer11 }}{{ context.port.channel_ds_data_rate_profile_num }}{{ context.spacer12 }}{{ context.port.channel_us_data_rate_profile_num }}{{ context.spacer13 }}{{ context.port.channel_inp_data_rate_profile_num }}{{ context.spacer14 }}{{ context.port.channel_ds_rate_adapt_ratio }}{{ context.spacer15 }}{{ context.port.channel_us_rate_adapt_ratio }} +{{ context.spacer_beg3 }}{{ context.channelname }}{{ context.spacer11 }}{{ context.port.channel_ds_data_rate_profile_num }}{{ context.spacer12 }}{{ context.port.channel_us_data_rate_profile_num }}{{ context.spacer13 }}{{ context.port.channel_inp_data_rate_profile_num }}{{ context.spacer14 }}{{ context.port.channel_ds_rate_adapt_ratio }}{{ context.spacer15 }}{{ context.port.channel_us_rate_adapt_ratio }} ------------------------------------------------------------------------------ Note: DDR: Downstream Data Rate UDR: Upstream Data Rate diff --git a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py index 08cfc1d..3a9e6b4 100644 --- a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py @@ -100,6 +100,10 @@ def do_display(self, command, *args, context=None): context['spaced_out_name'] = self.space_out_port_name(port.name) context['spacer'] = self.create_spacers((7,), (port.dynamic_profile_index,))[0] * ' ' + if port.operational_state == 'activated': + context['port_o_state'] = 'up' + else: + context['port_o_state'] = 'down' try: service_port = self._model.get_service_port('connected_id', port.id) @@ -146,24 +150,32 @@ def do_display(self, command, *args, context=None): channelname = portname + '.1' context['portname'] = portname context['channelname'] = channelname + context['port_a_state'] = port.admin_state.capitalize() + port_a_state = port.admin_state.capitalize() + context['port_loopback'] = port.loopback.capitalize() + port_loopback = port.loopback.capitalize() - text = '' if port.admin_state == 'activated': - context['spacer1'] = self.create_spacers((7,), (portname,))[0] * ' ' - context['spacer2'] = self.create_spacers((15,), (port.admin_state,))[0] * ' ' - context['spacer3'] = self.create_spacers((25,), (port.loopback,))[0] * ' ' - context['spacer4'] = self.create_spacers((14,), (port.alarm_template_num,))[0] * ' ' - context['spacer5'] = self.create_spacers((13,), (port.spectrum_profile_num,))[0] * ' ' - context['spacer6'] = self.create_spacers((17,), (portname,))[0] * ' ' - context['spacer7'] = self.create_spacers((14,), (port.dpbo_profile_num,))[0] * ' ' - context['spacer8'] = self.create_spacers((14,), (port.rfi_profile_num,))[0] * ' ' - context['spacer9'] = self.create_spacers((13,), (port.noise_margin_profile_num,))[0] * ' ' - context['spacer10'] = self.create_spacers((12,), (port.virtual_noise_profile_num,))[0] * ' ' - context['spacer11'] = self.create_spacers((18,), (channelname,))[0] * ' ' - context['spacer12'] = self.create_spacers((13,), (port.channel_ds_data_rate_profile_num,))[0] * ' ' - context['spacer13'] = self.create_spacers((13,), (port.channel_us_data_rate_profile_num,))[0] * ' ' - context['spacer14'] = self.create_spacers((11,), (port.channel_inp_data_rate_profile_num,))[0] * ' ' - context['spacer15'] = self.create_spacers((15,), (port.channel_ds_rate_adapt_ratio,))[0] * ' ' + context['spacer_beg1'] = self.create_spacers((6,), (portname,))[0] * ' ' + context['spacer1'] = self.create_spacers((3,), ('',))[0] * ' ' + context['spacer2'] = self.create_spacers((15,), (port_a_state,))[0] * ' ' + context['spacer3'] = self.create_spacers((30,), (port_loopback + str(port.alarm_template_num),))[0] * ' ' + context['spacer4'] = self.create_spacers((13,), (port.spectrum_profile_num,))[0] * ' ' + context['spacer5'] = self.create_spacers((13,), (port.upbo_profile_num,))[0] * ' ' + + context['spacer_beg2'] = self.create_spacers((6,), (portname,))[0] * ' ' + context['spacer6'] = self.create_spacers((22,), (port.dpbo_profile_num,))[0] * ' ' + context['spacer7'] = self.create_spacers((13,), (port.rfi_profile_num,))[0] * ' ' + context['spacer8'] = self.create_spacers((13,), (port.noise_margin_profile_num,))[0] * ' ' + context['spacer9'] = self.create_spacers((13,), (port.virtual_noise_profile_num,))[0] * ' ' + context['spacer10'] = self.create_spacers((13,), (port.inm_profile_num,))[0] * ' ' + + context['spacer_beg3'] = self.create_spacers((7,), (channelname,))[0] * ' ' + context['spacer11'] = self.create_spacers((21,), (port.channel_ds_data_rate_profile_num,))[0] * ' ' + context['spacer12'] = self.create_spacers((13,), (port.channel_us_data_rate_profile_num,))[0] * ' ' + context['spacer13'] = self.create_spacers((13,), (port.channel_inp_data_rate_profile_num,))[0] * ' ' + context['spacer14'] = self.create_spacers((13,), (port.channel_ds_rate_adapt_ratio,))[0] * ' ' + context['spacer15'] = self.create_spacers((13,), (port.channel_us_rate_adapt_ratio,))[0] * ' ' text = self._render( 'display_product_port_state_num_card_port_activated', context=dict(context, port=port)) diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index b37877a..dd13c2e 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -126,9 +126,14 @@ def do_display(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - text = self._render( - 'display_port_state', - context=dict(context, port=port)) + if port.operational_state == 'activated': + text = self._render( + 'display_port_state', + context=dict(context, port=port)) + else: + text = self._render( + 'display_port_state_offline', + context=dict(context, port=port)) self._write(text) else: @@ -426,8 +431,8 @@ def do_activate(self, command, *args, context=None): if self._model.dsl_mode == 'tr165': raise exceptions.CommandSyntaxError(command=command) if card.product == 'adsl' or card.product == 'vdsl': - #Template looks like this: {huawei_downstream}_{huawei_downstream}_ADSL - #Template looks like this: {huawei_downstream}_{huawei_downstream}_{summary} vdsl + # Template looks like this: {huawei_downstream}_{huawei_downstream}_ADSL + # Template looks like this: {huawei_downstream}_{huawei_downstream}_{summary} vdsl port_idx, template_name = self._dissect(args, str, 'template-name', str) try: From 450eb6ddf16f8b1db059ae02cadba48b2b64123b Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Thu, 17 Sep 2020 11:48:57 +0200 Subject: [PATCH 053/318] Small adjustments --- bootup/conf/bootstraps/create-huawei-5623.sh | 18 +++++++++--------- .../Huawei_Base/huaweiBaseCommandProcessor.py | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 6e9b047..a5e3a95 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -265,10 +265,10 @@ req='{ port_0_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Serviceport 0/0/0 ### +### Serviceport 0 ### req='{ - "name": "0/0/0", + "name": "0", "connected_id": '$port_0_0_0', "connected_type": "port", "admin_state": "1", @@ -277,7 +277,7 @@ req='{ service_port_0_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) -### Service PPPoE Vlan at ServicePort 0/0/0 ### +### Service PPPoE Vlan at ServicePort 0 ### req='{ "name": "2620", @@ -782,10 +782,10 @@ req='{ ont_port_0_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) -### Serviceport 0/3/0/1/1 ### +### Serviceport 1 ### req='{ - "name": "0/3/0/1/1", + "name": "1", "connected_id": '$ont_port_0_3_0_1_1', "connected_type": "ont", "admin_state": "1", @@ -794,7 +794,7 @@ req='{ service_port_0_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) -### Service PPPoE Vlan at ServicePort 0/3/0/1/1 ### +### Service PPPoE Vlan at ServicePort 1 ### req='{ "name": "2620", @@ -827,10 +827,10 @@ req='{ cpe_port_0_3_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) -### Serviceport 0/3/0/1/1/1/1 ### +### Serviceport 2 ### req='{ - "name": "0/3/0/1/1/1/1", + "name": "2", "connected_id": '$cpe_port_0_3_0_1_1_1_1', "connected_type": "cpe", "admin_state": "1", @@ -839,7 +839,7 @@ req='{ service_port_0_3_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) -### Service PPPoE Vlan at ServicePort 0/3/0/1/1/1/1 ### +### Service PPPoE Vlan at ServicePort 2 ### req='{ "name": "2620", diff --git a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py index c7bc641..6c1a0e5 100644 --- a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py @@ -498,7 +498,7 @@ def display_service_port(self, command, args, context): text += self._render('display_service_port_all_middle', context=dict(context, port=port, s_port=s_port, vlan=vlan)) - if s_port.operational_state == '1': + if s_port.operational_state == 'up': s_port_up += 1 else: s_port_down += 1 From 039e235067f2fea8d770cfe21668c6955252db6e Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 17 Sep 2020 15:17:27 +0200 Subject: [PATCH 054/318] Repaired 'ont add' command --- .../enable/config/interface/ont_added.j2 | 3 + .../config/interface/ont_already_exists.j2 | 2 + .../enable/config/interface/ont_not_online.j2 | 2 + .../Huawei_Base/interfaceCommandProcessor.py | 58 ++++++++++++------- 4 files changed, 45 insertions(+), 20 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_added.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_already_exists.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_not_online.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_added.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_added.j2 new file mode 100644 index 0000000..b2da286 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_added.j2 @@ -0,0 +1,3 @@ + Number of ONTs that can be added: 1, success: 1 + PortID :1, ONTID :2 + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_already_exists.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_already_exists.j2 new file mode 100644 index 0000000..bd31dd9 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_already_exists.j2 @@ -0,0 +1,2 @@ + Failure: The ONT ID has already existed + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_not_online.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_not_online.j2 new file mode 100644 index 0000000..9e23e56 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_not_online.j2 @@ -0,0 +1,2 @@ + Failure: The ONT is not online + diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index dd13c2e..84df4bc 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -155,7 +155,8 @@ def do_display(self, command, *args, context=None): ont_port = self._model.get_ont_port('name', ont_portname) except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError(command=command) + self._write(self._render('ont_not_online', context=context)) + return if port.id != ont.port_id or ont_port.ont_id != ont.id: raise exceptions.CommandSyntaxError(command=command) @@ -555,33 +556,50 @@ def do_shutdown(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_ont(self, command, *args, context=None): - if self._validate(args, 'add', str, str, 'sn-auth', str, 'omci', 'ont-lineprofile-id', str, 'ont-srvprofile-id', - str, 'desc', str): - port_idx, ont_idx, cpe_device_id, lineprofile_id, srvprofile_id, description = \ - self._dissect(args, 'add', str, str, 'sn-auth', str, 'omci', 'ont-lineprofile-id', str, - 'ont-srvprofile-id', str, 'desc', str) + if self._validate(args[:11], 'add', str, str, 'sn-auth', str, 'omci', 'ont-lineprofile-id', str, 'ont-srvprofile-id', + str, 'desc'): + port_idx, ont_idx, cpe_device_id, lineprofile_id, srvprofile_id = \ + self._dissect(args[:11], 'add', str, str, 'sn-auth', str, 'omci', 'ont-lineprofile-id', str, + 'ont-srvprofile-id', str, 'desc') + + def arg_joiner(arguments): + saved_args = [] + save = False + + if len(arguments) == 1: + return arguments + + for i in range(len(arguments)): + if arguments[i].startswith("\""): + save = True + if save: + saved_args.append(arguments[i]) + if arguments[i].endswith("\""): + save = False + arg = ' '.join(saved_args).replace("\"", "") + + return arg + + description = arg_joiner(args[11:]) + card = context['component'] - # create ont port = self._model.get_port('name', card.name + '/' + port_idx) + + ont = None try: - self._model.get_ont('name', card.name + '/' + port_idx + '/' + ont_idx) - raise exceptions.CommandSyntaxError(command=command) + ont = self._model.get_ont('name', card.name + '/' + port_idx + '/' + ont_idx) except exceptions.InvalidInputError: pass - ont = self._model.add_ont(port_id=port.id, name=card.name + '/' + port_idx + '/' + ont_idx, + + if ont is not None: + self._write(self._render('ont_already_exists', context=context)) + return + + self._model.add_ont(port_id=port.id, name=card.name + '/' + port_idx + '/' + ont_idx, description=description, lineprofile_id=lineprofile_id, srvprofile_id=srvprofile_id) - if ont is None: - raise exceptions.CommandSyntaxError(command=command) - - try: - ont = self._model.get_ont('name', card.name + '/' + port_idx + '/' + ont_idx) - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError(command=command) - ont_port = self._model.add_ont_port(ont_id=ont.id) - if ont_port is None: - raise exceptions.CommandSyntaxError(command=command) + self._write(self._render('ont_added', context=context)) elif self._validate(args, 'delete', str, str): # delete all subcomponents port_idx, ont_idx = self._dissect(args, 'delete', str, str) From 242d444ae10d22d1500a2935dce9ada4054332d3 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Thu, 17 Sep 2020 16:38:58 +0200 Subject: [PATCH 055/318] Added more ports to the ftth cards & removed wrong function --- bootup/conf/bootstraps/create-huawei-5623.sh | 313 +++++++++++++++++- .../Huawei_Base/configCommandProcessor.py | 16 - 2 files changed, 309 insertions(+), 20 deletions(-) diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index a5e3a95..b755e7a 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -52,8 +52,18 @@ path="`dirname \"$0\"`" # | | |-> Cpe 0/2/1 0/1 1 # # | | |-> CpePort 0/2/1 0/1 1/1 # # | |-> Port 0/2/2 # -# | |-> Ont 0/2/2 0 # -# | |-> OntPort 0/2/2 0/1 # +# | | |-> Ont 0/2/2 0 # +# | | |-> OntPort 0/2/2 0/1 # +# | |-> Port 0/2/3 # +# | | |-> Ont 0/2/3 0 # +# | | |-> OntPort 0/2/3 0/1 # +# | | |-> Cpe 0/2/3 0/1 1 # +# | | |-> CpePort 0/2/3 0/1 1/1 # +# | |-> Port 0/2/4 # +# | |-> Ont 0/2/4 0 # +# | |-> OntPort 0/2/4 0/1 # +# | | |-> Cpe 0/2/4 0/1 1 # +# | | |-> CpePort 0/2/4 0/1 1/1 # # | # # |---> Card 0/3 (ftth-pon) # # | |-> Port 0/3/0 # @@ -81,8 +91,18 @@ path="`dirname \"$0\"`" # | | |-> Cpe 0/4/1 0/1 1 # # | | |-> CpePort 0/4/1 0/1 1/1 # # | |-> Port 0/4/2 # -# | |-> Ont 0/4/2 0 # -# | |-> OntPort 0/4/2 0/1 # +# | | |-> Ont 0/4/2 0 # +# | | |-> OntPort 0/4/2 0/1 # +# | |-> Port 0/4/3 # +# | | |-> Ont 0/4/3 0 # +# | | |-> OntPort 0/4/3 0/1 # +# | | |-> Cpe 0/4/3 0/1 1 # +# | | |-> CpePort 0/4/3 0/1 1/1 # +# | |-> Port 0/4/4 # +# | |-> Ont 0/4/4 0 # +# | |-> OntPort 0/4/4 0/1 # +# | | |-> Cpe 0/4/4 0/1 1 # +# | | |-> CpePort 0/4/4 0/1 1/1 # #--------------------------------------------------------# # Create a network device (admin operation) @@ -673,6 +693,149 @@ req='{ ont_port_0_2_2_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +### PORT 0/2/3 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card_0_2', + "description": "Physical port 0/2/3", + "loopback": "disable", + "upstream": 0, + "downstream": 0, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "1", + "operational_state": "1" +}' + +port_0_2_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Ont at port 0/2/3 ### + +# Create a physical ont at the network device (admin operation) +req='{ + "port_id":'$port_0_2_3', + "description": "Ont 0/2/3 0", + "memory_occupation": "50%", + "cpu_occupation": "1%", + "operational_state": "1", + "admin_state": "1", + "index": 0, + "vendor_id": "HWTC", + "version": "535.B", + "software_version": "V3R025C29D195" +}' + +ont_0_2_3_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### OntPort 0/2/3 0/1 ### + +# Create a physical ont-port at the ont (admin operation) +req='{ + "ont_id": '$ont_0_2_3_0', + "ont_port_index": 0, + "description": "0/2/3 0/1", + "operational_state": "1", + "admin_state": "1", + "ont_port_type": "ETH" +}' + +ont_port_0_2_3_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) + +### Cpe 0/2/3 0/1 1 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "ont_port_id": '$ont_port_0_2_3_0_1', + "description": "Cpe 0/2/3 0/1 1", + "admin_state": "1", + "mac": "e8a0-c51e-8adc" +}' + +cpe_0_2_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 0/2/3 0/1 1/1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_2_3_0_1_1', + "description": "CpePort 0/2/3 0/1 1/1" +}' + +cpe_port_0_2_3_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + +### PORT 0/2/4 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card_0_2', + "description": "Physical port 0/2/4", + "loopback": "disable", + "upstream": 0, + "downstream": 0, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "1", + "operational_state": "1", + "speed_h": "100" +}' + +port_0_2_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Ont at port 0/2/4 ### + +# Create a physical ont at the network device (admin operation) +req='{ + "port_id":'$port_0_2_4', + "description": "Ont 0/2/4 0", + "memory_occupation": "50%", + "cpu_occupation": "1%", + "operational_state": "1", + "admin_state": "1", + "index": 0, + "vendor_id": "HWTC", + "version": "535.B", + "software_version": "V3R025C29D195" +}' + +ont_0_2_4_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### OntPort 0/2/4 0/1 ### + +# Create a physical ont-port at the ont (admin operation) +req='{ + "ont_id": '$ont_0_2_4_0', + "ont_port_index": 0, + "description": "0/2/4 0/1", + "operational_state": "1", + "admin_state": "1", + "ont_port_type": "ETH" +}' + +ont_port_0_2_4_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) + +### Cpe 0/2/4 0/1 1 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "ont_port_id": '$ont_port_0_2_4_0_1', + "description": "Cpe 0/2/4 0/1 1", + "admin_state": "1", + "mac": "b2b5-e273-7860" +}' + +cpe_0_2_4_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 0/2/4 0/1 1/1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_2_4_0_1_1', + "description": "CpePort 0/2/4 0/1 1/1" +}' + +cpe_port_0_2_4_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + ### Card 0/3 ### # Create a physical card at the network device (admin operation) @@ -1080,6 +1243,148 @@ req='{ ont_port_0_4_2_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +### PORT 0/4/3 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card_0_4', + "description": "Physical port 0/4/3", + "loopback": "disable", + "upstream": 0, + "downstream": 0, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "1", + "operational_state": "1" +}' + +port_0_4_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Ont at port 0/4/3 ### + +# Create a physical ont at the network device (admin operation) +req='{ + "port_id":'$port_0_4_3', + "description": "Ont 0/4/3 0", + "memory_occupation": "50%", + "cpu_occupation": "1%", + "operational_state": "1", + "admin_state": "1", + "index": 0, + "vendor_id": "HWTC", + "version": "535.B", + "software_version": "V3R025C29D195" +}' + +ont_0_4_3_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### OntPort 0/4/3 0/1 ### + +# Create a physical ont-port at the ont (admin operation) +req='{ + "ont_id": '$ont_0_4_3_0', + "ont_port_index": 0, + "description": "0/4/3 0/1", + "operational_state": "1", + "admin_state": "1", + "ont_port_type": "ETH" +}' + +ont_port_0_4_3_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) + +### Cpe 0/4/3 0/1 1 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "ont_port_id": '$ont_port_0_4_3_0_1', + "description": "Cpe 0/4/3 0/1 1", + "admin_state": "1", + "mac": "e8a0-c51e-8adc" +}' + +cpe_0_4_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 0/4/3 0/1 1/1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_4_3_0_1_1', + "description": "CpePort 0/4/3 0/1 1/1" +}' + +cpe_port_0_2_4_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + +### PORT 0/4/4 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card_0_4', + "description": "Physical port 0/4/4", + "loopback": "disable", + "upstream": 0, + "downstream": 0, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "1", + "operational_state": "1" +}' + +port_0_4_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Ont at port 0/4/4 ### + +# Create a physical ont at the network device (admin operation) +req='{ + "port_id":'$port_0_4_4', + "description": "Ont 0/4/4 0", + "memory_occupation": "50%", + "cpu_occupation": "1%", + "operational_state": "1", + "admin_state": "1", + "index": 0, + "vendor_id": "HWTC", + "version": "535.B", + "software_version": "V3R025C29D195" +}' + +ont_0_4_4_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) + +### OntPort 0/4/4 0/1 ### + +# Create a physical ont-port at the ont (admin operation) +req='{ + "ont_id": '$ont_0_4_4_0', + "ont_port_index": 0, + "description": "0/4/4 0/1", + "operational_state": "1", + "admin_state": "1", + "ont_port_type": "ETH" +}' + +ont_port_0_4_4_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) + +### Cpe 0/4/4 0/1 1 ### + +# Create a physical cpe at the ont-port (admin operation) +req='{ + "ont_port_id": '$ont_port_0_4_4_0_1', + "description": "Cpe 0/4/4 0/1 1", + "admin_state": "1", + "mac": "444c-8a1a-7596" +}' + +cpe_0_4_4_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) + +### CpePort 0/4/4 0/1 1/1 ### + +# Create a physical cpe-port at the cpe (admin operation) +req='{ + "cpe_id": '$cpe_0_4_4_0_1_1', + "description": "CpePort 0/4/4 0/1 1/1" +}' + +cpe_port_0_4_4_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) + ### Management Card 0/6 ### # Create a physical card at the network device (admin operation) diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index c5a3742..eb6fc07 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -990,22 +990,6 @@ def do_port(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def do_deactivate(self, command, *args, context=None): - if self._validate(args, 'all'): - for component in self._model.cpes: - component.down() - for component in self._model.ont_ports: - component.down() - for component in self._model.onts: - component.down() - for component in self._model.ports: - component.admin_down() - for component in self._model.service_ports: - component.set_admin_state(0) - return - else: - raise exceptions.CommandSyntaxError(command=command) - def do_xdsl(self, command, *args, context=None): if self._validate(args, 'vectoring-group', 'link', 'add', str, str): profile_idx, port_idx = self._dissect(args, 'vectoring-group', 'link', 'add', str, str) From b4faed8aa3587cdedc31377c3a723633eca3467f Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 18 Sep 2020 08:36:56 +0200 Subject: [PATCH 056/318] Reorganized setup-script for Huawei 5612A box --- bootup/conf/bootstraps/create-huawei-5623.sh | 893 +++++++++---------- 1 file changed, 446 insertions(+), 447 deletions(-) diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index b755e7a..e86cd5f 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -22,16 +22,7 @@ path="`dirname \"$0\"`" #--------------------------------------------------------# # # # Subrack 0 # -# |---> Card 0/0 (vdsl) # -# | |-> Port 0/0/0 # -# | | |-> Cpe 0/0/0 1 # -# | | |-> CpePort 0/0/0 1/1 # -# | |-> Port 0/0/1 # -# | | |-> Cpe 0/0/1 1 # -# | | |-> CpePort 0/0/1 1/1 # -# | |-> Port 0/0/2 # -# | # -# |---> Card 0/1 (adsl) # +# |---> Card 0/1 (vdsl) # # | |-> Port 0/1/0 # # | | |-> Cpe 0/1/0 1 # # | | |-> CpePort 0/1/0 1/1 # @@ -40,69 +31,78 @@ path="`dirname \"$0\"`" # | | |-> CpePort 0/1/1 1/1 # # | |-> Port 0/1/2 # # | # -# |---> Card 0/2 (ftth) # +# |---> Card 0/2 (adsl) # # | |-> Port 0/2/0 # -# | | |-> Ont 0/2/0 0 # -# | | |-> OntPort 0/2/0 0/1 # -# | | |-> Cpe 0/2/0 0/1 1 # -# | | |-> CpePort 0/2/0 0/1 1/1 # +# | | |-> Cpe 0/2/0 1 # +# | | |-> CpePort 0/2/0 1/1 # # | |-> Port 0/2/1 # -# | | |-> Ont 0/2/1 0 # -# | | |-> OntPort 0/2/1 0/1 # -# | | |-> Cpe 0/2/1 0/1 1 # -# | | |-> CpePort 0/2/1 0/1 1/1 # +# | | |-> Cpe 0/2/1 1 # +# | | |-> CpePort 0/2/1 1/1 # # | |-> Port 0/2/2 # -# | | |-> Ont 0/2/2 0 # -# | | |-> OntPort 0/2/2 0/1 # -# | |-> Port 0/2/3 # -# | | |-> Ont 0/2/3 0 # -# | | |-> OntPort 0/2/3 0/1 # -# | | |-> Cpe 0/2/3 0/1 1 # -# | | |-> CpePort 0/2/3 0/1 1/1 # -# | |-> Port 0/2/4 # -# | |-> Ont 0/2/4 0 # -# | |-> OntPort 0/2/4 0/1 # -# | | |-> Cpe 0/2/4 0/1 1 # -# | | |-> CpePort 0/2/4 0/1 1/1 # # | # -# |---> Card 0/3 (ftth-pon) # +# |---> Card 0/3 (ftth) # # | |-> Port 0/3/0 # -# | |-> Ont 0/3/0 0 # -# | | |-> OntPort 0/3/0 0/1 # -# | | |-> Cpe 0/3/0 0/1 1 # -# | | |-> CpePort 0/3/0 0/1 1/1 # -# | |-> Ont 0/3/0 1 # -# | |-> OntPort 0/3/0 1/1 # -# | | |-> Cpe 0/3/0 1/1 1 # -# | | |-> CpePort 0/3/0 1/1 1/1 # -# | |-> OntPort 0/3/0 1/2 # -# | |-> Cpe 0/3/0 1/2 1 # -# | |-> CpePort 0/3/0 1/2 1/1 # +# | | |-> Ont 0/3/0 0 # +# | | |-> OntPort 0/3/0 0/1 # +# | | |-> Cpe 0/3/0 0/1 1 # +# | | |-> CpePort 0/3/0 0/1 1/1 # +# | |-> Port 0/3/1 # +# | | |-> Ont 0/3/1 0 # +# | | |-> OntPort 0/3/1 0/1 # +# | | |-> Cpe 0/3/1 0/1 1 # +# | | |-> CpePort 0/3/1 0/1 1/1 # +# | |-> Port 0/3/2 # +# | | |-> Ont 0/3/2 0 # +# | | |-> OntPort 0/3/2 0/1 # +# | |-> Port 0/3/3 # +# | | |-> Ont 0/3/3 0 # +# | | |-> OntPort 0/3/3 0/1 # +# | | |-> Cpe 0/3/3 0/1 1 # +# | | |-> CpePort 0/3/3 0/1 1/1 # +# | |-> Port 0/3/4 # +# | |-> Ont 0/3/4 0 # +# | |-> OntPort 0/3/4 0/1 # +# | |-> Cpe 0/3/4 0/1 1 # +# | |-> CpePort 0/3/4 0/1 1/1 # # | # -# |---> Card 0/4 (ftth) # +# |---> Card 0/4 (ftth-pon) # # | |-> Port 0/4/0 # -# | | |-> Ont 0/4/0 0 # -# | | |-> OntPort 0/4/0 0/1 # -# | | |-> Cpe 0/4/0 0/1 1 # -# | | |-> CpePort 0/4/0 0/1 1/1 # -# | |-> Port 0/4/1 # -# | | |-> Ont 0/4/1 0 # -# | | |-> OntPort 0/4/1 0/1 # -# | | |-> Cpe 0/4/1 0/1 1 # -# | | |-> CpePort 0/4/1 0/1 1/1 # -# | |-> Port 0/4/2 # -# | | |-> Ont 0/4/2 0 # -# | | |-> OntPort 0/4/2 0/1 # -# | |-> Port 0/4/3 # -# | | |-> Ont 0/4/3 0 # -# | | |-> OntPort 0/4/3 0/1 # -# | | |-> Cpe 0/4/3 0/1 1 # -# | | |-> CpePort 0/4/3 0/1 1/1 # -# | |-> Port 0/4/4 # -# | |-> Ont 0/4/4 0 # -# | |-> OntPort 0/4/4 0/1 # -# | | |-> Cpe 0/4/4 0/1 1 # -# | | |-> CpePort 0/4/4 0/1 1/1 # +# | |-> Ont 0/4/0 0 # +# | | |-> OntPort 0/4/0 0/1 # +# | | |-> Cpe 0/4/0 0/1 1 # +# | | |-> CpePort 0/4/0 0/1 1/1 # +# | |-> Ont 0/4/0 1 # +# | |-> OntPort 0/4/0 1/1 # +# | | |-> Cpe 0/4/0 1/1 1 # +# | | |-> CpePort 0/4/0 1/1 1/1 # +# | |-> OntPort 0/4/0 1/2 # +# | |-> Cpe 0/4/0 1/2 1 # +# | |-> CpePort 0/4/0 1/2 1/1 # +# | # +# |---> Card 0/5 (ftth) # +# | |-> Port 0/5/0 # +# | | |-> Ont 0/5/0 0 # +# | | |-> OntPort 0/5/0 0/1 # +# | | |-> Cpe 0/5/0 0/1 1 # +# | | |-> CpePort 0/5/0 0/1 1/1 # +# | |-> Port 0/5/1 # +# | | |-> Ont 0/5/1 0 # +# | | |-> OntPort 0/5/1 0/1 # +# | | |-> Cpe 0/5/1 0/1 1 # +# | | |-> CpePort 0/5/1 0/1 1/1 # +# | |-> Port 0/5/2 # +# | | |-> Ont 0/5/2 0 # +# | | |-> OntPort 0/5/2 0/1 # +# | |-> Port 0/5/3 # +# | | |-> Ont 0/5/3 0 # +# | | |-> OntPort 0/5/3 0/1 # +# | | |-> Cpe 0/5/3 0/1 1 # +# | | |-> CpePort 0/5/3 0/1 1/1 # +# | |-> Port 0/5/4 # +# | |-> Ont 0/5/4 0 # +# | |-> OntPort 0/5/4 0/1 # +# | |-> Cpe 0/5/4 0/1 1 # +# | |-> CpePort 0/5/4 0/1 1/1 # #--------------------------------------------------------# # Create a network device (admin operation) @@ -256,14 +256,15 @@ req='{ subrack_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks) -### Card 0/0 ### +### Management Card 0/0 ### # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_0', "description": "Physical card 0/0", - "product": "vdsl", - "board_name": "H80DSDPM" + "product": "mgnt", + "board_name": "HS22CCVW", + "board_status": "Active_normal" }' card_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -280,62 +281,132 @@ req='{ "upstream_max": 100000, "downstream_max": 100000, "admin_state": "1", - "operational_state": "1" + "operational_state": "1", + "combo_status": "-", + "optic_status": "normal", + "mdi": "-", + "speed_h": "auto_1000", + "duplex": "auto_full", + "flow_ctrl": "off", + "active_state": "active", + "link": "online", + "alm_prof_15_min" : "-", + "warn_prof_15_min": "-", + "alm_prof_24_hour": "-", + "warn_prof_24_hour": "-" }' port_0_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +### PORT 0/0/1 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card_0_0', + "description": "Physical port 0/0/1", + "loopback": "disable", + "upstream": 10000, + "downstream": 25000, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "1", + "operational_state": "1", + "combo_status": "-", + "optic_status": "normal", + "mdi": "-", + "speed_h": "auto_1000", + "duplex": "auto_full", + "flow_ctrl": "off", + "active_state": "active", + "link": "online", + "alm_prof_15_min" : "-", + "warn_prof_15_min": "-", + "alm_prof_24_hour": "-", + "warn_prof_24_hour": "-" +}' + +port_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Card 0/1 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_0', + "description": "Physical card 0/1", + "product": "vdsl", + "board_name": "H80DSDPM" +}' + +card_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### PORT 0/1/0 and deps ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$card_0_1', + "description": "Physical port 0/1/0", + "loopback": "disable", + "upstream": 10000, + "downstream": 25000, + "upstream_max": 100000, + "downstream_max": 100000, + "admin_state": "1", + "operational_state": "1" +}' + +port_0_1_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + ### Serviceport 0 ### req='{ "name": "0", - "connected_id": '$port_0_0_0', + "connected_id": '$port_0_1_0', "connected_type": "port", "admin_state": "1", "operational_state": "1" }' -service_port_0_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) +service_port_0_1_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) ### Service PPPoE Vlan at ServicePort 0 ### req='{ "name": "2620", - "service_port_id": '$service_port_0_0_0', + "service_port_id": '$service_port_0_1_0', "vlan_id": '$vlan_pppoe', - "card_id": '$card_0_0' + "card_id": '$card_0_1' }' -service_vlan_0_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlans) +service_vlan_0_1_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlans) -### Cpe at port 0/0/0 ### +### Cpe at port 0/1/0 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "port_id": '$port_0_0_0', - "description": "Cpe 0/0/0 1", + "port_id": '$port_0_1_0', + "description": "Cpe 0/1/0 1", "mac": "03ed-5da1-4d5d", "admin_state": "1" }' -cpe_0_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_1_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) ### CpePort 1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_0_0_1', - "description": "CpePort 0/0/0 1/1" + "cpe_id": '$cpe_0_1_0_1', + "description": "CpePort 0/1/0 1/1" }' -cpe_port_0_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +cpe_port_0_1_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) -### PORT 0/0/1 and deps ### +### PORT 0/1/1 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_0', - "description": "Physical port 0/0/1", + "card_id": '$card_0_1', + "description": "Physical port 0/1/1", "loopback": "disable", "upstream": 0, "downstream": 0, @@ -345,36 +416,36 @@ req='{ "operational_state": "0" }' -port_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Cpe at port 0/0/1 ### +### Cpe at port 0/1/1 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "port_id": '$port_0_0_1', - "description": "Cpe 0/0/1 1", + "port_id": '$port_0_1_1', + "description": "Cpe 0/1/1 1", "mac": "8e1c-0205-a3dc", "admin_state": "0" }' -cpe_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) ### CpePort 1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_0_1_1', - "description": "CpePort 0/0/1 1/1" + "cpe_id": '$cpe_0_1_1_1', + "description": "CpePort 0/1/1 1/1" }' -cpe_port_0_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +cpe_port_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) -### PORT 0/0/2 and deps ### +### PORT 0/1/2 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_0', - "description": "Physical port 0/0/2", + "card_id": '$card_0_1', + "description": "Physical port 0/1/2", "loopback": "disable", "upstream": 0, "downstream": 0, @@ -384,26 +455,26 @@ req='{ "operational_state": "0" }' -port_0_0_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_1_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Card 0/1 ### +### Card 0/2 ### # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_0', - "description": "Physical card 0/1", + "description": "Physical card 0/2", "product": "adsl", "board_name": "H83BVCNN" }' -card_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +card_0_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) -### PORT 0/1/0 and deps ### +### PORT 0/2/0 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_1', - "description": "Physical port 0/1/0", + "card_id": '$card_0_2', + "description": "Physical port 0/2/0", "loopback": "disable", "upstream": 10000, "downstream": 25000, @@ -413,36 +484,36 @@ req='{ "operational_state": "1" }' -port_0_1_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_2_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Cpe at port 0/1/0 ### +### Cpe at port 0/2/0 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "port_id": '$port_0_1_0', - "description": "Cpe 0/1/0 1", + "port_id": '$port_0_2_0', + "description": "Cpe 0/2/0 1", "mac": "6126-5ceb-8aa6", "admin_state": "1" }' -cpe_0_1_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_2_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) ### CpePort 1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_1_0_1', - "description": "CpePort 0/1/0 1/1" + "cpe_id": '$cpe_0_2_0_1', + "description": "CpePort 0/2/0 1/1" }' -cpe_port_0_1_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +cpe_port_0_2_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) -### PORT 0/1/1 and deps ### +### PORT 0/2/1 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_1', - "description": "Physical port 0/1/1", + "card_id": '$card_0_2', + "description": "Physical port 0/2/1", "loopback": "disable", "upstream": 0, "downstream": 0, @@ -452,36 +523,36 @@ req='{ "operational_state": "0" }' -port_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Cpe at port 0/1/1 ### +### Cpe at port 0/2/1 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "port_id": '$port_0_1_1', - "description": "Cpe 0/1/1 1", + "port_id": '$port_0_2_1', + "description": "Cpe 0/2/1 1", "mac": "49a6-2391-f47b", "admin_state": "0" }' -cpe_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_2_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) ### CpePort 1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_1_1_1', - "description": "CpePort 0/1/1 1/1" + "cpe_id": '$cpe_0_2_1_1', + "description": "CpePort 0/2/1 1/1" }' -cpe_port_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +cpe_port_0_2_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) -### PORT 0/1/2 and deps ### +### PORT 0/2/2 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_1', - "description": "Physical port 0/1/2", + "card_id": '$card_0_2', + "description": "Physical port 0/2/2", "loopback": "disable", "upstream": 0, "downstream": 0, @@ -491,26 +562,26 @@ req='{ "operational_state": "0" }' -port_0_1_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_2_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Card 0/2 ### +### Card 0/3 ### # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_0', - "description": "Physical card 0/2", + "description": "Physical card 0/3", "product": "ftth", "board_name": "H831EIUD" }' -card_0_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +card_0_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) -### PORT 0/2/0 and deps ### +### PORT 0/3/0 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_2', - "description": "Physical port 0/2/0", + "card_id": '$card_0_3', + "description": "Physical port 0/3/0", "loopback": "disable", "upstream": 10000, "downstream": 25000, @@ -520,14 +591,14 @@ req='{ "operational_state": "1" }' -port_0_2_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_3_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Ont at port 0/2/0 ### +### Ont at port 0/3/0 ### # Create a physical ont at the network device (admin operation) req='{ - "port_id":'$port_0_2_0', - "description": "Ont 0/2/0 0", + "port_id":'$port_0_3_0', + "description": "Ont 0/3/0 0", "memory_occupation": "50%", "cpu_occupation": "1%", "operational_state": "1", @@ -538,50 +609,50 @@ req='{ "software_version": "V3R025C29D195" }' -ont_0_2_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) +ont_0_3_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) -### OntPort 0/2/0 0/1 ### +### OntPort 0/3/0 0/1 ### # Create a physical ont-port at the ont (admin operation) req='{ - "ont_id": '$ont_0_2_0_0', + "ont_id": '$ont_0_3_0_0', "ont_port_index": 0, - "description": "0/2/0 0/1", + "description": "0/3/0 0/1", "operational_state": "1", "admin_state": "1", "ont_port_type": "ETH" }' -ont_port_0_2_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +ont_port_0_3_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) -### Cpe 0/2/0 0/1 1 ### +### Cpe 0/3/0 0/1 1 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "ont_port_id": '$ont_port_0_2_0_0_1', - "description": "Cpe 0/2/0 0/1 1", + "ont_port_id": '$ont_port_0_3_0_0_1', + "description": "Cpe 0/3/0 0/1 1", "admin_state": "1", "mac": "a710-053f-5796" }' -cpe_0_2_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_3_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) -### CpePort 0/2/0 0/1 1/1 ### +### CpePort 0/3/0 0/1 1/1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_2_0_0_1_1', - "description": "CpePort 0/2/0 0/1 1/1" + "cpe_id": '$cpe_0_3_0_0_1_1', + "description": "CpePort 0/3/0 0/1 1/1" }' -cpe_port_0_2_0_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +cpe_port_0_3_0_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) -### PORT 0/2/1 and deps ### +### PORT 0/3/1 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_2', - "description": "Physical port 0/2/1", + "card_id": '$card_0_3', + "description": "Physical port 0/3/1", "loopback": "disable", "upstream": 0, "downstream": 0, @@ -591,14 +662,14 @@ req='{ "operational_state": "0" }' -port_0_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_3_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Ont at port 0/2/1 ### +### Ont at port 0/3/1 ### # Create a physical ont at the network device (admin operation) req='{ - "port_id":'$port_0_2_1', - "description": "Ont 0/2/1 0", + "port_id":'$port_0_3_1', + "description": "Ont 0/3/1 0", "memory_occupation": "50%", "cpu_occupation": "1%", "operational_state": "1", @@ -606,50 +677,50 @@ req='{ "index": 0 }' -ont_0_2_1_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) +ont_0_3_1_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) -### OntPort 0/2/1 0/1 ### +### OntPort 0/3/1 0/1 ### # Create a physical ont-port at the ont (admin operation) req='{ - "ont_id": '$ont_0_2_1_0', + "ont_id": '$ont_0_3_1_0', "ont_port_index": 0, - "description": "0/2/1 0/1", + "description": "0/3/1 0/1", "operational_state": "0", "admin_state": "1", "ont_port_type": "ETH" }' -ont_port_0_2_1_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +ont_port_0_3_1_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) -### Cpe 0/2/1 0/1 1 ### +### Cpe 0/3/1 0/1 1 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "ont_port_id": '$ont_port_0_2_1_0_1', - "description": "Cpe 0/2/1 0/1 1", + "ont_port_id": '$ont_port_0_3_1_0_1', + "description": "Cpe 0/3/1 0/1 1", "admin_state": "0", "mac": "d43f-3def-d99a" }' -cpe_0_2_1_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_3_1_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) -### CpePort 0/2/1 0/1 1/1 ### +### CpePort 0/3/1 0/1 1/1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_2_1_0_1_1', - "description": "CpePort 0/2/1 0/1 1/1" + "cpe_id": '$cpe_0_3_1_0_1_1', + "description": "CpePort 0/3/1 0/1 1/1" }' -cpe_port_0_2_1_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +cpe_port_0_3_1_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) -### PORT 0/2/2 and deps ### +### PORT 0/3/2 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_2', - "description": "Physical port 0/2/2", + "card_id": '$card_0_3', + "description": "Physical port 0/3/2", "loopback": "disable", "upstream": 0, "downstream": 0, @@ -659,14 +730,14 @@ req='{ "operational_state": "0" }' -port_0_2_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_3_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Ont at port 0/2/2 ### +### Ont at port 0/3/2 ### # Create a physical ont at the network device (admin operation) req='{ - "port_id":'$port_0_2_2', - "description": "Ont 0/2/2 0", + "port_id":'$port_0_3_2', + "description": "Ont 0/3/2 0", "memory_occupation": "50%", "cpu_occupation": "1%", "operational_state": "1", @@ -677,28 +748,28 @@ req='{ "software_version": "V3R025C29D195" }' -ont_0_2_2_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) +ont_0_3_2_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) -### OntPort 0/2/2 0/1 ### +### OntPort 0/3/2 0/1 ### # Create a physical ont-port at the ont (admin operation) req='{ - "ont_id": '$ont_0_2_2_0', + "ont_id": '$ont_0_3_2_0', "ont_port_index": 0, - "description": "0/2/2 0/1", + "description": "0/3/2 0/1", "operational_state": "0", "admin_state": "0", "ont_port_type": "ETH" }' -ont_port_0_2_2_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +ont_port_0_3_2_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) -### PORT 0/2/3 and deps ### +### PORT 0/3/3 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_2', - "description": "Physical port 0/2/3", + "card_id": '$card_0_3', + "description": "Physical port 0/3/3", "loopback": "disable", "upstream": 0, "downstream": 0, @@ -708,14 +779,14 @@ req='{ "operational_state": "1" }' -port_0_2_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_3_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Ont at port 0/2/3 ### +### Ont at port 0/3/3 ### # Create a physical ont at the network device (admin operation) req='{ - "port_id":'$port_0_2_3', - "description": "Ont 0/2/3 0", + "port_id":'$port_0_3_3', + "description": "Ont 0/3/3 0", "memory_occupation": "50%", "cpu_occupation": "1%", "operational_state": "1", @@ -726,50 +797,50 @@ req='{ "software_version": "V3R025C29D195" }' -ont_0_2_3_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) +ont_0_3_3_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) -### OntPort 0/2/3 0/1 ### +### OntPort 0/3/3 0/1 ### # Create a physical ont-port at the ont (admin operation) req='{ - "ont_id": '$ont_0_2_3_0', + "ont_id": '$ont_0_3_3_0', "ont_port_index": 0, - "description": "0/2/3 0/1", + "description": "0/3/3 0/1", "operational_state": "1", "admin_state": "1", "ont_port_type": "ETH" }' -ont_port_0_2_3_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +ont_port_0_3_3_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) -### Cpe 0/2/3 0/1 1 ### +### Cpe 0/3/3 0/1 1 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "ont_port_id": '$ont_port_0_2_3_0_1', - "description": "Cpe 0/2/3 0/1 1", + "ont_port_id": '$ont_port_0_3_3_0_1', + "description": "Cpe 0/3/3 0/1 1", "admin_state": "1", "mac": "e8a0-c51e-8adc" }' -cpe_0_2_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_3_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) -### CpePort 0/2/3 0/1 1/1 ### +### CpePort 0/3/3 0/1 1/1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_2_3_0_1_1', - "description": "CpePort 0/2/3 0/1 1/1" + "cpe_id": '$cpe_0_3_3_0_1_1', + "description": "CpePort 0/3/3 0/1 1/1" }' -cpe_port_0_2_3_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +cpe_port_0_3_3_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) -### PORT 0/2/4 and deps ### +### PORT 0/3/4 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_2', - "description": "Physical port 0/2/4", + "card_id": '$card_0_3', + "description": "Physical port 0/3/4", "loopback": "disable", "upstream": 0, "downstream": 0, @@ -780,14 +851,14 @@ req='{ "speed_h": "100" }' -port_0_2_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_3_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Ont at port 0/2/4 ### +### Ont at port 0/3/4 ### # Create a physical ont at the network device (admin operation) req='{ - "port_id":'$port_0_2_4', - "description": "Ont 0/2/4 0", + "port_id":'$port_0_3_4', + "description": "Ont 0/3/4 0", "memory_occupation": "50%", "cpu_occupation": "1%", "operational_state": "1", @@ -798,62 +869,62 @@ req='{ "software_version": "V3R025C29D195" }' -ont_0_2_4_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) +ont_0_3_4_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) -### OntPort 0/2/4 0/1 ### +### OntPort 0/3/4 0/1 ### # Create a physical ont-port at the ont (admin operation) req='{ - "ont_id": '$ont_0_2_4_0', + "ont_id": '$ont_0_3_4_0', "ont_port_index": 0, - "description": "0/2/4 0/1", + "description": "0/3/4 0/1", "operational_state": "1", "admin_state": "1", "ont_port_type": "ETH" }' -ont_port_0_2_4_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +ont_port_0_3_4_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) -### Cpe 0/2/4 0/1 1 ### +### Cpe 0/3/4 0/1 1 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "ont_port_id": '$ont_port_0_2_4_0_1', - "description": "Cpe 0/2/4 0/1 1", + "ont_port_id": '$ont_port_0_3_4_0_1', + "description": "Cpe 0/3/4 0/1 1", "admin_state": "1", "mac": "b2b5-e273-7860" }' -cpe_0_2_4_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_3_4_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) -### CpePort 0/2/4 0/1 1/1 ### +### CpePort 0/3/4 0/1 1/1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_2_4_0_1_1', - "description": "CpePort 0/2/4 0/1 1/1" + "cpe_id": '$cpe_0_3_4_0_1_1', + "description": "CpePort 0/3/4 0/1 1/1" }' -cpe_port_0_2_4_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +cpe_port_0_3_4_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) -### Card 0/3 ### +### Card 0/4 ### # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_0', - "description": "Physical card 0/3", + "description": "Physical card 0/4", "product": "ftth-pon", "board_name": "H807GPBH" }' -card_0_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +card_0_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) -### PORT 0/3/0 and deps ### +### PORT 0/4/0 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_3', - "description": "Physical port 0/3/0", + "card_id": '$card_0_4', + "description": "Physical port 0/4/0", "loopback": "disable", "upstream": 10000, "downstream": 25000, @@ -863,14 +934,14 @@ req='{ "operational_state": "1" }' -port_0_3_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_4_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Ont at port 0/3/0 ### +### Ont at port 0/4/0 ### # Create a physical ont at the network device (admin operation) req='{ - "port_id":'$port_0_3_0', - "description": "Ont 0/3/0 0", + "port_id":'$port_0_4_0', + "description": "Ont 0/4/0 0", "memory_occupation": "50%", "cpu_occupation": "1%", "operational_state": "1", @@ -878,50 +949,50 @@ req='{ "index": 0 }' -ont_0_3_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) +ont_0_4_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) -### OntPort 0/3/0 0/1 ### +### OntPort 0/4/0 0/1 ### # Create a physical ont-port at the ont (admin operation) req='{ - "ont_id": '$ont_0_3_0_0', + "ont_id": '$ont_0_4_0_0', "ont_port_index": 0, - "description": "0/3/0 0/1", + "description": "0/4/0 0/1", "operational_state": "0", "admin_state": "1", "ont_port_type": "ETH" }' -ont_port_0_3_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +ont_port_0_4_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) -### Cpe 0/3/0 0/1 1 ### +### Cpe 0/4/0 0/1 1 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "ont_port_id": '$ont_port_0_3_0_0_1', - "description": "Cpe 0/3/0 0/1 1", + "ont_port_id": '$ont_port_0_4_0_0_1', + "description": "Cpe 0/4/0 0/1 1", "admin_state": "0", "mac": "7b80-9599-6590" }' -cpe_0_3_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_4_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) -### CpePort 0/3/0 0/1 1/1 ### +### CpePort 0/4/0 0/1 1/1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_3_0_0_1_1', - "description": "CpePort 0/3/0 0/1 1/1" + "cpe_id": '$cpe_0_4_0_0_1_1', + "description": "CpePort 0/4/0 0/1 1/1" }' -cpe_port_0_3_0_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +cpe_port_0_4_0_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) -### Ont at port 0/3/0 ### +### Ont at port 0/4/0 ### # Create a physical ont at the network device (admin operation) req='{ - "port_id":'$port_0_3_0', - "description": "Ont 0/3/0 1", + "port_id":'$port_0_4_0', + "description": "Ont 0/4/0 1", "memory_occupation": "50%", "cpu_occupation": "1%", "operational_state": "0", @@ -929,144 +1000,144 @@ req='{ "index": 1 }' -ont_0_3_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) +ont_0_4_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) -### OntPort 0/3/0 1/1 ### +### OntPort 0/4/0 1/1 ### # Create a physical ont-port at the ont (admin operation) req='{ - "ont_id": '$ont_0_3_0_1', + "ont_id": '$ont_0_4_0_1', "ont_port_index": 0, - "description": "0/3/0 1/1", + "description": "0/4/0 1/1", "operational_state": "1", "admin_state": "1", "ont_port_type": "ETH" }' -ont_port_0_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +ont_port_0_4_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) ### Serviceport 1 ### req='{ "name": "1", - "connected_id": '$ont_port_0_3_0_1_1', + "connected_id": '$ont_port_0_4_0_1_1', "connected_type": "ont", "admin_state": "1", "operational_state": "1" }' -service_port_0_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) +service_port_0_4_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) ### Service PPPoE Vlan at ServicePort 1 ### req='{ "name": "2620", - "service_port_id": '$service_port_0_3_0_1_1', + "service_port_id": '$service_port_0_4_0_1_1', "vlan_id": '$vlan_pppoe', - "card_id": '$card_0_3' + "card_id": '$card_0_4' }' -service_vlan_0_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlans) +service_vlan_0_4_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlans) -### Cpe 0/3/0 1/1 1 ### +### Cpe 0/4/0 1/1 1 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "ont_port_id": '$ont_port_0_3_0_1_1', - "description": "Cpe 0/3/0 1/1 1", + "ont_port_id": '$ont_port_0_4_0_1_1', + "description": "Cpe 0/4/0 1/1 1", "admin_state": "1", "mac": "261b-9d83-545a" }' -cpe_0_3_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_4_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) -### CpePort 0/3/0 1/1 1/1 ### +### CpePort 0/4/0 1/1 1/1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_3_0_1_1_1', - "description": "CpePort 0/3/0 1/1 1/1" + "cpe_id": '$cpe_0_4_0_1_1_1', + "description": "CpePort 0/4/0 1/1 1/1" }' -cpe_port_0_3_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +cpe_port_0_4_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) ### Serviceport 2 ### req='{ "name": "2", - "connected_id": '$cpe_port_0_3_0_1_1_1_1', + "connected_id": '$cpe_port_0_4_0_1_1_1_1', "connected_type": "cpe", "admin_state": "1", "operational_state": "1" }' -service_port_0_3_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) +service_port_0_4_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_ports) ### Service PPPoE Vlan at ServicePort 2 ### req='{ "name": "2620", - "service_port_id": '$service_port_0_3_0_1_1_1_1', + "service_port_id": '$service_port_0_4_0_1_1_1_1', "vlan_id": '$vlan_pppoe', - "card_id": '$card_0_3' + "card_id": '$card_0_4' }' -service_vlan_0_3_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlans) +service_vlan_0_4_0_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/service_vlans) -### OntPort 0/3/0 1/2 ### +### OntPort 0/4/0 1/2 ### # Create a physical ont-port at the ont (admin operation) req='{ - "ont_id": '$ont_0_3_0_1', + "ont_id": '$ont_0_4_0_1', "ont_port_index": 0, - "description": "0/3/0 1/2", + "description": "0/4/0 1/2", "operational_state": "0", "admin_state": "1", "ont_port_type": "ETH" }' -ont_port_0_3_0_1_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +ont_port_0_4_0_1_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) -### Cpe 0/3/0 1/2 1 ### +### Cpe 0/4/0 1/2 1 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "ont_port_id": '$ont_port_0_3_0_1_2', - "description": "Cpe 0/3/0 1/2 1", + "ont_port_id": '$ont_port_0_4_0_1_2', + "description": "Cpe 0/4/0 1/2 1", "admin_state": "0", "mac": "261b-9d83-545a" }' -cpe_0_3_0_1_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_4_0_1_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) -### CpePort 0/3/0 1/2 1/1 ### +### CpePort 0/4/0 1/2 1/1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_3_0_1_2_1', - "description": "CpePort 0/3/0 1/2 1/1" + "cpe_id": '$cpe_0_4_0_1_2_1', + "description": "CpePort 0/4/0 1/2 1/1" }' -cpe_port_0_3_0_1_2_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +cpe_port_0_4_0_1_2_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) -### Card 0/4 ### +### Card 0/5 ### # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_0', - "description": "Physical card 0/4", + "description": "Physical card 0/5", "product": "ftth", "board_name": "H802OPGE" }' -card_0_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +card_0_5=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) -### PORT 0/4/0 and deps ### +### PORT 0/5/0 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_4', - "description": "Physical port 0/4/0", + "card_id": '$card_0_5', + "description": "Physical port 0/5/0", "loopback": "disable", "upstream": 10000, "downstream": 25000, @@ -1076,14 +1147,14 @@ req='{ "operational_state": "1" }' -port_0_4_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_5_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Ont at port 0/4/0 ### +### Ont at port 0/5/0 ### # Create a physical ont at the network device (admin operation) req='{ - "port_id":'$port_0_4_0', - "description": "Ont 0/4/0 0", + "port_id":'$port_0_5_0', + "description": "Ont 0/5/0 0", "memory_occupation": "50%", "cpu_occupation": "1%", "operational_state": "1", @@ -1091,50 +1162,50 @@ req='{ "index": 0 }' -ont_0_4_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) +ont_0_5_0_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) -### OntPort 0/4/0 0/1 ### +### OntPort 0/5/0 0/1 ### # Create a physical ont-port at the ont (admin operation) req='{ - "ont_id": '$ont_0_4_0_0', + "ont_id": '$ont_0_5_0_0', "ont_port_index": 0, - "description": "0/4/0 0/1", + "description": "0/5/0 0/1", "operational_state": "1", "admin_state": "1", "ont_port_type": "ETH" }' -ont_port_0_4_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +ont_port_0_5_0_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) -### Cpe 0/4/0 0/1 1 ### +### Cpe 0/5/0 0/1 1 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "ont_port_id": '$ont_port_0_4_0_0_1', - "description": "Cpe 0/4/0 0/1 1", + "ont_port_id": '$ont_port_0_5_0_0_1', + "description": "Cpe 0/5/0 0/1 1", "admin_state": "1", "mac": "0cdb-be79-2528" }' -cpe_0_4_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_5_0_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) -### CpePort 0/4/0 0/1 1/1 ### +### CpePort 0/5/0 0/1 1/1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_4_0_0_1_1', - "description": "CpePort 0/4/0 0/1 1/1" + "cpe_id": '$cpe_0_5_0_0_1_1', + "description": "CpePort 0/5/0 0/1 1/1" }' -cpe_port_0_4_0_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +cpe_port_0_5_0_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) -### PORT 0/4/1 and deps ### +### PORT 0/5/1 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_4', - "description": "Physical port 0/4/1", + "card_id": '$card_0_5', + "description": "Physical port 0/5/1", "loopback": "disable", "upstream": 0, "downstream": 0, @@ -1144,14 +1215,14 @@ req='{ "operational_state": "0" }' -port_0_4_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_5_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Ont at port 0/4/1 ### +### Ont at port 0/5/1 ### # Create a physical ont at the network device (admin operation) req='{ - "port_id":'$port_0_4_1', - "description": "Ont 0/4/1 0", + "port_id":'$port_0_5_1', + "description": "Ont 0/5/1 0", "memory_occupation": "50%", "cpu_occupation": "1%", "operational_state": "1", @@ -1159,50 +1230,50 @@ req='{ "index": 0 }' -ont_0_4_1_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) +ont_0_5_1_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) -### OntPort 0/4/1 0/1 ### +### OntPort 0/5/1 0/1 ### # Create a physical ont-port at the ont (admin operation) req='{ - "ont_id": '$ont_0_4_1_0', + "ont_id": '$ont_0_5_1_0', "ont_port_index": 0, - "description": "0/4/1 0/1", + "description": "0/5/1 0/1", "operational_state": "0", "admin_state": "1", "ont_port_type": "ETH" }' -ont_port_0_4_1_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +ont_port_0_5_1_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) -### Cpe 0/4/1 0/1 1 ### +### Cpe 0/5/1 0/1 1 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "ont_port_id": '$ont_port_0_4_1_0_1', - "description": "Cpe 0/4/1 0/1 1", + "ont_port_id": '$ont_port_0_5_1_0_1', + "description": "Cpe 0/5/1 0/1 1", "admin_state": "0", "mac": "c8cd-656b-7110" }' -cpe_0_4_1_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_5_1_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) -### CpePort 0/4/1 0/1 1/1 ### +### CpePort 0/5/1 0/1 1/1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_4_1_0_1_1', - "description": "CpePort 0/4/1 0/1 1/1" + "cpe_id": '$cpe_0_5_1_0_1_1', + "description": "CpePort 0/5/1 0/1 1/1" }' -cpe_port_0_4_1_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +cpe_port_0_5_1_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) -### PORT 0/4/2 and deps ### +### PORT 0/5/2 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_4', - "description": "Physical port 0/4/2", + "card_id": '$card_0_5', + "description": "Physical port 0/5/2", "loopback": "disable", "upstream": 0, "downstream": 0, @@ -1212,14 +1283,14 @@ req='{ "operational_state": "0" }' -port_0_4_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_5_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) ### Ont at port 0/4/2 ### # Create a physical ont at the network device (admin operation) req='{ - "port_id":'$port_0_4_2', - "description": "Ont 0/4/2 0", + "port_id":'$port_0_5_2', + "description": "Ont 0/5/2 0", "memory_occupation": "50%", "cpu_occupation": "1%", "operational_state": "0", @@ -1227,28 +1298,28 @@ req='{ "index": 0 }' -ont_0_4_2_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) +ont_0_5_2_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) -### OntPort 0/4/2 0/1 ### +### OntPort 0/5/2 0/1 ### # Create a physical ont-port at the ont (admin operation) req='{ - "ont_id": '$ont_0_4_2_0', + "ont_id": '$ont_0_5_2_0', "ont_port_index": 0, - "description": "0/4/2 0/1", + "description": "0/5/2 0/1", "operational_state": "0", "admin_state": "0", "ont_port_type": "ETH" }' -ont_port_0_4_2_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +ont_port_0_5_2_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) -### PORT 0/4/3 and deps ### +### PORT 0/5/3 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_4', - "description": "Physical port 0/4/3", + "card_id": '$card_0_5', + "description": "Physical port 0/5/3", "loopback": "disable", "upstream": 0, "downstream": 0, @@ -1258,14 +1329,14 @@ req='{ "operational_state": "1" }' -port_0_4_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_5_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Ont at port 0/4/3 ### +### Ont at port 0/5/3 ### # Create a physical ont at the network device (admin operation) req='{ - "port_id":'$port_0_4_3', - "description": "Ont 0/4/3 0", + "port_id":'$port_0_5_3', + "description": "Ont 0/5/3 0", "memory_occupation": "50%", "cpu_occupation": "1%", "operational_state": "1", @@ -1276,50 +1347,50 @@ req='{ "software_version": "V3R025C29D195" }' -ont_0_4_3_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) +ont_0_5_3_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) -### OntPort 0/4/3 0/1 ### +### OntPort 0/5/3 0/1 ### # Create a physical ont-port at the ont (admin operation) req='{ - "ont_id": '$ont_0_4_3_0', + "ont_id": '$ont_0_5_3_0', "ont_port_index": 0, - "description": "0/4/3 0/1", + "description": "0/5/3 0/1", "operational_state": "1", "admin_state": "1", "ont_port_type": "ETH" }' -ont_port_0_4_3_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +ont_port_0_5_3_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) -### Cpe 0/4/3 0/1 1 ### +### Cpe 0/5/3 0/1 1 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "ont_port_id": '$ont_port_0_4_3_0_1', - "description": "Cpe 0/4/3 0/1 1", + "ont_port_id": '$ont_port_0_5_3_0_1', + "description": "Cpe 0/5/3 0/1 1", "admin_state": "1", "mac": "e8a0-c51e-8adc" }' -cpe_0_4_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_5_3_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) -### CpePort 0/4/3 0/1 1/1 ### +### CpePort 0/5/3 0/1 1/1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_4_3_0_1_1', - "description": "CpePort 0/4/3 0/1 1/1" + "cpe_id": '$cpe_0_5_3_0_1_1', + "description": "CpePort 0/5/3 0/1 1/1" }' -cpe_port_0_2_4_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) +cpe_port_0_5_4_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) -### PORT 0/4/4 and deps ### +### PORT 0/5/4 and deps ### # Create a physical port at the network device (admin operation) req='{ - "card_id": '$card_0_4', - "description": "Physical port 0/4/4", + "card_id": '$card_0_5', + "description": "Physical port 0/5/4", "loopback": "disable", "upstream": 0, "downstream": 0, @@ -1329,14 +1400,14 @@ req='{ "operational_state": "1" }' -port_0_4_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_0_5_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### Ont at port 0/4/4 ### +### Ont at port 0/5/4 ### # Create a physical ont at the network device (admin operation) req='{ - "port_id":'$port_0_4_4', - "description": "Ont 0/4/4 0", + "port_id":'$port_0_5_4', + "description": "Ont 0/5/4 0", "memory_occupation": "50%", "cpu_occupation": "1%", "operational_state": "1", @@ -1347,112 +1418,40 @@ req='{ "software_version": "V3R025C29D195" }' -ont_0_4_4_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) +ont_0_5_4_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/onts) -### OntPort 0/4/4 0/1 ### +### OntPort 0/5/4 0/1 ### # Create a physical ont-port at the ont (admin operation) req='{ - "ont_id": '$ont_0_4_4_0', + "ont_id": '$ont_0_5_4_0', "ont_port_index": 0, - "description": "0/4/4 0/1", + "description": "0/5/4 0/1", "operational_state": "1", "admin_state": "1", "ont_port_type": "ETH" }' -ont_port_0_4_4_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) +ont_port_0_5_4_0_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ont_ports) -### Cpe 0/4/4 0/1 1 ### +### Cpe 0/5/4 0/1 1 ### # Create a physical cpe at the ont-port (admin operation) req='{ - "ont_port_id": '$ont_port_0_4_4_0_1', - "description": "Cpe 0/4/4 0/1 1", + "ont_port_id": '$ont_port_0_5_4_0_1', + "description": "Cpe 0/5/4 0/1 1", "admin_state": "1", "mac": "444c-8a1a-7596" }' -cpe_0_4_4_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) +cpe_0_5_4_0_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpes) -### CpePort 0/4/4 0/1 1/1 ### +### CpePort 0/5/4 0/1 1/1 ### # Create a physical cpe-port at the cpe (admin operation) req='{ - "cpe_id": '$cpe_0_4_4_0_1_1', + "cpe_id": '$cpe_0_5_4_0_1_1', "description": "CpePort 0/4/4 0/1 1/1" }' -cpe_port_0_4_4_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) - -### Management Card 0/6 ### - -# Create a physical card at the network device (admin operation) -req='{ - "subrack_id": '$subrack_0', - "name": "0/6", - "description": "Physical card 0/6", - "product": "mgnt", - "board_name": "HS22CCVW", - "board_status": "Active_normal" -}' - -card_0_6=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - -### PORT 0/6/0 and deps ### - -# Create a physical port at the network device (admin operation) -req='{ - "card_id": '$card_0_6', - "description": "Physical port 0/6/0", - "loopback": "disable", - "upstream": 10000, - "downstream": 25000, - "upstream_max": 100000, - "downstream_max": 100000, - "admin_state": "1", - "operational_state": "1", - "combo_status": "-", - "optic_status": "normal", - "mdi": "-", - "speed_h": "auto_1000", - "duplex": "auto_full", - "flow_ctrl": "off", - "active_state": "active", - "link": "online", - "alm_prof_15_min" : "-", - "warn_prof_15_min": "-", - "alm_prof_24_hour": "-", - "warn_prof_24_hour": "-" -}' - -port_0_6_0=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) - -### PORT 0/6/1 and deps ### - -# Create a physical port at the network device (admin operation) -req='{ - "card_id": '$card_0_6', - "description": "Physical port 0/6/1", - "loopback": "disable", - "upstream": 10000, - "downstream": 25000, - "upstream_max": 100000, - "downstream_max": 100000, - "admin_state": "1", - "operational_state": "1", - "combo_status": "-", - "optic_status": "normal", - "mdi": "-", - "speed_h": "auto_1000", - "duplex": "auto_full", - "flow_ctrl": "off", - "active_state": "active", - "link": "online", - "alm_prof_15_min" : "-", - "warn_prof_15_min": "-", - "alm_prof_24_hour": "-", - "warn_prof_24_hour": "-" -}' - -port_0_6_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +cpe_port_0_5_4_0_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cpe_ports) From e2c8118a0d7e8cfd9e002f1aef8aa48acbbb43f8 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 18 Sep 2020 08:57:16 +0200 Subject: [PATCH 057/318] Fixed the gpon output for the 'display board' command --- .../Base/Huawei_Base/huaweiBaseCommandProcessor.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py index 6c1a0e5..9767501 100644 --- a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py @@ -134,6 +134,7 @@ def display_board(self, command, args, context=None): elif card.product == 'ftth-pon': text1 = '' text2 = '' + text3 = '' context['spacer1'] = self.create_spacers((18,), (card.power_status,))[0] * ' ' context['spacer2'] = self.create_spacers((35,), (card.power_off_cause,))[0] * ' ' @@ -176,6 +177,7 @@ def display_board(self, command, args, context=None): else: text2 += self._render('display_board_ftth_pon_middle_top', context=context) + text3 += self._render('display_board_ftth_pon_bottom_top', context=context) for ont in onts: self.map_states(ont, 'ont') context['ont_id'] = ont.index @@ -188,25 +190,23 @@ def display_board(self, command, args, context=None): context['spacer12'] = self.create_spacers((9,), (ont.config_state,))[0] * ' ' context['spacer13'] = self.create_spacers((8,), (ont.match_state,))[0] * ' ' context['spacer14'] = self.create_spacers((4,), ('',))[0] * ' ' - text2 += self._render('display_board_ftth_pon_middle_middle', context=dict(context, ont=ont)) - text2 += self._render('display_board_ftth_pon_bottom_top', context=context) context['ont_id'] = ont.index context['spacer_beg3'] = self.create_spacers((4,), (subrackname,))[0] * ' ' context['spacer15'] = self.create_spacers((4,), (cardportname,))[0] * ' ' context['spacer16'] = self.create_spacers((8,), (ont.index,))[0] * ' ' context['spacer17'] = self.create_spacers((3,), ('',))[0] * ' ' - text2 += self._render('display_board_ftth_pon_bottom_middle', + text3 += self._render('display_board_ftth_pon_bottom_middle', context=dict(context, ont=ont)) - text2 += self._render('display_board_ftth_pon_bottom_bottom', context=context) - text2 += self._render('display_board_ftth_pon_ont_summary', context=context) + text3 += self._render('display_board_ftth_pon_bottom_bottom', context=context) + text3 += self._render('display_board_ftth_pon_ont_summary', context=context) text1 += self._render('display_board_ftth_pon_top_bottom', context=context) - text1 += text2 + text1 += text2 + text3 self._write(text1) From 3901ab4425b761cb7b680b8acb44d75d22708d16 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 18 Sep 2020 10:44:21 +0200 Subject: [PATCH 058/318] Made the melt test more true to reality --- bootup/conf/bootstraps/create-huawei-5623.sh | 2 +- .../Base/1/login/mainloop/enable/config/test/melt_test.j2 | 1 + vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index e86cd5f..d9b775e 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -110,7 +110,7 @@ req='{ "vendor": "Huawei", "model": "5623", "version": "A", - "description": "Example Switch", + "description": "Huawei 5623A box", "hostname": "Huawei_5623A", "mgmt_address": "10.0.0.12", "software_version": "MA5623V800R016C00", diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test.j2 index 854406f..5276514 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test.j2 @@ -1,3 +1,4 @@ + Tested port: {{ context.port_name }} Start time of the test: {{ context.time_beg }} End time of the test: {{ context.time_end }} diff --git a/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py index 8c48f67..39ef44e 100644 --- a/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py @@ -61,6 +61,9 @@ def do_xdsl(self, command, *args, context=None): self._write(text) sleep(2) + text = self._render('on_cycle', context=context) + self._write(text) + context['time_end'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") text = self._render('melt_test', context=context) self._write(text) From dafbe4036f94a90cb5d27de452289daac49e3097 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 18 Sep 2020 12:43:58 +0200 Subject: [PATCH 059/318] Added several new error message templates and fixed some bugs in vlan service-profile commands --- .../schemas/huawei_port_profile_schemas.py | 4 +-- .../huawei_resources/huawei_port_profile.py | 1 + nesi/softbox/api/models/portprofile_models.py | 1 + .../operation_not_supported_by_board.j2 | 2 ++ .../enable/config/port_already_in_vlan.j2 | 2 ++ .../enable/config/srvprof/on_cycle.j2 | 2 +- .../enable/config/vlan_already_exists.j2 | 2 -- ...e-profile_vlan-id_profile-id_profile-id.j2 | 2 +- .../vlan_service_profile_does_not_exist.j2 | 2 ++ .../Huawei_Base/configCommandProcessor.py | 30 ++++++++++++------- .../Huawei_Base/enableCommandProcessor.py | 2 +- .../Huawei_Base/userViewCommandProcessor.py | 2 +- 12 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_board.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/port_already_in_vlan.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/vlan_service_profile_does_not_exist.j2 diff --git a/nesi/huawei/api/schemas/huawei_port_profile_schemas.py b/nesi/huawei/api/schemas/huawei_port_profile_schemas.py index 0279aa5..ed27dc4 100644 --- a/nesi/huawei/api/schemas/huawei_port_profile_schemas.py +++ b/nesi/huawei/api/schemas/huawei_port_profile_schemas.py @@ -35,5 +35,5 @@ class Meta: 'AnnexB_G_993_2', 'ETSI', 'us0_psd_mask', 'vdsltoneblackout', 'vmac_ipoe', 'vmac_pppoe', 'vmac_pppoa', 'vlan_mac', 'packet_policy_multicast', 'packet_policy_unicast', - 'security_anti_ipspoofing', - 'security_anti_macspoofing', 'igmp_mismatch', 'commit') + 'security_anti_ipspoofing', 'security_anti_macspoofing', + 'igmp_mismatch', 'commit', 'internal_id') diff --git a/nesi/huawei/huawei_resources/huawei_port_profile.py b/nesi/huawei/huawei_resources/huawei_port_profile.py index a283243..1f6aad0 100644 --- a/nesi/huawei/huawei_resources/huawei_port_profile.py +++ b/nesi/huawei/huawei_resources/huawei_port_profile.py @@ -76,6 +76,7 @@ class HuaweiPortProfile(PortProfile): ETSI = base.Field('ETSI') us0_psd_mask = base.Field('us0_psd_mask') vdsltoneblackout = base.Field('vdsltoneblackout') + internal_id = base.Field('internal_id') vmac_ipoe = base.Field('vmac_ipoe') vmac_pppoe = base.Field('vmac_pppoe') diff --git a/nesi/softbox/api/models/portprofile_models.py b/nesi/softbox/api/models/portprofile_models.py index a912476..d9ea0b7 100644 --- a/nesi/softbox/api/models/portprofile_models.py +++ b/nesi/softbox/api/models/portprofile_models.py @@ -87,6 +87,7 @@ class PortProfile(db.Model): ETSI = db.Column(db.String(), default=None) us0_psd_mask = db.Column(db.Integer(), default=None) vdsltoneblackout = db.Column(db.String(), default=None) + internal_id = db.Column(db.Integer(), default=None) vmac_ipoe = db.Column(db.Enum('enable', 'disable'), default=None) vmac_pppoe = db.Column(db.Enum('enable', 'disable'), default=None) diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_board.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_board.j2 new file mode 100644 index 0000000..0d96e1d --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_board.j2 @@ -0,0 +1,2 @@ + Failure: Board does not support the operation + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/port_already_in_vlan.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/port_already_in_vlan.j2 new file mode 100644 index 0000000..92062b6 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/port_already_in_vlan.j2 @@ -0,0 +1,2 @@ + Failure: The port is already in the VLAN + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_cycle.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_cycle.j2 index 73bcb7e..b44accc 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_cycle.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_cycle.j2 @@ -1,2 +1,2 @@ -{{ model.hostname }}(config-vlan-srvprof-{{ context.srvprof.id }})# \ No newline at end of file +{{ model.hostname }}(config-vlan-srvprof-{{ context.srvprof.internal_id }})# \ No newline at end of file diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_already_exists.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_already_exists.j2 index 8247e53..cc7372d 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_already_exists.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_already_exists.j2 @@ -1,4 +1,2 @@ Failure: VLAN does already exist - - diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_bind_service-profile_vlan-id_profile-id_profile-id.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_bind_service-profile_vlan-id_profile-id_profile-id.j2 index 8364af5..8149860 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_bind_service-profile_vlan-id_profile-id_profile-id.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_bind_service-profile_vlan-id_profile-id_profile-id.j2 @@ -1,2 +1,2 @@ - Binding will last for several minutes, please do not delete the VLAN. + Binding will last for several minutes, please do not delete the VLAN. diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_service_profile_does_not_exist.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_service_profile_does_not_exist.j2 new file mode 100644 index 0000000..367955b --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_service_profile_does_not_exist.j2 @@ -0,0 +1,2 @@ + Failure: The input VLAN service profile does not exist + diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index eb6fc07..68facd1 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -636,14 +636,19 @@ def do_vlan(self, command, *args, context=None): if self._validate(args, 'bind', 'service-profile', str, 'profile-id', str): trafficvlan, id = self._dissect(args, 'bind', 'service-profile', str, 'profile-id', str) try: - vlan = self._model.get_vlan("number", int(trafficvlan)) - profile = self._model.get_port_profile("id", int(id)) + profile = self._model.get_port_profile('internal_id', int(id)) assert profile.box_id == self._model.id assert profile.type == "service" - except (exceptions.SoftboxenError, AssertionError): - raise exceptions.CommandSyntaxError(command=command) + except (exceptions.InvalidInputError, AssertionError): + self._write(self._render('vlan_service_profile_does_not_exist', context=context)) + return + try: + vlan = self._model.get_vlan("number", int(trafficvlan)) + except exceptions.InvalidInputError: + self._write(self._render('vlan_does_not_exist', context=context)) + return - vlan.set_service_profile_id(int(id)) + vlan.set_service_profile_id(int(profile.id)) text = self._render( 'vlan_bind_service-profile_vlan-id_profile-id_profile-id', context=context) @@ -652,17 +657,17 @@ def do_vlan(self, command, *args, context=None): elif self._validate(args, 'service-profile', 'profile-name', str, 'profile-id', str): name, id = self._dissect(args, 'service-profile', 'profile-name', str, 'profile-id', str) try: - profile = self._model.get_port_profile('id', int(id)) + profile = self._model.get_port_profile('internal_id', int(id)) assert profile.type == "service" except exceptions.SoftboxenError: try: - self._model.add_port_profile(name=name, type='service', id=id) + self._model.add_port_profile(name=name, type='service', internal_id=id) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) except AssertionError: raise exceptions.CommandSyntaxError(command=command) try: - profile = self._model.get_port_profile('id', int(id)) + profile = self._model.get_port_profile('internal_id', int(id)) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -881,7 +886,7 @@ def do_terminal(self, command, *args, context=None): self._write(text) login = self.user_input(" User Name(length<6,15>):", False, 15) - password = self.user_input(" User Password(length<6,15>):", False, ) + password = self.user_input(" User Password(length<6,15>):", False, 15) while len(password) < 6: text = self._render('terminal_pw_short', context=context) self._write(text) @@ -979,12 +984,17 @@ def do_port(self, command, *args, context=None): try: card = self._model.get_card('name', cardident) if card.product != 'mgnt': - raise exceptions.CommandSyntaxError(command=command) + self._write(self._render('operation_not_supported_by_board', context=context)) + return port = self._model.get_port("name", portident) vlan = self._model.get_vlan("number", int(trafficvlan)) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) + if port.vlan_id == vlan.number: + self._write(self._render('port_already_in_vlan', context=context)) + return + port.set_vlan_id(vlan.number) else: diff --git a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py index 3a9e6b4..003bdfb 100644 --- a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py @@ -42,7 +42,7 @@ def do_disable(self, command, *args, context=None): def do_quit(self, command, *args, context=None): self._write(" Check whether system data has been changed. Please save data before logout.\n") - answer = self.user_input("Are you sure to log out? (y/n)[n]:") + answer = self.user_input("Are you sure to log out? (y/n)[n]:", False, 1) if answer == "y": self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) user = self._model.get_user('status', 'Online') diff --git a/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py index 6ff0b2e..2ce319d 100644 --- a/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py @@ -37,7 +37,7 @@ def on_unknown_command(self, command, *args, context=None): def do_quit(self, command, *args, context=None): self._write(" Check whether system data has been changed. Please save data before logout.\n") - answer = self.user_input("Are you sure to log out? (y/n)[n]:") + answer = self.user_input("Are you sure to log out? (y/n)[n]:", False, 1) if answer == "y": self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) user = self._model.get_user('status', 'Online') From 63b99dd370d6dc05dcb24e193a3eb7161903fbcc Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 18 Sep 2020 13:10:21 +0200 Subject: [PATCH 060/318] Now hiding user password when adding new user --- vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 68facd1..378d43b 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -886,6 +886,7 @@ def do_terminal(self, command, *args, context=None): self._write(text) login = self.user_input(" User Name(length<6,15>):", False, 15) + self.hide_input = True password = self.user_input(" User Password(length<6,15>):", False, 15) while len(password) < 6: text = self._render('terminal_pw_short', context=context) @@ -897,8 +898,9 @@ def do_terminal(self, command, *args, context=None): text = self._render('terminal_pw_error', context=context) self._write(text) password_repeat = self.user_input(" Confirm Password(length<6,15>):", False, 15) + self.hide_input = False - profile = self.user_input(" User profile name(<=15 chars)[root]:") + profile = self.user_input(" User profile name(<=15 chars)[root]:", False, 15) while (profile != 'root') and (profile != 'admin') and (profile != 'operator') \ and (profile != 'commonuser'): text = self._render('terminal_profile_error', context=context) @@ -949,7 +951,7 @@ def do_terminal(self, command, *args, context=None): text = self._render('user_created', context=context) self._write(text) - var_n = self.user_input(" Repeat this operation? (y/n)[n]:", False) + var_n = self.user_input(" Repeat this operation? (y/n)[n]:", False, 1) if var_n == 'y': self.do_terminal(command, 'user', 'name', context=context) return From 55446ac9cc7ee2b2d25bb2ae4a8d5b294cfc29e6 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 18 Sep 2020 15:57:38 +0200 Subject: [PATCH 061/318] Added new failure messages in case of de-/activating already de-/activated ports --- .../interface/port_has_been_activated.j2 | 2 ++ .../interface/port_has_been_deactivated.j2 | 2 ++ .../Huawei_Base/interfaceCommandProcessor.py | 34 +++++++++++++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/interface/port_has_been_activated.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/config/interface/port_has_been_deactivated.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/port_has_been_activated.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/port_has_been_activated.j2 new file mode 100644 index 0000000..fffad6d --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/port_has_been_activated.j2 @@ -0,0 +1,2 @@ + Failure: Port {{ context.port_name }} is being activated + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/port_has_been_deactivated.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/port_has_been_deactivated.j2 new file mode 100644 index 0000000..688e619 --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/interface/port_has_been_deactivated.j2 @@ -0,0 +1,2 @@ + Failure: Port {{ context.port_name }} has been deactivated + diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index 84df4bc..e65af0d 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -450,10 +450,16 @@ def do_activate(self, command, *args, context=None): elif self._validate(args, 'all'): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) + if context['iftype'] not in ('adsl', 'vdsl'): + self._write(self._render('operation_not_supported_by_port_failure', context=context)) + return self.card_ports_up(card) elif self._validate(args, str): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) + if context['iftype'] not in ('adsl', 'vdsl'): + self._write(self._render('operation_not_supported_by_port_failure', context=context)) + return port_identifier, = self._dissect( args, str) @@ -464,6 +470,10 @@ def do_activate(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) + if port.admin_state == '2': + self._write(self._render('port_has_been_activated', context=dict(context, port_name=port.name.split('/')[2]))) + return + port.admin_up() else: @@ -472,6 +482,9 @@ def do_activate(self, command, *args, context=None): def do_deactivate(self, command, *args, context=None): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) + if context['iftype'] not in ('adsl', 'vdsl'): + self._write(self._render('operation_not_supported_by_port_failure', context=context)) + return card = context['component'] if self._validate(args, 'all'): self.card_ports_down(card) @@ -484,6 +497,10 @@ def do_deactivate(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) + if port.admin_state == '0': + self._write(self._render('port_has_been_deactivated', context=dict(context, port_name=port.name.split('/')[2]))) + return + port.admin_down() else: raise exceptions.CommandSyntaxError(command=command) @@ -539,6 +556,9 @@ def do_vectoring_config(self, command, *args, context=None): def do_shutdown(self, command, *args, context=None): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) + if context['iftype'] not in ('opg', 'eth'): + self._write(self._render('operation_not_supported_by_port_failure', context=context)) + return card = context['component'] if self._validate(args, 'all'): self.card_ports_down(card) @@ -750,13 +770,17 @@ def do_undo(self, command, *args, context=None): elif self._validate(args, 'shutdown', 'all'): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) - + if context['iftype'] not in ('opg', 'eth'): + self._write(self._render('operation_not_supported_by_port_failure', context=context)) + return card = context['component'] self.card_ports_up(card) elif self._validate(args, 'shutdown', str): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) - + if context['iftype'] not in ('opg', 'eth'): + self._write(self._render('operation_not_supported_by_port_failure', context=context)) + return port_identifier, = self._dissect(args, 'shutdown', str) card = context['component'] @@ -776,6 +800,9 @@ def card_ports_down(self, card): if not ports: raise exceptions.CommandSyntaxError() for port in ports: + if port.admin_state == '0': + self._write(self._render('port_has_been_deactivated', context=dict(port_name=port.name.split('/')[2]))) + continue port.admin_down() def card_ports_up(self, card): @@ -783,4 +810,7 @@ def card_ports_up(self, card): if not ports: raise exceptions.CommandSyntaxError() for port in ports: + if port.admin_state == '2': + self._write(self._render('port_has_been_activated', context=dict(port_name=port.name.split('/')[2]))) + continue port.admin_up() From 494bd948a6d9ba152c47f5a2dac916764532bb80 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 21 Sep 2020 10:57:01 +0200 Subject: [PATCH 062/318] Fixed error messages when invoking deactivate command on eth or opg interface --- .../Huawei/Base/Huawei_Base/interfaceCommandProcessor.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index e65af0d..ba9e096 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -483,8 +483,7 @@ def do_deactivate(self, command, *args, context=None): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) if context['iftype'] not in ('adsl', 'vdsl'): - self._write(self._render('operation_not_supported_by_port_failure', context=context)) - return + raise exceptions.CommandSyntaxError(command=command) card = context['component'] if self._validate(args, 'all'): self.card_ports_down(card) @@ -771,16 +770,14 @@ def do_undo(self, command, *args, context=None): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) if context['iftype'] not in ('opg', 'eth'): - self._write(self._render('operation_not_supported_by_port_failure', context=context)) - return + raise exceptions.CommandSyntaxError(command=command) card = context['component'] self.card_ports_up(card) elif self._validate(args, 'shutdown', str): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) if context['iftype'] not in ('opg', 'eth'): - self._write(self._render('operation_not_supported_by_port_failure', context=context)) - return + raise exceptions.CommandSyntaxError(command=command) port_identifier, = self._dissect(args, 'shutdown', str) card = context['component'] From 1eaea3916892fb9d4cf55e3b65ee21041ae28c0a Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Mon, 21 Sep 2020 10:59:31 +0200 Subject: [PATCH 063/318] Small code adjustments --- .../Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py | 8 ++++---- vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py | 1 + .../Huawei/Base/Huawei_Base/userViewCommandProcessor.py | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py index b373524..1da9b1f 100644 --- a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py @@ -117,10 +117,10 @@ def do_switch(self, command, *args, context=None): if dsl_mode != 'tr129' and dsl_mode != 'tr165': raise exceptions.CommandSyntaxError(command=command) - self.user_input('{ |adsl }:', False) - - text = self._render('switch_dsl_mode_temp_1', context=context) - self._write(text) + if self._model.interactive_mode: + self.user_input('{ |adsl }:', False) + text = self._render('switch_dsl_mode_temp_1', context=context) + self._write(text) if self._model.dsl_mode == dsl_mode: text = self._render('switch_dsl_mode_failure', context=context) diff --git a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py index 003bdfb..0166bd6 100644 --- a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py @@ -47,6 +47,7 @@ def do_quit(self, command, *args, context=None): self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) user = self._model.get_user('status', 'Online') user.set_offline() + self._model.enable_interactive() exc = exceptions.TerminalExitError() exc.return_to = 'sysexit' raise exc diff --git a/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py index 2ce319d..19ec2c5 100644 --- a/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py @@ -42,6 +42,7 @@ def do_quit(self, command, *args, context=None): self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) user = self._model.get_user('status', 'Online') user.set_offline() + self._model.enable_interactive() exc = exceptions.TerminalExitError() exc.return_to = 'sysexit' raise exc From d3d995b9da8f2661bea65225777a4c15cf2744b8 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Mon, 21 Sep 2020 16:22:16 +0200 Subject: [PATCH 064/318] Upstream/Downstream Max Fields now contain strings instead of integers --- bootup/conf/bootstraps/create-alcatel-7360.sh | 56 +++++++------- bootup/conf/bootstraps/create-huawei-5623.sh | 76 +++++++++---------- bootup/conf/bootstraps/test-api-endpoints.sh | 4 +- nesi/softbox/api/models/port_models.py | 4 +- test_cases/unit_tests/huawei/test_huawei.py | 4 +- .../Huawei_Base/interfaceCommandProcessor.py | 4 +- 6 files changed, 74 insertions(+), 74 deletions(-) diff --git a/bootup/conf/bootstraps/create-alcatel-7360.sh b/bootup/conf/bootstraps/create-alcatel-7360.sh index 04f9320..a1b2009 100755 --- a/bootup/conf/bootstraps/create-alcatel-7360.sh +++ b/bootup/conf/bootstraps/create-alcatel-7360.sh @@ -399,8 +399,8 @@ req='{ "admin_state": "1", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, @@ -537,8 +537,8 @@ req='{ "admin_state": "1", "upstream": 10000, "downstream": 25000, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, @@ -743,8 +743,8 @@ req='{ "admin_state": "1", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, @@ -892,8 +892,8 @@ req='{ "admin_state": "0", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, @@ -1051,8 +1051,8 @@ req='{ "admin_state": "1", "upstream": 10000, "downstream": 25000, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, @@ -1200,8 +1200,8 @@ req='{ "admin_state": "1", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, @@ -1349,8 +1349,8 @@ req='{ "admin_state": "0", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, @@ -1508,8 +1508,8 @@ req='{ "admin_state": "1", "upstream": 10000, "downstream": 25000, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, @@ -1657,8 +1657,8 @@ req='{ "admin_state": "1", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, @@ -1806,8 +1806,8 @@ req='{ "admin_state": "0", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, @@ -1965,8 +1965,8 @@ req='{ "admin_state": "1", "upstream": 10000, "downstream": 25000, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, @@ -2207,8 +2207,8 @@ req='{ "admin_state": "1", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, @@ -2451,8 +2451,8 @@ req='{ "admin_state": "0", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, @@ -2730,8 +2730,8 @@ req='{ "admin_state": "1", "upstream": 10000, "downstream": 25000, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index d9b775e..fe9b521 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -278,8 +278,8 @@ req='{ "loopback": "disable", "upstream": 10000, "downstream": 25000, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "1", "combo_status": "-", @@ -307,8 +307,8 @@ req='{ "loopback": "disable", "upstream": 10000, "downstream": 25000, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "1", "combo_status": "-", @@ -348,8 +348,8 @@ req='{ "loopback": "disable", "upstream": 10000, "downstream": 25000, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "1" }' @@ -410,8 +410,8 @@ req='{ "loopback": "disable", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "0" }' @@ -449,8 +449,8 @@ req='{ "loopback": "disable", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "0", "operational_state": "0" }' @@ -478,8 +478,8 @@ req='{ "loopback": "disable", "upstream": 10000, "downstream": 25000, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "1" }' @@ -517,8 +517,8 @@ req='{ "loopback": "disable", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "0" }' @@ -556,8 +556,8 @@ req='{ "loopback": "disable", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "0", "operational_state": "0" }' @@ -585,8 +585,8 @@ req='{ "loopback": "disable", "upstream": 10000, "downstream": 25000, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "1" }' @@ -656,8 +656,8 @@ req='{ "loopback": "disable", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "0" }' @@ -724,8 +724,8 @@ req='{ "loopback": "disable", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "0", "operational_state": "0" }' @@ -773,8 +773,8 @@ req='{ "loopback": "disable", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "1" }' @@ -844,8 +844,8 @@ req='{ "loopback": "disable", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "1", "speed_h": "100" @@ -928,8 +928,8 @@ req='{ "loopback": "disable", "upstream": 10000, "downstream": 25000, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "1" }' @@ -1141,8 +1141,8 @@ req='{ "loopback": "disable", "upstream": 10000, "downstream": 25000, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "1" }' @@ -1209,8 +1209,8 @@ req='{ "loopback": "disable", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "0" }' @@ -1277,8 +1277,8 @@ req='{ "loopback": "disable", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "0", "operational_state": "0" }' @@ -1323,8 +1323,8 @@ req='{ "loopback": "disable", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "1" }' @@ -1394,8 +1394,8 @@ req='{ "loopback": "disable", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "admin_state": "1", "operational_state": "1" }' diff --git a/bootup/conf/bootstraps/test-api-endpoints.sh b/bootup/conf/bootstraps/test-api-endpoints.sh index 4f47a2f..347de91 100755 --- a/bootup/conf/bootstraps/test-api-endpoints.sh +++ b/bootup/conf/bootstraps/test-api-endpoints.sh @@ -190,8 +190,8 @@ req='{ "admin_state": "0", "upstream": 0, "downstream": 0, - "upstream_max": 100000, - "downstream_max": 100000, + "upstream_max": "100000", + "downstream_max": "100000", "noise_margin_up": 0, "noise_margin_down": 0, "tgt_noise_margin_up": 0, diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index ed6a5fb..f6d5ab1 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -33,8 +33,8 @@ class Port(db.Model): admin_state = db.Column(db.Enum('0', '1', '2'), default='0') # Alcatel: 0 => down, 1 => up, 2 => not-appl; Huawei: 0 => deactivated, 1 => activated, 2 => activating upstream = db.Column(db.Integer(), default=0) downstream = db.Column(db.Integer(), default=0) - upstream_max = db.Column(db.Integer(), default=100000) - downstream_max = db.Column(db.Integer(), default=100000) + upstream_max = db.Column(db.String(), default="100000") + downstream_max = db.Column(db.String(), default="100000") cur_init_state = db.Column(db.Enum('up', 'down', 'shutdown'), default='down') auto_negotiation = db.Column(db.Boolean(), default=True) mtu = db.Column(db.Integer(), default=1500) diff --git a/test_cases/unit_tests/huawei/test_huawei.py b/test_cases/unit_tests/huawei/test_huawei.py index 0789401..17e893a 100644 --- a/test_cases/unit_tests/huawei/test_huawei.py +++ b/test_cases/unit_tests/huawei/test_huawei.py @@ -35,9 +35,9 @@ def test_portup_portdown(self): def test_port_rest(self): port = self.model.get_port("name", '0/0/0') - assert port.downstream_max == 100000 + assert port.downstream_max == "100000" port.port_downstream_set(1) - assert port.downstream_max == 1 + assert port.downstream_max == "1" try: port.port_downstream_set('failure') assert False diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index ba9e096..bba6fe3 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -409,8 +409,8 @@ def do_activate(self, command, *args, context=None): try: port.admin_up() - port.set('downstream_max', int(ds_rate)) - port.set('upstream_max', int(us_rate)) + port.set('downstream_max', ds_rate) + port.set('upstream_max', us_rate) port.set('line_spectrum_profile', spectrum_profile) port.set('spectrum_profile_num', int(spectrum_id)) port.set('noise_margin_profile', noise_profile) From 58dabca537fe7c3e517cfb6f8dcfec4cd7282c09 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 21 Sep 2020 16:32:41 +0200 Subject: [PATCH 065/318] Fixed unit and integration tests --- .../integration_tests/huawei/backupTest.txt | 2 +- .../huawei/changeAllPorts16.txt | 6 ++-- .../integration_tests/huawei/changeONT13.txt | 2 +- .../huawei/changeOntPorts1.txt | 2 +- .../integration_tests/huawei/changePort5.txt | 4 +-- .../huawei/changeSPort20.txt | 18 +++++----- .../huawei/changeTerminalUser15.txt | 2 +- .../huawei/displayEquipment1.txt | 2 +- .../huawei/displayMonitor2.txt | 2 +- .../integration_tests/huawei/displayOnt5.txt | 4 +-- .../huawei/displayState9.txt | 20 +++++------ .../integration_tests/huawei/unchangeDSL4.txt | 8 ++--- .../huawei/unchangeONT14.txt | 2 +- .../huawei/unchangePort6.txt | 6 ++-- test_cases/unit_tests/huawei/test_huawei.py | 34 +++++++++---------- 15 files changed, 57 insertions(+), 57 deletions(-) diff --git a/test_cases/integration_tests/huawei/backupTest.txt b/test_cases/integration_tests/huawei/backupTest.txt index 2cb9524..ec33fb9 100644 --- a/test_cases/integration_tests/huawei/backupTest.txt +++ b/test_cases/integration_tests/huawei/backupTest.txt @@ -3,7 +3,7 @@ secret enable config test -xdsl melt 0/0/0 measured-frequency 25Hz busy force +xdsl melt 0/1/0 measured-frequency 25Hz busy force return quit diff --git a/test_cases/integration_tests/huawei/changeAllPorts16.txt b/test_cases/integration_tests/huawei/changeAllPorts16.txt index 12ae3fc..0967ad7 100644 --- a/test_cases/integration_tests/huawei/changeAllPorts16.txt +++ b/test_cases/integration_tests/huawei/changeAllPorts16.txt @@ -2,15 +2,15 @@ root secret enable config -interface vdsl 0/0 +interface vdsl 0/1 deactivate all shutdown all quit -interface eth 0/2 +interface eth 0/3 deactivate all shutdown all quit -interface gpon 0/3 +interface gpon 0/4 deactivate all shutdown all quit diff --git a/test_cases/integration_tests/huawei/changeONT13.txt b/test_cases/integration_tests/huawei/changeONT13.txt index f0ff075..7019c2f 100644 --- a/test_cases/integration_tests/huawei/changeONT13.txt +++ b/test_cases/integration_tests/huawei/changeONT13.txt @@ -2,7 +2,7 @@ root secret enable config -interface gpon 0/3 +interface gpon 0/4 ont add 0 2 sn-auth 1 omci ont-lineprofile-id 0 ont-srvprofile-id 0 desc "This is a new ont" quit save diff --git a/test_cases/integration_tests/huawei/changeOntPorts1.txt b/test_cases/integration_tests/huawei/changeOntPorts1.txt index 255b9fc..28634bc 100644 --- a/test_cases/integration_tests/huawei/changeOntPorts1.txt +++ b/test_cases/integration_tests/huawei/changeOntPorts1.txt @@ -2,7 +2,7 @@ root secret enable config -interface gpon 0/3 +interface gpon 0/4 ont port attribute 0 0 eth 1 operational-state on quit save diff --git a/test_cases/integration_tests/huawei/changePort5.txt b/test_cases/integration_tests/huawei/changePort5.txt index 374b218..d74c670 100644 --- a/test_cases/integration_tests/huawei/changePort5.txt +++ b/test_cases/integration_tests/huawei/changePort5.txt @@ -2,11 +2,11 @@ root secret enable config -interface vdsl 0/0 +interface vdsl 0/1 activate 0 return config -interface opg 0/4 +interface opg 0/5 undo shutdown 0 return quit diff --git a/test_cases/integration_tests/huawei/changeSPort20.txt b/test_cases/integration_tests/huawei/changeSPort20.txt index adc498b..09bcf05 100644 --- a/test_cases/integration_tests/huawei/changeSPort20.txt +++ b/test_cases/integration_tests/huawei/changeSPort20.txt @@ -2,15 +2,15 @@ root secret enable config -display service-port 0/0/0 -undo service-port 0/0/0 -service-port 1 vlan 2620 adsl 0/1/0 vpi 1 vci 32 multi-service user-encap pppoe inbound traffic-table index 10 outbound traffic-table index 10 -service-port 2 vlan 2620 vdsl mode atm 0/0/0 vpi 1 vci 32 multi-service user-encap pppoe inbound traffic-table index 10 outbound traffic-table index 10 -service-port 3 vlan 2620 vdsl mode ptm 0/0/1 multi-service user-encap pppoe inbound traffic-table index 10 outbound traffic-table index 1 -service-port 4 vlan 2620 eth 0/2/0 multi-service user-vlan 2620 user-encap pppoe inbound traffic-table index intable outbound traffic-table index outtable -service-port 5 vlan 2620 vdsl mode ptm 0/0/2 multi-service user-vlan untagged -service-port 6 vlan 2620 vdsl mode atm 0/1/1 vpi 1 vci 32 multi-service user-vlan untagged -service-port 7 vlan 2620 eth 0/2/1 multi-service user-vlan 2620 user-encap pppoe inbound traffic-table index intable outbound traffic-table index outtable +display service-port 0 +undo service-port 0 +service-port 1 vlan 2620 adsl 0/2/0 vpi 1 vci 32 multi-service user-encap pppoe inbound traffic-table index 10 outbound traffic-table index 10 +service-port 2 vlan 2620 vdsl mode atm 0/1/0 vpi 1 vci 32 multi-service user-encap pppoe inbound traffic-table index 10 outbound traffic-table index 10 +service-port 3 vlan 2620 vdsl mode ptm 0/1/1 multi-service user-encap pppoe inbound traffic-table index 10 outbound traffic-table index 1 +service-port 4 vlan 2620 eth 0/3/0 multi-service user-vlan 2620 user-encap pppoe inbound traffic-table index intable outbound traffic-table index outtable +service-port 5 vlan 2620 vdsl mode ptm 0/1/2 multi-service user-vlan untagged +service-port 6 vlan 2620 vdsl mode atm 0/2/1 vpi 1 vci 32 multi-service user-vlan untagged +service-port 7 vlan 2620 eth 0/3/1 multi-service user-vlan 2620 user-encap pppoe inbound traffic-table index intable outbound traffic-table index outtable return quit y \ No newline at end of file diff --git a/test_cases/integration_tests/huawei/changeTerminalUser15.txt b/test_cases/integration_tests/huawei/changeTerminalUser15.txt index 154c578..998979a 100644 --- a/test_cases/integration_tests/huawei/changeTerminalUser15.txt +++ b/test_cases/integration_tests/huawei/changeTerminalUser15.txt @@ -9,7 +9,7 @@ testuser root 3 4 -\r\n + n return quit diff --git a/test_cases/integration_tests/huawei/displayEquipment1.txt b/test_cases/integration_tests/huawei/displayEquipment1.txt index a7486b4..3960c1e 100644 --- a/test_cases/integration_tests/huawei/displayEquipment1.txt +++ b/test_cases/integration_tests/huawei/displayEquipment1.txt @@ -3,7 +3,7 @@ secret enable config display board 0 -display board 0/0 +display board 0/1 display vlan all display interface vlanif 2620 diff --git a/test_cases/integration_tests/huawei/displayMonitor2.txt b/test_cases/integration_tests/huawei/displayMonitor2.txt index f64407c..91a73b2 100644 --- a/test_cases/integration_tests/huawei/displayMonitor2.txt +++ b/test_cases/integration_tests/huawei/displayMonitor2.txt @@ -5,8 +5,8 @@ diagnose system status collect all display system status collection quit -display temperature 0/0 display temperature 0/1 +display temperature 0/2 config display version diff --git a/test_cases/integration_tests/huawei/displayOnt5.txt b/test_cases/integration_tests/huawei/displayOnt5.txt index 0b8a6fb..199dd28 100644 --- a/test_cases/integration_tests/huawei/displayOnt5.txt +++ b/test_cases/integration_tests/huawei/displayOnt5.txt @@ -2,8 +2,8 @@ root secret enable config -display service-port 0/0/0 -interface gpon 0/3 +display service-port 0 +interface gpon 0/4 display port state 0 display ont port state 0 0 eth-port 1 display ont info 0 0 diff --git a/test_cases/integration_tests/huawei/displayState9.txt b/test_cases/integration_tests/huawei/displayState9.txt index 5f7cb0c..b8af6a8 100644 --- a/test_cases/integration_tests/huawei/displayState9.txt +++ b/test_cases/integration_tests/huawei/displayState9.txt @@ -1,26 +1,26 @@ root secret enable -display interface vdsl 0/0/0 -display vdsl port state 0/0/0 -display vdsl line operation port 0/0/0 +display interface vdsl 0/1/0 +display vdsl port state 0/1/0 +display vdsl line operation port 0/1/0 config -interface vdsl 0/0 +interface vdsl 0/1 display inventory cpe 0 return -display interface adsl 0/1/0 -display adsl port state 0/1/0 -display adsl line operation port 0/1/0 +display interface adsl 0/2/0 +display adsl port state 0/2/0 +display adsl line operation port 0/2/0 config -interface adsl 0/1 +interface adsl 0/2 display inventory cpe 0 return config -interface gpon 0/3 +interface gpon 0/4 display port state 0 return config -interface eth 0/2 +interface eth 0/3 display port ddm-info 0 return diff --git a/test_cases/integration_tests/huawei/unchangeDSL4.txt b/test_cases/integration_tests/huawei/unchangeDSL4.txt index 510b0dd..0e1a3cd 100644 --- a/test_cases/integration_tests/huawei/unchangeDSL4.txt +++ b/test_cases/integration_tests/huawei/unchangeDSL4.txt @@ -2,16 +2,16 @@ root secret enable config -interface vdsl 0/0 +interface vdsl 0/1 deactivate 1 quit -interface adsl 0/1 +interface adsl 0/2 deactivate 2 quit -interface opg 0/4 +interface opg 0/5 shutdown 1 quit -interface eth 0/2 +interface eth 0/3 shutdown 1 quit return diff --git a/test_cases/integration_tests/huawei/unchangeONT14.txt b/test_cases/integration_tests/huawei/unchangeONT14.txt index 8af312c..38c5cfa 100644 --- a/test_cases/integration_tests/huawei/unchangeONT14.txt +++ b/test_cases/integration_tests/huawei/unchangeONT14.txt @@ -2,7 +2,7 @@ root secret enable config -interface gpon 0/3 +interface gpon 0/4 ont delete 0 0 quit save diff --git a/test_cases/integration_tests/huawei/unchangePort6.txt b/test_cases/integration_tests/huawei/unchangePort6.txt index 28a3fe9..a8f4c43 100644 --- a/test_cases/integration_tests/huawei/unchangePort6.txt +++ b/test_cases/integration_tests/huawei/unchangePort6.txt @@ -2,15 +2,15 @@ root secret enable config -interface vdsl 0/0 +interface vdsl 0/1 deactivate 1 return config -interface opg 0/4 +interface opg 0/5 shutdown 0 return config -interface eth 0/2 +interface eth 0/3 shutdown 0 return quit diff --git a/test_cases/unit_tests/huawei/test_huawei.py b/test_cases/unit_tests/huawei/test_huawei.py index 17e893a..8431c58 100644 --- a/test_cases/unit_tests/huawei/test_huawei.py +++ b/test_cases/unit_tests/huawei/test_huawei.py @@ -36,7 +36,7 @@ def test_portup_portdown(self): def test_port_rest(self): port = self.model.get_port("name", '0/0/0') assert port.downstream_max == "100000" - port.port_downstream_set(1) + port.port_downstream_set("1") assert port.downstream_max == "1" try: port.port_downstream_set('failure') @@ -44,9 +44,9 @@ def test_port_rest(self): except exceptions.SoftboxenError: assert True - assert port.upstream_max == 100000 - port.port_upstream_set(1) - assert port.upstream_max == 1 + assert port.upstream_max == "100000" + port.port_upstream_set("1") + assert port.upstream_max == "1" try: port.port_upstream_set('failure') assert False @@ -63,7 +63,7 @@ def test_port_rest(self): assert True def test_ont_fields(self): - port = self.model.get_ont("name", '0/2/0/0') + port = self.model.get_ont("name", '0/3/0/0') assert port.ont_online_duration is None port.set_online_duration('1') assert (port.ont_online_duration == '1') @@ -74,7 +74,7 @@ def test_ont_fields(self): assert True def test_ont_ports(self): - port = self.model.get_ont_port("name", '0/2/0/0/1') + port = self.model.get_ont_port("name", '0/3/0/0/1') port.up() assert (port.admin_state == '1') port.down() @@ -93,7 +93,7 @@ def test_port_profiles(self): port.set('type', 'service') def test_service_port(self): - port = self.model.get_service_port("name", "0/0/0") + port = self.model.get_service_port("name", "0") assert port.vpi == '-' port.set_vpi('vpi') assert port.vpi == 'vpi' @@ -235,7 +235,7 @@ def test_vlan(self): except exceptions.SoftboxenError: assert True - assert vlan.bind_service_profile_id == 1 + assert vlan.bind_service_profile_id == 2 vlan.set_service_profile_id(22) assert vlan.bind_service_profile_id == 22 try: @@ -258,18 +258,18 @@ def test_vlaninterface(self): def test_box_properties(self): assert len(self.model.subracks) == 1 - assert len(self.model.cards) == 5 - assert len(self.model.ports) == 13 - assert len(self.model.onts) == 8 - assert len(self.model.ont_ports) == 9 - assert len(self.model.cpes) == 11 - assert len(self.model.cpe_ports) == 11 + assert len(self.model.cards) == 6 + assert len(self.model.ports) == 19 + assert len(self.model.onts) == 12 + assert len(self.model.ont_ports) == 13 + assert len(self.model.cpes) == 15 + assert len(self.model.cpe_ports) == 15 assert len(self.model.vlans) == 2 - assert len(self.model.service_vlans) == 1 - assert len(self.model.service_ports) == 1 + assert len(self.model.service_vlans) == 3 + assert len(self.model.service_ports) == 3 assert len(self.model.credentials) == 1 assert len(self.model.routes) == 0 - assert len(self.model.port_profiles) == 1 + assert len(self.model.port_profiles) == 2 assert len(self.model.emus) == 2 assert len(self.model.users) == 1 assert len(self.model.vlan_interfaces) == 1 From 8943f4771d0ec32c11fbdae82c991b626830b0db Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 22 Sep 2020 08:13:14 +0200 Subject: [PATCH 066/318] Fixed small bugs --- nesi/softbox/api/models/vlan_interface_models.py | 2 +- .../mainloop/enable/config/display_interface_vlanif_num.j2 | 6 ++++-- .../1/login/mainloop/enable/config/display_vlan_all_mid.j2 | 2 +- vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py | 1 + 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/nesi/softbox/api/models/vlan_interface_models.py b/nesi/softbox/api/models/vlan_interface_models.py index 5a53ae8..ad54bcc 100644 --- a/nesi/softbox/api/models/vlan_interface_models.py +++ b/nesi/softbox/api/models/vlan_interface_models.py @@ -20,7 +20,7 @@ class VlanInterface(db.Model): name = db.Column(db.String()) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) vlan_id = db.Column(db.Integer, db.ForeignKey('vlan.id')) - admin_state = db.Column(db.Enum('0', '1'), default='0') + admin_state = db.Column(db.Enum('0', '1'), default='0') # 0 => DOWN, 1 => UP line_proto_state = db.Column(db.Enum('0', '1'), default='0') # 0 => DOWN, 1 => UP input_packets = db.Column(db.Integer(), default=0) input_bytes = db.Column(db.Integer(), default=0) diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_interface_vlanif_num.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_interface_vlanif_num.j2 index cec9959..33d57e9 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_interface_vlanif_num.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_interface_vlanif_num.j2 @@ -1,5 +1,7 @@ -{{ context.vlanif.name }} current state : {{ context.vlanif.admin_state }} -Line protocol current state : {{ context.vlanif.line_proto_state }} +{{ context.vlanif.name }} current state : {% if context.vlanif.admin_state == '1' %} UP {% else %} DOWN {% endif %} + +Line protocol current state : {% if context.vlanif.line_proto_state == '1' %} UP {% else %} DOWN {% endif %} + Description : HUAWEI, SmartAX Series, {{ context.vlanif.name }} Interface The Maximum Transmit Unit is {{ context.vlanif.mtu }} bytes {% if context.vlanif.internet_protocol == 'enabled' %}Internet Address is {{ context.vlanif.internet_address }}/{{ context.vlanif.subnet_num }} diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_mid.j2 b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_mid.j2 index 83efa36..2db43ea 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_mid.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_mid.j2 @@ -1,2 +1,2 @@ -{{ context.spacer1 }}{{ context.vlan.number }} {{ context.vlan.type }}{{ context.spacer2 }}{{ context.vlan.attribute }}{{ context.spacer3 }}{{ context.portnum}}{{ context.spacer4 }}{{ context.servportnum }} +{{ context.spacer1 }}{{ context.vlan.number }} {{ context.vlan.type }}{{ context.spacer2 }}{{ context.vlan.attribute }}{{ context.spacer3 }}{{ context.portnum}}{{ context.spacer4 }}{{ context.servportnum }}{{ context.spacer5 }} diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 378d43b..9524295 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -262,6 +262,7 @@ def generate_ont_info_summary(port): context['spacer2'] = self.create_spacers((10,), (vlan.type,))[0] * ' ' context['spacer3'] = self.create_spacers((23,), (vlan.attribute,))[0] * ' ' context['spacer4'] = self.create_spacers((16,), (len(str(servportnum)),))[0] * ' ' + context['spacer5'] = ' ' text += self._render('display_vlan_all_mid', context=dict(context, vlan=vlan)) count += 1 From f1e893ed93bde7423b4725f5be9af59eca549ca9 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 22 Sep 2020 10:14:33 +0200 Subject: [PATCH 067/318] Added line buffer to process multi line inputs --- bootup/sockets/telnet.py | 2 +- nesi/softbox/cli/base.py | 11 ++++++++++- templates/Huawei/5623/A/on_enter.j2 | 7 ------- .../enable/diagnose/switch_dsl_mode_temp_2.j2 | 1 - templates/Huawei/Base/1/on_enter.j2 | 7 ------- templates/Huawei/Base/1/on_exit.j2 | 1 - .../Huawei/Base/Huawei_Base/baseCommandProcessor.py | 6 +++++- .../Huawei/Base/Huawei_Base/configCommandProcessor.py | 1 + .../Base/Huawei_Base/diagnoseCommandProcessor.py | 5 +++++ 9 files changed, 22 insertions(+), 19 deletions(-) diff --git a/bootup/sockets/telnet.py b/bootup/sockets/telnet.py index 021ae8a..bd67c69 100644 --- a/bootup/sockets/telnet.py +++ b/bootup/sockets/telnet.py @@ -59,7 +59,7 @@ def run(self): self.telnet.lock.release() def readline(self): - return self.socket.recv(1024) + return self.socket.recv(4096) def write(self, data): return self.socket.sendall(data) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 61723ea..6cd8c52 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -67,6 +67,7 @@ def __init__(self, model, input_stream, output_stream, history, self.daemon = daemon # CLI specific attributes + self.line_buffer = [] self.history_enabled = True self.hide_input = False self.history_pos = 0 @@ -337,8 +338,14 @@ def loop(self, context=None, return_to=None, command=None): self.on_cycle(context) while True: - if command is None: + line = '' + if len(self.line_buffer) != 0 and command is None: + command = self.line_buffer.pop(0) + if command is None and line == '': line = self._read() + if '\r\n' in line and len(line.split('\r\n')) > 2: + self.line_buffer = line.split('\r\n') + continue context['raw_line'] = line else: line = command @@ -348,9 +355,11 @@ def loop(self, context=None, return_to=None, command=None): self.process_command(line, context) except exceptions.CommandSyntaxError as exc: + self.line_buffer = [] # manually clear buffer in case of exception self.on_error(dict(context, command=exc.command)) except exceptions.TerminalExitError as exc: + self.line_buffer = [] # manually clear buffer in case of exception if not exc.return_to: exc.return_to = return_to diff --git a/templates/Huawei/5623/A/on_enter.j2 b/templates/Huawei/5623/A/on_enter.j2 index 111c0db..e69de29 100644 --- a/templates/Huawei/5623/A/on_enter.j2 +++ b/templates/Huawei/5623/A/on_enter.j2 @@ -1,7 +0,0 @@ - - -Escape character is '^]'. - -Warning: Telnet is not a secure protocol, and it is recommended to use Stelnet. - - diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_2.j2 b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_2.j2 index 2c43fa1..95fe23e 100644 --- a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_2.j2 +++ b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_2.j2 @@ -1,4 +1,3 @@ It will take several minutes, please wait... The data is being saved, please wait a moment... - diff --git a/templates/Huawei/Base/1/on_enter.j2 b/templates/Huawei/Base/1/on_enter.j2 index 111c0db..e69de29 100644 --- a/templates/Huawei/Base/1/on_enter.j2 +++ b/templates/Huawei/Base/1/on_enter.j2 @@ -1,7 +0,0 @@ - - -Escape character is '^]'. - -Warning: Telnet is not a secure protocol, and it is recommended to use Stelnet. - - diff --git a/templates/Huawei/Base/1/on_exit.j2 b/templates/Huawei/Base/1/on_exit.j2 index 25b73e2..071fe94 100644 --- a/templates/Huawei/Base/1/on_exit.j2 +++ b/templates/Huawei/Base/1/on_exit.j2 @@ -1,3 +1,2 @@ Configuration console exit, please retry to log on -Connection closed by foreign host. diff --git a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py index af044a1..5aa27ad 100644 --- a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py @@ -72,7 +72,11 @@ def user_input(self, prompt, allow_history=True, tmp_boundary=None): self.prompt_end_pos = len(prompt) - 1 if not allow_history: self.history_enabled = False - input = self._read(tmp_boundary).strip() + + if len(self.line_buffer) != 0: + input = self.line_buffer.pop(0) + else: + input = self._read(tmp_boundary).strip() if not allow_history: self.history_enabled = True self.prompt_end_pos = prompt_end_pos diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 9524295..5684811 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -881,6 +881,7 @@ def do_terminal(self, command, *args, context=None): context['user_name'] = login text = self._render('user_already_exists', context=context) self._write(text) + self.line_buffer = [] # manually clear buffer in case of 'Exception' return while len(login) < 6: text = self._render('terminal_name_short', context=context) diff --git a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py index 1da9b1f..85f657a 100644 --- a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py @@ -115,6 +115,7 @@ def do_switch(self, command, *args, context=None): dsl_mode, = self._dissect(args, 'vdsl', 'mode', 'to', str) context['dsl_mode'] = dsl_mode if dsl_mode != 'tr129' and dsl_mode != 'tr165': + self.line_buffer = [] raise exceptions.CommandSyntaxError(command=command) if self._model.interactive_mode: @@ -125,20 +126,24 @@ def do_switch(self, command, *args, context=None): if self._model.dsl_mode == dsl_mode: text = self._render('switch_dsl_mode_failure', context=context) self._write(text) + self.line_buffer = [] return answer_one = self.user_input(' Warning: The operation will result in loss of all VDSL configuration. ' 'Are you sure to proceed? (y/n)[n]:', False) if answer_one != 'y': + self.line_buffer = [] return answer_two = self.user_input(' Warning: The operation will automatically save and reboot system. ' 'Are you sure you want to proceed? (y/n)[n]:', False) if answer_two != 'y': + self.line_buffer = [] return text = self._render('switch_dsl_mode_temp_2', context=context) self._write(text) self._model.set_dsl_mode(dsl_mode) + self.on_cycle(context=context) time.sleep(10) self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) user = self._model.get_user('status', 'Online') From a15fddb186c386a3a35f230ed6b716c400c77f93 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Tue, 22 Sep 2020 10:21:53 +0200 Subject: [PATCH 068/318] Reworked adding profiles to ports --- .../schemas/huawei_port_profile_schemas.py | 2 +- .../huawei_resources/huawei_port_profile.py | 1 + nesi/softbox/api/models/portprofile_models.py | 1 + .../Huawei_Base/configCommandProcessor.py | 23 +++++++---- .../Huawei_Base/interfaceCommandProcessor.py | 40 +++++++++++-------- 5 files changed, 41 insertions(+), 26 deletions(-) diff --git a/nesi/huawei/api/schemas/huawei_port_profile_schemas.py b/nesi/huawei/api/schemas/huawei_port_profile_schemas.py index ed27dc4..cfd4734 100644 --- a/nesi/huawei/api/schemas/huawei_port_profile_schemas.py +++ b/nesi/huawei/api/schemas/huawei_port_profile_schemas.py @@ -36,4 +36,4 @@ class Meta: 'vmac_ipoe', 'vmac_pppoe', 'vmac_pppoa', 'vlan_mac', 'packet_policy_multicast', 'packet_policy_unicast', 'security_anti_ipspoofing', 'security_anti_macspoofing', - 'igmp_mismatch', 'commit', 'internal_id') + 'igmp_mismatch', 'commit', 'internal_id', 'number') diff --git a/nesi/huawei/huawei_resources/huawei_port_profile.py b/nesi/huawei/huawei_resources/huawei_port_profile.py index 1f6aad0..c3c0859 100644 --- a/nesi/huawei/huawei_resources/huawei_port_profile.py +++ b/nesi/huawei/huawei_resources/huawei_port_profile.py @@ -88,6 +88,7 @@ class HuaweiPortProfile(PortProfile): security_anti_macspoofing = base.Field('security_anti_macspoofing') igmp_mismatch = base.Field('igmp_mismatch') commit = base.Field('commit') + number = base.Field('number') def set(self, field, value): mapping = {field: value} diff --git a/nesi/softbox/api/models/portprofile_models.py b/nesi/softbox/api/models/portprofile_models.py index d9ea0b7..e588fea 100644 --- a/nesi/softbox/api/models/portprofile_models.py +++ b/nesi/softbox/api/models/portprofile_models.py @@ -99,3 +99,4 @@ class PortProfile(db.Model): security_anti_macspoofing = db.Column(db.Enum('enable', 'disable'), default=None) igmp_mismatch = db.Column(db.Enum('transparent'), default=None) commit = db.Column(db.Boolean(), default=False) + number = db.Column(db.Integer, default=None) diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index 5684811..c854431 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -870,6 +870,9 @@ def do_system(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_terminal(self, command, *args, context=None): + creating_user = self._model.get_user('status', 'Online') + if creating_user.level != 'Super' and creating_user.level != 'Admin': + raise exceptions.CommandSyntaxError(command=command) if self._validate(args, 'user', 'name'): login = self.user_input(" User Name(length<6,15>):", False, 15) @@ -911,13 +914,17 @@ def do_terminal(self, command, *args, context=None): text = self._render('user_level', context=context) self._write(text) - level = self.user_input(" 1. Common User 2. Operator 3. Administrator:", False) + if creating_user.level == 'Super': + prompt = " 1. Common User 2. Operator 3. Administrator:" + else: + prompt = " 1. Common User 2. Operator:" + level = self.user_input(prompt, False) while (level != '1') and (level != '2') and (level != '3'): text = self._render('terminal_level_error', context=context) self._write(text) text = self._render('user_level', context=context) self._write(text) - level = self.user_input(" 1. Common User 2. Operator 3. Administrator:", False) + level = self.user_input(prompt, False) if level == '1': lvl = 'User' @@ -1038,7 +1045,7 @@ def do_xdsl(self, command, *args, context=None): try: _ = self._model.get_port_profile('name', name) except exceptions.SoftboxenError: - self._model.add_port_profile(name=name, type='data-rate') + self._model.add_port_profile(name=name, type='data-rate', number=profile_num) try: port_profile = self._model.get_port_profile('name', name) except exceptions.SoftboxenError: @@ -1067,7 +1074,7 @@ def do_xdsl(self, command, *args, context=None): try: _ = self._model.get_port_profile('name', name) except exceptions.SoftboxenError: - self._model.add_port_profile(name=name, type='dpbo') + self._model.add_port_profile(name=name, type='dpbo', number=profile_num) try: port_profile = self._model.get_port_profile('name', name) except exceptions.SoftboxenError: @@ -1113,7 +1120,7 @@ def do_xdsl(self, command, *args, context=None): try: _ = self._model.get_port_profile('name', name) except exceptions.SoftboxenError: - self._model.add_port_profile(name=name, type='noise-margin') + self._model.add_port_profile(name=name, type='noise-margin', number=profile_num) try: port_profile = self._model.get_port_profile('name', name) except exceptions.SoftboxenError: @@ -1151,7 +1158,7 @@ def do_xdsl(self, command, *args, context=None): try: _ = self._model.get_port_profile('name', name) except exceptions.SoftboxenError: - self._model.add_port_profile(name=name, type='inp-delay') + self._model.add_port_profile(name=name, type='inp-delay', number=profile_num) try: port_profile = self._model.get_port_profile('name', name) except exceptions.SoftboxenError: @@ -1191,7 +1198,7 @@ def do_xdsl(self, command, *args, context=None): try: _ = self._model.get_port_profile('name', name) except exceptions.SoftboxenError: - self._model.add_port_profile(name=name, type='mode-specific-psd') + self._model.add_port_profile(name=name, type='mode-specific-psd', number=profile_num) try: port_profile = self._model.get_port_profile('name', name) except exceptions.SoftboxenError: @@ -1219,7 +1226,7 @@ def do_xdsl(self, command, *args, context=None): try: _ = self._model.get_port_profile('name', name) except exceptions.SoftboxenError: - self._model.add_port_profile(name=name, type='spectrum') + self._model.add_port_profile(name=name, type='spectrum', number=profile_num) try: port_profile = self._model.get_port_profile('name', name) except exceptions.SoftboxenError: diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index bba6fe3..5df75d1 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -351,6 +351,8 @@ def do_display(self, command, *args, context=None): def do_activate(self, command, *args, context=None): card = context['component'] if self._validate(args[:6], str, 'prof-desc', 'ds-rate', str, 'us-rate', str): + spectrum_flag = False + dpbo_flag = False #elif self._validate(args, str, 'prof.desc', 'ds-rate', str, 'us-rate', str, '(spectrum str)', 'noise-margin', 'ADSL_6db', 'inp-delay', 'ADSL','(dpbo DPBO:str)'): if context['iftype'] == 'vlanif': raise exceptions.CommandSyntaxError(command=command) @@ -372,17 +374,19 @@ def do_activate(self, command, *args, context=None): i += 2 try: profile = self._model.get_port_profile('description', spectrum) - spectrum_profile = 'No. ' + profile.id + ' ' + spectrum - spectrum_id = profile.id + spectrum_profile = 'No. ' + str(profile.number) + ' ' + spectrum + spectrum_id = str(profile.number) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) + else: + spectrum_flag = True elif args[i] == 'noise-margin': noise = args[i+1] i += 2 try: profile = self._model.get_port_profile('description', noise) - noise_profile = 'No. ' + profile.id + ' ' + noise - noise_id = profile.id + noise_profile = 'No. ' + str(profile.number) + ' ' + noise + noise_id = str(profile.number) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) elif args[i] == 'inp-delay': @@ -390,8 +394,8 @@ def do_activate(self, command, *args, context=None): i += 2 try: profile = self._model.get_port_profile('description', inp) - inp_profile = 'No. ' + profile.id + ' ' + inp - inp_id = profile.id + inp_profile = 'No. ' + str(profile.number) + ' ' + inp + inp_id = str(profile.number) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) elif args[i] == 'dpbo': @@ -399,11 +403,12 @@ def do_activate(self, command, *args, context=None): i += 2 try: profile = self._model.get_port_profile('description', dpbo) - dpbo_profile = 'No. ' + profile.id + ' ' + dpbo - dpbo_id = profile.id + dpbo_profile = 'No. ' + str(profile.number) + ' ' + dpbo + dpbo_id = str(profile.number) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - + else: + dpbo_flag = True else: raise exceptions.CommandSyntaxError(command=command) @@ -411,15 +416,16 @@ def do_activate(self, command, *args, context=None): port.admin_up() port.set('downstream_max', ds_rate) port.set('upstream_max', us_rate) - port.set('line_spectrum_profile', spectrum_profile) - port.set('spectrum_profile_num', int(spectrum_id)) + if spectrum_flag: + port.set('line_spectrum_profile', spectrum_profile) + port.set('spectrum_profile_num', spectrum_id) port.set('noise_margin_profile', noise_profile) - port.set('noise_margin_profile_num', int(noise_id)) - port.set('line_spectrum_profile', inp_profile) - port.set('spectrum_profile_num', int(inp_id)) - port.set('line_spectrum_profile', dpbo_profile) - port.set('spectrum_profile_num', int(dpbo_id)) - + port.set('noise_margin_profile_num', noise_id) + port.set('inm_profile', inp_profile) + port.set('inm_profile_num', inp_id) + if dpbo_flag: + port.set('dpbo_profile', dpbo_profile) + port.set('dpbo_profile_num', dpbo_id) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) From ee350e94e4119dac42dab56ec9e40e530d2f5baf Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 22 Sep 2020 13:48:10 +0200 Subject: [PATCH 069/318] Added correct output templates for 'switch dsl mode' command --- nesi/huawei/api/schemas/huawei_box_schemas.py | 2 +- nesi/huawei/huawei_resources/huawei_box.py | 9 +++++ nesi/softbox/api/models/box_models.py | 1 + nesi/softbox/api/schemas/card_schemas.py | 2 +- templates/Huawei/5623/A/on_cycle.j2 | 1 + .../enable/diagnose/saving_complete.j2 | 3 ++ .../enable/diagnose/saving_progress.j2 | 4 ++ .../1/login/mainloop/enable/on_enable_quit.j2 | 1 - templates/Huawei/Base/1/login/on_enter.j2 | 2 +- templates/Huawei/Base/1/on_cycle.j2 | 3 +- .../Base/Huawei_Base/baseCommandProcessor.py | 23 +++++++++-- .../Huawei_Base/configCommandProcessor.py | 39 +++++++++++++------ .../Huawei_Base/diagnoseCommandProcessor.py | 30 +++++++++++--- .../Huawei_Base/enableCommandProcessor.py | 20 +++------- .../Huawei_Base/huaweiBaseCommandProcessor.py | 2 +- .../Huawei_Base/interfaceCommandProcessor.py | 22 ++++++++++- .../Base/Huawei_Base/testCommandProcessor.py | 2 +- .../Huawei_Base/userViewCommandProcessor.py | 5 ++- 18 files changed, 127 insertions(+), 44 deletions(-) create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/diagnose/saving_complete.j2 create mode 100644 templates/Huawei/Base/1/login/mainloop/enable/diagnose/saving_progress.j2 delete mode 100644 templates/Huawei/Base/1/login/mainloop/enable/on_enable_quit.j2 diff --git a/nesi/huawei/api/schemas/huawei_box_schemas.py b/nesi/huawei/api/schemas/huawei_box_schemas.py index 057504b..70270f7 100644 --- a/nesi/huawei/api/schemas/huawei_box_schemas.py +++ b/nesi/huawei/api/schemas/huawei_box_schemas.py @@ -17,7 +17,7 @@ class HuaweiBoxSchema(BoxSchema): class Meta: model = Box fields = BoxSchema.Meta.fields + ('cpu_occupancy', 'vlan_interfaces', 'raio_anid', 'handshake_mode', - 'handshake_interval', 'interactive_mode', 'pitp', 'pitp_mode', 'dsl_mode') + 'handshake_interval', 'interactive_mode', 'smart_mode', 'pitp', 'pitp_mode', 'dsl_mode') vlan_interfaces = ma.Hyperlinks( {'_links': { diff --git a/nesi/huawei/huawei_resources/huawei_box.py b/nesi/huawei/huawei_resources/huawei_box.py index 4e0e097..9a3116d 100644 --- a/nesi/huawei/huawei_resources/huawei_box.py +++ b/nesi/huawei/huawei_resources/huawei_box.py @@ -30,6 +30,7 @@ class HuaweiBox(Box): handshake_mode = base.Field('handshake_mode') handshake_interval = base.Field('handshake_interval') interactive_mode = base.Field('interactive_mode') + smart_mode = base.Field('smart_mode') pitp = base.Field('pitp') pitp_mode = base.Field('pitp_mode') dsl_mode = base.Field('dsl_mode') @@ -397,6 +398,14 @@ def set_handshake_interval(self, interval): """Change the handshake interval of a box""" self.update(handshake_interval=interval) + def disable_smart(self): + """Disable Smart function.""" + self.update(smart_mode=False) + + def enable_smart(self): + """Enable Smart function.""" + self.update(smart_mode=True) + def disable_interactive(self): """Disable Interactive function.""" self.update(interactive_mode=False) diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 1a796f5..dcb31d3 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -104,6 +104,7 @@ class Box(db.Model): handshake_mode = db.Column(db.Enum('enable', 'disable'), default='disable') handshake_interval = db.Column(db.Integer(), default=None) interactive_mode = db.Column(db.Boolean(), default=True) + smart_mode = db.Column(db.Boolean, default=True) pitp = db.Column(db.Enum('enable', 'disable'), default='disable') pitp_mode = db.Column(db.String(), default='') dsl_mode = db.Column(db.Enum('tr165', 'tr129'), default='tr165') diff --git a/nesi/softbox/api/schemas/card_schemas.py b/nesi/softbox/api/schemas/card_schemas.py index db80f08..703b137 100644 --- a/nesi/softbox/api/schemas/card_schemas.py +++ b/nesi/softbox/api/schemas/card_schemas.py @@ -39,7 +39,7 @@ class Meta: class CardSchema(ma.ModelSchema): class Meta: model = Card - fields = ('id', 'name', 'ppc', 'operational_state', 'ports', '_links') + fields = ('id', 'name', 'product', 'ppc', 'operational_state', 'ports', '_links') ports = ma.Nested(PortsSchema.PortSchema, many=True) diff --git a/templates/Huawei/5623/A/on_cycle.j2 b/templates/Huawei/5623/A/on_cycle.j2 index b24a03e..0fd4bc2 100644 --- a/templates/Huawei/5623/A/on_cycle.j2 +++ b/templates/Huawei/5623/A/on_cycle.j2 @@ -1 +1,2 @@ + >>User name: \ No newline at end of file diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/saving_complete.j2 b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/saving_complete.j2 new file mode 100644 index 0000000..fbbf3db --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/saving_complete.j2 @@ -0,0 +1,3 @@ + + 1 [{{ context.current_time }}+02:00 DST]:The data of {{ context.mgmt_card }} slot's control board is saved completely + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/saving_progress.j2 b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/saving_progress.j2 new file mode 100644 index 0000000..57c49de --- /dev/null +++ b/templates/Huawei/Base/1/login/mainloop/enable/diagnose/saving_progress.j2 @@ -0,0 +1,4 @@ + + 1 [{{ context.current_time }}+02:00 DST]:The percentage of saved data on {{ context.mgmt_card }} slot's +control board is: {{ context.progress }}% + diff --git a/templates/Huawei/Base/1/login/mainloop/enable/on_enable_quit.j2 b/templates/Huawei/Base/1/login/mainloop/enable/on_enable_quit.j2 deleted file mode 100644 index be08876..0000000 --- a/templates/Huawei/Base/1/login/mainloop/enable/on_enable_quit.j2 +++ /dev/null @@ -1 +0,0 @@ -Are you sure to log out? (y/n)[n]: \ No newline at end of file diff --git a/templates/Huawei/Base/1/login/on_enter.j2 b/templates/Huawei/Base/1/login/on_enter.j2 index 29e04b9..3adfb18 100644 --- a/templates/Huawei/Base/1/login/on_enter.j2 +++ b/templates/Huawei/Base/1/login/on_enter.j2 @@ -1 +1 @@ -Password: \ No newline at end of file +>>User password: \ No newline at end of file diff --git a/templates/Huawei/Base/1/on_cycle.j2 b/templates/Huawei/Base/1/on_cycle.j2 index 731749d..0fd4bc2 100644 --- a/templates/Huawei/Base/1/on_cycle.j2 +++ b/templates/Huawei/Base/1/on_cycle.j2 @@ -1 +1,2 @@ -login: \ No newline at end of file + +>>User name: \ No newline at end of file diff --git a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py index 5aa27ad..f244ad7 100644 --- a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py @@ -66,6 +66,20 @@ def map_states(self, object, type): if type in ('port', 'ont_port'): object.operational_state = 'activating' + def do_smart(self, command, *args, context=None): + if self._validate(args,): + self._write(" Interactive function is enabled\n") + self._model.enable_smart() + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_interactive(self, command, *args, context=None): + if self._validate(args,): + self._write(" Interactive function is enabled\n") + self._model.enable_interactive() + else: + raise exceptions.CommandSyntaxError(command=command) + def user_input(self, prompt, allow_history=True, tmp_boundary=None): self._write(prompt) prompt_end_pos = self.prompt_end_pos @@ -91,11 +105,14 @@ def do_undo(self, command, *args, context=None): return elif self._validate(args, 'event', 'output', 'all'): return + elif self._validate(args, 'system', 'snmp-user', 'password', 'security'): + return elif self._validate(args, 'smart'): + self._write(" Interactive function is disabled\n") + self._model.disable_smart() + elif self._validate(args, 'interactive'): self._write(" Interactive function is disabled\n") self._model.disable_interactive() - elif self._validate(args, 'system', 'snmp-user', 'password', 'security'): - return else: raise exceptions.CommandSyntaxError(command=command) @@ -104,7 +121,7 @@ def on_unknown_command(self, command, *args, context=None): def do_scroll(self, command, *args, context=None): if args == (): - if self._model.interactive_mode: + if self._model.smart_mode: self.user_input('{ |number<10,512> }:') return elif self._validate(args, str): diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py index c854431..8572e39 100644 --- a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py @@ -242,7 +242,7 @@ def generate_ont_info_summary(port): text = self._render('display_interface_vlanif_num', context=dict(context, vlanif=vlanif)) self._write(text) elif self._validate(args, 'vlan', 'all'): - if self._model.interactive_mode: + if self._model.smart_mode: self.user_input('{ |vlanattr|vlantype }:') text = self._render('display_vlan_all_top', context=context) count = 0 @@ -270,7 +270,7 @@ def generate_ont_info_summary(port): self._write(text) elif self._validate(args, 'version'): - if self._model.interactive_mode: + if self._model.smart_mode: self.user_input('{ |backplane|frameid/slotid }:') text = self._render('display_version', context=dict(context, box=self._model)) self._write(text) @@ -286,7 +286,7 @@ def generate_ont_info_summary(port): self._write(text) elif self._validate(args, 'mac-address', 'all'): - if self._model.interactive_mode: + if self._model.smart_mode: self.user_input('{ || }:') self._write(' It will take some time, please wait...\n') @@ -351,7 +351,7 @@ def generate_ont_info_summary(port): self._write(text) elif self._validate(args, 'current-configuration', 'section', 'vlan-srvprof'): - if self._model.interactive_mode: + if self._model.smart_mode: self.user_input('{ || }:') text = self._render('display_current_configuration_section_vlan_srvprof_top', context=dict(context, box=self._model)) @@ -419,6 +419,20 @@ def generate_ont_info_summary(port): else: raise exceptions.CommandSyntaxError(command=command) + def do_smart(self, command, *args, context=None): + if self._validate(args,): + self._write(" Interactive function is enabled\n") + self._model.enable_smart() + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_interactive(self, command, *args, context=None): + if self._validate(args,): + self._write(" Interactive function is enabled\n") + self._model.enable_interactive() + else: + raise exceptions.CommandSyntaxError(command=command) + def do_service_port(self, command, *args, context=None): if args[3] == 'vdsl': port_idx = args[6] @@ -767,6 +781,12 @@ def do_undo(self, command, *args, context=None): if self._validate(args, 'system', 'snmp-user', 'password', 'security'): # importend for future snmp interactions return + elif self._validate(args, 'smart'): + self._write(" Interactive function is disabled\n") + self._model.disable_smart() + elif self._validate(args, 'interactive'): + self._write(" Interactive function is disabled\n") + self._model.disable_interactive() elif self._validate(args, 'service-port', str): s_port_idx, = self._dissect(args, 'service-port', str) @@ -778,13 +798,6 @@ def do_undo(self, command, *args, context=None): s_port.delete() s_vlan.delete() - - elif self._validate(args, 'smart'): - self._write(" Interactive function is disabled\n") - self._model.disable_interactive() - elif self._validate(args, 'interactive'): - return - elif self._validate(args, 'ip', 'route-static', 'all'): answer = self.user_input('Are you sure? [Y/N]:') if answer != 'Y': @@ -960,7 +973,9 @@ def do_terminal(self, command, *args, context=None): text = self._render('user_created', context=context) self._write(text) - var_n = self.user_input(" Repeat this operation? (y/n)[n]:", False, 1) + var_n = 'n' + if self._model.interactive_mode: + var_n = self.user_input(" Repeat this operation? (y/n)[n]:", False, 1) if var_n == 'y': self.do_terminal(command, 'user', 'name', context=context) return diff --git a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py index 85f657a..911369a 100644 --- a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py @@ -118,7 +118,7 @@ def do_switch(self, command, *args, context=None): self.line_buffer = [] raise exceptions.CommandSyntaxError(command=command) - if self._model.interactive_mode: + if self._model.smart_mode: self.user_input('{ |adsl }:', False) text = self._render('switch_dsl_mode_temp_1', context=context) self._write(text) @@ -129,13 +129,18 @@ def do_switch(self, command, *args, context=None): self.line_buffer = [] return - answer_one = self.user_input(' Warning: The operation will result in loss of all VDSL configuration. ' - 'Are you sure to proceed? (y/n)[n]:', False) + answer_one = 'y' + if self._model.interactive_mode: + answer_one = self.user_input(' Warning: The operation will result in loss of all VDSL configuration. ' + 'Are you sure to proceed? (y/n)[n]:', False) if answer_one != 'y': self.line_buffer = [] return - answer_two = self.user_input(' Warning: The operation will automatically save and reboot system. ' - 'Are you sure you want to proceed? (y/n)[n]:', False) + + answer_two = 'y' + if self._model.interactive_mode: + answer_two = self.user_input(' Warning: The operation will automatically save and reboot system. ' + 'Are you sure you want to proceed? (y/n)[n]:', False) if answer_two != 'y': self.line_buffer = [] return @@ -144,6 +149,21 @@ def do_switch(self, command, *args, context=None): self._write(text) self._model.set_dsl_mode(dsl_mode) self.on_cycle(context=context) + + mgmt_card = self._model.get_card('product', 'mgnt') + context['mgmt_card'] = mgmt_card.name[2:] + x = 6 + while x <= 100: + time.sleep(1) + context['current_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + context['progress'] = x + self._write(self._render('saving_progress', context=context)) + self.on_cycle(context=context) + x += 6 + + context['current_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + self._write(self._render('saving_complete', context=context)) + self.on_cycle(context=context) time.sleep(10) self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) user = self._model.get_user('status', 'Online') diff --git a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py index 0166bd6..e7d93b4 100644 --- a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py @@ -18,20 +18,6 @@ class EnableCommandProcessor(HuaweiBaseCommandProcessor): - def do_undo(self, command, *args, context=None): - if self._validate(args, 'smart'): - self._write(" Interactive function is disabled\n") - self._model.disable_interactive() - else: - raise exceptions.CommandSyntaxError(command=command) - - def do_smart(self, command, *args, context=None): - if self._validate(args,): - self._write(" Interactive function is enabled\n") - self._model.enable_interactive() - else: - raise exceptions.CommandSyntaxError(command=command) - def do_disable(self, command, *args, context=None): from .userViewCommandProcessor import UserViewCommandProcessor @@ -42,11 +28,14 @@ def do_disable(self, command, *args, context=None): def do_quit(self, command, *args, context=None): self._write(" Check whether system data has been changed. Please save data before logout.\n") - answer = self.user_input("Are you sure to log out? (y/n)[n]:", False, 1) + answer = 'y' + if self._model.interactive_mode: + answer = self.user_input("Are you sure to log out? (y/n)[n]:", False, 1) if answer == "y": self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) user = self._model.get_user('status', 'Online') user.set_offline() + self._model.enable_smart() self._model.enable_interactive() exc = exceptions.TerminalExitError() exc.return_to = 'sysexit' @@ -258,6 +247,7 @@ def do_save(self, command, *args, context=None): def do_reboot(self, command, *args, context=None): if self._validate(args, 'system'): + self.on_cycle(context=context) time.sleep(10) self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) user = self._model.get_user('status', 'Online') diff --git a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py index 9767501..e45b419 100644 --- a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py @@ -464,7 +464,7 @@ def display_service_port(self, command, args, context): s_port_idx, = self._dissect(args, 'service-port', str) if s_port_idx == 'all': - if self._model.interactive_mode: + if self._model.smart_mode: self.user_input('{ |sort-by|| }:') text = self._render('display_service_port_all_top', context=context) diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py index 5df75d1..abf7ca0 100644 --- a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py @@ -318,7 +318,7 @@ def do_display(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - if self._model.interactive_mode: + if self._model.smart_mode: self.user_input('{ |sort-by|| }:') text = self._render( 'display_port_ddm-info', @@ -758,6 +758,20 @@ def do_ip(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_smart(self, command, *args, context=None): + if self._validate(args,): + self._write(" Interactive function is enabled\n") + self._model.enable_smart() + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_interactive(self, command, *args, context=None): + if self._validate(args,): + self._write(" Interactive function is enabled\n") + self._model.enable_interactive() + else: + raise exceptions.CommandSyntaxError(command=command) + def do_undo(self, command, *args, context=None): if self._validate(args, 'ip', 'address', str, str): if context['iftype'] == 'vlanif': @@ -795,6 +809,12 @@ def do_undo(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) port.admin_up() + elif self._validate(args, 'smart'): + self._write(" Interactive function is disabled\n") + self._model.disable_smart() + elif self._validate(args, 'interactive'): + self._write(" Interactive function is disabled\n") + self._model.disable_interactive() else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py index 39ef44e..9d48c7b 100644 --- a/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py @@ -46,7 +46,7 @@ def do_xdsl(self, command, *args, context=None): except (exceptions.SoftboxenError, AssertionError): raise exceptions.CommandSyntaxError(command=command) - if self._model.interactive_mode: + if self._model.smart_mode: self.user_input('{ |discharge|fault-force-test }:') context['port_name'] = port.name diff --git a/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py b/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py index 19ec2c5..ac1a067 100644 --- a/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py +++ b/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py @@ -37,11 +37,14 @@ def on_unknown_command(self, command, *args, context=None): def do_quit(self, command, *args, context=None): self._write(" Check whether system data has been changed. Please save data before logout.\n") - answer = self.user_input("Are you sure to log out? (y/n)[n]:", False, 1) + answer = 'y' + if self._model.interactive_mode: + answer = self.user_input("Are you sure to log out? (y/n)[n]:", False, 1) if answer == "y": self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) user = self._model.get_user('status', 'Online') user.set_offline() + self._model.enable_smart() self._model.enable_interactive() exc = exceptions.TerminalExitError() exc.return_to = 'sysexit' From 3fe1da98bc72b97d9a88303a1e4a494c47ad8db9 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 22 Sep 2020 14:24:38 +0200 Subject: [PATCH 070/318] Repaired integration and unit tests --- test_cases/integration_tests/huawei/changeMode17.txt | 10 ++++++---- test_cases/unit_tests/huawei/test_huawei.py | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/test_cases/integration_tests/huawei/changeMode17.txt b/test_cases/integration_tests/huawei/changeMode17.txt index ec20156..3f202e7 100644 --- a/test_cases/integration_tests/huawei/changeMode17.txt +++ b/test_cases/integration_tests/huawei/changeMode17.txt @@ -2,10 +2,12 @@ root secret enable config +undo smart +undo interactive diagnose -switch vdsl mode to timode -y -y -return +switch vdsl mode to tr129 +root +secret +enable quit y \ No newline at end of file diff --git a/test_cases/unit_tests/huawei/test_huawei.py b/test_cases/unit_tests/huawei/test_huawei.py index 8431c58..dc2d5e9 100644 --- a/test_cases/unit_tests/huawei/test_huawei.py +++ b/test_cases/unit_tests/huawei/test_huawei.py @@ -39,7 +39,7 @@ def test_port_rest(self): port.port_downstream_set("1") assert port.downstream_max == "1" try: - port.port_downstream_set('failure') + port.port_downstream_set(0) assert False except exceptions.SoftboxenError: assert True @@ -48,7 +48,7 @@ def test_port_rest(self): port.port_upstream_set("1") assert port.upstream_max == "1" try: - port.port_upstream_set('failure') + port.port_upstream_set(0) assert False except exceptions.SoftboxenError: assert True From 7a67251bf2c4526ba7fa004da63d63728ea407a6 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 22 Sep 2020 14:50:26 +0200 Subject: [PATCH 071/318] Removed obsolete template_root and changed directories of files --- bootup/box.sh | 4 ++-- cli.py | 18 ++++++------------ nesi/alcatel/alcatel_resources/alcatel_box.py | 4 ++-- nesi/alcatel/alcatel_resources/alcatel_card.py | 3 ++- nesi/alcatel/alcatel_resources/alcatel_ont.py | 3 ++- .../alcatel_resources/alcatel_ont_port.py | 3 ++- nesi/alcatel/alcatel_resources/alcatel_port.py | 3 ++- .../alcatel_resources/alcatel_port_profile.py | 3 ++- .../alcatel_resources/alcatel_qos_interface.py | 3 ++- .../alcatel_resources/alcatel_service_port.py | 3 ++- .../alcatel_resources/alcatel_service_vlan.py | 3 ++- .../alcatel_resources/alcatel_subrack.py | 3 ++- nesi/alcatel/alcatel_resources/alcatel_vlan.py | 3 ++- nesi/huawei/huawei_resources/huawei_box.py | 4 ++-- nesi/huawei/huawei_resources/huawei_card.py | 3 ++- nesi/huawei/huawei_resources/huawei_cpe.py | 3 ++- nesi/huawei/huawei_resources/huawei_emu.py | 3 ++- nesi/huawei/huawei_resources/huawei_ont.py | 3 ++- .../huawei/huawei_resources/huawei_ont_port.py | 3 ++- nesi/huawei/huawei_resources/huawei_port.py | 3 ++- .../huawei_resources/huawei_port_profile.py | 3 ++- nesi/huawei/huawei_resources/huawei_route.py | 3 ++- .../huawei_resources/huawei_service_port.py | 3 ++- .../huawei_resources/huawei_service_vlan.py | 3 ++- nesi/huawei/huawei_resources/huawei_subrack.py | 3 ++- nesi/huawei/huawei_resources/huawei_user.py | 3 ++- nesi/huawei/huawei_resources/huawei_vlan.py | 3 ++- .../huawei_resources/huawei_vlan_interface.py | 3 ++- nesi/softbox/{ => base_resources}/base.py | 0 nesi/softbox/base_resources/box.py | 2 +- nesi/softbox/base_resources/card.py | 2 +- nesi/softbox/base_resources/cpe.py | 2 +- nesi/softbox/base_resources/cpe_port.py | 2 +- nesi/softbox/base_resources/credentials.py | 2 +- nesi/softbox/base_resources/ont.py | 2 +- nesi/softbox/base_resources/ont_port.py | 2 +- nesi/softbox/base_resources/port.py | 2 +- nesi/softbox/base_resources/port_profile.py | 2 +- nesi/softbox/base_resources/qos_interface.py | 2 +- nesi/softbox/{ => base_resources}/root.py | 2 -- nesi/softbox/base_resources/route.py | 2 +- nesi/softbox/base_resources/service_port.py | 2 +- nesi/softbox/base_resources/service_vlan.py | 2 +- nesi/softbox/base_resources/subrack.py | 2 +- nesi/softbox/base_resources/user.py | 2 +- nesi/softbox/base_resources/vlan.py | 2 +- nesi/softbox/base_resources/vlan_interface.py | 2 +- nesi/softbox/cli/base.py | 12 ++---------- nesi/softbox/{ => cli}/rest_client.py | 0 templates/Alcatel/Base/1/login/on_enter.j2 | 1 - templates/Alcatel/Base/1/login/on_exit.j2 | 3 --- templates/Alcatel/Base/1/on_cycle.j2 | 1 - templates/Alcatel/Base/1/on_enter.j2 | 4 ---- templates/Alcatel/Base/1/on_exit.j2 | 0 .../Alcatel/{Base/1 => }/login/mainloop/?.j2 | 0 .../{Base/1 => }/login/mainloop/admin/?.j2 | 0 .../mainloop/admin/instance_does_not_exist.j2 | 0 .../1 => }/login/mainloop/admin/on_cycle.j2 | 0 .../{Base/1 => }/login/mainloop/configure/?.j2 | 0 .../1 => }/login/mainloop/configure/alarm/?.j2 | 0 .../alarm/entry/board-hw-issue/on_cycle.j2 | 0 .../alarm/entry/board-hw-issue/on_error.j2 | 0 .../alarm/entry/board-init/on_cycle.j2 | 0 .../alarm/entry/board-init/on_error.j2 | 0 .../entry/board-instl-missing/on_cycle.j2 | 0 .../entry/board-instl-missing/on_error.j2 | 0 .../alarm/entry/board-missing/on_cycle.j2 | 0 .../alarm/entry/board-missing/on_error.j2 | 0 .../alarm/entry/plugin-dc-b/on_cycle.j2 | 0 .../alarm/entry/plugin-dc-b/on_error.j2 | 0 .../login/mainloop/configure/alarm/on_cycle.j2 | 0 .../login/mainloop/configure/alarm/on_error.j2 | 0 .../bridge/instance_does_not_exist.j2 | 0 .../mainloop/configure/bridge/on_cycle.j2 | 0 .../mainloop/configure/bridge/on_error.j2 | 0 .../vlan-id/vlan_identifier/on_cycle.j2 | 0 .../port_identifier/instance_does_not_exist.j2 | 0 .../bridge/port/port_identifier/on_cycle.j2 | 0 .../ethernet/line/port_identifier/on_cycle.j2 | 0 .../configure/instance_does_not_exist.j2 | 0 .../configure/interface/port/on_cycle.j2 | 0 .../mainloop/configure/linetest/on_cycle.j2 | 0 .../mainloop/configure/linetest/on_error.j2 | 0 .../lineid/port_identifier/on_cycle.j2 | 0 .../lineid/port_identifier/on_error.j2 | 0 .../single/ltsession/session_id/on_cycle.j2 | 0 .../single/ltsession/session_id/on_error.j2 | 0 .../configure/linetest/single/on_cycle.j2 | 0 .../configure/linetest/single/on_error.j2 | 0 .../login/mainloop/configure/on_cycle.j2 | 0 .../login/mainloop/configure/on_error.j2 | 0 .../configure/qos/interface/on_cycle.j2 | 0 .../configure/qos/interface/on_error.j2 | 0 .../login/mainloop/configure/qos/on_cycle.j2 | 0 .../login/mainloop/configure/qos/on_error.j2 | 0 .../mainloop/configure/service/on_cycle.j2 | 0 .../mainloop/configure/service/on_error.j2 | 0 .../configure/software_mngt/oswp/2/on_cycle.j2 | 0 .../system/loop_id_syntax/on_cycle.j2 | 0 .../mainloop/configure/system/on_cycle.j2 | 0 .../mainloop/configure/system/on_error.j2 | 0 .../configure/system/security/on_cycle.j2 | 0 .../configure/system/security/on_error.j2 | 0 .../system/security/operator/on_error.j2 | 0 .../security/operator/user_name/on_cycle.j2 | 0 .../security/operator/user_name/on_error.j2 | 0 .../system/security/profile/admin/on_cycle.j2 | 0 .../system/security/profile/admin/on_error.j2 | 0 .../mainloop/configure/system/sntp/on_cycle.j2 | 0 .../mainloop/configure/system/sntp/on_error.j2 | 0 .../server_table/ip_address/ip/on_cycle.j2 | 0 .../mainloop/configure/vlan/id/on_cycle.j2 | 0 .../mainloop/configure/vlan/id/on_error.j2 | 0 .../vlan/id/shub/instance_does_not_exist.j2 | 0 .../configure/vlan/id/shub/on_cycle.j2 | 0 .../configure/vlan/id/shub/on_error.j2 | 0 .../login/mainloop/configure/vlan/info_body.j2 | 0 .../mainloop/configure/vlan/info_bottom.j2 | 0 .../login/mainloop/configure/vlan/info_head.j2 | 0 .../configure/vlan/instance_does_not_exist.j2 | 0 .../login/mainloop/configure/vlan/on_cycle.j2 | 0 .../login/mainloop/configure/vlan/on_error.j2 | 0 .../id/EgressPort/instance_does_not_exist.j2 | 0 .../vlan/shub/id/EgressPort/on_cycle.j2 | 0 .../vlan/shub/id/EgressPort/on_error.j2 | 0 .../vlan/shub/id/instance_does_not_exist.j2 | 0 .../configure/vlan/shub/id/on_cycle.j2 | 0 .../configure/vlan/shub/id/on_error.j2 | 0 .../vlan/shub/instance_does_not_exist.j2 | 0 .../mainloop/configure/vlan/shub/on_cycle.j2 | 0 .../mainloop/configure/vlan/shub/on_error.j2 | 0 .../xdsl/board/instance_does_not_exist.j2 | 0 .../xdsl/board/nt/instance_does_not_exist.j2 | 0 .../configure/xdsl/board/nt/on_cycle.j2 | 0 .../configure/xdsl/instance_does_not_exist.j2 | 0 .../xdsl/line/port_identifier/on_cycle.j2 | 0 .../mainloop/configure/xdsl_line_admin_up.j2 | 0 .../mainloop/configure_bridge_port_bottom.j2 | 0 .../configure_bridge_port_identifier_detail.j2 | 0 ...igure_bridge_port_identifier_detail_vlan.j2 | 0 .../configure_bridge_port_middle_bottom.j2 | 0 .../configure_bridge_port_middle_top.j2 | 0 .../mainloop/configure_bridge_port_top.j2 | 0 .../mainloop/configure_bridge_port_vlan.j2 | 0 .../configure_bridge_port_vlan_detail.j2 | 0 ...onfigure_ethernet_line_identifier_detail.j2 | 0 ...et_line_identifier_mau_identifier_detail.j2 | 0 ...configure_ethernet_ont_ontportidx_detail.j2 | 0 .../mainloop/configure_product_line_port.j2 | 0 .../configure_product_line_port_detail.j2 | 0 .../configure_qos_profiles_policer_middle.j2 | 0 .../configure_qos_profiles_session_bottom.j2 | 0 .../configure_qos_profiles_session_middle.j2 | 0 .../configure_qos_profiles_session_top.j2 | 0 .../mainloop/configure_vlan_id_vlan_id.j2 | 0 .../1 => }/login/mainloop/environment/?.j2 | 0 .../environment/inhibit_alarms_help.j2 | 0 .../inhibit_alarms_mode_batch_help.j2 | 0 .../inhibit_alarms_mode_batch_print_help.j2 | 0 ...bit_alarms_mode_batch_print_no_more_help.j2 | 0 .../environment/inhibit_alarms_mode_help.j2 | 0 .../login/mainloop/environment/on_cycle.j2 | 0 .../login/mainloop/environment/on_error.j2 | 0 .../mainloop/info/configure/qos/on_cycle.j2 | 0 .../login/mainloop/info_configure_vlan_body.j2 | 0 .../mainloop/info_configure_vlan_bottom.j2 | 0 .../login/mainloop/info_configure_vlan_head.j2 | 0 .../mainloop/info_configure_vlan_shub_top.j2 | 0 .../mainloop/info_configure_vlan_shub_vlan.j2 | 0 ...nfo_configure_vlan_shub_vlan_egress_port.j2 | 0 .../info_configure_vlan_shub_vlan_end.j2 | 0 .../login/mainloop/instance_does_not_exist.j2 | 0 .../{Base/1 => }/login/mainloop/on_cycle.j2 | 0 .../{Base/1 => }/login/mainloop/on_enter.j2 | 0 .../{Base/1 => }/login/mainloop/on_error.j2 | 0 .../{Base/1 => }/login/mainloop/show/?.j2 | 0 .../mainloop/show/alarm_current_table_bot.j2 | 0 .../mainloop/show/alarm_current_table_mid.j2 | 0 .../mainloop/show/alarm_current_table_top.j2 | 0 .../port_identifier/on_cycle.j2 | 0 ...equipment_diagnostics_sfp_sfpport_detail.j2 | 0 ...quipment_ont_interface_ontportidx_detail.j2 | 0 ...t_ont_operational-data_ontportidx_detail.j2 | 0 .../equipment_ont_optics_ontportidx_detail.j2 | 0 .../show/equipment_ont_slot_detail_bottom.j2 | 0 .../show/equipment_ont_slot_detail_middle.j2 | 0 .../show/equipment_ont_slot_detail_top.j2 | 0 .../mainloop/show/equipment_shelf_body.j2 | 0 .../mainloop/show/equipment_shelf_bottom.j2 | 0 .../show/equipment_shelf_detail_body.j2 | 0 .../show/equipment_shelf_detail_bottom.j2 | 0 .../show/equipment_shelf_detail_head.j2 | 0 .../show/equipment_shelf_shelfid_detail.j2 | 0 .../login/mainloop/show/equipment_shelf_top.j2 | 0 .../mainloop/show/equipment_slot_bottom.j2 | 0 .../show/equipment_slot_detail_body.j2 | 0 .../show/equipment_slot_detail_head.j2 | 0 .../mainloop/show/equipment_slot_middle.j2 | 0 .../show/equipment_slot_slotid_detail.j2 | 0 .../login/mainloop/show/equipment_slot_top.j2 | 0 .../show/equipment_temperature_bottom.j2 | 0 .../show/equipment_temperature_middle.j2 | 0 .../mainloop/show/equipment_temperature_top.j2 | 0 ..._transceiver_inventory_identifier_bottom.j2 | 0 ..._transceiver_inventory_identifier_detail.j2 | 0 ...ent_transceiver_inventory_identifier_mid.j2 | 0 ...ent_transceiver_inventory_identifier_top.j2 | 0 .../login/mainloop/show/ethernet_mau_bottom.j2 | 0 .../login/mainloop/show/ethernet_mau_middle.j2 | 0 .../mainloop/show/ethernet_mau_port_detail.j2 | 0 .../login/mainloop/show/ethernet_mau_top.j2 | 0 ...t_ont_operational_data_ontportidx_detail.j2 | 0 .../mainloop/show/instance_does_not_exist.j2 | 0 .../mainloop/show/interface_port_bottom.j2 | 0 .../mainloop/show/interface_port_middle.j2 | 0 ...terface_port_pipe_match_match_exact_port.j2 | 0 ...pipe_match_match_exact_product_line_port.j2 | 0 .../show/interface_port_ponport_detail.j2 | 0 .../login/mainloop/show/interface_port_top.j2 | 0 .../linetest_single_lineid_ext_rept_empty.j2 | 0 .../linetest_single_lineid_ext_rept_filled.j2 | 0 .../1 => }/login/mainloop/show/on_cycle.j2 | 0 .../1 => }/login/mainloop/show/on_error.j2 | 0 .../show/pon_unprovision_onu_detail_bottom.j2 | 0 .../show/pon_unprovision_onu_detail_middle.j2 | 0 .../show/pon_unprovision_onu_detail_top.j2 | 0 .../show/product_cpeinventory_port_detail.j2 | 0 .../1 => }/login/mainloop/show/product_help.j2 | 0 .../show/product_linkuprecord_port_detail.j2 | 0 .../show/product_operational_data_help.j2 | 0 .../show/product_operational_data_line_help.j2 | 0 ...roduct_operational_data_line_port_detail.j2 | 0 ...t_operational_data_line_port_detail_help.j2 | 0 .../show/shdsl_span_status_port_detail.j2 | 0 .../software_mngt_upload_download_detail.j2 | 0 .../show/software_mngt_version_etsi_detail.j2 | 0 .../ether_ifmault/port_identifier/on_cycle.j2 | 0 ...bridge_port-fdb_ontportidx_detail_bottom.j2 | 0 ...an_bridge_port-fdb_ontportidx_detail_mid.j2 | 0 ...an_bridge_port-fdb_ontportidx_detail_top.j2 | 0 .../show/vlan_bridge_port_fdb_bottom.j2 | 0 .../show/vlan_bridge_port_fdb_middle.j2 | 0 .../mainloop/show/vlan_bridge_port_fdb_top.j2 | 0 .../login/mainloop/show/vlan_name_bottom.j2 | 0 .../login/mainloop/show/vlan_name_middle.j2 | 0 .../mainloop/show/vlan_name_name_detail.j2 | 0 .../login/mainloop/show/vlan_name_top.j2 | 0 .../Alcatel/{7360/FX-4 => }/login/on_cycle.j2 | 0 .../Alcatel/{7360/FX-4 => }/login/on_enter.j2 | 0 .../Alcatel/{7360/FX-4 => }/login/on_exit.j2 | 0 .../Alcatel/{7360/FX-4 => }/login/password.j2 | 0 templates/Alcatel/{7360/FX-4 => }/on_cycle.j2 | 0 templates/Alcatel/{7360/FX-4 => }/on_enter.j2 | 0 templates/Alcatel/{7360/FX-4 => }/on_exit.j2 | 0 templates/Huawei/5623/A/login/password.j2 | 2 -- templates/Huawei/Base/1/login/on_cycle.j2 | 0 templates/Huawei/Base/1/login/on_enter.j2 | 1 - templates/Huawei/Base/1/login/password.j2 | 2 -- templates/Huawei/Base/1/on_cycle.j2 | 2 -- templates/Huawei/Base/1/on_enter.j2 | 0 templates/Huawei/Base/1/on_exit.j2 | 2 -- .../Huawei/{Base/1 => }/login/mainloop/?.j2 | 0 .../login/mainloop/display_board_0_bottom.j2 | 0 .../login/mainloop/display_board_0_empty.j2 | 0 .../login/mainloop/display_board_0_middle.j2 | 0 .../login/mainloop/display_board_0_top.j2 | 0 .../display_board_dsl_product_bottom_bottom.j2 | 0 .../display_board_dsl_product_bottom_middle.j2 | 0 .../display_board_dsl_product_bottom_top.j2 | 0 .../display_board_dsl_product_middle_bottom.j2 | 0 .../display_board_dsl_product_middle_middle.j2 | 0 .../display_board_dsl_product_middle_top.j2 | 0 .../display_board_dsl_product_top_bottom.j2 | 0 .../display_board_dsl_product_top_middle.j2 | 0 .../display_board_dsl_product_top_top.j2 | 0 .../display_board_ftth_failed_link_bottom.j2 | 0 .../display_board_ftth_failed_link_middle.j2 | 0 .../display_board_ftth_failed_link_top.j2 | 0 .../display_board_ftth_normal_bottom_bottom.j2 | 0 .../display_board_ftth_normal_bottom_middle.j2 | 0 .../display_board_ftth_normal_bottom_top.j2 | 0 .../display_board_ftth_normal_header.j2 | 0 .../display_board_ftth_normal_top_bottom.j2 | 0 .../display_board_ftth_normal_top_middle.j2 | 0 .../display_board_ftth_normal_top_top.j2 | 0 .../display_board_ftth_pon_bottom_bottom.j2 | 0 .../display_board_ftth_pon_bottom_middle.j2 | 0 .../display_board_ftth_pon_bottom_top.j2 | 0 .../display_board_ftth_pon_middle_bottom.j2 | 0 .../display_board_ftth_pon_middle_middle.j2 | 0 .../display_board_ftth_pon_middle_top.j2 | 0 .../display_board_ftth_pon_ont_summary.j2 | 0 .../display_board_ftth_pon_top_bottom.j2 | 0 .../display_board_ftth_pon_top_middle.j2 | 0 .../mainloop/display_board_ftth_pon_top_top.j2 | 0 ...display_board_ftth_special_bottom_bottom.j2 | 0 ...display_board_ftth_special_bottom_middle.j2 | 0 .../display_board_ftth_special_bottom_top.j2 | 0 .../display_board_ftth_special_header.j2 | 0 ...display_board_ftth_special_middle_bottom.j2 | 0 ...display_board_ftth_special_middle_middle.j2 | 0 .../display_board_ftth_special_middle_top.j2 | 0 .../display_board_ftth_special_top_bottom.j2 | 0 .../display_board_ftth_special_top_middle.j2 | 0 .../display_board_ftth_special_top_top.j2 | 0 .../display_board_mgnt_bottom_bottom.j2 | 0 .../mainloop/display_board_mgnt_bottom_mid.j2 | 0 .../mainloop/display_board_mgnt_bottom_top.j2 | 0 .../display_board_mgnt_failed_bottom.j2 | 0 .../mainloop/display_board_mgnt_failed_mid.j2 | 0 .../mainloop/display_board_mgnt_failed_top.j2 | 0 .../mainloop/display_board_mgnt_header.j2 | 0 .../mainloop/display_board_mgnt_top_bottom.j2 | 0 .../mainloop/display_board_mgnt_top_mid.j2 | 0 .../mainloop/display_board_mgnt_top_top.j2 | 0 .../{Base/1 => }/login/mainloop/enable/?.j2 | 0 .../1 => }/login/mainloop/enable/config/?.j2 | 0 .../enable/config/backup_configuration_tftp.j2 | 0 .../mainloop/enable/config/board_type_error.j2 | 0 .../enable/config/delete_vlan_if_first.j2 | 0 ...larm_active_alarmtype_environment_detail.j2 | 0 .../enable/config/display_board_0_bottom.j2 | 0 .../enable/config/display_board_0_empty.j2 | 0 .../enable/config/display_board_0_middle.j2 | 0 .../enable/config/display_board_0_top.j2 | 0 .../display_board_dsl_product_bottom_bottom.j2 | 0 .../display_board_dsl_product_bottom_middle.j2 | 0 .../display_board_dsl_product_bottom_top.j2 | 0 .../display_board_dsl_product_middle_bottom.j2 | 0 .../display_board_dsl_product_middle_middle.j2 | 0 .../display_board_dsl_product_middle_top.j2 | 0 .../display_board_dsl_product_top_bottom.j2 | 0 .../display_board_dsl_product_top_middle.j2 | 0 .../display_board_dsl_product_top_top.j2 | 0 .../display_board_ftth_failed_link_bottom.j2 | 0 .../display_board_ftth_failed_link_middle.j2 | 0 .../display_board_ftth_failed_link_top.j2 | 0 .../display_board_ftth_normal_bottom_bottom.j2 | 0 .../display_board_ftth_normal_bottom_middle.j2 | 0 .../display_board_ftth_normal_bottom_top.j2 | 0 .../config/display_board_ftth_normal_header.j2 | 0 .../display_board_ftth_normal_top_bottom.j2 | 0 .../display_board_ftth_normal_top_middle.j2 | 0 .../display_board_ftth_normal_top_top.j2 | 0 .../display_board_ftth_pon_bottom_bottom.j2 | 0 .../display_board_ftth_pon_bottom_middle.j2 | 0 .../display_board_ftth_pon_bottom_top.j2 | 0 .../display_board_ftth_pon_middle_bottom.j2 | 0 .../display_board_ftth_pon_middle_middle.j2 | 0 .../display_board_ftth_pon_middle_top.j2 | 0 .../display_board_ftth_pon_ont_summary.j2 | 0 .../display_board_ftth_pon_top_bottom.j2 | 0 .../display_board_ftth_pon_top_middle.j2 | 0 .../config/display_board_ftth_pon_top_top.j2 | 0 ...display_board_ftth_special_bottom_bottom.j2 | 0 ...display_board_ftth_special_bottom_middle.j2 | 0 .../display_board_ftth_special_bottom_top.j2 | 0 .../display_board_ftth_special_header.j2 | 0 ...display_board_ftth_special_middle_bottom.j2 | 0 ...display_board_ftth_special_middle_middle.j2 | 0 .../display_board_ftth_special_middle_top.j2 | 0 .../display_board_ftth_special_top_bottom.j2 | 0 .../display_board_ftth_special_top_middle.j2 | 0 .../display_board_ftth_special_top_top.j2 | 0 .../config/display_board_mgnt_bottom_bottom.j2 | 0 .../config/display_board_mgnt_bottom_mid.j2 | 0 .../config/display_board_mgnt_bottom_top.j2 | 0 .../config/display_board_mgnt_failed_bottom.j2 | 0 .../config/display_board_mgnt_failed_mid.j2 | 0 .../config/display_board_mgnt_failed_top.j2 | 0 .../enable/config/display_board_mgnt_header.j2 | 0 .../config/display_board_mgnt_top_bottom.j2 | 0 .../config/display_board_mgnt_top_mid.j2 | 0 .../config/display_board_mgnt_top_top.j2 | 0 .../enable/config/display_board_num.j2 | 0 .../enable/config/display_board_num_0.j2 | 0 .../enable/config/display_board_num_1.j2 | 0 ...t_configuration_section_vlan_srvprof_bot.j2 | 0 ..._configuration_section_vlan_srvprof_bot2.j2 | 0 ...t_configuration_section_vlan_srvprof_mid.j2 | 0 ...t_configuration_section_vlan_srvprof_top.j2 | 0 .../mainloop/enable/config/display_emu.j2 | 0 .../mainloop/enable/config/display_emu_id.j2 | 0 .../config/display_interface_vlanif_num.j2 | 0 .../config/display_mac_address_all_bottom.j2 | 0 .../config/display_mac_address_all_middle.j2 | 0 .../config/display_mac_address_all_top.j2 | 0 .../config/display_ont_autofind_all_body.j2 | 0 .../config/display_ont_autofind_all_failure.j2 | 0 .../config/display_ont_autofind_all_footer.j2 | 0 .../display_ont_info_summary_0_bottom.j2 | 0 .../display_ont_info_summary_0_middle.j2 | 0 .../display_ont_info_summary_0_middle2.j2 | 0 .../config/display_ont_info_summary_0_top.j2 | 0 .../config/display_ont_info_summary_0_top2.j2 | 0 .../enable/config/display_pitp_config.j2 | 0 .../enable/config/display_service_port.j2 | 0 .../config/display_service_port_all_bottom.j2 | 0 .../config/display_service_port_all_middle.j2 | 0 .../config/display_service_port_all_top.j2 | 0 .../config/display_terminal_user_all_bottom.j2 | 0 .../config/display_terminal_user_all_middle.j2 | 0 .../config/display_terminal_user_all_top.j2 | 0 .../mainloop/enable/config/display_version.j2 | 0 .../enable/config/display_vlan_all_bottom.j2 | 0 .../enable/config/display_vlan_all_mid.j2 | 0 .../enable/config/display_vlan_all_top.j2 | 0 .../enable/config/interface/adsl_help.j2 | 0 .../interface/display_adsl_line-profile_num.j2 | 0 .../config/interface/display_inventory_cpe.j2 | 0 .../display_ont_info_port_ont_header.j2 | 0 .../display_ont_info_port_ont_loop1_loop2.j2 | 0 .../display_ont_info_port_ont_loop1_middle.j2 | 0 .../display_ont_info_port_ont_loop2_loop3.j2 | 0 .../display_ont_info_port_ont_loop2_middle.j2 | 0 .../display_ont_info_port_ont_loop3_middle.j2 | 0 .../display_ont_info_port_ont_loop4_bottom.j2 | 0 .../display_ont_info_port_ont_loop4_middle.j2 | 0 .../display_ont_info_port_ont_loop4_top.j2 | 0 .../display_ont_info_port_ont_vlan_bottom.j2 | 0 .../display_ont_info_port_ont_vlan_middle.j2 | 0 .../display_ont_info_port_ont_vlan_top.j2 | 0 .../display_ont_optical-info_num_num.j2 | 0 ...play_ont_port_state_num_num_eth-port_num.j2 | 0 .../config/interface/display_port_ddm-info.j2 | 0 .../config/interface/display_port_state.j2 | 0 .../interface/display_port_state_offline.j2 | 0 .../config/interface/display_power_run_info.j2 | 0 .../display_traffic_table_ip_index.j2 | 0 .../interface/display_vdsl_line-profile_num.j2 | 0 .../enable/config/interface/gpon_help.j2 | 0 .../enable/config/interface/on_cycle.j2 | 0 .../enable/config/interface/on_error.j2 | 0 .../enable/config/interface/ont_added.j2 | 0 .../config/interface/ont_already_exists.j2 | 0 .../enable/config/interface/ont_not_online.j2 | 0 .../operation_not_supported_by_port_failure.j2 | 0 .../interface/port_has_been_activated.j2 | 0 .../interface/port_has_been_deactivated.j2 | 0 .../enable/config/interface/vdsl_help.j2 | 0 .../enable/config/interface/vlan_help.j2 | 0 .../login/mainloop/enable/config/on_cycle.j2 | 0 .../login/mainloop/enable/config/on_error.j2 | 0 .../config/operation_not_supported_by_board.j2 | 0 ...operation_not_supported_by_board_failure.j2 | 0 .../operation_not_supported_by_port_failure.j2 | 0 .../enable/config/pitp_enable_pmode.j2 | 0 .../enable/config/please_wait_commit.j2 | 0 .../enable/config/port_already_in_vlan.j2 | 0 .../config/port_profile_already_exists.j2 | 0 .../config/port_profile_does_not_exist.j2 | 0 ...rd_port_multi-service_user-vlan_untagged.j2 | 0 .../config/service_port_does_already_exist.j2 | 0 .../login/mainloop/enable/config/srvprof/?.j2 | 0 .../mainloop/enable/config/srvprof/on_cycle.j2 | 0 .../mainloop/enable/config/srvprof/on_error.j2 | 0 .../config/srvprof/please_wait_commit.j2 | 0 .../enable/config/terminal_error_choice.j2 | 0 .../enable/config/terminal_level_error.j2 | 0 .../enable/config/terminal_name_short.j2 | 0 .../enable/config/terminal_profile_error.j2 | 0 .../enable/config/terminal_pw_error.j2 | 0 .../enable/config/terminal_pw_short.j2 | 0 .../login/mainloop/enable/config/test/?.j2 | 0 .../mainloop/enable/config/test/melt_test.j2 | 0 .../enable/config/test/melt_test_wait.j2 | 0 .../mainloop/enable/config/test/on_cycle.j2 | 0 .../mainloop/enable/config/test/on_error.j2 | 0 .../enable/config/user_already_exists.j2 | 0 .../enable/config/user_already_unlocked.j2 | 0 .../mainloop/enable/config/user_created.j2 | 0 .../login/mainloop/enable/config/user_level.j2 | 0 .../enable/config/vlan_already_exists.j2 | 0 ...ce-profile_vlan-id_profile-id_profile-id.j2 | 0 .../enable/config/vlan_does_not_exist.j2 | 0 .../vlan_service_profile_does_not_exist.j2 | 0 .../1 => }/login/mainloop/enable/diagnose/?.j2 | 0 .../display_system_status_collection.j2 | 0 .../display_system_status_collection_1.j2 | 0 .../display_system_status_collection_10.j2 | 0 .../display_system_status_collection_2.j2 | 0 .../display_system_status_collection_3.j2 | 0 .../display_system_status_collection_4.j2 | 0 .../display_system_status_collection_5.j2 | 0 .../display_system_status_collection_6.j2 | 0 .../display_system_status_collection_7.j2 | 0 .../display_system_status_collection_8.j2 | 0 .../display_system_status_collection_9.j2 | 0 .../login/mainloop/enable/diagnose/on_cycle.j2 | 0 .../login/mainloop/enable/diagnose/on_error.j2 | 0 .../enable/diagnose/saving_complete.j2 | 0 .../enable/diagnose/saving_progress.j2 | 0 .../enable/diagnose/switch_dsl_mode_failure.j2 | 0 .../enable/diagnose/switch_dsl_mode_temp_1.j2 | 0 .../enable/diagnose/switch_dsl_mode_temp_2.j2 | 0 ...y_adsl_line_operation_port_num_card_port.j2 | 0 .../mainloop/enable/display_board_0_bottom.j2 | 0 .../mainloop/enable/display_board_0_empty.j2 | 0 .../mainloop/enable/display_board_0_middle.j2 | 0 .../mainloop/enable/display_board_0_top.j2 | 0 .../display_board_dsl_product_bottom_bottom.j2 | 0 .../display_board_dsl_product_bottom_middle.j2 | 0 .../display_board_dsl_product_bottom_top.j2 | 0 .../display_board_dsl_product_middle_bottom.j2 | 0 .../display_board_dsl_product_middle_middle.j2 | 0 .../display_board_dsl_product_middle_top.j2 | 0 .../display_board_dsl_product_top_bottom.j2 | 0 .../display_board_dsl_product_top_middle.j2 | 0 .../display_board_dsl_product_top_top.j2 | 0 .../display_board_ftth_failed_link_bottom.j2 | 0 .../display_board_ftth_failed_link_middle.j2 | 0 .../display_board_ftth_failed_link_top.j2 | 0 .../display_board_ftth_normal_bottom_bottom.j2 | 0 .../display_board_ftth_normal_bottom_middle.j2 | 0 .../display_board_ftth_normal_bottom_top.j2 | 0 .../enable/display_board_ftth_normal_header.j2 | 0 .../display_board_ftth_normal_top_bottom.j2 | 0 .../display_board_ftth_normal_top_middle.j2 | 0 .../display_board_ftth_normal_top_top.j2 | 0 .../display_board_ftth_pon_bottom_bottom.j2 | 0 .../display_board_ftth_pon_bottom_middle.j2 | 0 .../display_board_ftth_pon_bottom_top.j2 | 0 .../display_board_ftth_pon_middle_bottom.j2 | 0 .../display_board_ftth_pon_middle_middle.j2 | 0 .../display_board_ftth_pon_middle_top.j2 | 0 .../display_board_ftth_pon_ont_summary.j2 | 0 .../display_board_ftth_pon_top_bottom.j2 | 0 .../display_board_ftth_pon_top_middle.j2 | 0 .../enable/display_board_ftth_pon_top_top.j2 | 0 ...display_board_ftth_special_bottom_bottom.j2 | 0 ...display_board_ftth_special_bottom_middle.j2 | 0 .../display_board_ftth_special_bottom_top.j2 | 0 .../display_board_ftth_special_header.j2 | 0 ...display_board_ftth_special_middle_bottom.j2 | 0 ...display_board_ftth_special_middle_middle.j2 | 0 .../display_board_ftth_special_middle_top.j2 | 0 .../display_board_ftth_special_top_bottom.j2 | 0 .../display_board_ftth_special_top_middle.j2 | 0 .../display_board_ftth_special_top_top.j2 | 0 .../enable/display_board_mgnt_bottom_bottom.j2 | 0 .../enable/display_board_mgnt_bottom_mid.j2 | 0 .../enable/display_board_mgnt_bottom_top.j2 | 0 .../enable/display_board_mgnt_failed_bottom.j2 | 0 .../enable/display_board_mgnt_failed_mid.j2 | 0 .../enable/display_board_mgnt_failed_top.j2 | 0 .../enable/display_board_mgnt_header.j2 | 0 .../enable/display_board_mgnt_top_bottom.j2 | 0 .../enable/display_board_mgnt_top_mid.j2 | 0 .../enable/display_board_mgnt_top_top.j2 | 0 .../enable/display_interface_product_port.j2 | 0 ...oduct_port_state_num_card_port_activated.j2 | 0 ...uct_port_state_num_card_port_deactivated.j2 | 0 .../mainloop/enable/display_service_port.j2 | 0 .../enable/display_service_port_all_bottom.j2 | 0 .../enable/display_service_port_all_middle.j2 | 0 .../enable/display_service_port_all_top.j2 | 0 .../mainloop/enable/display_temperature.j2 | 0 .../enable/display_terminal_user_all_bottom.j2 | 0 .../enable/display_terminal_user_all_middle.j2 | 0 .../enable/display_terminal_user_all_top.j2 | 0 .../enable/display_vdsl_line-profile_num.j2 | 0 ...y_vdsl_line_operation_port_num_card_port.j2 | 0 .../1 => }/login/mainloop/enable/on_cycle.j2 | 0 .../login/mainloop/enable/on_enable_quit.j2} | 0 .../1 => }/login/mainloop/enable/on_error.j2 | 0 .../Huawei/{Base/1 => }/login/mainloop/help.j2 | 0 .../{Base/1 => }/login/mainloop/on_cycle.j2 | 0 .../{Base/1 => }/login/mainloop/on_enter.j2 | 0 .../{Base/1 => }/login/mainloop/on_error.j2 | 0 .../Huawei/{5623/A => }/login/on_cycle.j2 | 0 .../Huawei/{5623/A => }/login/on_enter.j2 | 0 .../Base/1 => Huawei}/login/password.j2 | 0 .../Huawei/{5623/A => }/login/user_locked.j2 | 0 templates/Huawei/{5623/A => }/on_cycle.j2 | 0 templates/Huawei/{5623/A => }/on_enter.j2 | 0 templates/Huawei/{5623/A => }/on_exit.j2 | 0 test_cases/unit_tests/alcatel/test_alcatel.py | 6 +++--- test_cases/unit_tests/test_core.py | 15 +++++++-------- vendors/Alcatel/7360/Alcatel_7360/__init__.py | 2 -- vendors/Alcatel/7360/__init__.py | 0 vendors/Alcatel/Base/Alcatel_Base/__init__.py | 2 -- vendors/Alcatel/Base/__init__.py | 0 .../Alcatel_Base => }/adminCommandProcessor.py | 0 .../Alcatel_Base => }/baseCommandProcessor.py | 4 ---- .../{Base/Alcatel_Base => }/baseMixIn.py | 0 .../configureCommandProcessor.py | 0 .../environmentCommandProcessor.py | 0 .../Alcatel/{7360/Alcatel_7360 => }/main.py | 16 ++++------------ .../Alcatel_Base => }/showCommandProcessor.py | 0 .../userViewCommandProcessor.py | 0 vendors/Huawei/5623/Huawei_5623/__init__.py | 2 -- vendors/Huawei/5623/__init__.py | 0 vendors/Huawei/Base/Huawei_Base/__init__.py | 2 -- vendors/Huawei/Base/__init__.py | 0 .../Huawei_Base => }/baseCommandProcessor.py | 4 ---- .../Huawei/{Base/Huawei_Base => }/baseMixIn.py | 0 .../Huawei_Base => }/configCommandProcessor.py | 0 .../diagnoseCommandProcessor.py | 0 .../Huawei_Base => }/enableCommandProcessor.py | 0 .../huaweiBaseCommandProcessor.py | 3 +-- .../interfaceCommandProcessor.py | 0 vendors/Huawei/{5623/Huawei_5623 => }/main.py | 15 +++------------ .../Huawei_Base => }/testCommandProcessor.py | 0 .../userViewCommandProcessor.py | 0 .../vlanSrvprofCommandProcessor.py | 0 605 files changed, 97 insertions(+), 142 deletions(-) rename nesi/softbox/{ => base_resources}/base.py (100%) rename nesi/softbox/{ => base_resources}/root.py (99%) rename nesi/softbox/{ => cli}/rest_client.py (100%) delete mode 100644 templates/Alcatel/Base/1/login/on_enter.j2 delete mode 100644 templates/Alcatel/Base/1/login/on_exit.j2 delete mode 100644 templates/Alcatel/Base/1/on_cycle.j2 delete mode 100644 templates/Alcatel/Base/1/on_enter.j2 delete mode 100644 templates/Alcatel/Base/1/on_exit.j2 rename templates/Alcatel/{Base/1 => }/login/mainloop/?.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/admin/?.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/admin/instance_does_not_exist.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/admin/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/?.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/alarm/?.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/alarm/entry/board-hw-issue/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/alarm/entry/board-hw-issue/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/alarm/entry/board-init/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/alarm/entry/board-init/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/alarm/entry/board-instl-missing/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/alarm/entry/board-instl-missing/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/alarm/entry/board-missing/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/alarm/entry/board-missing/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/alarm/entry/plugin-dc-b/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/alarm/entry/plugin-dc-b/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/alarm/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/alarm/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/bridge/instance_does_not_exist.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/bridge/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/bridge/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/bridge/port/nt-a:xfp:1/vlan-id/vlan_identifier/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/bridge/port/port_identifier/instance_does_not_exist.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/bridge/port/port_identifier/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/ethernet/line/port_identifier/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/instance_does_not_exist.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/interface/port/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/linetest/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/linetest/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/linetest/single/ltline/session_id/lineid/port_identifier/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/linetest/single/ltline/session_id/lineid/port_identifier/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/linetest/single/ltsession/session_id/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/linetest/single/ltsession/session_id/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/linetest/single/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/linetest/single/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/qos/interface/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/qos/interface/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/qos/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/qos/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/service/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/service/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/software_mngt/oswp/2/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/system/loop_id_syntax/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/system/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/system/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/system/security/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/system/security/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/system/security/operator/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/system/security/operator/user_name/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/system/security/operator/user_name/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/system/security/profile/admin/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/system/security/profile/admin/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/system/sntp/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/system/sntp/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/system/sntp/server_table/ip_address/ip/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/id/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/id/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/id/shub/instance_does_not_exist.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/id/shub/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/id/shub/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/info_body.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/info_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/info_head.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/instance_does_not_exist.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/shub/id/EgressPort/instance_does_not_exist.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/shub/id/EgressPort/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/shub/id/EgressPort/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/shub/id/instance_does_not_exist.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/shub/id/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/shub/id/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/shub/instance_does_not_exist.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/shub/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/vlan/shub/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/xdsl/board/instance_does_not_exist.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/xdsl/board/nt/instance_does_not_exist.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/xdsl/board/nt/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/xdsl/instance_does_not_exist.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/xdsl/line/port_identifier/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure/xdsl_line_admin_up.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_bridge_port_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_bridge_port_identifier_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_bridge_port_identifier_detail_vlan.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_bridge_port_middle_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_bridge_port_middle_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_bridge_port_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_bridge_port_vlan.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_bridge_port_vlan_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_ethernet_line_identifier_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_ethernet_line_identifier_mau_identifier_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_ethernet_ont_ontportidx_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_product_line_port.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_product_line_port_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_qos_profiles_policer_middle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_qos_profiles_session_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_qos_profiles_session_middle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_qos_profiles_session_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/configure_vlan_id_vlan_id.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/environment/?.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/environment/inhibit_alarms_help.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/environment/inhibit_alarms_mode_batch_help.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/environment/inhibit_alarms_mode_batch_print_help.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/environment/inhibit_alarms_mode_batch_print_no_more_help.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/environment/inhibit_alarms_mode_help.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/environment/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/environment/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/info/configure/qos/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/info_configure_vlan_body.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/info_configure_vlan_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/info_configure_vlan_head.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/info_configure_vlan_shub_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/info_configure_vlan_shub_vlan.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/info_configure_vlan_shub_vlan_egress_port.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/info_configure_vlan_shub_vlan_end.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/instance_does_not_exist.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/on_enter.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/?.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/alarm_current_table_bot.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/alarm_current_table_mid.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/alarm_current_table_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment/transceiver-inventory/port_identifier/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_diagnostics_sfp_sfpport_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_ont_interface_ontportidx_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_ont_operational-data_ontportidx_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_ont_optics_ontportidx_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_ont_slot_detail_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_ont_slot_detail_middle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_ont_slot_detail_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_shelf_body.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_shelf_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_shelf_detail_body.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_shelf_detail_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_shelf_detail_head.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_shelf_shelfid_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_shelf_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_slot_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_slot_detail_body.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_slot_detail_head.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_slot_middle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_slot_slotid_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_slot_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_temperature_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_temperature_middle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_temperature_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_transceiver_inventory_identifier_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_transceiver_inventory_identifier_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_transceiver_inventory_identifier_mid.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/equipment_transceiver_inventory_identifier_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/ethernet_mau_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/ethernet_mau_middle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/ethernet_mau_port_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/ethernet_mau_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/ethernet_ont_operational_data_ontportidx_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/instance_does_not_exist.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/interface_port_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/interface_port_middle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/interface_port_pipe_match_match_exact_port.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/interface_port_pipe_match_match_exact_product_line_port.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/interface_port_ponport_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/interface_port_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/linetest_single_lineid_ext_rept_empty.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/linetest_single_lineid_ext_rept_filled.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/on_error.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/pon_unprovision_onu_detail_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/pon_unprovision_onu_detail_middle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/pon_unprovision_onu_detail_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/product_cpeinventory_port_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/product_help.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/product_linkuprecord_port_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/product_operational_data_help.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/product_operational_data_line_help.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/product_operational_data_line_port_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/product_operational_data_line_port_detail_help.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/shdsl_span_status_port_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/software_mngt_upload_download_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/software_mngt_version_etsi_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/transport/ether_ifmault/port_identifier/on_cycle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_mid.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/vlan_bridge_port_fdb_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/vlan_bridge_port_fdb_middle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/vlan_bridge_port_fdb_top.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/vlan_name_bottom.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/vlan_name_middle.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/vlan_name_name_detail.j2 (100%) rename templates/Alcatel/{Base/1 => }/login/mainloop/show/vlan_name_top.j2 (100%) rename templates/Alcatel/{7360/FX-4 => }/login/on_cycle.j2 (100%) rename templates/Alcatel/{7360/FX-4 => }/login/on_enter.j2 (100%) rename templates/Alcatel/{7360/FX-4 => }/login/on_exit.j2 (100%) rename templates/Alcatel/{7360/FX-4 => }/login/password.j2 (100%) rename templates/Alcatel/{7360/FX-4 => }/on_cycle.j2 (100%) rename templates/Alcatel/{7360/FX-4 => }/on_enter.j2 (100%) rename templates/Alcatel/{7360/FX-4 => }/on_exit.j2 (100%) delete mode 100644 templates/Huawei/5623/A/login/password.j2 delete mode 100644 templates/Huawei/Base/1/login/on_cycle.j2 delete mode 100644 templates/Huawei/Base/1/login/on_enter.j2 delete mode 100644 templates/Huawei/Base/1/login/password.j2 delete mode 100644 templates/Huawei/Base/1/on_cycle.j2 delete mode 100644 templates/Huawei/Base/1/on_enter.j2 delete mode 100644 templates/Huawei/Base/1/on_exit.j2 rename templates/Huawei/{Base/1 => }/login/mainloop/?.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_0_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_0_empty.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_0_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_0_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_dsl_product_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_dsl_product_bottom_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_dsl_product_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_dsl_product_middle_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_dsl_product_middle_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_dsl_product_middle_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_dsl_product_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_dsl_product_top_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_dsl_product_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_failed_link_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_failed_link_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_failed_link_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_normal_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_normal_bottom_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_normal_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_normal_header.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_normal_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_normal_top_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_normal_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_pon_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_pon_bottom_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_pon_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_pon_middle_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_pon_middle_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_pon_middle_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_pon_ont_summary.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_pon_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_pon_top_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_pon_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_special_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_special_bottom_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_special_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_special_header.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_special_middle_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_special_middle_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_special_middle_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_special_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_special_top_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_ftth_special_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_mgnt_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_mgnt_bottom_mid.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_mgnt_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_mgnt_failed_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_mgnt_failed_mid.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_mgnt_failed_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_mgnt_header.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_mgnt_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_mgnt_top_mid.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/display_board_mgnt_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/?.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/?.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/backup_configuration_tftp.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/board_type_error.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/delete_vlan_if_first.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_alarm_active_alarmtype_environment_detail.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_0_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_0_empty.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_0_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_0_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_dsl_product_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_dsl_product_bottom_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_dsl_product_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_dsl_product_middle_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_dsl_product_middle_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_dsl_product_middle_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_dsl_product_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_dsl_product_top_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_dsl_product_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_failed_link_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_failed_link_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_failed_link_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_normal_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_normal_bottom_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_normal_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_normal_header.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_normal_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_normal_top_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_normal_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_pon_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_pon_bottom_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_pon_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_pon_middle_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_pon_middle_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_pon_middle_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_pon_ont_summary.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_pon_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_pon_top_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_pon_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_special_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_special_bottom_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_special_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_special_header.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_special_middle_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_special_middle_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_special_middle_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_special_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_special_top_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_ftth_special_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_mgnt_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_mgnt_bottom_mid.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_mgnt_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_mgnt_failed_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_mgnt_failed_mid.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_mgnt_failed_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_mgnt_header.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_mgnt_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_mgnt_top_mid.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_mgnt_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_num.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_num_0.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_board_num_1.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_bot.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_bot2.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_mid.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_emu.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_emu_id.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_interface_vlanif_num.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_mac_address_all_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_mac_address_all_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_mac_address_all_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_ont_autofind_all_body.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_ont_autofind_all_failure.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_ont_autofind_all_footer.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_ont_info_summary_0_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_ont_info_summary_0_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_ont_info_summary_0_middle2.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_ont_info_summary_0_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_ont_info_summary_0_top2.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_pitp_config.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_service_port.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_service_port_all_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_service_port_all_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_service_port_all_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_terminal_user_all_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_terminal_user_all_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_terminal_user_all_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_version.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_vlan_all_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_vlan_all_mid.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/display_vlan_all_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/adsl_help.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_adsl_line-profile_num.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_inventory_cpe.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_ont_info_port_ont_header.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop1_loop2.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop1_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop2_loop3.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop2_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop3_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_ont_optical-info_num_num.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_ont_port_state_num_num_eth-port_num.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_port_ddm-info.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_port_state.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_port_state_offline.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_power_run_info.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_traffic_table_ip_index.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/display_vdsl_line-profile_num.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/gpon_help.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/on_cycle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/on_error.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/ont_added.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/ont_already_exists.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/ont_not_online.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/operation_not_supported_by_port_failure.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/port_has_been_activated.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/port_has_been_deactivated.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/vdsl_help.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/interface/vlan_help.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/on_cycle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/on_error.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/operation_not_supported_by_board.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/operation_not_supported_by_board_failure.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/operation_not_supported_by_port_failure.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/pitp_enable_pmode.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/please_wait_commit.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/port_already_in_vlan.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/port_profile_already_exists.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/port_profile_does_not_exist.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/service-port_num_vlan_vlan-id_vdsl_mode_ptm_0_card_port_multi-service_user-vlan_untagged.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/service_port_does_already_exist.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/srvprof/?.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/srvprof/on_cycle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/srvprof/on_error.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/srvprof/please_wait_commit.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/terminal_error_choice.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/terminal_level_error.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/terminal_name_short.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/terminal_profile_error.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/terminal_pw_error.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/terminal_pw_short.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/test/?.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/test/melt_test.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/test/melt_test_wait.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/test/on_cycle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/test/on_error.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/user_already_exists.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/user_already_unlocked.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/user_created.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/user_level.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/vlan_already_exists.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/vlan_bind_service-profile_vlan-id_profile-id_profile-id.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/vlan_does_not_exist.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/config/vlan_service_profile_does_not_exist.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/?.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/display_system_status_collection.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/display_system_status_collection_1.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/display_system_status_collection_10.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/display_system_status_collection_2.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/display_system_status_collection_3.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/display_system_status_collection_4.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/display_system_status_collection_5.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/display_system_status_collection_6.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/display_system_status_collection_7.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/display_system_status_collection_8.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/display_system_status_collection_9.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/on_cycle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/on_error.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/saving_complete.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/saving_progress.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/switch_dsl_mode_failure.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/switch_dsl_mode_temp_1.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/diagnose/switch_dsl_mode_temp_2.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_adsl_line_operation_port_num_card_port.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_0_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_0_empty.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_0_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_0_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_dsl_product_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_dsl_product_bottom_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_dsl_product_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_dsl_product_middle_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_dsl_product_middle_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_dsl_product_middle_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_dsl_product_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_dsl_product_top_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_dsl_product_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_failed_link_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_failed_link_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_failed_link_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_normal_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_normal_bottom_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_normal_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_normal_header.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_normal_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_normal_top_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_normal_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_pon_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_pon_bottom_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_pon_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_pon_middle_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_pon_middle_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_pon_middle_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_pon_ont_summary.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_pon_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_pon_top_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_pon_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_special_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_special_bottom_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_special_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_special_header.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_special_middle_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_special_middle_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_special_middle_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_special_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_special_top_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_ftth_special_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_mgnt_bottom_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_mgnt_bottom_mid.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_mgnt_bottom_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_mgnt_failed_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_mgnt_failed_mid.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_mgnt_failed_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_mgnt_header.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_mgnt_top_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_mgnt_top_mid.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_board_mgnt_top_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_interface_product_port.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_product_port_state_num_card_port_activated.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_product_port_state_num_card_port_deactivated.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_service_port.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_service_port_all_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_service_port_all_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_service_port_all_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_temperature.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_terminal_user_all_bottom.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_terminal_user_all_middle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_terminal_user_all_top.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_vdsl_line-profile_num.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/display_vdsl_line_operation_port_num_card_port.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/on_cycle.j2 (100%) rename templates/{Alcatel/Base/1/login/on_cycle.j2 => Huawei/login/mainloop/enable/on_enable_quit.j2} (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/enable/on_error.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/help.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/on_cycle.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/on_enter.j2 (100%) rename templates/Huawei/{Base/1 => }/login/mainloop/on_error.j2 (100%) rename templates/Huawei/{5623/A => }/login/on_cycle.j2 (100%) rename templates/Huawei/{5623/A => }/login/on_enter.j2 (100%) rename templates/{Alcatel/Base/1 => Huawei}/login/password.j2 (100%) rename templates/Huawei/{5623/A => }/login/user_locked.j2 (100%) rename templates/Huawei/{5623/A => }/on_cycle.j2 (100%) rename templates/Huawei/{5623/A => }/on_enter.j2 (100%) rename templates/Huawei/{5623/A => }/on_exit.j2 (100%) delete mode 100644 vendors/Alcatel/7360/Alcatel_7360/__init__.py delete mode 100644 vendors/Alcatel/7360/__init__.py delete mode 100644 vendors/Alcatel/Base/Alcatel_Base/__init__.py delete mode 100644 vendors/Alcatel/Base/__init__.py rename vendors/Alcatel/{Base/Alcatel_Base => }/adminCommandProcessor.py (100%) rename vendors/Alcatel/{Base/Alcatel_Base => }/baseCommandProcessor.py (98%) rename vendors/Alcatel/{Base/Alcatel_Base => }/baseMixIn.py (100%) rename vendors/Alcatel/{Base/Alcatel_Base => }/configureCommandProcessor.py (100%) rename vendors/Alcatel/{Base/Alcatel_Base => }/environmentCommandProcessor.py (100%) rename vendors/Alcatel/{7360/Alcatel_7360 => }/main.py (82%) rename vendors/Alcatel/{Base/Alcatel_Base => }/showCommandProcessor.py (100%) rename vendors/Alcatel/{Base/Alcatel_Base => }/userViewCommandProcessor.py (100%) delete mode 100644 vendors/Huawei/5623/Huawei_5623/__init__.py delete mode 100644 vendors/Huawei/5623/__init__.py delete mode 100644 vendors/Huawei/Base/Huawei_Base/__init__.py delete mode 100644 vendors/Huawei/Base/__init__.py rename vendors/Huawei/{Base/Huawei_Base => }/baseCommandProcessor.py (98%) rename vendors/Huawei/{Base/Huawei_Base => }/baseMixIn.py (100%) rename vendors/Huawei/{Base/Huawei_Base => }/configCommandProcessor.py (100%) rename vendors/Huawei/{Base/Huawei_Base => }/diagnoseCommandProcessor.py (100%) rename vendors/Huawei/{Base/Huawei_Base => }/enableCommandProcessor.py (100%) rename vendors/Huawei/{Base/Huawei_Base => }/huaweiBaseCommandProcessor.py (99%) rename vendors/Huawei/{Base/Huawei_Base => }/interfaceCommandProcessor.py (100%) rename vendors/Huawei/{5623/Huawei_5623 => }/main.py (90%) rename vendors/Huawei/{Base/Huawei_Base => }/testCommandProcessor.py (100%) rename vendors/Huawei/{Base/Huawei_Base => }/userViewCommandProcessor.py (100%) rename vendors/Huawei/{Base/Huawei_Base => }/vlanSrvprofCommandProcessor.py (100%) diff --git a/bootup/box.sh b/bootup/box.sh index 4f20ef9..8115cbc 100755 --- a/bootup/box.sh +++ b/bootup/box.sh @@ -60,7 +60,7 @@ do done if $list_boxen; then - python3 ./cli.py --service-root http://127.0.0.1:5000/nesi/v1 --template-root templates/ --list-boxen + python3 ./cli.py --service-root http://127.0.0.1:5000/nesi/v1 --list-boxen elif [ "$uuid" != "" ]; then args='' @@ -75,6 +75,6 @@ elif [ "$uuid" != "" ]; then if $standalone; then args="${args} --standalone" fi - python3 ./cli.py --service-root http://127.0.0.1:5000/nesi/v1 --template-root templates/ --box-uuid $uuid $args + python3 ./cli.py --service-root http://127.0.0.1:5000/nesi/v1 --box-uuid $uuid $args fi diff --git a/cli.py b/cli.py index 0a8926d..a64a13a 100644 --- a/cli.py +++ b/cli.py @@ -20,15 +20,12 @@ from nesi import __version__ from nesi import exceptions -from nesi.softbox import rest_client -from nesi.softbox import root, base +from nesi.softbox.cli import rest_client +from nesi.softbox.base_resources import root, base from bootup.sockets.telnet import TelnetSocket -import pydevd_pycharm import pytest import subprocess -from nesi.softbox.api import app -from nesi.softbox.api import db from nesi.softbox.api.views import * # noqa import pydevd_pycharm import time @@ -54,10 +51,6 @@ def main(): '--insecure', action='store_true', help='Disable TLS X.509 validation.') - parser.add_argument( - '--template-root', metavar='', type=str, - help='Top directory of CLI command loop Jinja2 templates') - parser.add_argument( '--list-boxen', action='store_true', help='Discover and print out existing box models') @@ -164,8 +157,9 @@ def main(): try: model = root_resource.get_box(base.get_member_identity(model.json), model.vendor) - main = importlib.import_module('vendors.' + model.vendor + '.' + model.model + '.' + model.vendor + '_' + model.model + '.main') + main = importlib.import_module('vendors.' + model.vendor + '.main') cli = main.PreLoginCommandProcessor + template_root = 'templates/' + str(model.vendor) except exceptions.ExtensionNotFoundError as exc: parser.error(exc) @@ -187,7 +181,7 @@ def main(): return if model.network_protocol == 'telnet': - telnet = TelnetSocket(cli, model, args.template_root, ip_address, int(port)) + telnet = TelnetSocket(cli, model, template_root, ip_address, int(port)) telnet.start() elif model.network_protocol == 'ssh': ssh = None @@ -199,7 +193,7 @@ def main(): while True: command_processor = cli( - model, stdin, stdout, (), template_root=args.template_root, daemon=False) + model, stdin, stdout, (), template_root=template_root, daemon=False) try: context = dict() diff --git a/nesi/alcatel/alcatel_resources/alcatel_box.py b/nesi/alcatel/alcatel_resources/alcatel_box.py index c52d769..e80aff2 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_box.py +++ b/nesi/alcatel/alcatel_resources/alcatel_box.py @@ -13,10 +13,10 @@ from nesi.alcatel.alcatel_resources import * import logging -from nesi.softbox.base_resources import credentials +from nesi.softbox.base_resources import credentials, base from nesi.softbox.base_resources import user from nesi.softbox.base_resources import route -from nesi.softbox.base_resources.box import Box, BoxCollection, base, os +from nesi.softbox.base_resources.box import Box, BoxCollection, os LOG = logging.getLogger(__name__) diff --git a/nesi/alcatel/alcatel_resources/alcatel_card.py b/nesi/alcatel/alcatel_resources/alcatel_card.py index 552db1f..37354c5 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_card.py +++ b/nesi/alcatel/alcatel_resources/alcatel_card.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.card import CardCollection, Card, logging, base +from nesi.softbox.base_resources.card import CardCollection, Card, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/alcatel/alcatel_resources/alcatel_ont.py b/nesi/alcatel/alcatel_resources/alcatel_ont.py index 00c2847..bd6dc5e 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_ont.py +++ b/nesi/alcatel/alcatel_resources/alcatel_ont.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.ont import OntCollection, Ont, base +from nesi.softbox.base_resources.ont import OntCollection, Ont +from nesi.softbox.base_resources import base class AlcatelOnt(Ont): diff --git a/nesi/alcatel/alcatel_resources/alcatel_ont_port.py b/nesi/alcatel/alcatel_resources/alcatel_ont_port.py index 061f765..1365158 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_ont_port.py +++ b/nesi/alcatel/alcatel_resources/alcatel_ont_port.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.ont_port import OntPortCollection, OntPort, base, logging +from nesi.softbox.base_resources.ont_port import OntPortCollection, OntPort, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/alcatel/alcatel_resources/alcatel_port.py b/nesi/alcatel/alcatel_resources/alcatel_port.py index 48f52d1..8864d12 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_port.py +++ b/nesi/alcatel/alcatel_resources/alcatel_port.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.port import PortCollection, Port, logging, base +from nesi.softbox.base_resources.port import PortCollection, Port, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/alcatel/alcatel_resources/alcatel_port_profile.py b/nesi/alcatel/alcatel_resources/alcatel_port_profile.py index e1dceea..55d9e7b 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_port_profile.py +++ b/nesi/alcatel/alcatel_resources/alcatel_port_profile.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.port_profile import PortProfile, PortProfileCollection, logging, base +from nesi.softbox.base_resources.port_profile import PortProfile, PortProfileCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/alcatel/alcatel_resources/alcatel_qos_interface.py b/nesi/alcatel/alcatel_resources/alcatel_qos_interface.py index 828425c..66926bd 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_qos_interface.py +++ b/nesi/alcatel/alcatel_resources/alcatel_qos_interface.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.qos_interface import QosInterface, QosInterfaceCollection, logging, base +from nesi.softbox.base_resources.qos_interface import QosInterface, QosInterfaceCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/alcatel/alcatel_resources/alcatel_service_port.py b/nesi/alcatel/alcatel_resources/alcatel_service_port.py index 0a207a6..78b63da 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_service_port.py +++ b/nesi/alcatel/alcatel_resources/alcatel_service_port.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.service_port import ServicePort, ServicePortCollection, base, logging +from nesi.softbox.base_resources.service_port import ServicePort, ServicePortCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/alcatel/alcatel_resources/alcatel_service_vlan.py b/nesi/alcatel/alcatel_resources/alcatel_service_vlan.py index 4d7cbc6..94063e0 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_service_vlan.py +++ b/nesi/alcatel/alcatel_resources/alcatel_service_vlan.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.service_vlan import ServiceVlan, ServiceVlanCollection, logging, base +from nesi.softbox.base_resources.service_vlan import ServiceVlan, ServiceVlanCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/alcatel/alcatel_resources/alcatel_subrack.py b/nesi/alcatel/alcatel_resources/alcatel_subrack.py index e13254c..da7f561 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_subrack.py +++ b/nesi/alcatel/alcatel_resources/alcatel_subrack.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.subrack import Subrack, SubrackCollection, logging, base +from nesi.softbox.base_resources.subrack import Subrack, SubrackCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/alcatel/alcatel_resources/alcatel_vlan.py b/nesi/alcatel/alcatel_resources/alcatel_vlan.py index 78f029d..aad7a6b 100644 --- a/nesi/alcatel/alcatel_resources/alcatel_vlan.py +++ b/nesi/alcatel/alcatel_resources/alcatel_vlan.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.vlan import VlanCollection, Vlan, logging, base +from nesi.softbox.base_resources.vlan import VlanCollection, Vlan, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/huawei/huawei_resources/huawei_box.py b/nesi/huawei/huawei_resources/huawei_box.py index 9a3116d..a170fc8 100644 --- a/nesi/huawei/huawei_resources/huawei_box.py +++ b/nesi/huawei/huawei_resources/huawei_box.py @@ -12,9 +12,9 @@ from nesi.huawei.huawei_resources import * -from nesi.softbox.base_resources import credentials +from nesi.softbox.base_resources import credentials, base from nesi.softbox.base_resources import route -from nesi.softbox.base_resources.box import BoxCollection, Box, logging, base, os +from nesi.softbox.base_resources.box import BoxCollection, Box, logging, os LOG = logging.getLogger(__name__) diff --git a/nesi/huawei/huawei_resources/huawei_card.py b/nesi/huawei/huawei_resources/huawei_card.py index 55998ef..30c1ffa 100644 --- a/nesi/huawei/huawei_resources/huawei_card.py +++ b/nesi/huawei/huawei_resources/huawei_card.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.card import Card, CardCollection, logging, base +from nesi.softbox.base_resources.card import Card, CardCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/huawei/huawei_resources/huawei_cpe.py b/nesi/huawei/huawei_resources/huawei_cpe.py index 70b24b2..913b4b6 100644 --- a/nesi/huawei/huawei_resources/huawei_cpe.py +++ b/nesi/huawei/huawei_resources/huawei_cpe.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.cpe import CpeCollection, Cpe, logging, base +from nesi.softbox.base_resources.cpe import CpeCollection, Cpe, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/huawei/huawei_resources/huawei_emu.py b/nesi/huawei/huawei_resources/huawei_emu.py index 8351d62..8ce3416 100644 --- a/nesi/huawei/huawei_resources/huawei_emu.py +++ b/nesi/huawei/huawei_resources/huawei_emu.py @@ -1,4 +1,5 @@ -from nesi.softbox.base_resources.service_port import base, logging +from nesi.softbox.base_resources.service_port import logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/huawei/huawei_resources/huawei_ont.py b/nesi/huawei/huawei_resources/huawei_ont.py index 880dba2..615581e 100644 --- a/nesi/huawei/huawei_resources/huawei_ont.py +++ b/nesi/huawei/huawei_resources/huawei_ont.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.ont import Ont, OntCollection, base +from nesi.softbox.base_resources.ont import Ont, OntCollection +from nesi.softbox.base_resources import base class HuaweiOnt(Ont): diff --git a/nesi/huawei/huawei_resources/huawei_ont_port.py b/nesi/huawei/huawei_resources/huawei_ont_port.py index 0c362d7..fd3e11d 100644 --- a/nesi/huawei/huawei_resources/huawei_ont_port.py +++ b/nesi/huawei/huawei_resources/huawei_ont_port.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.ont_port import OntPort, OntPortCollection, logging, base +from nesi.softbox.base_resources.ont_port import OntPort, OntPortCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/huawei/huawei_resources/huawei_port.py b/nesi/huawei/huawei_resources/huawei_port.py index 5cc3db1..8f0400d 100644 --- a/nesi/huawei/huawei_resources/huawei_port.py +++ b/nesi/huawei/huawei_resources/huawei_port.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.port import Port, PortCollection, logging, base +from nesi.softbox.base_resources.port import Port, PortCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/huawei/huawei_resources/huawei_port_profile.py b/nesi/huawei/huawei_resources/huawei_port_profile.py index c3c0859..7b56a41 100644 --- a/nesi/huawei/huawei_resources/huawei_port_profile.py +++ b/nesi/huawei/huawei_resources/huawei_port_profile.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.port_profile import PortProfile, PortProfileCollection, base, logging +from nesi.softbox.base_resources.port_profile import PortProfile, PortProfileCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/huawei/huawei_resources/huawei_route.py b/nesi/huawei/huawei_resources/huawei_route.py index 51b9439..3953bec 100644 --- a/nesi/huawei/huawei_resources/huawei_route.py +++ b/nesi/huawei/huawei_resources/huawei_route.py @@ -1,4 +1,5 @@ -from nesi.softbox.base_resources.route import Route, RouteCollection, base, logging +from nesi.softbox.base_resources.route import Route, RouteCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/huawei/huawei_resources/huawei_service_port.py b/nesi/huawei/huawei_resources/huawei_service_port.py index fdc8792..ad1ce3a 100644 --- a/nesi/huawei/huawei_resources/huawei_service_port.py +++ b/nesi/huawei/huawei_resources/huawei_service_port.py @@ -1,4 +1,5 @@ -from nesi.softbox.base_resources.service_port import ServicePort, ServicePortCollection, base, logging +from nesi.softbox.base_resources.service_port import ServicePort, ServicePortCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/huawei/huawei_resources/huawei_service_vlan.py b/nesi/huawei/huawei_resources/huawei_service_vlan.py index cbe2602..6ef4be6 100644 --- a/nesi/huawei/huawei_resources/huawei_service_vlan.py +++ b/nesi/huawei/huawei_resources/huawei_service_vlan.py @@ -1,4 +1,5 @@ -from nesi.softbox.base_resources.service_vlan import ServiceVlan, ServiceVlanCollection, logging, base +from nesi.softbox.base_resources.service_vlan import ServiceVlan, ServiceVlanCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/huawei/huawei_resources/huawei_subrack.py b/nesi/huawei/huawei_resources/huawei_subrack.py index 65845e0..e5fd1b1 100644 --- a/nesi/huawei/huawei_resources/huawei_subrack.py +++ b/nesi/huawei/huawei_resources/huawei_subrack.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.subrack import SubrackCollection, Subrack, logging, base +from nesi.softbox.base_resources.subrack import SubrackCollection, Subrack, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/huawei/huawei_resources/huawei_user.py b/nesi/huawei/huawei_resources/huawei_user.py index e0af311..090f2cf 100644 --- a/nesi/huawei/huawei_resources/huawei_user.py +++ b/nesi/huawei/huawei_resources/huawei_user.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.user import User, UserCollection, base, logging +from nesi.softbox.base_resources.user import User, UserCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/huawei/huawei_resources/huawei_vlan.py b/nesi/huawei/huawei_resources/huawei_vlan.py index 12210a6..6a4e97e 100644 --- a/nesi/huawei/huawei_resources/huawei_vlan.py +++ b/nesi/huawei/huawei_resources/huawei_vlan.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.vlan import Vlan, VlanCollection, base, logging +from nesi.softbox.base_resources.vlan import Vlan, VlanCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/huawei/huawei_resources/huawei_vlan_interface.py b/nesi/huawei/huawei_resources/huawei_vlan_interface.py index 0a2617e..45aad84 100644 --- a/nesi/huawei/huawei_resources/huawei_vlan_interface.py +++ b/nesi/huawei/huawei_resources/huawei_vlan_interface.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.vlan_interface import VlanInterface, VlanInterfaceCollection, logging, base +from nesi.softbox.base_resources.vlan_interface import VlanInterface, VlanInterfaceCollection, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/base.py b/nesi/softbox/base_resources/base.py similarity index 100% rename from nesi/softbox/base.py rename to nesi/softbox/base_resources/base.py diff --git a/nesi/softbox/base_resources/box.py b/nesi/softbox/base_resources/box.py index 88fbafa..df93d87 100644 --- a/nesi/softbox/base_resources/box.py +++ b/nesi/softbox/base_resources/box.py @@ -12,7 +12,7 @@ import logging import os -from nesi.softbox import base +from nesi.softbox.base_resources import base from nesi.exceptions import PropertyNotFoundError from nesi.exceptions import FunctionNotFoundError diff --git a/nesi/softbox/base_resources/card.py b/nesi/softbox/base_resources/card.py index 1e52cde..2de330b 100644 --- a/nesi/softbox/base_resources/card.py +++ b/nesi/softbox/base_resources/card.py @@ -12,7 +12,7 @@ import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/base_resources/cpe.py b/nesi/softbox/base_resources/cpe.py index 513a9f1..5fbe1c7 100644 --- a/nesi/softbox/base_resources/cpe.py +++ b/nesi/softbox/base_resources/cpe.py @@ -12,7 +12,7 @@ import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/base_resources/cpe_port.py b/nesi/softbox/base_resources/cpe_port.py index c87a6e5..867a434 100644 --- a/nesi/softbox/base_resources/cpe_port.py +++ b/nesi/softbox/base_resources/cpe_port.py @@ -12,7 +12,7 @@ import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/base_resources/credentials.py b/nesi/softbox/base_resources/credentials.py index a441972..dc48bd6 100644 --- a/nesi/softbox/base_resources/credentials.py +++ b/nesi/softbox/base_resources/credentials.py @@ -12,7 +12,7 @@ import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/base_resources/ont.py b/nesi/softbox/base_resources/ont.py index 5ea1f7e..d248d2f 100644 --- a/nesi/softbox/base_resources/ont.py +++ b/nesi/softbox/base_resources/ont.py @@ -10,7 +10,7 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox import base +from nesi.softbox.base_resources import base class Ont(base.Resource): diff --git a/nesi/softbox/base_resources/ont_port.py b/nesi/softbox/base_resources/ont_port.py index 14cc2d6..654ed5c 100644 --- a/nesi/softbox/base_resources/ont_port.py +++ b/nesi/softbox/base_resources/ont_port.py @@ -12,7 +12,7 @@ import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/base_resources/port.py b/nesi/softbox/base_resources/port.py index 74adc98..5b51433 100644 --- a/nesi/softbox/base_resources/port.py +++ b/nesi/softbox/base_resources/port.py @@ -12,7 +12,7 @@ import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/base_resources/port_profile.py b/nesi/softbox/base_resources/port_profile.py index b70bf69..2eb6c6f 100644 --- a/nesi/softbox/base_resources/port_profile.py +++ b/nesi/softbox/base_resources/port_profile.py @@ -12,7 +12,7 @@ import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/base_resources/qos_interface.py b/nesi/softbox/base_resources/qos_interface.py index bf24ef5..35b1e1d 100644 --- a/nesi/softbox/base_resources/qos_interface.py +++ b/nesi/softbox/base_resources/qos_interface.py @@ -12,7 +12,7 @@ import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/root.py b/nesi/softbox/base_resources/root.py similarity index 99% rename from nesi/softbox/root.py rename to nesi/softbox/base_resources/root.py index dbfc052..0cd970a 100644 --- a/nesi/softbox/root.py +++ b/nesi/softbox/base_resources/root.py @@ -10,8 +10,6 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -import logging - from nesi.alcatel.alcatel_resources.alcatel_box import * from nesi.huawei.huawei_resources.huawei_box import * from nesi.edgecore.edgecore_resources.edgecore_box import * diff --git a/nesi/softbox/base_resources/route.py b/nesi/softbox/base_resources/route.py index 8297dfa..0235e18 100644 --- a/nesi/softbox/base_resources/route.py +++ b/nesi/softbox/base_resources/route.py @@ -12,7 +12,7 @@ import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/base_resources/service_port.py b/nesi/softbox/base_resources/service_port.py index 132bf73..4de34d2 100644 --- a/nesi/softbox/base_resources/service_port.py +++ b/nesi/softbox/base_resources/service_port.py @@ -12,7 +12,7 @@ import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/base_resources/service_vlan.py b/nesi/softbox/base_resources/service_vlan.py index 7a53bdb..106971e 100644 --- a/nesi/softbox/base_resources/service_vlan.py +++ b/nesi/softbox/base_resources/service_vlan.py @@ -12,7 +12,7 @@ import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/base_resources/subrack.py b/nesi/softbox/base_resources/subrack.py index 548f1a0..184127c 100644 --- a/nesi/softbox/base_resources/subrack.py +++ b/nesi/softbox/base_resources/subrack.py @@ -12,7 +12,7 @@ import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/base_resources/user.py b/nesi/softbox/base_resources/user.py index 2272dc0..a82a0eb 100644 --- a/nesi/softbox/base_resources/user.py +++ b/nesi/softbox/base_resources/user.py @@ -11,7 +11,7 @@ # License: https://github.com/inexio/NESi/LICENSE.rst import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/base_resources/vlan.py b/nesi/softbox/base_resources/vlan.py index 0dea9f4..8b75ea7 100644 --- a/nesi/softbox/base_resources/vlan.py +++ b/nesi/softbox/base_resources/vlan.py @@ -11,7 +11,7 @@ # License: https://github.com/inexio/NESi/LICENSE.rst import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/base_resources/vlan_interface.py b/nesi/softbox/base_resources/vlan_interface.py index 0b2ba7d..d9be7d8 100644 --- a/nesi/softbox/base_resources/vlan_interface.py +++ b/nesi/softbox/base_resources/vlan_interface.py @@ -12,7 +12,7 @@ import logging -from nesi.softbox import base +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 6cd8c52..c69e2d6 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -44,11 +44,6 @@ class CommandProcessor: followed by the name of this command processor """ - # Identify backend models to load and use - VENDOR = '?' - MODEL = '?' - VERSION = '?' - def __init__(self, model, input_stream, output_stream, history, template_root=None, scopes=(), daemon=False): self._model = model @@ -57,8 +52,7 @@ def __init__(self, model, input_stream, output_stream, history, self._scopes = scopes self._template_root = template_root self._template_dir = os.path.join( - template_root, self.VENDOR, self.MODEL, self.VERSION, - *scopes) + template_root, *scopes) self._jenv = jinja2.Environment( loader=(jinja2.FileSystemLoader(self._template_dir) @@ -229,9 +223,7 @@ def _render(self, template, *scopes, context=None, ignore_errors=False): try: if scopes: - template_dir = os.path.join( - self._template_root, self.VENDOR, self.MODEL, self.VERSION, - *scopes) + template_dir = os.path.join(self._template_root, *scopes) tmp_jenv = jinja2.Environment( loader=(jinja2.FileSystemLoader(template_dir) if self._template_root else None), diff --git a/nesi/softbox/rest_client.py b/nesi/softbox/cli/rest_client.py similarity index 100% rename from nesi/softbox/rest_client.py rename to nesi/softbox/cli/rest_client.py diff --git a/templates/Alcatel/Base/1/login/on_enter.j2 b/templates/Alcatel/Base/1/login/on_enter.j2 deleted file mode 100644 index 0e34cce..0000000 --- a/templates/Alcatel/Base/1/login/on_enter.j2 +++ /dev/null @@ -1 +0,0 @@ -password: diff --git a/templates/Alcatel/Base/1/login/on_exit.j2 b/templates/Alcatel/Base/1/login/on_exit.j2 deleted file mode 100644 index d249009..0000000 --- a/templates/Alcatel/Base/1/login/on_exit.j2 +++ /dev/null @@ -1,3 +0,0 @@ -{{ context.welcome_banner }} -last login : {{ context.timestamp }} - diff --git a/templates/Alcatel/Base/1/on_cycle.j2 b/templates/Alcatel/Base/1/on_cycle.j2 deleted file mode 100644 index e3cb851..0000000 --- a/templates/Alcatel/Base/1/on_cycle.j2 +++ /dev/null @@ -1 +0,0 @@ -login: diff --git a/templates/Alcatel/Base/1/on_enter.j2 b/templates/Alcatel/Base/1/on_enter.j2 deleted file mode 100644 index 3e3ae4a..0000000 --- a/templates/Alcatel/Base/1/on_enter.j2 +++ /dev/null @@ -1,4 +0,0 @@ - -{{ context.login_banner | safe }} - - diff --git a/templates/Alcatel/Base/1/on_exit.j2 b/templates/Alcatel/Base/1/on_exit.j2 deleted file mode 100644 index e69de29..0000000 diff --git a/templates/Alcatel/Base/1/login/mainloop/?.j2 b/templates/Alcatel/login/mainloop/?.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/?.j2 rename to templates/Alcatel/login/mainloop/?.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/admin/?.j2 b/templates/Alcatel/login/mainloop/admin/?.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/admin/?.j2 rename to templates/Alcatel/login/mainloop/admin/?.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/admin/instance_does_not_exist.j2 b/templates/Alcatel/login/mainloop/admin/instance_does_not_exist.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/admin/instance_does_not_exist.j2 rename to templates/Alcatel/login/mainloop/admin/instance_does_not_exist.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/admin/on_cycle.j2 b/templates/Alcatel/login/mainloop/admin/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/admin/on_cycle.j2 rename to templates/Alcatel/login/mainloop/admin/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/?.j2 b/templates/Alcatel/login/mainloop/configure/?.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/?.j2 rename to templates/Alcatel/login/mainloop/configure/?.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/alarm/?.j2 b/templates/Alcatel/login/mainloop/configure/alarm/?.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/alarm/?.j2 rename to templates/Alcatel/login/mainloop/configure/alarm/?.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-hw-issue/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/alarm/entry/board-hw-issue/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-hw-issue/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/alarm/entry/board-hw-issue/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-hw-issue/on_error.j2 b/templates/Alcatel/login/mainloop/configure/alarm/entry/board-hw-issue/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-hw-issue/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/alarm/entry/board-hw-issue/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-init/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/alarm/entry/board-init/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-init/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/alarm/entry/board-init/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-init/on_error.j2 b/templates/Alcatel/login/mainloop/configure/alarm/entry/board-init/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-init/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/alarm/entry/board-init/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-instl-missing/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/alarm/entry/board-instl-missing/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-instl-missing/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/alarm/entry/board-instl-missing/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-instl-missing/on_error.j2 b/templates/Alcatel/login/mainloop/configure/alarm/entry/board-instl-missing/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-instl-missing/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/alarm/entry/board-instl-missing/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-missing/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/alarm/entry/board-missing/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-missing/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/alarm/entry/board-missing/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-missing/on_error.j2 b/templates/Alcatel/login/mainloop/configure/alarm/entry/board-missing/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/board-missing/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/alarm/entry/board-missing/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/plugin-dc-b/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/alarm/entry/plugin-dc-b/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/plugin-dc-b/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/alarm/entry/plugin-dc-b/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/plugin-dc-b/on_error.j2 b/templates/Alcatel/login/mainloop/configure/alarm/entry/plugin-dc-b/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/alarm/entry/plugin-dc-b/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/alarm/entry/plugin-dc-b/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/alarm/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/alarm/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/alarm/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/alarm/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/alarm/on_error.j2 b/templates/Alcatel/login/mainloop/configure/alarm/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/alarm/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/alarm/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/bridge/instance_does_not_exist.j2 b/templates/Alcatel/login/mainloop/configure/bridge/instance_does_not_exist.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/bridge/instance_does_not_exist.j2 rename to templates/Alcatel/login/mainloop/configure/bridge/instance_does_not_exist.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/bridge/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/bridge/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/bridge/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/bridge/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/bridge/on_error.j2 b/templates/Alcatel/login/mainloop/configure/bridge/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/bridge/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/bridge/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/bridge/port/nt-a:xfp:1/vlan-id/vlan_identifier/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/bridge/port/nt-a:xfp:1/vlan-id/vlan_identifier/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/bridge/port/nt-a:xfp:1/vlan-id/vlan_identifier/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/bridge/port/nt-a:xfp:1/vlan-id/vlan_identifier/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/bridge/port/port_identifier/instance_does_not_exist.j2 b/templates/Alcatel/login/mainloop/configure/bridge/port/port_identifier/instance_does_not_exist.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/bridge/port/port_identifier/instance_does_not_exist.j2 rename to templates/Alcatel/login/mainloop/configure/bridge/port/port_identifier/instance_does_not_exist.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/bridge/port/port_identifier/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/bridge/port/port_identifier/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/bridge/port/port_identifier/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/bridge/port/port_identifier/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/ethernet/line/port_identifier/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/ethernet/line/port_identifier/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/ethernet/line/port_identifier/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/ethernet/line/port_identifier/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/instance_does_not_exist.j2 b/templates/Alcatel/login/mainloop/configure/instance_does_not_exist.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/instance_does_not_exist.j2 rename to templates/Alcatel/login/mainloop/configure/instance_does_not_exist.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/interface/port/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/interface/port/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/interface/port/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/interface/port/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/linetest/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/linetest/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/linetest/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/linetest/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/linetest/on_error.j2 b/templates/Alcatel/login/mainloop/configure/linetest/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/linetest/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/linetest/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/linetest/single/ltline/session_id/lineid/port_identifier/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/linetest/single/ltline/session_id/lineid/port_identifier/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/linetest/single/ltline/session_id/lineid/port_identifier/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/linetest/single/ltline/session_id/lineid/port_identifier/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/linetest/single/ltline/session_id/lineid/port_identifier/on_error.j2 b/templates/Alcatel/login/mainloop/configure/linetest/single/ltline/session_id/lineid/port_identifier/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/linetest/single/ltline/session_id/lineid/port_identifier/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/linetest/single/ltline/session_id/lineid/port_identifier/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/linetest/single/ltsession/session_id/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/linetest/single/ltsession/session_id/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/linetest/single/ltsession/session_id/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/linetest/single/ltsession/session_id/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/linetest/single/ltsession/session_id/on_error.j2 b/templates/Alcatel/login/mainloop/configure/linetest/single/ltsession/session_id/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/linetest/single/ltsession/session_id/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/linetest/single/ltsession/session_id/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/linetest/single/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/linetest/single/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/linetest/single/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/linetest/single/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/linetest/single/on_error.j2 b/templates/Alcatel/login/mainloop/configure/linetest/single/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/linetest/single/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/linetest/single/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/on_error.j2 b/templates/Alcatel/login/mainloop/configure/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/qos/interface/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/qos/interface/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/qos/interface/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/qos/interface/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/qos/interface/on_error.j2 b/templates/Alcatel/login/mainloop/configure/qos/interface/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/qos/interface/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/qos/interface/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/qos/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/qos/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/qos/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/qos/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/qos/on_error.j2 b/templates/Alcatel/login/mainloop/configure/qos/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/qos/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/qos/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/service/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/service/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/service/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/service/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/service/on_error.j2 b/templates/Alcatel/login/mainloop/configure/service/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/service/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/service/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/software_mngt/oswp/2/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/software_mngt/oswp/2/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/software_mngt/oswp/2/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/software_mngt/oswp/2/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/system/loop_id_syntax/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/system/loop_id_syntax/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/system/loop_id_syntax/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/system/loop_id_syntax/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/system/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/system/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/system/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/system/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/system/on_error.j2 b/templates/Alcatel/login/mainloop/configure/system/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/system/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/system/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/system/security/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/system/security/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/system/security/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/system/security/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/system/security/on_error.j2 b/templates/Alcatel/login/mainloop/configure/system/security/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/system/security/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/system/security/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/system/security/operator/on_error.j2 b/templates/Alcatel/login/mainloop/configure/system/security/operator/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/system/security/operator/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/system/security/operator/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/system/security/operator/user_name/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/system/security/operator/user_name/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/system/security/operator/user_name/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/system/security/operator/user_name/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/system/security/operator/user_name/on_error.j2 b/templates/Alcatel/login/mainloop/configure/system/security/operator/user_name/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/system/security/operator/user_name/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/system/security/operator/user_name/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/system/security/profile/admin/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/system/security/profile/admin/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/system/security/profile/admin/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/system/security/profile/admin/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/system/security/profile/admin/on_error.j2 b/templates/Alcatel/login/mainloop/configure/system/security/profile/admin/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/system/security/profile/admin/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/system/security/profile/admin/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/system/sntp/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/system/sntp/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/system/sntp/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/system/sntp/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/system/sntp/on_error.j2 b/templates/Alcatel/login/mainloop/configure/system/sntp/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/system/sntp/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/system/sntp/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/system/sntp/server_table/ip_address/ip/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/system/sntp/server_table/ip_address/ip/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/system/sntp/server_table/ip_address/ip/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/system/sntp/server_table/ip_address/ip/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/id/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/vlan/id/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/id/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/id/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/id/on_error.j2 b/templates/Alcatel/login/mainloop/configure/vlan/id/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/id/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/id/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/id/shub/instance_does_not_exist.j2 b/templates/Alcatel/login/mainloop/configure/vlan/id/shub/instance_does_not_exist.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/id/shub/instance_does_not_exist.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/id/shub/instance_does_not_exist.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/id/shub/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/vlan/id/shub/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/id/shub/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/id/shub/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/id/shub/on_error.j2 b/templates/Alcatel/login/mainloop/configure/vlan/id/shub/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/id/shub/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/id/shub/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/info_body.j2 b/templates/Alcatel/login/mainloop/configure/vlan/info_body.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/info_body.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/info_body.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/info_bottom.j2 b/templates/Alcatel/login/mainloop/configure/vlan/info_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/info_bottom.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/info_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/info_head.j2 b/templates/Alcatel/login/mainloop/configure/vlan/info_head.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/info_head.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/info_head.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/instance_does_not_exist.j2 b/templates/Alcatel/login/mainloop/configure/vlan/instance_does_not_exist.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/instance_does_not_exist.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/instance_does_not_exist.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/vlan/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/on_error.j2 b/templates/Alcatel/login/mainloop/configure/vlan/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/id/EgressPort/instance_does_not_exist.j2 b/templates/Alcatel/login/mainloop/configure/vlan/shub/id/EgressPort/instance_does_not_exist.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/id/EgressPort/instance_does_not_exist.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/shub/id/EgressPort/instance_does_not_exist.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/id/EgressPort/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/vlan/shub/id/EgressPort/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/id/EgressPort/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/shub/id/EgressPort/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/id/EgressPort/on_error.j2 b/templates/Alcatel/login/mainloop/configure/vlan/shub/id/EgressPort/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/id/EgressPort/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/shub/id/EgressPort/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/id/instance_does_not_exist.j2 b/templates/Alcatel/login/mainloop/configure/vlan/shub/id/instance_does_not_exist.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/id/instance_does_not_exist.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/shub/id/instance_does_not_exist.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/id/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/vlan/shub/id/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/id/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/shub/id/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/id/on_error.j2 b/templates/Alcatel/login/mainloop/configure/vlan/shub/id/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/id/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/shub/id/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/instance_does_not_exist.j2 b/templates/Alcatel/login/mainloop/configure/vlan/shub/instance_does_not_exist.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/instance_does_not_exist.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/shub/instance_does_not_exist.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/vlan/shub/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/shub/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/on_error.j2 b/templates/Alcatel/login/mainloop/configure/vlan/shub/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/vlan/shub/on_error.j2 rename to templates/Alcatel/login/mainloop/configure/vlan/shub/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/xdsl/board/instance_does_not_exist.j2 b/templates/Alcatel/login/mainloop/configure/xdsl/board/instance_does_not_exist.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/xdsl/board/instance_does_not_exist.j2 rename to templates/Alcatel/login/mainloop/configure/xdsl/board/instance_does_not_exist.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/xdsl/board/nt/instance_does_not_exist.j2 b/templates/Alcatel/login/mainloop/configure/xdsl/board/nt/instance_does_not_exist.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/xdsl/board/nt/instance_does_not_exist.j2 rename to templates/Alcatel/login/mainloop/configure/xdsl/board/nt/instance_does_not_exist.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/xdsl/board/nt/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/xdsl/board/nt/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/xdsl/board/nt/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/xdsl/board/nt/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/xdsl/instance_does_not_exist.j2 b/templates/Alcatel/login/mainloop/configure/xdsl/instance_does_not_exist.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/xdsl/instance_does_not_exist.j2 rename to templates/Alcatel/login/mainloop/configure/xdsl/instance_does_not_exist.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/xdsl/line/port_identifier/on_cycle.j2 b/templates/Alcatel/login/mainloop/configure/xdsl/line/port_identifier/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/xdsl/line/port_identifier/on_cycle.j2 rename to templates/Alcatel/login/mainloop/configure/xdsl/line/port_identifier/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure/xdsl_line_admin_up.j2 b/templates/Alcatel/login/mainloop/configure/xdsl_line_admin_up.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure/xdsl_line_admin_up.j2 rename to templates/Alcatel/login/mainloop/configure/xdsl_line_admin_up.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_bottom.j2 b/templates/Alcatel/login/mainloop/configure_bridge_port_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_bottom.j2 rename to templates/Alcatel/login/mainloop/configure_bridge_port_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_identifier_detail.j2 b/templates/Alcatel/login/mainloop/configure_bridge_port_identifier_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_identifier_detail.j2 rename to templates/Alcatel/login/mainloop/configure_bridge_port_identifier_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_identifier_detail_vlan.j2 b/templates/Alcatel/login/mainloop/configure_bridge_port_identifier_detail_vlan.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_identifier_detail_vlan.j2 rename to templates/Alcatel/login/mainloop/configure_bridge_port_identifier_detail_vlan.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_middle_bottom.j2 b/templates/Alcatel/login/mainloop/configure_bridge_port_middle_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_middle_bottom.j2 rename to templates/Alcatel/login/mainloop/configure_bridge_port_middle_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_middle_top.j2 b/templates/Alcatel/login/mainloop/configure_bridge_port_middle_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_middle_top.j2 rename to templates/Alcatel/login/mainloop/configure_bridge_port_middle_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_top.j2 b/templates/Alcatel/login/mainloop/configure_bridge_port_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_top.j2 rename to templates/Alcatel/login/mainloop/configure_bridge_port_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_vlan.j2 b/templates/Alcatel/login/mainloop/configure_bridge_port_vlan.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_vlan.j2 rename to templates/Alcatel/login/mainloop/configure_bridge_port_vlan.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_vlan_detail.j2 b/templates/Alcatel/login/mainloop/configure_bridge_port_vlan_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_bridge_port_vlan_detail.j2 rename to templates/Alcatel/login/mainloop/configure_bridge_port_vlan_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_ethernet_line_identifier_detail.j2 b/templates/Alcatel/login/mainloop/configure_ethernet_line_identifier_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_ethernet_line_identifier_detail.j2 rename to templates/Alcatel/login/mainloop/configure_ethernet_line_identifier_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_ethernet_line_identifier_mau_identifier_detail.j2 b/templates/Alcatel/login/mainloop/configure_ethernet_line_identifier_mau_identifier_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_ethernet_line_identifier_mau_identifier_detail.j2 rename to templates/Alcatel/login/mainloop/configure_ethernet_line_identifier_mau_identifier_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_ethernet_ont_ontportidx_detail.j2 b/templates/Alcatel/login/mainloop/configure_ethernet_ont_ontportidx_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_ethernet_ont_ontportidx_detail.j2 rename to templates/Alcatel/login/mainloop/configure_ethernet_ont_ontportidx_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_product_line_port.j2 b/templates/Alcatel/login/mainloop/configure_product_line_port.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_product_line_port.j2 rename to templates/Alcatel/login/mainloop/configure_product_line_port.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_product_line_port_detail.j2 b/templates/Alcatel/login/mainloop/configure_product_line_port_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_product_line_port_detail.j2 rename to templates/Alcatel/login/mainloop/configure_product_line_port_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_qos_profiles_policer_middle.j2 b/templates/Alcatel/login/mainloop/configure_qos_profiles_policer_middle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_qos_profiles_policer_middle.j2 rename to templates/Alcatel/login/mainloop/configure_qos_profiles_policer_middle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_qos_profiles_session_bottom.j2 b/templates/Alcatel/login/mainloop/configure_qos_profiles_session_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_qos_profiles_session_bottom.j2 rename to templates/Alcatel/login/mainloop/configure_qos_profiles_session_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_qos_profiles_session_middle.j2 b/templates/Alcatel/login/mainloop/configure_qos_profiles_session_middle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_qos_profiles_session_middle.j2 rename to templates/Alcatel/login/mainloop/configure_qos_profiles_session_middle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_qos_profiles_session_top.j2 b/templates/Alcatel/login/mainloop/configure_qos_profiles_session_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_qos_profiles_session_top.j2 rename to templates/Alcatel/login/mainloop/configure_qos_profiles_session_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/configure_vlan_id_vlan_id.j2 b/templates/Alcatel/login/mainloop/configure_vlan_id_vlan_id.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/configure_vlan_id_vlan_id.j2 rename to templates/Alcatel/login/mainloop/configure_vlan_id_vlan_id.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/environment/?.j2 b/templates/Alcatel/login/mainloop/environment/?.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/environment/?.j2 rename to templates/Alcatel/login/mainloop/environment/?.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/environment/inhibit_alarms_help.j2 b/templates/Alcatel/login/mainloop/environment/inhibit_alarms_help.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/environment/inhibit_alarms_help.j2 rename to templates/Alcatel/login/mainloop/environment/inhibit_alarms_help.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/environment/inhibit_alarms_mode_batch_help.j2 b/templates/Alcatel/login/mainloop/environment/inhibit_alarms_mode_batch_help.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/environment/inhibit_alarms_mode_batch_help.j2 rename to templates/Alcatel/login/mainloop/environment/inhibit_alarms_mode_batch_help.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/environment/inhibit_alarms_mode_batch_print_help.j2 b/templates/Alcatel/login/mainloop/environment/inhibit_alarms_mode_batch_print_help.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/environment/inhibit_alarms_mode_batch_print_help.j2 rename to templates/Alcatel/login/mainloop/environment/inhibit_alarms_mode_batch_print_help.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/environment/inhibit_alarms_mode_batch_print_no_more_help.j2 b/templates/Alcatel/login/mainloop/environment/inhibit_alarms_mode_batch_print_no_more_help.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/environment/inhibit_alarms_mode_batch_print_no_more_help.j2 rename to templates/Alcatel/login/mainloop/environment/inhibit_alarms_mode_batch_print_no_more_help.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/environment/inhibit_alarms_mode_help.j2 b/templates/Alcatel/login/mainloop/environment/inhibit_alarms_mode_help.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/environment/inhibit_alarms_mode_help.j2 rename to templates/Alcatel/login/mainloop/environment/inhibit_alarms_mode_help.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/environment/on_cycle.j2 b/templates/Alcatel/login/mainloop/environment/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/environment/on_cycle.j2 rename to templates/Alcatel/login/mainloop/environment/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/environment/on_error.j2 b/templates/Alcatel/login/mainloop/environment/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/environment/on_error.j2 rename to templates/Alcatel/login/mainloop/environment/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/info/configure/qos/on_cycle.j2 b/templates/Alcatel/login/mainloop/info/configure/qos/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/info/configure/qos/on_cycle.j2 rename to templates/Alcatel/login/mainloop/info/configure/qos/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/info_configure_vlan_body.j2 b/templates/Alcatel/login/mainloop/info_configure_vlan_body.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/info_configure_vlan_body.j2 rename to templates/Alcatel/login/mainloop/info_configure_vlan_body.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/info_configure_vlan_bottom.j2 b/templates/Alcatel/login/mainloop/info_configure_vlan_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/info_configure_vlan_bottom.j2 rename to templates/Alcatel/login/mainloop/info_configure_vlan_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/info_configure_vlan_head.j2 b/templates/Alcatel/login/mainloop/info_configure_vlan_head.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/info_configure_vlan_head.j2 rename to templates/Alcatel/login/mainloop/info_configure_vlan_head.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/info_configure_vlan_shub_top.j2 b/templates/Alcatel/login/mainloop/info_configure_vlan_shub_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/info_configure_vlan_shub_top.j2 rename to templates/Alcatel/login/mainloop/info_configure_vlan_shub_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/info_configure_vlan_shub_vlan.j2 b/templates/Alcatel/login/mainloop/info_configure_vlan_shub_vlan.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/info_configure_vlan_shub_vlan.j2 rename to templates/Alcatel/login/mainloop/info_configure_vlan_shub_vlan.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/info_configure_vlan_shub_vlan_egress_port.j2 b/templates/Alcatel/login/mainloop/info_configure_vlan_shub_vlan_egress_port.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/info_configure_vlan_shub_vlan_egress_port.j2 rename to templates/Alcatel/login/mainloop/info_configure_vlan_shub_vlan_egress_port.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/info_configure_vlan_shub_vlan_end.j2 b/templates/Alcatel/login/mainloop/info_configure_vlan_shub_vlan_end.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/info_configure_vlan_shub_vlan_end.j2 rename to templates/Alcatel/login/mainloop/info_configure_vlan_shub_vlan_end.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/instance_does_not_exist.j2 b/templates/Alcatel/login/mainloop/instance_does_not_exist.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/instance_does_not_exist.j2 rename to templates/Alcatel/login/mainloop/instance_does_not_exist.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/on_cycle.j2 b/templates/Alcatel/login/mainloop/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/on_cycle.j2 rename to templates/Alcatel/login/mainloop/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/on_enter.j2 b/templates/Alcatel/login/mainloop/on_enter.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/on_enter.j2 rename to templates/Alcatel/login/mainloop/on_enter.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/on_error.j2 b/templates/Alcatel/login/mainloop/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/on_error.j2 rename to templates/Alcatel/login/mainloop/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/?.j2 b/templates/Alcatel/login/mainloop/show/?.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/?.j2 rename to templates/Alcatel/login/mainloop/show/?.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/alarm_current_table_bot.j2 b/templates/Alcatel/login/mainloop/show/alarm_current_table_bot.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/alarm_current_table_bot.j2 rename to templates/Alcatel/login/mainloop/show/alarm_current_table_bot.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/alarm_current_table_mid.j2 b/templates/Alcatel/login/mainloop/show/alarm_current_table_mid.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/alarm_current_table_mid.j2 rename to templates/Alcatel/login/mainloop/show/alarm_current_table_mid.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/alarm_current_table_top.j2 b/templates/Alcatel/login/mainloop/show/alarm_current_table_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/alarm_current_table_top.j2 rename to templates/Alcatel/login/mainloop/show/alarm_current_table_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment/transceiver-inventory/port_identifier/on_cycle.j2 b/templates/Alcatel/login/mainloop/show/equipment/transceiver-inventory/port_identifier/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment/transceiver-inventory/port_identifier/on_cycle.j2 rename to templates/Alcatel/login/mainloop/show/equipment/transceiver-inventory/port_identifier/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_diagnostics_sfp_sfpport_detail.j2 b/templates/Alcatel/login/mainloop/show/equipment_diagnostics_sfp_sfpport_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_diagnostics_sfp_sfpport_detail.j2 rename to templates/Alcatel/login/mainloop/show/equipment_diagnostics_sfp_sfpport_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_ont_interface_ontportidx_detail.j2 b/templates/Alcatel/login/mainloop/show/equipment_ont_interface_ontportidx_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_ont_interface_ontportidx_detail.j2 rename to templates/Alcatel/login/mainloop/show/equipment_ont_interface_ontportidx_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_ont_operational-data_ontportidx_detail.j2 b/templates/Alcatel/login/mainloop/show/equipment_ont_operational-data_ontportidx_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_ont_operational-data_ontportidx_detail.j2 rename to templates/Alcatel/login/mainloop/show/equipment_ont_operational-data_ontportidx_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_ont_optics_ontportidx_detail.j2 b/templates/Alcatel/login/mainloop/show/equipment_ont_optics_ontportidx_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_ont_optics_ontportidx_detail.j2 rename to templates/Alcatel/login/mainloop/show/equipment_ont_optics_ontportidx_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_ont_slot_detail_bottom.j2 b/templates/Alcatel/login/mainloop/show/equipment_ont_slot_detail_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_ont_slot_detail_bottom.j2 rename to templates/Alcatel/login/mainloop/show/equipment_ont_slot_detail_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_ont_slot_detail_middle.j2 b/templates/Alcatel/login/mainloop/show/equipment_ont_slot_detail_middle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_ont_slot_detail_middle.j2 rename to templates/Alcatel/login/mainloop/show/equipment_ont_slot_detail_middle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_ont_slot_detail_top.j2 b/templates/Alcatel/login/mainloop/show/equipment_ont_slot_detail_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_ont_slot_detail_top.j2 rename to templates/Alcatel/login/mainloop/show/equipment_ont_slot_detail_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_shelf_body.j2 b/templates/Alcatel/login/mainloop/show/equipment_shelf_body.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_shelf_body.j2 rename to templates/Alcatel/login/mainloop/show/equipment_shelf_body.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_shelf_bottom.j2 b/templates/Alcatel/login/mainloop/show/equipment_shelf_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_shelf_bottom.j2 rename to templates/Alcatel/login/mainloop/show/equipment_shelf_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_shelf_detail_body.j2 b/templates/Alcatel/login/mainloop/show/equipment_shelf_detail_body.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_shelf_detail_body.j2 rename to templates/Alcatel/login/mainloop/show/equipment_shelf_detail_body.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_shelf_detail_bottom.j2 b/templates/Alcatel/login/mainloop/show/equipment_shelf_detail_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_shelf_detail_bottom.j2 rename to templates/Alcatel/login/mainloop/show/equipment_shelf_detail_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_shelf_detail_head.j2 b/templates/Alcatel/login/mainloop/show/equipment_shelf_detail_head.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_shelf_detail_head.j2 rename to templates/Alcatel/login/mainloop/show/equipment_shelf_detail_head.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_shelf_shelfid_detail.j2 b/templates/Alcatel/login/mainloop/show/equipment_shelf_shelfid_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_shelf_shelfid_detail.j2 rename to templates/Alcatel/login/mainloop/show/equipment_shelf_shelfid_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_shelf_top.j2 b/templates/Alcatel/login/mainloop/show/equipment_shelf_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_shelf_top.j2 rename to templates/Alcatel/login/mainloop/show/equipment_shelf_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_bottom.j2 b/templates/Alcatel/login/mainloop/show/equipment_slot_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_bottom.j2 rename to templates/Alcatel/login/mainloop/show/equipment_slot_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_detail_body.j2 b/templates/Alcatel/login/mainloop/show/equipment_slot_detail_body.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_detail_body.j2 rename to templates/Alcatel/login/mainloop/show/equipment_slot_detail_body.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_detail_head.j2 b/templates/Alcatel/login/mainloop/show/equipment_slot_detail_head.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_detail_head.j2 rename to templates/Alcatel/login/mainloop/show/equipment_slot_detail_head.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_middle.j2 b/templates/Alcatel/login/mainloop/show/equipment_slot_middle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_middle.j2 rename to templates/Alcatel/login/mainloop/show/equipment_slot_middle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_slotid_detail.j2 b/templates/Alcatel/login/mainloop/show/equipment_slot_slotid_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_slotid_detail.j2 rename to templates/Alcatel/login/mainloop/show/equipment_slot_slotid_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_top.j2 b/templates/Alcatel/login/mainloop/show/equipment_slot_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_slot_top.j2 rename to templates/Alcatel/login/mainloop/show/equipment_slot_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_temperature_bottom.j2 b/templates/Alcatel/login/mainloop/show/equipment_temperature_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_temperature_bottom.j2 rename to templates/Alcatel/login/mainloop/show/equipment_temperature_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_temperature_middle.j2 b/templates/Alcatel/login/mainloop/show/equipment_temperature_middle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_temperature_middle.j2 rename to templates/Alcatel/login/mainloop/show/equipment_temperature_middle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_temperature_top.j2 b/templates/Alcatel/login/mainloop/show/equipment_temperature_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_temperature_top.j2 rename to templates/Alcatel/login/mainloop/show/equipment_temperature_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_transceiver_inventory_identifier_bottom.j2 b/templates/Alcatel/login/mainloop/show/equipment_transceiver_inventory_identifier_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_transceiver_inventory_identifier_bottom.j2 rename to templates/Alcatel/login/mainloop/show/equipment_transceiver_inventory_identifier_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_transceiver_inventory_identifier_detail.j2 b/templates/Alcatel/login/mainloop/show/equipment_transceiver_inventory_identifier_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_transceiver_inventory_identifier_detail.j2 rename to templates/Alcatel/login/mainloop/show/equipment_transceiver_inventory_identifier_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_transceiver_inventory_identifier_mid.j2 b/templates/Alcatel/login/mainloop/show/equipment_transceiver_inventory_identifier_mid.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_transceiver_inventory_identifier_mid.j2 rename to templates/Alcatel/login/mainloop/show/equipment_transceiver_inventory_identifier_mid.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/equipment_transceiver_inventory_identifier_top.j2 b/templates/Alcatel/login/mainloop/show/equipment_transceiver_inventory_identifier_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/equipment_transceiver_inventory_identifier_top.j2 rename to templates/Alcatel/login/mainloop/show/equipment_transceiver_inventory_identifier_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/ethernet_mau_bottom.j2 b/templates/Alcatel/login/mainloop/show/ethernet_mau_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/ethernet_mau_bottom.j2 rename to templates/Alcatel/login/mainloop/show/ethernet_mau_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/ethernet_mau_middle.j2 b/templates/Alcatel/login/mainloop/show/ethernet_mau_middle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/ethernet_mau_middle.j2 rename to templates/Alcatel/login/mainloop/show/ethernet_mau_middle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/ethernet_mau_port_detail.j2 b/templates/Alcatel/login/mainloop/show/ethernet_mau_port_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/ethernet_mau_port_detail.j2 rename to templates/Alcatel/login/mainloop/show/ethernet_mau_port_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/ethernet_mau_top.j2 b/templates/Alcatel/login/mainloop/show/ethernet_mau_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/ethernet_mau_top.j2 rename to templates/Alcatel/login/mainloop/show/ethernet_mau_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/ethernet_ont_operational_data_ontportidx_detail.j2 b/templates/Alcatel/login/mainloop/show/ethernet_ont_operational_data_ontportidx_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/ethernet_ont_operational_data_ontportidx_detail.j2 rename to templates/Alcatel/login/mainloop/show/ethernet_ont_operational_data_ontportidx_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/instance_does_not_exist.j2 b/templates/Alcatel/login/mainloop/show/instance_does_not_exist.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/instance_does_not_exist.j2 rename to templates/Alcatel/login/mainloop/show/instance_does_not_exist.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/interface_port_bottom.j2 b/templates/Alcatel/login/mainloop/show/interface_port_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/interface_port_bottom.j2 rename to templates/Alcatel/login/mainloop/show/interface_port_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/interface_port_middle.j2 b/templates/Alcatel/login/mainloop/show/interface_port_middle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/interface_port_middle.j2 rename to templates/Alcatel/login/mainloop/show/interface_port_middle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/interface_port_pipe_match_match_exact_port.j2 b/templates/Alcatel/login/mainloop/show/interface_port_pipe_match_match_exact_port.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/interface_port_pipe_match_match_exact_port.j2 rename to templates/Alcatel/login/mainloop/show/interface_port_pipe_match_match_exact_port.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/interface_port_pipe_match_match_exact_product_line_port.j2 b/templates/Alcatel/login/mainloop/show/interface_port_pipe_match_match_exact_product_line_port.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/interface_port_pipe_match_match_exact_product_line_port.j2 rename to templates/Alcatel/login/mainloop/show/interface_port_pipe_match_match_exact_product_line_port.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/interface_port_ponport_detail.j2 b/templates/Alcatel/login/mainloop/show/interface_port_ponport_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/interface_port_ponport_detail.j2 rename to templates/Alcatel/login/mainloop/show/interface_port_ponport_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/interface_port_top.j2 b/templates/Alcatel/login/mainloop/show/interface_port_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/interface_port_top.j2 rename to templates/Alcatel/login/mainloop/show/interface_port_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/linetest_single_lineid_ext_rept_empty.j2 b/templates/Alcatel/login/mainloop/show/linetest_single_lineid_ext_rept_empty.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/linetest_single_lineid_ext_rept_empty.j2 rename to templates/Alcatel/login/mainloop/show/linetest_single_lineid_ext_rept_empty.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/linetest_single_lineid_ext_rept_filled.j2 b/templates/Alcatel/login/mainloop/show/linetest_single_lineid_ext_rept_filled.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/linetest_single_lineid_ext_rept_filled.j2 rename to templates/Alcatel/login/mainloop/show/linetest_single_lineid_ext_rept_filled.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/on_cycle.j2 b/templates/Alcatel/login/mainloop/show/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/on_cycle.j2 rename to templates/Alcatel/login/mainloop/show/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/on_error.j2 b/templates/Alcatel/login/mainloop/show/on_error.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/on_error.j2 rename to templates/Alcatel/login/mainloop/show/on_error.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/pon_unprovision_onu_detail_bottom.j2 b/templates/Alcatel/login/mainloop/show/pon_unprovision_onu_detail_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/pon_unprovision_onu_detail_bottom.j2 rename to templates/Alcatel/login/mainloop/show/pon_unprovision_onu_detail_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/pon_unprovision_onu_detail_middle.j2 b/templates/Alcatel/login/mainloop/show/pon_unprovision_onu_detail_middle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/pon_unprovision_onu_detail_middle.j2 rename to templates/Alcatel/login/mainloop/show/pon_unprovision_onu_detail_middle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/pon_unprovision_onu_detail_top.j2 b/templates/Alcatel/login/mainloop/show/pon_unprovision_onu_detail_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/pon_unprovision_onu_detail_top.j2 rename to templates/Alcatel/login/mainloop/show/pon_unprovision_onu_detail_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/product_cpeinventory_port_detail.j2 b/templates/Alcatel/login/mainloop/show/product_cpeinventory_port_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/product_cpeinventory_port_detail.j2 rename to templates/Alcatel/login/mainloop/show/product_cpeinventory_port_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/product_help.j2 b/templates/Alcatel/login/mainloop/show/product_help.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/product_help.j2 rename to templates/Alcatel/login/mainloop/show/product_help.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/product_linkuprecord_port_detail.j2 b/templates/Alcatel/login/mainloop/show/product_linkuprecord_port_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/product_linkuprecord_port_detail.j2 rename to templates/Alcatel/login/mainloop/show/product_linkuprecord_port_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/product_operational_data_help.j2 b/templates/Alcatel/login/mainloop/show/product_operational_data_help.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/product_operational_data_help.j2 rename to templates/Alcatel/login/mainloop/show/product_operational_data_help.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/product_operational_data_line_help.j2 b/templates/Alcatel/login/mainloop/show/product_operational_data_line_help.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/product_operational_data_line_help.j2 rename to templates/Alcatel/login/mainloop/show/product_operational_data_line_help.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/product_operational_data_line_port_detail.j2 b/templates/Alcatel/login/mainloop/show/product_operational_data_line_port_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/product_operational_data_line_port_detail.j2 rename to templates/Alcatel/login/mainloop/show/product_operational_data_line_port_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/product_operational_data_line_port_detail_help.j2 b/templates/Alcatel/login/mainloop/show/product_operational_data_line_port_detail_help.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/product_operational_data_line_port_detail_help.j2 rename to templates/Alcatel/login/mainloop/show/product_operational_data_line_port_detail_help.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/shdsl_span_status_port_detail.j2 b/templates/Alcatel/login/mainloop/show/shdsl_span_status_port_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/shdsl_span_status_port_detail.j2 rename to templates/Alcatel/login/mainloop/show/shdsl_span_status_port_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/software_mngt_upload_download_detail.j2 b/templates/Alcatel/login/mainloop/show/software_mngt_upload_download_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/software_mngt_upload_download_detail.j2 rename to templates/Alcatel/login/mainloop/show/software_mngt_upload_download_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/software_mngt_version_etsi_detail.j2 b/templates/Alcatel/login/mainloop/show/software_mngt_version_etsi_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/software_mngt_version_etsi_detail.j2 rename to templates/Alcatel/login/mainloop/show/software_mngt_version_etsi_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/transport/ether_ifmault/port_identifier/on_cycle.j2 b/templates/Alcatel/login/mainloop/show/transport/ether_ifmault/port_identifier/on_cycle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/transport/ether_ifmault/port_identifier/on_cycle.j2 rename to templates/Alcatel/login/mainloop/show/transport/ether_ifmault/port_identifier/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_bottom.j2 b/templates/Alcatel/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_bottom.j2 rename to templates/Alcatel/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_mid.j2 b/templates/Alcatel/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_mid.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_mid.j2 rename to templates/Alcatel/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_mid.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_top.j2 b/templates/Alcatel/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_top.j2 rename to templates/Alcatel/login/mainloop/show/vlan_bridge_port-fdb_ontportidx_detail_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/vlan_bridge_port_fdb_bottom.j2 b/templates/Alcatel/login/mainloop/show/vlan_bridge_port_fdb_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/vlan_bridge_port_fdb_bottom.j2 rename to templates/Alcatel/login/mainloop/show/vlan_bridge_port_fdb_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/vlan_bridge_port_fdb_middle.j2 b/templates/Alcatel/login/mainloop/show/vlan_bridge_port_fdb_middle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/vlan_bridge_port_fdb_middle.j2 rename to templates/Alcatel/login/mainloop/show/vlan_bridge_port_fdb_middle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/vlan_bridge_port_fdb_top.j2 b/templates/Alcatel/login/mainloop/show/vlan_bridge_port_fdb_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/vlan_bridge_port_fdb_top.j2 rename to templates/Alcatel/login/mainloop/show/vlan_bridge_port_fdb_top.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/vlan_name_bottom.j2 b/templates/Alcatel/login/mainloop/show/vlan_name_bottom.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/vlan_name_bottom.j2 rename to templates/Alcatel/login/mainloop/show/vlan_name_bottom.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/vlan_name_middle.j2 b/templates/Alcatel/login/mainloop/show/vlan_name_middle.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/vlan_name_middle.j2 rename to templates/Alcatel/login/mainloop/show/vlan_name_middle.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/vlan_name_name_detail.j2 b/templates/Alcatel/login/mainloop/show/vlan_name_name_detail.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/vlan_name_name_detail.j2 rename to templates/Alcatel/login/mainloop/show/vlan_name_name_detail.j2 diff --git a/templates/Alcatel/Base/1/login/mainloop/show/vlan_name_top.j2 b/templates/Alcatel/login/mainloop/show/vlan_name_top.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/mainloop/show/vlan_name_top.j2 rename to templates/Alcatel/login/mainloop/show/vlan_name_top.j2 diff --git a/templates/Alcatel/7360/FX-4/login/on_cycle.j2 b/templates/Alcatel/login/on_cycle.j2 similarity index 100% rename from templates/Alcatel/7360/FX-4/login/on_cycle.j2 rename to templates/Alcatel/login/on_cycle.j2 diff --git a/templates/Alcatel/7360/FX-4/login/on_enter.j2 b/templates/Alcatel/login/on_enter.j2 similarity index 100% rename from templates/Alcatel/7360/FX-4/login/on_enter.j2 rename to templates/Alcatel/login/on_enter.j2 diff --git a/templates/Alcatel/7360/FX-4/login/on_exit.j2 b/templates/Alcatel/login/on_exit.j2 similarity index 100% rename from templates/Alcatel/7360/FX-4/login/on_exit.j2 rename to templates/Alcatel/login/on_exit.j2 diff --git a/templates/Alcatel/7360/FX-4/login/password.j2 b/templates/Alcatel/login/password.j2 similarity index 100% rename from templates/Alcatel/7360/FX-4/login/password.j2 rename to templates/Alcatel/login/password.j2 diff --git a/templates/Alcatel/7360/FX-4/on_cycle.j2 b/templates/Alcatel/on_cycle.j2 similarity index 100% rename from templates/Alcatel/7360/FX-4/on_cycle.j2 rename to templates/Alcatel/on_cycle.j2 diff --git a/templates/Alcatel/7360/FX-4/on_enter.j2 b/templates/Alcatel/on_enter.j2 similarity index 100% rename from templates/Alcatel/7360/FX-4/on_enter.j2 rename to templates/Alcatel/on_enter.j2 diff --git a/templates/Alcatel/7360/FX-4/on_exit.j2 b/templates/Alcatel/on_exit.j2 similarity index 100% rename from templates/Alcatel/7360/FX-4/on_exit.j2 rename to templates/Alcatel/on_exit.j2 diff --git a/templates/Huawei/5623/A/login/password.j2 b/templates/Huawei/5623/A/login/password.j2 deleted file mode 100644 index a64789f..0000000 --- a/templates/Huawei/5623/A/login/password.j2 +++ /dev/null @@ -1,2 +0,0 @@ -Bad username or password - diff --git a/templates/Huawei/Base/1/login/on_cycle.j2 b/templates/Huawei/Base/1/login/on_cycle.j2 deleted file mode 100644 index e69de29..0000000 diff --git a/templates/Huawei/Base/1/login/on_enter.j2 b/templates/Huawei/Base/1/login/on_enter.j2 deleted file mode 100644 index 3adfb18..0000000 --- a/templates/Huawei/Base/1/login/on_enter.j2 +++ /dev/null @@ -1 +0,0 @@ ->>User password: \ No newline at end of file diff --git a/templates/Huawei/Base/1/login/password.j2 b/templates/Huawei/Base/1/login/password.j2 deleted file mode 100644 index a64789f..0000000 --- a/templates/Huawei/Base/1/login/password.j2 +++ /dev/null @@ -1,2 +0,0 @@ -Bad username or password - diff --git a/templates/Huawei/Base/1/on_cycle.j2 b/templates/Huawei/Base/1/on_cycle.j2 deleted file mode 100644 index 0fd4bc2..0000000 --- a/templates/Huawei/Base/1/on_cycle.j2 +++ /dev/null @@ -1,2 +0,0 @@ - ->>User name: \ No newline at end of file diff --git a/templates/Huawei/Base/1/on_enter.j2 b/templates/Huawei/Base/1/on_enter.j2 deleted file mode 100644 index e69de29..0000000 diff --git a/templates/Huawei/Base/1/on_exit.j2 b/templates/Huawei/Base/1/on_exit.j2 deleted file mode 100644 index 071fe94..0000000 --- a/templates/Huawei/Base/1/on_exit.j2 +++ /dev/null @@ -1,2 +0,0 @@ - Configuration console exit, please retry to log on - diff --git a/templates/Huawei/Base/1/login/mainloop/?.j2 b/templates/Huawei/login/mainloop/?.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/?.j2 rename to templates/Huawei/login/mainloop/?.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_0_bottom.j2 b/templates/Huawei/login/mainloop/display_board_0_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_0_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_0_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_0_empty.j2 b/templates/Huawei/login/mainloop/display_board_0_empty.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_0_empty.j2 rename to templates/Huawei/login/mainloop/display_board_0_empty.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_0_middle.j2 b/templates/Huawei/login/mainloop/display_board_0_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_0_middle.j2 rename to templates/Huawei/login/mainloop/display_board_0_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_0_top.j2 b/templates/Huawei/login/mainloop/display_board_0_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_0_top.j2 rename to templates/Huawei/login/mainloop/display_board_0_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_bottom.j2 b/templates/Huawei/login/mainloop/display_board_dsl_product_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_dsl_product_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_middle.j2 b/templates/Huawei/login/mainloop/display_board_dsl_product_bottom_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_middle.j2 rename to templates/Huawei/login/mainloop/display_board_dsl_product_bottom_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_top.j2 b/templates/Huawei/login/mainloop/display_board_dsl_product_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_bottom_top.j2 rename to templates/Huawei/login/mainloop/display_board_dsl_product_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_bottom.j2 b/templates/Huawei/login/mainloop/display_board_dsl_product_middle_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_dsl_product_middle_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_middle.j2 b/templates/Huawei/login/mainloop/display_board_dsl_product_middle_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_middle.j2 rename to templates/Huawei/login/mainloop/display_board_dsl_product_middle_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_top.j2 b/templates/Huawei/login/mainloop/display_board_dsl_product_middle_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_middle_top.j2 rename to templates/Huawei/login/mainloop/display_board_dsl_product_middle_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_bottom.j2 b/templates/Huawei/login/mainloop/display_board_dsl_product_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_dsl_product_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_middle.j2 b/templates/Huawei/login/mainloop/display_board_dsl_product_top_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_middle.j2 rename to templates/Huawei/login/mainloop/display_board_dsl_product_top_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_top.j2 b/templates/Huawei/login/mainloop/display_board_dsl_product_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_dsl_product_top_top.j2 rename to templates/Huawei/login/mainloop/display_board_dsl_product_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_bottom.j2 b/templates/Huawei/login/mainloop/display_board_ftth_failed_link_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_failed_link_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_middle.j2 b/templates/Huawei/login/mainloop/display_board_ftth_failed_link_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_middle.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_failed_link_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_top.j2 b/templates/Huawei/login/mainloop/display_board_ftth_failed_link_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_failed_link_top.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_failed_link_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_bottom.j2 b/templates/Huawei/login/mainloop/display_board_ftth_normal_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_normal_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_middle.j2 b/templates/Huawei/login/mainloop/display_board_ftth_normal_bottom_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_middle.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_normal_bottom_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_top.j2 b/templates/Huawei/login/mainloop/display_board_ftth_normal_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_bottom_top.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_normal_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_header.j2 b/templates/Huawei/login/mainloop/display_board_ftth_normal_header.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_header.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_normal_header.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_bottom.j2 b/templates/Huawei/login/mainloop/display_board_ftth_normal_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_normal_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_middle.j2 b/templates/Huawei/login/mainloop/display_board_ftth_normal_top_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_middle.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_normal_top_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_top.j2 b/templates/Huawei/login/mainloop/display_board_ftth_normal_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_normal_top_top.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_normal_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_bottom.j2 b/templates/Huawei/login/mainloop/display_board_ftth_pon_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_pon_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_middle.j2 b/templates/Huawei/login/mainloop/display_board_ftth_pon_bottom_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_middle.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_pon_bottom_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_top.j2 b/templates/Huawei/login/mainloop/display_board_ftth_pon_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_bottom_top.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_pon_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_bottom.j2 b/templates/Huawei/login/mainloop/display_board_ftth_pon_middle_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_pon_middle_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_middle.j2 b/templates/Huawei/login/mainloop/display_board_ftth_pon_middle_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_middle.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_pon_middle_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_top.j2 b/templates/Huawei/login/mainloop/display_board_ftth_pon_middle_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_middle_top.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_pon_middle_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_ont_summary.j2 b/templates/Huawei/login/mainloop/display_board_ftth_pon_ont_summary.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_ont_summary.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_pon_ont_summary.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_bottom.j2 b/templates/Huawei/login/mainloop/display_board_ftth_pon_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_pon_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_middle.j2 b/templates/Huawei/login/mainloop/display_board_ftth_pon_top_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_middle.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_pon_top_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_top.j2 b/templates/Huawei/login/mainloop/display_board_ftth_pon_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_pon_top_top.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_pon_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_bottom.j2 b/templates/Huawei/login/mainloop/display_board_ftth_special_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_special_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_middle.j2 b/templates/Huawei/login/mainloop/display_board_ftth_special_bottom_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_middle.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_special_bottom_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_top.j2 b/templates/Huawei/login/mainloop/display_board_ftth_special_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_bottom_top.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_special_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_header.j2 b/templates/Huawei/login/mainloop/display_board_ftth_special_header.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_header.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_special_header.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_bottom.j2 b/templates/Huawei/login/mainloop/display_board_ftth_special_middle_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_special_middle_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_middle.j2 b/templates/Huawei/login/mainloop/display_board_ftth_special_middle_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_middle.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_special_middle_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_top.j2 b/templates/Huawei/login/mainloop/display_board_ftth_special_middle_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_middle_top.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_special_middle_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_bottom.j2 b/templates/Huawei/login/mainloop/display_board_ftth_special_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_special_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_middle.j2 b/templates/Huawei/login/mainloop/display_board_ftth_special_top_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_middle.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_special_top_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_top.j2 b/templates/Huawei/login/mainloop/display_board_ftth_special_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_ftth_special_top_top.j2 rename to templates/Huawei/login/mainloop/display_board_ftth_special_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_bottom.j2 b/templates/Huawei/login/mainloop/display_board_mgnt_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_mgnt_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_mid.j2 b/templates/Huawei/login/mainloop/display_board_mgnt_bottom_mid.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_mid.j2 rename to templates/Huawei/login/mainloop/display_board_mgnt_bottom_mid.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_top.j2 b/templates/Huawei/login/mainloop/display_board_mgnt_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_mgnt_bottom_top.j2 rename to templates/Huawei/login/mainloop/display_board_mgnt_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_bottom.j2 b/templates/Huawei/login/mainloop/display_board_mgnt_failed_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_mgnt_failed_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_mid.j2 b/templates/Huawei/login/mainloop/display_board_mgnt_failed_mid.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_mid.j2 rename to templates/Huawei/login/mainloop/display_board_mgnt_failed_mid.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_top.j2 b/templates/Huawei/login/mainloop/display_board_mgnt_failed_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_mgnt_failed_top.j2 rename to templates/Huawei/login/mainloop/display_board_mgnt_failed_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_header.j2 b/templates/Huawei/login/mainloop/display_board_mgnt_header.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_mgnt_header.j2 rename to templates/Huawei/login/mainloop/display_board_mgnt_header.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_bottom.j2 b/templates/Huawei/login/mainloop/display_board_mgnt_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_bottom.j2 rename to templates/Huawei/login/mainloop/display_board_mgnt_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_mid.j2 b/templates/Huawei/login/mainloop/display_board_mgnt_top_mid.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_mid.j2 rename to templates/Huawei/login/mainloop/display_board_mgnt_top_mid.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_top.j2 b/templates/Huawei/login/mainloop/display_board_mgnt_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/display_board_mgnt_top_top.j2 rename to templates/Huawei/login/mainloop/display_board_mgnt_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/?.j2 b/templates/Huawei/login/mainloop/enable/?.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/?.j2 rename to templates/Huawei/login/mainloop/enable/?.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/?.j2 b/templates/Huawei/login/mainloop/enable/config/?.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/?.j2 rename to templates/Huawei/login/mainloop/enable/config/?.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/backup_configuration_tftp.j2 b/templates/Huawei/login/mainloop/enable/config/backup_configuration_tftp.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/backup_configuration_tftp.j2 rename to templates/Huawei/login/mainloop/enable/config/backup_configuration_tftp.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/board_type_error.j2 b/templates/Huawei/login/mainloop/enable/config/board_type_error.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/board_type_error.j2 rename to templates/Huawei/login/mainloop/enable/config/board_type_error.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/delete_vlan_if_first.j2 b/templates/Huawei/login/mainloop/enable/config/delete_vlan_if_first.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/delete_vlan_if_first.j2 rename to templates/Huawei/login/mainloop/enable/config/delete_vlan_if_first.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_alarm_active_alarmtype_environment_detail.j2 b/templates/Huawei/login/mainloop/enable/config/display_alarm_active_alarmtype_environment_detail.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_alarm_active_alarmtype_environment_detail.j2 rename to templates/Huawei/login/mainloop/enable/config/display_alarm_active_alarmtype_environment_detail.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_0_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_0_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_0_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_0_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_0_empty.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_0_empty.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_0_empty.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_0_empty.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_0_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_0_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_0_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_0_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_0_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_0_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_0_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_0_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_bottom_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_bottom_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_bottom_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_bottom_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_bottom_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_bottom_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_bottom_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_middle_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_middle_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_middle_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_middle_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_middle_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_middle_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_middle_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_middle_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_middle_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_middle_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_middle_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_middle_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_top_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_top_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_top_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_top_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_top_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_top_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_top_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_dsl_product_top_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_dsl_product_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_failed_link_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_failed_link_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_failed_link_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_failed_link_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_failed_link_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_failed_link_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_failed_link_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_failed_link_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_failed_link_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_failed_link_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_failed_link_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_failed_link_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_normal_bottom_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_normal_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_normal_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_normal_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_normal_bottom_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_normal_bottom_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_normal_bottom_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_normal_bottom_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_normal_bottom_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_normal_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_normal_bottom_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_normal_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_normal_header.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_normal_header.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_normal_header.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_normal_header.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_normal_top_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_normal_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_normal_top_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_normal_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_normal_top_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_normal_top_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_normal_top_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_normal_top_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_normal_top_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_normal_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_normal_top_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_normal_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_bottom_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_bottom_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_bottom_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_bottom_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_bottom_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_bottom_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_bottom_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_middle_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_middle_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_middle_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_middle_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_middle_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_middle_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_middle_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_middle_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_middle_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_middle_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_middle_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_middle_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_ont_summary.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_ont_summary.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_ont_summary.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_ont_summary.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_top_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_top_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_top_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_top_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_top_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_top_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_top_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_pon_top_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_pon_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_bottom_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_bottom_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_bottom_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_bottom_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_bottom_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_bottom_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_bottom_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_header.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_header.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_header.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_header.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_middle_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_middle_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_middle_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_middle_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_middle_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_middle_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_middle_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_middle_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_middle_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_middle_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_middle_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_middle_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_top_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_top_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_top_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_top_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_top_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_top_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_top_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_ftth_special_top_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_ftth_special_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_mgnt_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_mgnt_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_mid.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_mgnt_bottom_mid.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_mid.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_mgnt_bottom_mid.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_mgnt_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_bottom_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_mgnt_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_mgnt_failed_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_mgnt_failed_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_mid.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_mgnt_failed_mid.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_mid.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_mgnt_failed_mid.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_mgnt_failed_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_failed_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_mgnt_failed_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_header.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_mgnt_header.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_header.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_mgnt_header.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_mgnt_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_mgnt_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_mid.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_mgnt_top_mid.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_mid.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_mgnt_top_mid.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_mgnt_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_mgnt_top_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_mgnt_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_num.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_num.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_num.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_num.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_num_0.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_num_0.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_num_0.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_num_0.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_board_num_1.j2 b/templates/Huawei/login/mainloop/enable/config/display_board_num_1.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_board_num_1.j2 rename to templates/Huawei/login/mainloop/enable/config/display_board_num_1.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_bot.j2 b/templates/Huawei/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_bot.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_bot.j2 rename to templates/Huawei/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_bot.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_bot2.j2 b/templates/Huawei/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_bot2.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_bot2.j2 rename to templates/Huawei/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_bot2.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_mid.j2 b/templates/Huawei/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_mid.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_mid.j2 rename to templates/Huawei/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_mid.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_current_configuration_section_vlan_srvprof_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_emu.j2 b/templates/Huawei/login/mainloop/enable/config/display_emu.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_emu.j2 rename to templates/Huawei/login/mainloop/enable/config/display_emu.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_emu_id.j2 b/templates/Huawei/login/mainloop/enable/config/display_emu_id.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_emu_id.j2 rename to templates/Huawei/login/mainloop/enable/config/display_emu_id.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_interface_vlanif_num.j2 b/templates/Huawei/login/mainloop/enable/config/display_interface_vlanif_num.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_interface_vlanif_num.j2 rename to templates/Huawei/login/mainloop/enable/config/display_interface_vlanif_num.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_mac_address_all_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_mac_address_all_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_mac_address_all_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_mac_address_all_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_mac_address_all_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_mac_address_all_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_mac_address_all_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all_body.j2 b/templates/Huawei/login/mainloop/enable/config/display_ont_autofind_all_body.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all_body.j2 rename to templates/Huawei/login/mainloop/enable/config/display_ont_autofind_all_body.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all_failure.j2 b/templates/Huawei/login/mainloop/enable/config/display_ont_autofind_all_failure.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all_failure.j2 rename to templates/Huawei/login/mainloop/enable/config/display_ont_autofind_all_failure.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all_footer.j2 b/templates/Huawei/login/mainloop/enable/config/display_ont_autofind_all_footer.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_autofind_all_footer.j2 rename to templates/Huawei/login/mainloop/enable/config/display_ont_autofind_all_footer.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_ont_info_summary_0_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_ont_info_summary_0_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_ont_info_summary_0_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_ont_info_summary_0_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_middle2.j2 b/templates/Huawei/login/mainloop/enable/config/display_ont_info_summary_0_middle2.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_middle2.j2 rename to templates/Huawei/login/mainloop/enable/config/display_ont_info_summary_0_middle2.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_ont_info_summary_0_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_ont_info_summary_0_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_top2.j2 b/templates/Huawei/login/mainloop/enable/config/display_ont_info_summary_0_top2.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_ont_info_summary_0_top2.j2 rename to templates/Huawei/login/mainloop/enable/config/display_ont_info_summary_0_top2.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_pitp_config.j2 b/templates/Huawei/login/mainloop/enable/config/display_pitp_config.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_pitp_config.j2 rename to templates/Huawei/login/mainloop/enable/config/display_pitp_config.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_service_port.j2 b/templates/Huawei/login/mainloop/enable/config/display_service_port.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_service_port.j2 rename to templates/Huawei/login/mainloop/enable/config/display_service_port.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_service_port_all_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_service_port_all_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_service_port_all_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_service_port_all_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_service_port_all_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_service_port_all_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_service_port_all_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_service_port_all_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_service_port_all_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_service_port_all_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_service_port_all_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_service_port_all_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_terminal_user_all_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_terminal_user_all_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_middle.j2 b/templates/Huawei/login/mainloop/enable/config/display_terminal_user_all_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/display_terminal_user_all_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_terminal_user_all_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_terminal_user_all_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_terminal_user_all_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_version.j2 b/templates/Huawei/login/mainloop/enable/config/display_version.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_version.j2 rename to templates/Huawei/login/mainloop/enable/config/display_version.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/display_vlan_all_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/display_vlan_all_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_mid.j2 b/templates/Huawei/login/mainloop/enable/config/display_vlan_all_mid.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_mid.j2 rename to templates/Huawei/login/mainloop/enable/config/display_vlan_all_mid.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_top.j2 b/templates/Huawei/login/mainloop/enable/config/display_vlan_all_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/display_vlan_all_top.j2 rename to templates/Huawei/login/mainloop/enable/config/display_vlan_all_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/adsl_help.j2 b/templates/Huawei/login/mainloop/enable/config/interface/adsl_help.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/adsl_help.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/adsl_help.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_adsl_line-profile_num.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_adsl_line-profile_num.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_adsl_line-profile_num.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_adsl_line-profile_num.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_inventory_cpe.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_inventory_cpe.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_inventory_cpe.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_inventory_cpe.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_header.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_header.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_header.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_header.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop1_loop2.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop1_loop2.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop1_loop2.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop1_loop2.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop1_middle.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop1_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop1_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop1_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop2_loop3.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop2_loop3.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop2_loop3.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop2_loop3.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop2_middle.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop2_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop2_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop2_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop3_middle.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop3_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop3_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop3_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_middle.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_top.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_top.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_loop4_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_bottom.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_bottom.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_middle.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_middle.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_top.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_top.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_ont_info_port_ont_vlan_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_optical-info_num_num.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_ont_optical-info_num_num.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_optical-info_num_num.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_ont_optical-info_num_num.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_port_state_num_num_eth-port_num.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_ont_port_state_num_num_eth-port_num.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_ont_port_state_num_num_eth-port_num.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_ont_port_state_num_num_eth-port_num.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_ddm-info.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_port_ddm-info.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_ddm-info.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_port_ddm-info.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_port_state.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_port_state.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state_offline.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_port_state_offline.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_port_state_offline.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_port_state_offline.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_power_run_info.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_power_run_info.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_power_run_info.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_power_run_info.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_traffic_table_ip_index.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_traffic_table_ip_index.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_traffic_table_ip_index.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_traffic_table_ip_index.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_vdsl_line-profile_num.j2 b/templates/Huawei/login/mainloop/enable/config/interface/display_vdsl_line-profile_num.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/display_vdsl_line-profile_num.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/display_vdsl_line-profile_num.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/gpon_help.j2 b/templates/Huawei/login/mainloop/enable/config/interface/gpon_help.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/gpon_help.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/gpon_help.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/on_cycle.j2 b/templates/Huawei/login/mainloop/enable/config/interface/on_cycle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/on_cycle.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/on_cycle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/on_error.j2 b/templates/Huawei/login/mainloop/enable/config/interface/on_error.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/on_error.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/on_error.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_added.j2 b/templates/Huawei/login/mainloop/enable/config/interface/ont_added.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_added.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/ont_added.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_already_exists.j2 b/templates/Huawei/login/mainloop/enable/config/interface/ont_already_exists.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_already_exists.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/ont_already_exists.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_not_online.j2 b/templates/Huawei/login/mainloop/enable/config/interface/ont_not_online.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/ont_not_online.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/ont_not_online.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/operation_not_supported_by_port_failure.j2 b/templates/Huawei/login/mainloop/enable/config/interface/operation_not_supported_by_port_failure.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/operation_not_supported_by_port_failure.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/operation_not_supported_by_port_failure.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/port_has_been_activated.j2 b/templates/Huawei/login/mainloop/enable/config/interface/port_has_been_activated.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/port_has_been_activated.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/port_has_been_activated.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/port_has_been_deactivated.j2 b/templates/Huawei/login/mainloop/enable/config/interface/port_has_been_deactivated.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/port_has_been_deactivated.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/port_has_been_deactivated.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/vdsl_help.j2 b/templates/Huawei/login/mainloop/enable/config/interface/vdsl_help.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/vdsl_help.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/vdsl_help.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/interface/vlan_help.j2 b/templates/Huawei/login/mainloop/enable/config/interface/vlan_help.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/interface/vlan_help.j2 rename to templates/Huawei/login/mainloop/enable/config/interface/vlan_help.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/on_cycle.j2 b/templates/Huawei/login/mainloop/enable/config/on_cycle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/on_cycle.j2 rename to templates/Huawei/login/mainloop/enable/config/on_cycle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/on_error.j2 b/templates/Huawei/login/mainloop/enable/config/on_error.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/on_error.j2 rename to templates/Huawei/login/mainloop/enable/config/on_error.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_board.j2 b/templates/Huawei/login/mainloop/enable/config/operation_not_supported_by_board.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_board.j2 rename to templates/Huawei/login/mainloop/enable/config/operation_not_supported_by_board.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_board_failure.j2 b/templates/Huawei/login/mainloop/enable/config/operation_not_supported_by_board_failure.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_board_failure.j2 rename to templates/Huawei/login/mainloop/enable/config/operation_not_supported_by_board_failure.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_port_failure.j2 b/templates/Huawei/login/mainloop/enable/config/operation_not_supported_by_port_failure.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/operation_not_supported_by_port_failure.j2 rename to templates/Huawei/login/mainloop/enable/config/operation_not_supported_by_port_failure.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/pitp_enable_pmode.j2 b/templates/Huawei/login/mainloop/enable/config/pitp_enable_pmode.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/pitp_enable_pmode.j2 rename to templates/Huawei/login/mainloop/enable/config/pitp_enable_pmode.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/please_wait_commit.j2 b/templates/Huawei/login/mainloop/enable/config/please_wait_commit.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/please_wait_commit.j2 rename to templates/Huawei/login/mainloop/enable/config/please_wait_commit.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/port_already_in_vlan.j2 b/templates/Huawei/login/mainloop/enable/config/port_already_in_vlan.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/port_already_in_vlan.j2 rename to templates/Huawei/login/mainloop/enable/config/port_already_in_vlan.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/port_profile_already_exists.j2 b/templates/Huawei/login/mainloop/enable/config/port_profile_already_exists.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/port_profile_already_exists.j2 rename to templates/Huawei/login/mainloop/enable/config/port_profile_already_exists.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/port_profile_does_not_exist.j2 b/templates/Huawei/login/mainloop/enable/config/port_profile_does_not_exist.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/port_profile_does_not_exist.j2 rename to templates/Huawei/login/mainloop/enable/config/port_profile_does_not_exist.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/service-port_num_vlan_vlan-id_vdsl_mode_ptm_0_card_port_multi-service_user-vlan_untagged.j2 b/templates/Huawei/login/mainloop/enable/config/service-port_num_vlan_vlan-id_vdsl_mode_ptm_0_card_port_multi-service_user-vlan_untagged.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/service-port_num_vlan_vlan-id_vdsl_mode_ptm_0_card_port_multi-service_user-vlan_untagged.j2 rename to templates/Huawei/login/mainloop/enable/config/service-port_num_vlan_vlan-id_vdsl_mode_ptm_0_card_port_multi-service_user-vlan_untagged.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/service_port_does_already_exist.j2 b/templates/Huawei/login/mainloop/enable/config/service_port_does_already_exist.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/service_port_does_already_exist.j2 rename to templates/Huawei/login/mainloop/enable/config/service_port_does_already_exist.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/?.j2 b/templates/Huawei/login/mainloop/enable/config/srvprof/?.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/?.j2 rename to templates/Huawei/login/mainloop/enable/config/srvprof/?.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_cycle.j2 b/templates/Huawei/login/mainloop/enable/config/srvprof/on_cycle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_cycle.j2 rename to templates/Huawei/login/mainloop/enable/config/srvprof/on_cycle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_error.j2 b/templates/Huawei/login/mainloop/enable/config/srvprof/on_error.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/on_error.j2 rename to templates/Huawei/login/mainloop/enable/config/srvprof/on_error.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/please_wait_commit.j2 b/templates/Huawei/login/mainloop/enable/config/srvprof/please_wait_commit.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/srvprof/please_wait_commit.j2 rename to templates/Huawei/login/mainloop/enable/config/srvprof/please_wait_commit.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_error_choice.j2 b/templates/Huawei/login/mainloop/enable/config/terminal_error_choice.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/terminal_error_choice.j2 rename to templates/Huawei/login/mainloop/enable/config/terminal_error_choice.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_level_error.j2 b/templates/Huawei/login/mainloop/enable/config/terminal_level_error.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/terminal_level_error.j2 rename to templates/Huawei/login/mainloop/enable/config/terminal_level_error.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_name_short.j2 b/templates/Huawei/login/mainloop/enable/config/terminal_name_short.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/terminal_name_short.j2 rename to templates/Huawei/login/mainloop/enable/config/terminal_name_short.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_profile_error.j2 b/templates/Huawei/login/mainloop/enable/config/terminal_profile_error.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/terminal_profile_error.j2 rename to templates/Huawei/login/mainloop/enable/config/terminal_profile_error.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_error.j2 b/templates/Huawei/login/mainloop/enable/config/terminal_pw_error.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_error.j2 rename to templates/Huawei/login/mainloop/enable/config/terminal_pw_error.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_short.j2 b/templates/Huawei/login/mainloop/enable/config/terminal_pw_short.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/terminal_pw_short.j2 rename to templates/Huawei/login/mainloop/enable/config/terminal_pw_short.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/test/?.j2 b/templates/Huawei/login/mainloop/enable/config/test/?.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/test/?.j2 rename to templates/Huawei/login/mainloop/enable/config/test/?.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test.j2 b/templates/Huawei/login/mainloop/enable/config/test/melt_test.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test.j2 rename to templates/Huawei/login/mainloop/enable/config/test/melt_test.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test_wait.j2 b/templates/Huawei/login/mainloop/enable/config/test/melt_test_wait.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/test/melt_test_wait.j2 rename to templates/Huawei/login/mainloop/enable/config/test/melt_test_wait.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/test/on_cycle.j2 b/templates/Huawei/login/mainloop/enable/config/test/on_cycle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/test/on_cycle.j2 rename to templates/Huawei/login/mainloop/enable/config/test/on_cycle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/test/on_error.j2 b/templates/Huawei/login/mainloop/enable/config/test/on_error.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/test/on_error.j2 rename to templates/Huawei/login/mainloop/enable/config/test/on_error.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/user_already_exists.j2 b/templates/Huawei/login/mainloop/enable/config/user_already_exists.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/user_already_exists.j2 rename to templates/Huawei/login/mainloop/enable/config/user_already_exists.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/user_already_unlocked.j2 b/templates/Huawei/login/mainloop/enable/config/user_already_unlocked.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/user_already_unlocked.j2 rename to templates/Huawei/login/mainloop/enable/config/user_already_unlocked.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/user_created.j2 b/templates/Huawei/login/mainloop/enable/config/user_created.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/user_created.j2 rename to templates/Huawei/login/mainloop/enable/config/user_created.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/user_level.j2 b/templates/Huawei/login/mainloop/enable/config/user_level.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/user_level.j2 rename to templates/Huawei/login/mainloop/enable/config/user_level.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_already_exists.j2 b/templates/Huawei/login/mainloop/enable/config/vlan_already_exists.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/vlan_already_exists.j2 rename to templates/Huawei/login/mainloop/enable/config/vlan_already_exists.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_bind_service-profile_vlan-id_profile-id_profile-id.j2 b/templates/Huawei/login/mainloop/enable/config/vlan_bind_service-profile_vlan-id_profile-id_profile-id.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/vlan_bind_service-profile_vlan-id_profile-id_profile-id.j2 rename to templates/Huawei/login/mainloop/enable/config/vlan_bind_service-profile_vlan-id_profile-id_profile-id.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_does_not_exist.j2 b/templates/Huawei/login/mainloop/enable/config/vlan_does_not_exist.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/vlan_does_not_exist.j2 rename to templates/Huawei/login/mainloop/enable/config/vlan_does_not_exist.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/config/vlan_service_profile_does_not_exist.j2 b/templates/Huawei/login/mainloop/enable/config/vlan_service_profile_does_not_exist.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/config/vlan_service_profile_does_not_exist.j2 rename to templates/Huawei/login/mainloop/enable/config/vlan_service_profile_does_not_exist.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/?.j2 b/templates/Huawei/login/mainloop/enable/diagnose/?.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/?.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/?.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection.j2 b/templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_1.j2 b/templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_1.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_1.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_1.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_10.j2 b/templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_10.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_10.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_10.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_2.j2 b/templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_2.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_2.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_2.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_3.j2 b/templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_3.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_3.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_3.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_4.j2 b/templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_4.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_4.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_4.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_5.j2 b/templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_5.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_5.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_5.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_6.j2 b/templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_6.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_6.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_6.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_7.j2 b/templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_7.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_7.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_7.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_8.j2 b/templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_8.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_8.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_8.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_9.j2 b/templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_9.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/display_system_status_collection_9.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/display_system_status_collection_9.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/on_cycle.j2 b/templates/Huawei/login/mainloop/enable/diagnose/on_cycle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/on_cycle.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/on_cycle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/on_error.j2 b/templates/Huawei/login/mainloop/enable/diagnose/on_error.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/on_error.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/on_error.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/saving_complete.j2 b/templates/Huawei/login/mainloop/enable/diagnose/saving_complete.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/saving_complete.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/saving_complete.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/saving_progress.j2 b/templates/Huawei/login/mainloop/enable/diagnose/saving_progress.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/saving_progress.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/saving_progress.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_failure.j2 b/templates/Huawei/login/mainloop/enable/diagnose/switch_dsl_mode_failure.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_failure.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/switch_dsl_mode_failure.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_1.j2 b/templates/Huawei/login/mainloop/enable/diagnose/switch_dsl_mode_temp_1.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_1.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/switch_dsl_mode_temp_1.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_2.j2 b/templates/Huawei/login/mainloop/enable/diagnose/switch_dsl_mode_temp_2.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/diagnose/switch_dsl_mode_temp_2.j2 rename to templates/Huawei/login/mainloop/enable/diagnose/switch_dsl_mode_temp_2.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_adsl_line_operation_port_num_card_port.j2 b/templates/Huawei/login/mainloop/enable/display_adsl_line_operation_port_num_card_port.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_adsl_line_operation_port_num_card_port.j2 rename to templates/Huawei/login/mainloop/enable/display_adsl_line_operation_port_num_card_port.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_0_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_0_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_0_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_0_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_0_empty.j2 b/templates/Huawei/login/mainloop/enable/display_board_0_empty.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_0_empty.j2 rename to templates/Huawei/login/mainloop/enable/display_board_0_empty.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_0_middle.j2 b/templates/Huawei/login/mainloop/enable/display_board_0_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_0_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_board_0_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_0_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_0_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_0_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_0_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_bottom_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_dsl_product_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_dsl_product_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_bottom_middle.j2 b/templates/Huawei/login/mainloop/enable/display_board_dsl_product_bottom_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_bottom_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_board_dsl_product_bottom_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_bottom_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_dsl_product_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_bottom_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_dsl_product_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_middle_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_dsl_product_middle_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_middle_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_dsl_product_middle_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_middle_middle.j2 b/templates/Huawei/login/mainloop/enable/display_board_dsl_product_middle_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_middle_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_board_dsl_product_middle_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_middle_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_dsl_product_middle_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_middle_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_dsl_product_middle_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_top_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_dsl_product_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_top_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_dsl_product_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_top_middle.j2 b/templates/Huawei/login/mainloop/enable/display_board_dsl_product_top_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_top_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_board_dsl_product_top_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_top_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_dsl_product_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_dsl_product_top_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_dsl_product_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_failed_link_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_failed_link_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_failed_link_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_failed_link_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_failed_link_middle.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_failed_link_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_failed_link_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_failed_link_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_failed_link_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_failed_link_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_failed_link_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_failed_link_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_normal_bottom_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_normal_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_normal_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_normal_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_normal_bottom_middle.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_normal_bottom_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_normal_bottom_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_normal_bottom_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_normal_bottom_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_normal_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_normal_bottom_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_normal_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_normal_header.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_normal_header.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_normal_header.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_normal_header.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_normal_top_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_normal_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_normal_top_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_normal_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_normal_top_middle.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_normal_top_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_normal_top_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_normal_top_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_normal_top_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_normal_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_normal_top_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_normal_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_bottom_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_pon_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_pon_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_bottom_middle.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_pon_bottom_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_bottom_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_pon_bottom_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_bottom_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_pon_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_bottom_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_pon_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_middle_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_pon_middle_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_middle_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_pon_middle_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_middle_middle.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_pon_middle_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_middle_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_pon_middle_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_middle_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_pon_middle_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_middle_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_pon_middle_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_ont_summary.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_pon_ont_summary.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_ont_summary.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_pon_ont_summary.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_top_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_pon_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_top_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_pon_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_top_middle.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_pon_top_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_top_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_pon_top_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_top_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_pon_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_pon_top_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_pon_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_bottom_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_special_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_special_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_bottom_middle.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_special_bottom_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_bottom_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_special_bottom_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_bottom_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_special_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_bottom_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_special_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_header.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_special_header.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_header.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_special_header.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_middle_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_special_middle_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_middle_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_special_middle_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_middle_middle.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_special_middle_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_middle_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_special_middle_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_middle_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_special_middle_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_middle_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_special_middle_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_top_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_special_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_top_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_special_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_top_middle.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_special_top_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_top_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_special_top_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_top_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_ftth_special_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_ftth_special_top_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_ftth_special_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_mgnt_bottom_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_mgnt_bottom_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_mid.j2 b/templates/Huawei/login/mainloop/enable/display_board_mgnt_bottom_mid.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_mid.j2 rename to templates/Huawei/login/mainloop/enable/display_board_mgnt_bottom_mid.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_mgnt_bottom_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_bottom_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_mgnt_bottom_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_mgnt_failed_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_mgnt_failed_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_mid.j2 b/templates/Huawei/login/mainloop/enable/display_board_mgnt_failed_mid.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_mid.j2 rename to templates/Huawei/login/mainloop/enable/display_board_mgnt_failed_mid.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_mgnt_failed_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_failed_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_mgnt_failed_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_header.j2 b/templates/Huawei/login/mainloop/enable/display_board_mgnt_header.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_header.j2 rename to templates/Huawei/login/mainloop/enable/display_board_mgnt_header.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_board_mgnt_top_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_board_mgnt_top_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_mid.j2 b/templates/Huawei/login/mainloop/enable/display_board_mgnt_top_mid.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_mid.j2 rename to templates/Huawei/login/mainloop/enable/display_board_mgnt_top_mid.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_top.j2 b/templates/Huawei/login/mainloop/enable/display_board_mgnt_top_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_board_mgnt_top_top.j2 rename to templates/Huawei/login/mainloop/enable/display_board_mgnt_top_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_interface_product_port.j2 b/templates/Huawei/login/mainloop/enable/display_interface_product_port.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_interface_product_port.j2 rename to templates/Huawei/login/mainloop/enable/display_interface_product_port.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_product_port_state_num_card_port_activated.j2 b/templates/Huawei/login/mainloop/enable/display_product_port_state_num_card_port_activated.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_product_port_state_num_card_port_activated.j2 rename to templates/Huawei/login/mainloop/enable/display_product_port_state_num_card_port_activated.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_product_port_state_num_card_port_deactivated.j2 b/templates/Huawei/login/mainloop/enable/display_product_port_state_num_card_port_deactivated.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_product_port_state_num_card_port_deactivated.j2 rename to templates/Huawei/login/mainloop/enable/display_product_port_state_num_card_port_deactivated.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_service_port.j2 b/templates/Huawei/login/mainloop/enable/display_service_port.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_service_port.j2 rename to templates/Huawei/login/mainloop/enable/display_service_port.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_service_port_all_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_service_port_all_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_service_port_all_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_service_port_all_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_service_port_all_middle.j2 b/templates/Huawei/login/mainloop/enable/display_service_port_all_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_service_port_all_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_service_port_all_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_service_port_all_top.j2 b/templates/Huawei/login/mainloop/enable/display_service_port_all_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_service_port_all_top.j2 rename to templates/Huawei/login/mainloop/enable/display_service_port_all_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_temperature.j2 b/templates/Huawei/login/mainloop/enable/display_temperature.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_temperature.j2 rename to templates/Huawei/login/mainloop/enable/display_temperature.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_bottom.j2 b/templates/Huawei/login/mainloop/enable/display_terminal_user_all_bottom.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_bottom.j2 rename to templates/Huawei/login/mainloop/enable/display_terminal_user_all_bottom.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_middle.j2 b/templates/Huawei/login/mainloop/enable/display_terminal_user_all_middle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_middle.j2 rename to templates/Huawei/login/mainloop/enable/display_terminal_user_all_middle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_top.j2 b/templates/Huawei/login/mainloop/enable/display_terminal_user_all_top.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_terminal_user_all_top.j2 rename to templates/Huawei/login/mainloop/enable/display_terminal_user_all_top.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_vdsl_line-profile_num.j2 b/templates/Huawei/login/mainloop/enable/display_vdsl_line-profile_num.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_vdsl_line-profile_num.j2 rename to templates/Huawei/login/mainloop/enable/display_vdsl_line-profile_num.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/display_vdsl_line_operation_port_num_card_port.j2 b/templates/Huawei/login/mainloop/enable/display_vdsl_line_operation_port_num_card_port.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/display_vdsl_line_operation_port_num_card_port.j2 rename to templates/Huawei/login/mainloop/enable/display_vdsl_line_operation_port_num_card_port.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/on_cycle.j2 b/templates/Huawei/login/mainloop/enable/on_cycle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/on_cycle.j2 rename to templates/Huawei/login/mainloop/enable/on_cycle.j2 diff --git a/templates/Alcatel/Base/1/login/on_cycle.j2 b/templates/Huawei/login/mainloop/enable/on_enable_quit.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/on_cycle.j2 rename to templates/Huawei/login/mainloop/enable/on_enable_quit.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/enable/on_error.j2 b/templates/Huawei/login/mainloop/enable/on_error.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/enable/on_error.j2 rename to templates/Huawei/login/mainloop/enable/on_error.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/help.j2 b/templates/Huawei/login/mainloop/help.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/help.j2 rename to templates/Huawei/login/mainloop/help.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/on_cycle.j2 b/templates/Huawei/login/mainloop/on_cycle.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/on_cycle.j2 rename to templates/Huawei/login/mainloop/on_cycle.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/on_enter.j2 b/templates/Huawei/login/mainloop/on_enter.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/on_enter.j2 rename to templates/Huawei/login/mainloop/on_enter.j2 diff --git a/templates/Huawei/Base/1/login/mainloop/on_error.j2 b/templates/Huawei/login/mainloop/on_error.j2 similarity index 100% rename from templates/Huawei/Base/1/login/mainloop/on_error.j2 rename to templates/Huawei/login/mainloop/on_error.j2 diff --git a/templates/Huawei/5623/A/login/on_cycle.j2 b/templates/Huawei/login/on_cycle.j2 similarity index 100% rename from templates/Huawei/5623/A/login/on_cycle.j2 rename to templates/Huawei/login/on_cycle.j2 diff --git a/templates/Huawei/5623/A/login/on_enter.j2 b/templates/Huawei/login/on_enter.j2 similarity index 100% rename from templates/Huawei/5623/A/login/on_enter.j2 rename to templates/Huawei/login/on_enter.j2 diff --git a/templates/Alcatel/Base/1/login/password.j2 b/templates/Huawei/login/password.j2 similarity index 100% rename from templates/Alcatel/Base/1/login/password.j2 rename to templates/Huawei/login/password.j2 diff --git a/templates/Huawei/5623/A/login/user_locked.j2 b/templates/Huawei/login/user_locked.j2 similarity index 100% rename from templates/Huawei/5623/A/login/user_locked.j2 rename to templates/Huawei/login/user_locked.j2 diff --git a/templates/Huawei/5623/A/on_cycle.j2 b/templates/Huawei/on_cycle.j2 similarity index 100% rename from templates/Huawei/5623/A/on_cycle.j2 rename to templates/Huawei/on_cycle.j2 diff --git a/templates/Huawei/5623/A/on_enter.j2 b/templates/Huawei/on_enter.j2 similarity index 100% rename from templates/Huawei/5623/A/on_enter.j2 rename to templates/Huawei/on_enter.j2 diff --git a/templates/Huawei/5623/A/on_exit.j2 b/templates/Huawei/on_exit.j2 similarity index 100% rename from templates/Huawei/5623/A/on_exit.j2 rename to templates/Huawei/on_exit.j2 diff --git a/test_cases/unit_tests/alcatel/test_alcatel.py b/test_cases/unit_tests/alcatel/test_alcatel.py index 46d4dc7..8a2a9b1 100644 --- a/test_cases/unit_tests/alcatel/test_alcatel.py +++ b/test_cases/unit_tests/alcatel/test_alcatel.py @@ -501,8 +501,8 @@ def test_box_properties(self): def test_box_add_resources(self): count = len(self.model.vlans) - self.model.add_vlan(name='lala', number=10101) - self.model.add_vlan(name='test_vlan2', number=9999, shutdown=False, tag='tagged') + self.model.add_vlan(name='lala', number=101) + self.model.add_vlan(name='test_vlan2', number=999, shutdown=False, tag='tagged') assert count + 2 == len(self.model.vlans) try: broken_vlan = self.model.add_vlan(tag='untagged') @@ -530,7 +530,7 @@ def test_box_add_resources(self): self.model.add_service_vlan(name='test_svlan1', vlan_id=1, service_port_id=1) assert count+2 == len(self.model.service_vlans) try: - broken_sport = self.model.add_service_vlan(name='test_svlan2') + broken_svort = self.model.add_service_vlan(name='test_svlan2') assert False except exceptions.SoftboxenError: assert True diff --git a/test_cases/unit_tests/test_core.py b/test_cases/unit_tests/test_core.py index 7040105..63b16c3 100644 --- a/test_cases/unit_tests/test_core.py +++ b/test_cases/unit_tests/test_core.py @@ -10,14 +10,12 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -import os, sys +import os from nesi import exceptions -from os import listdir -from os.path import isfile, join from urllib.parse import urlparse import importlib -from nesi.softbox import rest_client -from nesi.softbox import root, base +from nesi.softbox.cli import rest_client +from nesi.softbox.base_resources import root, base import pytest @@ -25,7 +23,7 @@ class TestCore: def prep_cli(self): self.prep_model() - main = importlib.import_module('vendors.' + self.model.vendor + '.' + self.model.model + '.' + self.model.vendor + '_' + self.model.model + '.main') + main = importlib.import_module('vendors.' + self.model.vendor + '.main') cli = main.PreLoginCommandProcessor self.cli = cli return cli @@ -68,7 +66,8 @@ def run(self, inpath, outpath): stdin1 = os.fdopen(fd1, 'rb', 0) while True: - command_processor = self.cli(self.model, stdin1, stdout1, (), template_root='templates/', daemon=True) + templ_root ='templates/' + str(self.model.vendor) + command_processor = self.cli(self.model, stdin1, stdout1, (), template_root=templ_root, daemon=True) try: context = dict() context['login_banner'] = self.model.login_banner @@ -80,7 +79,7 @@ def run(self, inpath, outpath): elif exc.return_to is not None and exc.return_to == 'sysreboot': continue else: - pass + break stdin1.close() stdout1.close() diff --git a/vendors/Alcatel/7360/Alcatel_7360/__init__.py b/vendors/Alcatel/7360/Alcatel_7360/__init__.py deleted file mode 100644 index 46f839c..0000000 --- a/vendors/Alcatel/7360/Alcatel_7360/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# http://www.python.org/dev/peps/pep-0396/ -__version__ = '0.0.0' diff --git a/vendors/Alcatel/7360/__init__.py b/vendors/Alcatel/7360/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/vendors/Alcatel/Base/Alcatel_Base/__init__.py b/vendors/Alcatel/Base/Alcatel_Base/__init__.py deleted file mode 100644 index 46f839c..0000000 --- a/vendors/Alcatel/Base/Alcatel_Base/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# http://www.python.org/dev/peps/pep-0396/ -__version__ = '0.0.0' diff --git a/vendors/Alcatel/Base/__init__.py b/vendors/Alcatel/Base/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/vendors/Alcatel/Base/Alcatel_Base/adminCommandProcessor.py b/vendors/Alcatel/adminCommandProcessor.py similarity index 100% rename from vendors/Alcatel/Base/Alcatel_Base/adminCommandProcessor.py rename to vendors/Alcatel/adminCommandProcessor.py diff --git a/vendors/Alcatel/Base/Alcatel_Base/baseCommandProcessor.py b/vendors/Alcatel/baseCommandProcessor.py similarity index 98% rename from vendors/Alcatel/Base/Alcatel_Base/baseCommandProcessor.py rename to vendors/Alcatel/baseCommandProcessor.py index d87a9ff..4b08499 100644 --- a/vendors/Alcatel/Base/Alcatel_Base/baseCommandProcessor.py +++ b/vendors/Alcatel/baseCommandProcessor.py @@ -17,10 +17,6 @@ class BaseCommandProcessor(base.CommandProcessor): """Create CLI REPR loop for example switch.""" - VENDOR = 'Alcatel' - MODEL = 'Base' - VERSION = '1' - def do_exit(self, command, *args, context=None): raise exceptions.TerminalExitError() diff --git a/vendors/Alcatel/Base/Alcatel_Base/baseMixIn.py b/vendors/Alcatel/baseMixIn.py similarity index 100% rename from vendors/Alcatel/Base/Alcatel_Base/baseMixIn.py rename to vendors/Alcatel/baseMixIn.py diff --git a/vendors/Alcatel/Base/Alcatel_Base/configureCommandProcessor.py b/vendors/Alcatel/configureCommandProcessor.py similarity index 100% rename from vendors/Alcatel/Base/Alcatel_Base/configureCommandProcessor.py rename to vendors/Alcatel/configureCommandProcessor.py diff --git a/vendors/Alcatel/Base/Alcatel_Base/environmentCommandProcessor.py b/vendors/Alcatel/environmentCommandProcessor.py similarity index 100% rename from vendors/Alcatel/Base/Alcatel_Base/environmentCommandProcessor.py rename to vendors/Alcatel/environmentCommandProcessor.py diff --git a/vendors/Alcatel/7360/Alcatel_7360/main.py b/vendors/Alcatel/main.py similarity index 82% rename from vendors/Alcatel/7360/Alcatel_7360/main.py rename to vendors/Alcatel/main.py index 3725989..ce5e702 100644 --- a/vendors/Alcatel/7360/Alcatel_7360/main.py +++ b/vendors/Alcatel/main.py @@ -12,19 +12,11 @@ from nesi.softbox.cli import base from nesi import exceptions -from datetime import datetime, date -from vendors.Alcatel.Base.Alcatel_Base.userViewCommandProcessor import UserViewCommandProcessor +from datetime import datetime +from vendors.Alcatel.userViewCommandProcessor import UserViewCommandProcessor -class ReadInputCommandProcessor(base.CommandProcessor): - """Create CLI REPR loop for example switch.""" - - VENDOR = 'Alcatel' - MODEL = '7360' - VERSION = 'FX-4' - - -class PreLoginCommandProcessor(ReadInputCommandProcessor): +class PreLoginCommandProcessor(base.CommandProcessor): def on_unknown_command(self, command, *args, context=None): subprocessor = self._create_subprocessor( @@ -44,7 +36,7 @@ def on_unknown_command(self, command, *args, context=None): raise exc -class LoginCommandProcessor(ReadInputCommandProcessor): +class LoginCommandProcessor(base.CommandProcessor): def on_unknown_command(self, command, *args, context=None): context['welcome_banner'] = self._model.welcome_banner diff --git a/vendors/Alcatel/Base/Alcatel_Base/showCommandProcessor.py b/vendors/Alcatel/showCommandProcessor.py similarity index 100% rename from vendors/Alcatel/Base/Alcatel_Base/showCommandProcessor.py rename to vendors/Alcatel/showCommandProcessor.py diff --git a/vendors/Alcatel/Base/Alcatel_Base/userViewCommandProcessor.py b/vendors/Alcatel/userViewCommandProcessor.py similarity index 100% rename from vendors/Alcatel/Base/Alcatel_Base/userViewCommandProcessor.py rename to vendors/Alcatel/userViewCommandProcessor.py diff --git a/vendors/Huawei/5623/Huawei_5623/__init__.py b/vendors/Huawei/5623/Huawei_5623/__init__.py deleted file mode 100644 index 46f839c..0000000 --- a/vendors/Huawei/5623/Huawei_5623/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# http://www.python.org/dev/peps/pep-0396/ -__version__ = '0.0.0' diff --git a/vendors/Huawei/5623/__init__.py b/vendors/Huawei/5623/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/vendors/Huawei/Base/Huawei_Base/__init__.py b/vendors/Huawei/Base/Huawei_Base/__init__.py deleted file mode 100644 index 46f839c..0000000 --- a/vendors/Huawei/Base/Huawei_Base/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# http://www.python.org/dev/peps/pep-0396/ -__version__ = '0.0.0' diff --git a/vendors/Huawei/Base/__init__.py b/vendors/Huawei/Base/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py b/vendors/Huawei/baseCommandProcessor.py similarity index 98% rename from vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py rename to vendors/Huawei/baseCommandProcessor.py index f244ad7..88b6ad3 100644 --- a/vendors/Huawei/Base/Huawei_Base/baseCommandProcessor.py +++ b/vendors/Huawei/baseCommandProcessor.py @@ -17,10 +17,6 @@ class BaseCommandProcessor(base.CommandProcessor): """Create CLI REPR loop for example switch.""" - VENDOR = 'Huawei' - MODEL = 'Base' - VERSION = '1' - def map_states(self, object, type): if object.admin_state == '0': if type == 'subrack': diff --git a/vendors/Huawei/Base/Huawei_Base/baseMixIn.py b/vendors/Huawei/baseMixIn.py similarity index 100% rename from vendors/Huawei/Base/Huawei_Base/baseMixIn.py rename to vendors/Huawei/baseMixIn.py diff --git a/vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py b/vendors/Huawei/configCommandProcessor.py similarity index 100% rename from vendors/Huawei/Base/Huawei_Base/configCommandProcessor.py rename to vendors/Huawei/configCommandProcessor.py diff --git a/vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py b/vendors/Huawei/diagnoseCommandProcessor.py similarity index 100% rename from vendors/Huawei/Base/Huawei_Base/diagnoseCommandProcessor.py rename to vendors/Huawei/diagnoseCommandProcessor.py diff --git a/vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py b/vendors/Huawei/enableCommandProcessor.py similarity index 100% rename from vendors/Huawei/Base/Huawei_Base/enableCommandProcessor.py rename to vendors/Huawei/enableCommandProcessor.py diff --git a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py b/vendors/Huawei/huaweiBaseCommandProcessor.py similarity index 99% rename from vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py rename to vendors/Huawei/huaweiBaseCommandProcessor.py index e45b419..572ebe0 100644 --- a/vendors/Huawei/Base/Huawei_Base/huaweiBaseCommandProcessor.py +++ b/vendors/Huawei/huaweiBaseCommandProcessor.py @@ -9,9 +9,8 @@ # - Alexander Dincher # # License: https://github.com/inexio/NESi/LICENSE.rst -import os -from vendors.Huawei.Base.Huawei_Base.baseCommandProcessor import BaseCommandProcessor +from vendors.Huawei.baseCommandProcessor import BaseCommandProcessor from nesi import exceptions diff --git a/vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py b/vendors/Huawei/interfaceCommandProcessor.py similarity index 100% rename from vendors/Huawei/Base/Huawei_Base/interfaceCommandProcessor.py rename to vendors/Huawei/interfaceCommandProcessor.py diff --git a/vendors/Huawei/5623/Huawei_5623/main.py b/vendors/Huawei/main.py similarity index 90% rename from vendors/Huawei/5623/Huawei_5623/main.py rename to vendors/Huawei/main.py index e985903..a93ce3f 100644 --- a/vendors/Huawei/5623/Huawei_5623/main.py +++ b/vendors/Huawei/main.py @@ -9,22 +9,13 @@ # - Alexander Dincher # # License: https://github.com/inexio/NESi/LICENSE.rst -from datetime import datetime from nesi.softbox.cli import base -from vendors.Huawei.Base.Huawei_Base.userViewCommandProcessor import * +from vendors.Huawei.userViewCommandProcessor import * from nesi import exceptions -class ReadInputCommandProcessor(base.CommandProcessor): - """Create CLI REPR loop for example switch.""" - - VENDOR = 'Huawei' - MODEL = '5623' - VERSION = 'A' - - -class PreLoginCommandProcessor(ReadInputCommandProcessor): +class PreLoginCommandProcessor(base.CommandProcessor): def on_unknown_command(self, command, *args, context=None): subprocessor = self._create_subprocessor( @@ -44,7 +35,7 @@ def on_unknown_command(self, command, *args, context=None): raise exc -class LoginCommandProcessor(ReadInputCommandProcessor): +class LoginCommandProcessor(base.CommandProcessor): def on_unknown_command(self, command, *args, context=None): username = context.pop('username') diff --git a/vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py b/vendors/Huawei/testCommandProcessor.py similarity index 100% rename from vendors/Huawei/Base/Huawei_Base/testCommandProcessor.py rename to vendors/Huawei/testCommandProcessor.py diff --git a/vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py b/vendors/Huawei/userViewCommandProcessor.py similarity index 100% rename from vendors/Huawei/Base/Huawei_Base/userViewCommandProcessor.py rename to vendors/Huawei/userViewCommandProcessor.py diff --git a/vendors/Huawei/Base/Huawei_Base/vlanSrvprofCommandProcessor.py b/vendors/Huawei/vlanSrvprofCommandProcessor.py similarity index 100% rename from vendors/Huawei/Base/Huawei_Base/vlanSrvprofCommandProcessor.py rename to vendors/Huawei/vlanSrvprofCommandProcessor.py From d56b039fa19386c054eb2c4e6d1a10440999f5d4 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 22 Sep 2020 15:45:35 +0200 Subject: [PATCH 072/318] Fixed a bug where the wrong card type was asserted when creating a service-port --- .../enable/config/service_port_does_already_exist.j2 | 2 -- vendors/Huawei/configCommandProcessor.py | 10 +++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/templates/Huawei/login/mainloop/enable/config/service_port_does_already_exist.j2 b/templates/Huawei/login/mainloop/enable/config/service_port_does_already_exist.j2 index f48d337..3aba4e8 100644 --- a/templates/Huawei/login/mainloop/enable/config/service_port_does_already_exist.j2 +++ b/templates/Huawei/login/mainloop/enable/config/service_port_does_already_exist.j2 @@ -1,5 +1,3 @@ Failure: Service virtual port has existed already Conflicted service virtual port index: {{ context.service_port.name }} - - diff --git a/vendors/Huawei/configCommandProcessor.py b/vendors/Huawei/configCommandProcessor.py index 8572e39..2427165 100644 --- a/vendors/Huawei/configCommandProcessor.py +++ b/vendors/Huawei/configCommandProcessor.py @@ -441,7 +441,7 @@ def do_service_port(self, command, *args, context=None): try: port = self._model.get_port('name', port_idx) except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError(command=command) + raise exceptions.CommandSyntaxError(command=command) # FIXME: parameter error if args[5] == 'ont': ont_idx = args[6] ont_port_idx = args[8] @@ -511,7 +511,7 @@ def do_service_port(self, command, *args, context=None): try: card = self._model.get_card('id', port.card_id) - assert (card.product == 'vdsl') or (card.product == 'xdsl') + assert card.product in ('adsl', 'vdsl', 'xdsl') except (exceptions.SoftboxenError, AssertionError): service_vlan.delete() service_port.delete() @@ -531,7 +531,7 @@ def do_service_port(self, command, *args, context=None): 'index', str) try: card = self._model.get_card('id', port.card_id) - assert (card.product == 'vdsl') or (card.product == 'xdsl') + assert card.product in ('adsl', 'vdsl', 'xdsl') except (exceptions.SoftboxenError, AssertionError): service_vlan.delete() service_port.delete() @@ -569,7 +569,7 @@ def do_service_port(self, command, *args, context=None): 'untagged'): try: card = self._model.get_card('id', port.card_id) - assert card.product == 'vdsl' + assert card.product in ('adsl', 'vdsl', 'xdsl') except (exceptions.SoftboxenError, AssertionError): service_vlan.delete() service_port.delete() @@ -585,7 +585,7 @@ def do_service_port(self, command, *args, context=None): str, 'multi-service', 'user-vlan', 'untagged') try: card = self._model.get_card('id', port.card_id) - assert (card.product == 'adsl') or (card.product == 'xdsl') + assert card.product in ('adsl', 'vdsl', 'xdsl') except (exceptions.SoftboxenError, AssertionError): service_vlan.delete() service_port.delete() From 01e78d8269090c2351509267a82aae28619e45de Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 23 Sep 2020 10:13:26 +0200 Subject: [PATCH 073/318] Initial commit for vendor KeyMile --- .../conf/bootstraps/create-keymile-MG2200.sh | 135 ++++++++++++++++++ bootup/restapi.sh | 7 +- nesi/keymile/keymile_resources/keymile_box.py | 17 ++- .../keymile/keymile_resources/keymile_card.py | 27 ++++ .../keymile_resources/keymile_subrack.py | 27 ++++ nesi/softbox/api/views/card_views.py | 33 ++--- nesi/softbox/cli/base.py | 8 +- templates/KeyMile/login/mainloop/help.j2 | 19 +++ templates/KeyMile/login/mainloop/help_cd.j2 | 9 ++ .../KeyMile/login/mainloop/help_download.j2 | 10 ++ templates/KeyMile/login/mainloop/help_exit.j2 | 9 ++ .../KeyMile/login/mainloop/help_ftpserver.j2 | 11 ++ templates/KeyMile/login/mainloop/help_get.j2 | 9 ++ templates/KeyMile/login/mainloop/help_help.j2 | 28 ++++ templates/KeyMile/login/mainloop/help_ls.j2 | 10 ++ templates/KeyMile/login/mainloop/help_mode.j2 | 14 ++ .../KeyMile/login/mainloop/help_profile.j2 | 14 ++ templates/KeyMile/login/mainloop/help_pwd.j2 | 4 + templates/KeyMile/login/mainloop/help_set.j2 | 12 ++ templates/KeyMile/login/mainloop/help_show.j2 | 13 ++ .../KeyMile/login/mainloop/help_upload.j2 | 10 ++ templates/KeyMile/login/mainloop/ls_body.j2 | 2 + templates/KeyMile/login/mainloop/ls_header.j2 | 23 +++ templates/KeyMile/login/mainloop/on_cycle.j2 | 1 + templates/KeyMile/login/mainloop/on_enter.j2 | 2 + templates/KeyMile/login/mainloop/on_error.j2 | 2 + templates/KeyMile/login/mainloop/on_exit.j2 | 0 templates/KeyMile/login/on_cycle.j2 | 0 templates/KeyMile/login/on_enter.j2 | 1 + templates/KeyMile/login/on_exit.j2 | 0 templates/KeyMile/login/password.j2 | 2 + templates/KeyMile/on_cycle.j2 | 1 + templates/KeyMile/on_enter.j2 | 0 templates/KeyMile/on_exit.j2 | 2 + vendors/KeyMile/__init__.py | 0 vendors/KeyMile/baseCommandProcessor.py | 18 +++ vendors/KeyMile/changeDirectoryProcessor.py | 20 +++ vendors/KeyMile/main.py | 66 +++++++++ vendors/KeyMile/rootCommandProcessor.py | 74 ++++++++++ 39 files changed, 612 insertions(+), 28 deletions(-) create mode 100644 bootup/conf/bootstraps/create-keymile-MG2200.sh create mode 100644 nesi/keymile/keymile_resources/keymile_card.py create mode 100644 nesi/keymile/keymile_resources/keymile_subrack.py create mode 100644 templates/KeyMile/login/mainloop/help.j2 create mode 100644 templates/KeyMile/login/mainloop/help_cd.j2 create mode 100644 templates/KeyMile/login/mainloop/help_download.j2 create mode 100644 templates/KeyMile/login/mainloop/help_exit.j2 create mode 100644 templates/KeyMile/login/mainloop/help_ftpserver.j2 create mode 100644 templates/KeyMile/login/mainloop/help_get.j2 create mode 100644 templates/KeyMile/login/mainloop/help_help.j2 create mode 100644 templates/KeyMile/login/mainloop/help_ls.j2 create mode 100644 templates/KeyMile/login/mainloop/help_mode.j2 create mode 100644 templates/KeyMile/login/mainloop/help_profile.j2 create mode 100644 templates/KeyMile/login/mainloop/help_pwd.j2 create mode 100644 templates/KeyMile/login/mainloop/help_set.j2 create mode 100644 templates/KeyMile/login/mainloop/help_show.j2 create mode 100644 templates/KeyMile/login/mainloop/help_upload.j2 create mode 100644 templates/KeyMile/login/mainloop/ls_body.j2 create mode 100644 templates/KeyMile/login/mainloop/ls_header.j2 create mode 100644 templates/KeyMile/login/mainloop/on_cycle.j2 create mode 100644 templates/KeyMile/login/mainloop/on_enter.j2 create mode 100644 templates/KeyMile/login/mainloop/on_error.j2 create mode 100644 templates/KeyMile/login/mainloop/on_exit.j2 create mode 100644 templates/KeyMile/login/on_cycle.j2 create mode 100644 templates/KeyMile/login/on_enter.j2 create mode 100644 templates/KeyMile/login/on_exit.j2 create mode 100644 templates/KeyMile/login/password.j2 create mode 100644 templates/KeyMile/on_cycle.j2 create mode 100644 templates/KeyMile/on_enter.j2 create mode 100644 templates/KeyMile/on_exit.j2 create mode 100644 vendors/KeyMile/__init__.py create mode 100644 vendors/KeyMile/baseCommandProcessor.py create mode 100644 vendors/KeyMile/changeDirectoryProcessor.py create mode 100644 vendors/KeyMile/main.py create mode 100644 vendors/KeyMile/rootCommandProcessor.py diff --git a/bootup/conf/bootstraps/create-keymile-MG2200.sh b/bootup/conf/bootstraps/create-keymile-MG2200.sh new file mode 100644 index 0000000..89263b1 --- /dev/null +++ b/bootup/conf/bootstraps/create-keymile-MG2200.sh @@ -0,0 +1,135 @@ +#!/bin/bash +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst +# +# Example NESi REST API server bootstrapping +# +ENDPOINT=http://localhost:5000/nesi/v1 + +path="`dirname \"$0\"`" + +. $path/functions.sh + +# Create a network device (admin operation) +req='{ + "vendor": "KeyMile", + "model": "MG2200", + "version": "1", + "description": "Example Switch", + "hostname": "KeyMileMG2200", + "mgmt_address": "10.0.0.12", + "software_version": "MG2200V800R016C00", + "network_protocol": "telnet", + "network_address": "127.0.0.1", + "network_port": 9023, + "uuid": "2200" +}' + +box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 + +# Admin credentials +req='{ + "username": "admin", + "password": "secret" +}' + +root_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +### Subrack 0 ### + +# Create a physical subrack at the network device (admin operation) +req='{ + "name": "", + "description": "Pseudo Subrack" +}' + +subrack_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks) + +### Unit-1 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "xdsl" +}' + +unit_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-2 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "xdsl" +}' + +unit_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-3 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "xdsl" +}' + +unit_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-2 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "xdsl" +}' + +unit_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-5 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "vdsl" +}' + +unit_5=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-6 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "vdsl" +}' + +unit_6=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-7 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "vdsl" +}' + +unit_7=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-8 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "vdsl" +}' + +unit_8=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) \ No newline at end of file diff --git a/bootup/restapi.sh b/bootup/restapi.sh index 6c7d600..d14d657 100755 --- a/bootup/restapi.sh +++ b/bootup/restapi.sh @@ -179,8 +179,9 @@ bash bootup/conf/bootstraps/create-vendors-and-models.sh if [ $recreate_db = "yes" ]; then #bash bootup/conf/bootstraps/create-box-port-vlan.sh - bash bootup/conf/bootstraps/create-alcatel-7360.sh - bash bootup/conf/bootstraps/create-huawei-5623.sh + #bash bootup/conf/bootstraps/create-alcatel-7360.sh + #bash bootup/conf/bootstraps/create-huawei-5623.sh + bash bootup/conf/bootstraps/create-keymile-MG2200.sh fi if [ $alcatel_api = "yes" ]; then @@ -190,7 +191,7 @@ if [ $huawei_api = "yes" ]; then bash bootup/conf/bootstraps/create-huawei-5623.sh fi if [ $keymile_api = "yes" ]; then - bash bootup/conf/bootstraps/create-alcatel-7360.sh #work_in_progress + bash bootup/conf/bootstraps/create-keymile-MG2200.sh #work_in_progress fi if [ $edgecore_api = "yes" ]; then bash bootup/conf/bootstraps/create-alcatel-7360.sh #work_in_progress diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 710f68c..295f363 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -9,10 +9,9 @@ # - Alexander Dincher # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.keymile.keymile_resources import * +from nesi.keymile.keymile_resources import keymile_card from nesi.softbox.base_resources import credentials -from nesi.softbox.base_resources import route from nesi.softbox.base_resources.box import * LOG = logging.getLogger(__name__) @@ -26,6 +25,20 @@ class KeyMileBox(Box): """ # Define Keymile Properties + @property + def credentials(self): + """Return `CredentialsCollection` object.""" + return credentials.CredentialsCollection( + self._conn, base.get_sub_resource_path_by( + self, 'credentials')) + + @property + def cards(self): + """Return `CredentialsCollection` object.""" + return keymile_card.KeyMileCardCollection( + self._conn, base.get_sub_resource_path_by( + self, 'cards')) + class KeyMileBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/keymile/keymile_resources/keymile_card.py b/nesi/keymile/keymile_resources/keymile_card.py new file mode 100644 index 0000000..3870bc6 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_card.py @@ -0,0 +1,27 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.card import CardCollection, Card, logging, base + +LOG = logging.getLogger(__name__) + + +class KeyMileCard(Card): + """Represent physical shelf resource.""" + + +class KeyMileCardCollection(CardCollection): + """Represent a collection of cards.""" + + @property + def _resource_type(self): + return KeyMileCard \ No newline at end of file diff --git a/nesi/keymile/keymile_resources/keymile_subrack.py b/nesi/keymile/keymile_resources/keymile_subrack.py new file mode 100644 index 0000000..b228dc6 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_subrack.py @@ -0,0 +1,27 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.subrack import Subrack, SubrackCollection, logging, base + +LOG = logging.getLogger(__name__) + + +class KeyMileSubrack(Subrack): + """Represent physical shelf resource.""" + + +class KeyMileSubrackCollection(SubrackCollection): + """Represent a collection of subracks.""" + + @property + def _resource_type(self): + return KeyMileSubrack \ No newline at end of file diff --git a/nesi/softbox/api/views/card_views.py b/nesi/softbox/api/views/card_views.py index 5ebe026..c063e89 100644 --- a/nesi/softbox/api/views/card_views.py +++ b/nesi/softbox/api/views/card_views.py @@ -42,49 +42,40 @@ def show_card(box_id, id): def new_card(box_id): req = flask.request.json + vendor = '' if 'name' not in req or req['name'] == "": subrack = json.loads(show_component(Subrack, box_id, req['subrack_id']).data.decode('utf-8')) box = json.loads(show_box(box_id)[0].data.decode('utf-8')) + vendor = box['vendor'] if len(subrack['cards']) > 0: last_card = subrack['cards'][len(subrack['cards']) - 1] - if last_card['name'].startswith('nt-'): + if last_card['name'].startswith('nt-') and vendor == 'Alcatel': if subrack['name'] != "": - if box['vendor'] == 'Huawei': - req['name'] = subrack['name'] + "/0" - else: - req['name'] = subrack['name'] + "/1" + req['name'] = subrack['name'] + "/1" else: - if box['vendor'] == 'Huawei': - req['name'] = "0" - else: - req['name'] = "1" + req['name'] = "1" else: - p = re.compile('[0-9]+/([0-9]+(/)?([0-9]+)?)') - last_card_index = '' - check = p.match(last_card['name']).groups(1) - if len(check[0]) <= 2 and not check[0].endswith('/'): - last_card_index = check[0] - elif len(check[0]) > 2: - _, last_card_index = check[0].split('/', maxsplit=1) - else: - return flask.Response(status=400) + p = re.compile('^([0-9]+)?/?([0-9]+)?/?([0-9]+)?$') + match_groups = p.match(last_card['name']).groups() + filtered_match_groups = [x for x in match_groups if x is not None] # filter out None values + last_card_index = filtered_match_groups[len(filtered_match_groups) - 1] if subrack['name'] != "": req['name'] = subrack['name'] + "/" + str(int(last_card_index) + 1) else: req['name'] = str(int(last_card_index) + 1) else: if subrack['name'] != "": - if box['vendor'] == 'Huawei': + if vendor == 'Huawei': req['name'] = subrack['name'] + "/0" else: req['name'] = subrack['name'] + "/1" else: - if box['vendor'] == 'Huawei': + if vendor == 'Huawei': req['name'] = "0" else: req['name'] = "1" - if 'position' not in req or req['position'] == "": + if 'position' not in req or req['position'] == "" and vendor == 'Alcatel': req['position'] = 'lt:' + req['name'] response = new_component(CardSchema(), Card, req, box_id) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index c69e2d6..f1a1f42 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -64,6 +64,7 @@ def __init__(self, model, input_stream, output_stream, history, self.line_buffer = [] self.history_enabled = True self.hide_input = False + self.star_input = False self.history_pos = 0 self.history = history self.prompt_end_pos = self.get_prompt_len() - 1 @@ -209,7 +210,10 @@ def getline(self, tmp_boundary=None): break if not self.hide_input: - self.updateline(line) + out = line + if self.star_input: + out = len(line) * '*' + self.updateline(out) if line != '\r' and line != '' and self.history_enabled: self.history += (line.replace('\r', '').rstrip(),) @@ -382,7 +386,7 @@ def get_prompt_len(self): def set_prompt_end_pos(self, context): text = self._render('on_cycle', context=context, ignore_errors=True) - if len(text) == 0: + if text is None or len(text) == 0: text = self._render('on_enter', context=context, ignore_errors=True) self.prompt_end_pos = len(text.replace('\n', '')) - 1 diff --git a/templates/KeyMile/login/mainloop/help.j2 b/templates/KeyMile/login/mainloop/help.j2 new file mode 100644 index 0000000..7e32ef8 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help.j2 @@ -0,0 +1,19 @@ + +commands +-------- + +cd -- Change to specified node address and/or MF +pwd -- Show current address +ls -- Show infos for current address +show -- Show settings +mode -- Configure operation modes +ftpserver -- Configure the (s)ftp-server settings +upload -- Upload a file (filename) from the NE into the (s)ftp server (serverpath) +download -- Download a file (serverpath/filename) from the (s)ftp server into the NE +get -- Get property values from the node +set -- Define property values and send them to the node +profile -- profile utility +help -- Show CLI operation help +exit -- Exit CLI session + + diff --git a/templates/KeyMile/login/mainloop/help_cd.j2 b/templates/KeyMile/login/mainloop/help_cd.j2 new file mode 100644 index 0000000..fd008c8 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_cd.j2 @@ -0,0 +1,9 @@ + +Syntax: + cd
+ +Change to specified node address and/or MF + + address -- node address and/or MF (i.e. /unit-11/main) + + diff --git a/templates/KeyMile/login/mainloop/help_download.j2 b/templates/KeyMile/login/mainloop/help_download.j2 new file mode 100644 index 0000000..d649a27 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_download.j2 @@ -0,0 +1,10 @@ + +Syntax: + download
+ +Download a file (serverpath/filename) from the (s)ftp server into the NE + + address MO address -- MO address of a file node + remoteFile characters -- Filepath and -name on file server + + diff --git a/templates/KeyMile/login/mainloop/help_exit.j2 b/templates/KeyMile/login/mainloop/help_exit.j2 new file mode 100644 index 0000000..719f4cc --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_exit.j2 @@ -0,0 +1,9 @@ + +Syntax: + exit [-s] + +Exit CLI session + + -s -- Save configuration on exit + + diff --git a/templates/KeyMile/login/mainloop/help_ftpserver.j2 b/templates/KeyMile/login/mainloop/help_ftpserver.j2 new file mode 100644 index 0000000..e24ebb7 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_ftpserver.j2 @@ -0,0 +1,11 @@ + +Syntax: + ftpserver + +Configure the (s)ftp-server settings + + ipAddress IP address -- IP address of the server + user characters -- User to logon the server + password characters -- Password to logon the server + + diff --git a/templates/KeyMile/login/mainloop/help_get.j2 b/templates/KeyMile/login/mainloop/help_get.j2 new file mode 100644 index 0000000..629d1ad --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_get.j2 @@ -0,0 +1,9 @@ + +Syntax: + get + +Get property values from the node + + property -- MO Address of a property + + diff --git a/templates/KeyMile/login/mainloop/help_help.j2 b/templates/KeyMile/login/mainloop/help_help.j2 new file mode 100644 index 0000000..0219d12 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_help.j2 @@ -0,0 +1,28 @@ + +Syntax: + help [] + +Display a description for global commands or for the optionally specified operation + + operation -- any valid command or property operation + +Notation syntax: + - Parameters enclosed in square brackets [ ] are optional + - Parameter values enclosed in angle brackets < > must be specified by the user + - Predefined selections are enclosed in parantheses ( ) and separated by a vertical bar | + - Elements in tables are enclosed in curly brackets { } and separated by a semicolon ; + +MO address syntax: + - An absolute address notation always begins with the slash '/' + - The addition of a MF after the MO address is optional + + [(. | ..)]/[/(main | cfgm | fm | pm | status)] + + / forward-slash -- substitute for the AP root and separator for multiple address elements + MO-address -- The MO address consists of one or several node IDs, separated with a slash + (main | cfgm | fm | pm | status) keywords for MFs -- The management function may be appended to the MO-address + ./ dot forward-slash -- substitute for the current location in the AP tree + ../ dot dot forward-slash -- one step upwards in the AP tree + + + diff --git a/templates/KeyMile/login/mainloop/help_ls.j2 b/templates/KeyMile/login/mainloop/help_ls.j2 new file mode 100644 index 0000000..6f452c1 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_ls.j2 @@ -0,0 +1,10 @@ + +Syntax: + ls [
] [-e] + +Show infos for current address + + address -- node address and/or MF (i.e. /unit-11/main) + -e -- Extends infos about children + + diff --git a/templates/KeyMile/login/mainloop/help_mode.j2 b/templates/KeyMile/login/mainloop/help_mode.j2 new file mode 100644 index 0000000..245edc4 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_mode.j2 @@ -0,0 +1,14 @@ + +mode commands +------------- + +display -- Configure display operation mode +etx -- Configure ETX mode (cli output termination) +prompt -- Configure prompt mode +syntaxversion -- Configure CLI syntax version for script compatibility +warnings -- Configure warnings mode (warnings on/off in plain display mode) + +Syntax: + mode + + diff --git a/templates/KeyMile/login/mainloop/help_profile.j2 b/templates/KeyMile/login/mainloop/help_profile.j2 new file mode 100644 index 0000000..b72b7f9 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_profile.j2 @@ -0,0 +1,14 @@ + +profile commands +---------------- + +create -- create a profile +list -- list profiles +showDefaults -- show default values of a profile type +showTypes -- show available profile types +showValues -- show values of a profile + +Syntax: + profile + + diff --git a/templates/KeyMile/login/mainloop/help_pwd.j2 b/templates/KeyMile/login/mainloop/help_pwd.j2 new file mode 100644 index 0000000..4073496 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_pwd.j2 @@ -0,0 +1,4 @@ + +Show current address + + diff --git a/templates/KeyMile/login/mainloop/help_set.j2 b/templates/KeyMile/login/mainloop/help_set.j2 new file mode 100644 index 0000000..bf73063 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_set.j2 @@ -0,0 +1,12 @@ + +Syntax: + set ... + +Define property values and send them to the node + + property characters + attr1 characters + attr2 characters + ... + + diff --git a/templates/KeyMile/login/mainloop/help_show.j2 b/templates/KeyMile/login/mainloop/help_show.j2 new file mode 100644 index 0000000..d22768f --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_show.j2 @@ -0,0 +1,13 @@ + +show commands +------------- + +mode -- Show current modes +version -- Show CLI version +ftpserver -- Show (S)FTP server settings +sessionIf -- Show CLI sessionIf + +Syntax: + show + + diff --git a/templates/KeyMile/login/mainloop/help_upload.j2 b/templates/KeyMile/login/mainloop/help_upload.j2 new file mode 100644 index 0000000..2f04846 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_upload.j2 @@ -0,0 +1,10 @@ + +Syntax: + upload
+ +Upload a file (filename) from the NE into the (s)ftp server (serverpath) + + address MO address -- MO address of a file node + remoteFile characters -- Filepath and -name on file server + + diff --git a/templates/KeyMile/login/mainloop/ls_body.j2 b/templates/KeyMile/login/mainloop/ls_body.j2 new file mode 100644 index 0000000..75c88ef --- /dev/null +++ b/templates/KeyMile/login/mainloop/ls_body.j2 @@ -0,0 +1,2 @@ + unit-{{ context.card.name }} + diff --git a/templates/KeyMile/login/mainloop/ls_header.j2 b/templates/KeyMile/login/mainloop/ls_header.j2 new file mode 100644 index 0000000..6080a9f --- /dev/null +++ b/templates/KeyMile/login/mainloop/ls_header.j2 @@ -0,0 +1,23 @@ +Infos of AP: / + Name : MileGate 2200 + Main Mode : + Equipment State : Ok + Alarm Severity : Cleared + Propagated Alarm Severity : Major + User Label : + Service Label : + Description : + +MF List: + main + cfgm + fm + status + +AP List: + eoam + fan + multicast + services + tdmConnections + diff --git a/templates/KeyMile/login/mainloop/on_cycle.j2 b/templates/KeyMile/login/mainloop/on_cycle.j2 new file mode 100644 index 0000000..050587e --- /dev/null +++ b/templates/KeyMile/login/mainloop/on_cycle.j2 @@ -0,0 +1 @@ +/> diff --git a/templates/KeyMile/login/mainloop/on_enter.j2 b/templates/KeyMile/login/mainloop/on_enter.j2 new file mode 100644 index 0000000..84f6b7f --- /dev/null +++ b/templates/KeyMile/login/mainloop/on_enter.j2 @@ -0,0 +1,2 @@ +---===### CLI Release R2A20, Build 2014-01-31 ###===--- + diff --git a/templates/KeyMile/login/mainloop/on_error.j2 b/templates/KeyMile/login/mainloop/on_error.j2 new file mode 100644 index 0000000..c36472c --- /dev/null +++ b/templates/KeyMile/login/mainloop/on_error.j2 @@ -0,0 +1,2 @@ +error: invalid management function + diff --git a/templates/KeyMile/login/mainloop/on_exit.j2 b/templates/KeyMile/login/mainloop/on_exit.j2 new file mode 100644 index 0000000..e69de29 diff --git a/templates/KeyMile/login/on_cycle.j2 b/templates/KeyMile/login/on_cycle.j2 new file mode 100644 index 0000000..e69de29 diff --git a/templates/KeyMile/login/on_enter.j2 b/templates/KeyMile/login/on_enter.j2 new file mode 100644 index 0000000..fb31150 --- /dev/null +++ b/templates/KeyMile/login/on_enter.j2 @@ -0,0 +1 @@ +password: diff --git a/templates/KeyMile/login/on_exit.j2 b/templates/KeyMile/login/on_exit.j2 new file mode 100644 index 0000000..e69de29 diff --git a/templates/KeyMile/login/password.j2 b/templates/KeyMile/login/password.j2 new file mode 100644 index 0000000..5d94c41 --- /dev/null +++ b/templates/KeyMile/login/password.j2 @@ -0,0 +1,2 @@ +Login failure: Unknown userclass + diff --git a/templates/KeyMile/on_cycle.j2 b/templates/KeyMile/on_cycle.j2 new file mode 100644 index 0000000..2a6191f --- /dev/null +++ b/templates/KeyMile/on_cycle.j2 @@ -0,0 +1 @@ +login as: diff --git a/templates/KeyMile/on_enter.j2 b/templates/KeyMile/on_enter.j2 new file mode 100644 index 0000000..e69de29 diff --git a/templates/KeyMile/on_exit.j2 b/templates/KeyMile/on_exit.j2 new file mode 100644 index 0000000..989d95b --- /dev/null +++ b/templates/KeyMile/on_exit.j2 @@ -0,0 +1,2 @@ +SESSION CLOSED + diff --git a/vendors/KeyMile/__init__.py b/vendors/KeyMile/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py new file mode 100644 index 0000000..6edfcdd --- /dev/null +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -0,0 +1,18 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from nesi.softbox.cli import base + + +class BaseCommandProcessor(base.CommandProcessor): + """Create CLI REPR loop for example switch.""" diff --git a/vendors/KeyMile/changeDirectoryProcessor.py b/vendors/KeyMile/changeDirectoryProcessor.py new file mode 100644 index 0000000..19abce5 --- /dev/null +++ b/vendors/KeyMile/changeDirectoryProcessor.py @@ -0,0 +1,20 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import re +from nesi import exceptions + + +class ChangeDirectoryProcessor: + + def do_cd(self, command, *args, context=None): + pass \ No newline at end of file diff --git a/vendors/KeyMile/main.py b/vendors/KeyMile/main.py new file mode 100644 index 0000000..b3dcf3f --- /dev/null +++ b/vendors/KeyMile/main.py @@ -0,0 +1,66 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.cli import base +from nesi import exceptions +from vendors.KeyMile.rootCommandProcessor import RootCommandProcessor + + +class ReadInputCommandProcessor(base.CommandProcessor): + """Create CLI REPR loop for example switch.""" + + VENDOR = 'KeyMile' + MODEL = 'MG2200' + VERSION = '1' + + +class PreLoginCommandProcessor(ReadInputCommandProcessor): + + def on_unknown_command(self, command, *args, context=None): + subprocessor = self._create_subprocessor( + LoginCommandProcessor, 'login') + + context['username'] = context['raw_line'].replace('\r', '').replace('\n', '') + + try: + subprocessor.history_enabled = False + subprocessor.star_input = True + subprocessor.loop(context=context) + except exceptions.TerminalExitError as exc: + if exc.return_to is not None and exc.return_to != 'sysexit': + raise exc + else: + self.on_exit(context) + raise exc + + +class LoginCommandProcessor(ReadInputCommandProcessor): + + def on_unknown_command(self, command, *args, context=None): + username = context.pop('username') + password = command + + for creds in self._model.credentials: + if creds.username == username and creds.password == password: + break + + else: + text = self._render('password', context=context) + self._write(text) + raise exceptions.TerminalExitError() + + subprocessor = self._create_subprocessor( + RootCommandProcessor, 'login', 'mainloop') + + subprocessor.loop(context=context) + + self.on_exit(context) diff --git a/vendors/KeyMile/rootCommandProcessor.py b/vendors/KeyMile/rootCommandProcessor.py new file mode 100644 index 0000000..71c0edf --- /dev/null +++ b/vendors/KeyMile/rootCommandProcessor.py @@ -0,0 +1,74 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from .baseCommandProcessor import BaseCommandProcessor +from .changeDirectoryProcessor import ChangeDirectoryProcessor + + +class RootCommandProcessor(BaseCommandProcessor, ChangeDirectoryProcessor): + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) + + def do_help(self, command, *args, context=None): + if self._validate(args, str): + help_arg, = self._dissect(args, str) + + if help_arg == 'cd': + self._write(self._render('help_cd', context=context)) + elif help_arg == 'pwd': + self._write(self._render('help_pwd', context=context)) + elif help_arg == 'ls': + self._write(self._render('help_ls', context=context)) + elif help_arg == 'show': + self._write(self._render('help_show', context=context)) + elif help_arg == 'mode': + self._write(self._render('help_mode', context=context)) + elif help_arg == 'ftpserver': + self._write(self._render('help_ftpserver', context=context)) + elif help_arg == 'upload': + self._write(self._render('help_upload', context=context)) + elif help_arg == 'download': + self._write(self._render('help_download', context=context)) + elif help_arg == 'get': + self._write(self._render('help_get', context=context)) + elif help_arg == 'set': + self._write(self._render('help_set', context=context)) + elif help_arg == 'profile': + self._write(self._render('help_profile', context=context)) + elif help_arg == 'help': + self._write(self._render('help_help', context=context)) + elif help_arg == 'exit': + self._write(self._render('help_exit', context=context)) + else: + raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args,): + self._write(self._render('help', context=context)) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_exit(self, command, *args, context=None): + exc = exceptions.TerminalExitError() + exc.return_to = 'sysexit' + raise exc + + def do_ls(self, command, *args, context=None): + if self._validate(args,): + text = self._render('ls_header', context=context) + + for card in self._model.cards: + text += self._render('ls_body', context=dict(context, card=card)) + + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file From 5a874542ddf4e37ed6fc3384d2eb1e5326ccb870 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 1 Oct 2020 10:09:20 +0200 Subject: [PATCH 074/318] Initial push for cd and ls commands --- .../conf/bootstraps/create-keymile-MG2200.sh | 74 ++++- nesi/exceptions.py | 23 ++ .../keymile/api/__init__.py | 0 .../keymile/api/schemas/__init__.py | 0 .../api/schemas/keymile_box_schemas.py | 27 ++ .../api/schemas/keymile_channel_schemas.py | 11 +- .../api/schemas/keymile_port_schemas.py | 21 ++ nesi/keymile/keymile_resources/__init__.py | 2 +- nesi/keymile/keymile_resources/keymile_box.py | 67 ++++- .../keymile_resources/keymile_channel.py | 34 +++ .../keymile_resources/keymile_interface.py | 34 +++ .../keymile/keymile_resources/keymile_port.py | 27 ++ nesi/softbox/api/models/box_models.py | 3 + nesi/softbox/api/models/channel_models.py | 23 ++ nesi/softbox/api/models/interface_models.py | 22 ++ nesi/softbox/api/models/port_models.py | 6 + nesi/softbox/api/schemas/box_schemas.py | 12 +- nesi/softbox/api/schemas/channel_schemas.py | 52 ++++ nesi/softbox/api/schemas/interface_schemas.py | 49 ++++ nesi/softbox/api/schemas/port_schemas.py | 8 +- nesi/softbox/api/views/__init__.py | 2 +- nesi/softbox/api/views/channel_views.py | 59 ++++ nesi/softbox/api/views/interface_views.py | 65 +++++ nesi/softbox/cli/base.py | 20 +- .../execution_errors/invalid_address_error.j2 | 2 + .../invalid_management_function_error.j2} | 0 .../login/{mainloop => base/help}/help.j2 | 0 .../login/{mainloop => base/help}/help_cd.j2 | 0 .../{mainloop => base/help}/help_download.j2 | 0 .../{mainloop => base/help}/help_exit.j2 | 0 .../{mainloop => base/help}/help_ftpserver.j2 | 0 .../login/{mainloop => base/help}/help_get.j2 | 0 .../{mainloop => base/help}/help_help.j2 | 0 .../login/{mainloop => base/help}/help_ls.j2 | 0 .../{mainloop => base/help}/help_mode.j2 | 0 .../{mainloop => base/help}/help_profile.j2 | 0 .../login/{mainloop => base/help}/help_pwd.j2 | 0 .../login/{mainloop => base/help}/help_set.j2 | 0 .../{mainloop => base/help}/help_show.j2 | 0 .../{mainloop => base/help}/help_upload.j2 | 0 .../on_enter.j2 => base/login_message.j2} | 0 templates/KeyMile/login/base/ls/ls_ap_list.j2 | 3 + .../login/{mainloop => base/ls}/ls_header.j2 | 15 +- .../KeyMile/login/base/ls/ls_list_body.j2 | 2 + templates/KeyMile/login/base/ls/ls_mf_body.j2 | 2 + .../KeyMile/login/base/ls/ls_mf_header.j2 | 2 + templates/KeyMile/login/base/ls/ls_mf_list.j2 | 3 + templates/KeyMile/login/base/on_cycle.j2 | 1 + templates/KeyMile/login/base/on_error.j2 | 2 + templates/KeyMile/login/base/pwd.j2 | 2 + .../login/base/syntax_errors/syntax_error.j2 | 2 + templates/KeyMile/login/mainloop/ls_body.j2 | 2 - templates/KeyMile/login/mainloop/on_cycle.j2 | 1 - templates/KeyMile/login/on_exit.j2 | 0 templates/KeyMile/on_enter.j2 | 0 .../accessPoints/root/eoamCommandProcessor.py | 29 ++ .../root/fan/fanAlarmCommandProcessor.py | 29 ++ .../root/fan/fanCommandProcessor.py | 29 ++ .../root/multicastCommandProcessor.py | 33 +++ .../accessPoints/root/rootCommandProcessor.py | 80 ++++++ .../root/services/servicesCommandProcessor.py | 29 ++ .../servicesMacAccessCtrlCommandProcessor.py | 31 ++ .../servicesPacketCommandProcessor.py | 25 ++ .../root/tdmConnectionsCommandProcessor.py | 27 ++ .../unit/port/chan/chanCommandProcessor.py | 47 ++++ .../unit/port/chan/vcc/vccCommandProcessor.py | 23 ++ .../interface/interfaceCommandProcessor.py | 34 +++ .../root/unit/port/portCommandProcessor.py | 42 +++ .../root/unit/unitCommandProcessor.py | 44 +++ vendors/KeyMile/baseCommandProcessor.py | 264 ++++++++++++++++++ vendors/KeyMile/main.py | 22 +- vendors/KeyMile/rootCommandProcessor.py | 74 ----- 72 files changed, 1420 insertions(+), 122 deletions(-) rename templates/KeyMile/login/mainloop/on_exit.j2 => nesi/keymile/api/__init__.py (100%) rename templates/KeyMile/login/on_cycle.j2 => nesi/keymile/api/schemas/__init__.py (100%) create mode 100644 nesi/keymile/api/schemas/keymile_box_schemas.py rename vendors/KeyMile/changeDirectoryProcessor.py => nesi/keymile/api/schemas/keymile_channel_schemas.py (66%) create mode 100644 nesi/keymile/api/schemas/keymile_port_schemas.py create mode 100644 nesi/keymile/keymile_resources/keymile_channel.py create mode 100644 nesi/keymile/keymile_resources/keymile_interface.py create mode 100644 nesi/keymile/keymile_resources/keymile_port.py create mode 100644 nesi/softbox/api/models/channel_models.py create mode 100644 nesi/softbox/api/models/interface_models.py create mode 100644 nesi/softbox/api/schemas/channel_schemas.py create mode 100644 nesi/softbox/api/schemas/interface_schemas.py create mode 100644 nesi/softbox/api/views/channel_views.py create mode 100644 nesi/softbox/api/views/interface_views.py create mode 100644 templates/KeyMile/login/base/execution_errors/invalid_address_error.j2 rename templates/KeyMile/login/{mainloop/on_error.j2 => base/execution_errors/invalid_management_function_error.j2} (100%) rename templates/KeyMile/login/{mainloop => base/help}/help.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_cd.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_download.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_exit.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_ftpserver.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_get.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_help.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_ls.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_mode.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_profile.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_pwd.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_set.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_show.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_upload.j2 (100%) rename templates/KeyMile/login/{mainloop/on_enter.j2 => base/login_message.j2} (100%) create mode 100644 templates/KeyMile/login/base/ls/ls_ap_list.j2 rename templates/KeyMile/login/{mainloop => base/ls}/ls_header.j2 (70%) create mode 100644 templates/KeyMile/login/base/ls/ls_list_body.j2 create mode 100644 templates/KeyMile/login/base/ls/ls_mf_body.j2 create mode 100644 templates/KeyMile/login/base/ls/ls_mf_header.j2 create mode 100644 templates/KeyMile/login/base/ls/ls_mf_list.j2 create mode 100644 templates/KeyMile/login/base/on_cycle.j2 create mode 100644 templates/KeyMile/login/base/on_error.j2 create mode 100644 templates/KeyMile/login/base/pwd.j2 create mode 100644 templates/KeyMile/login/base/syntax_errors/syntax_error.j2 delete mode 100644 templates/KeyMile/login/mainloop/ls_body.j2 delete mode 100644 templates/KeyMile/login/mainloop/on_cycle.j2 delete mode 100644 templates/KeyMile/login/on_exit.j2 delete mode 100644 templates/KeyMile/on_enter.j2 create mode 100644 vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/rootCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py delete mode 100644 vendors/KeyMile/rootCommandProcessor.py diff --git a/bootup/conf/bootstraps/create-keymile-MG2200.sh b/bootup/conf/bootstraps/create-keymile-MG2200.sh index 89263b1..7bd564b 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2200.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2200.sh @@ -64,6 +64,36 @@ req='{ unit_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_1', + "admin_state": "1", + "operational_state": "1" +}' + +port_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Chan-1 ### + +# Create a logical channel at the network device (admin operation) +req='{ + "port_id": '$port_1_1', + "description": "Channel #1" +}' + +chan_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/channels) + +### Interface-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "chan_id": '$chan_1_1_1' +}' + +interface_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) + ### Unit-2 ### # Create a physical card at the network device (admin operation) @@ -74,6 +104,28 @@ req='{ unit_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_2', + "admin_state": "1", + "operational_state": "1" +}' + +port_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Port-2 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_2', + "admin_state": "1", + "operational_state": "1" +}' + +port_2_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + ### Unit-3 ### # Create a physical card at the network device (admin operation) @@ -84,7 +136,27 @@ req='{ unit_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) -### Unit-2 ### +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_3', + "admin_state": "1", + "operational_state": "1" +}' + +port_3_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Interface-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "port_id": '$port_3_1' +}' + +interface_3_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) + +### Unit-4 ### # Create a physical card at the network device (admin operation) req='{ diff --git a/nesi/exceptions.py b/nesi/exceptions.py index 4607f66..fd9c50c 100644 --- a/nesi/exceptions.py +++ b/nesi/exceptions.py @@ -76,15 +76,24 @@ class TerminalExitError(SoftboxenError): def __init__(self, **kwargs): super(TerminalExitError, self).__init__(**kwargs) self._return_to = None + self._command = None @property def return_to(self): return self._return_to + @property + def command(self): + return self._command + @return_to.setter def return_to(self, return_to): self._return_to = return_to + @command.setter + def command(self, command): + self._command = command + class TemplateError(SoftboxenError): """Raise on template rendering error.""" @@ -102,6 +111,20 @@ class CommandSyntaxError(SoftboxenError): def __init__(self, **kwargs): super(CommandSyntaxError, self).__init__(**kwargs) self.command = kwargs.get('command') + self.template = None + self.template_scopes = () + + +class CommandExecutionError(SoftboxenError): + """Raise on CLI command execution error.""" + + message = 'Command execution error: %(command)s' + + def __init__(self, **kwargs): + super(CommandExecutionError, self).__init__(**kwargs) + self.command = kwargs.get('command') + self.template = kwargs.get('template') + self.template_scopes = kwargs.get('template_scopes') class RestApiError(SoftboxenError): diff --git a/templates/KeyMile/login/mainloop/on_exit.j2 b/nesi/keymile/api/__init__.py similarity index 100% rename from templates/KeyMile/login/mainloop/on_exit.j2 rename to nesi/keymile/api/__init__.py diff --git a/templates/KeyMile/login/on_cycle.j2 b/nesi/keymile/api/schemas/__init__.py similarity index 100% rename from templates/KeyMile/login/on_cycle.j2 rename to nesi/keymile/api/schemas/__init__.py diff --git a/nesi/keymile/api/schemas/keymile_box_schemas.py b/nesi/keymile/api/schemas/keymile_box_schemas.py new file mode 100644 index 0000000..b4e571e --- /dev/null +++ b/nesi/keymile/api/schemas/keymile_box_schemas.py @@ -0,0 +1,27 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.box_schemas import * + + +class HuaweiBoxSchema(BoxSchema): + class Meta: + model = Box + fields = BoxSchema.Meta.fields + ('channels', 'interfaces') + + interfaces = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_interfaces', box_id='')}}) + + channels = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_channels', box_id='')}}) diff --git a/vendors/KeyMile/changeDirectoryProcessor.py b/nesi/keymile/api/schemas/keymile_channel_schemas.py similarity index 66% rename from vendors/KeyMile/changeDirectoryProcessor.py rename to nesi/keymile/api/schemas/keymile_channel_schemas.py index 19abce5..5d1e101 100644 --- a/vendors/KeyMile/changeDirectoryProcessor.py +++ b/nesi/keymile/api/schemas/keymile_channel_schemas.py @@ -10,11 +10,10 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -import re -from nesi import exceptions +from nesi.softbox.api.schemas.channel_schemas import * -class ChangeDirectoryProcessor: - - def do_cd(self, command, *args, context=None): - pass \ No newline at end of file +class KeyMileChannelSchema(ChannelSchema): + class Meta: + model = Channel + fields = ChannelSchema.Meta.fields + ('vccs', 'interfaces') \ No newline at end of file diff --git a/nesi/keymile/api/schemas/keymile_port_schemas.py b/nesi/keymile/api/schemas/keymile_port_schemas.py new file mode 100644 index 0000000..667b9c6 --- /dev/null +++ b/nesi/keymile/api/schemas/keymile_port_schemas.py @@ -0,0 +1,21 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.port_schemas import * + + +class KeyMilePortSchema(PortSchema): + class Meta: + model = Port + fields = PortSchema.Meta.fields + ('channels',) + + channels = ma.Nested(CpesSchema.CpeSchema, many=True) \ No newline at end of file diff --git a/nesi/keymile/keymile_resources/__init__.py b/nesi/keymile/keymile_resources/__init__.py index a9a2c5b..e6be87c 100644 --- a/nesi/keymile/keymile_resources/__init__.py +++ b/nesi/keymile/keymile_resources/__init__.py @@ -1 +1 @@ -__all__ = [] +__all__ = ["keymile_card", "keymile_port", "keymile_subrack", "keymile_channel", "keymile_interface"] diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 295f363..87586b3 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -10,9 +10,11 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.keymile.keymile_resources import keymile_card -from nesi.softbox.base_resources import credentials -from nesi.softbox.base_resources.box import * +from nesi.keymile.keymile_resources import * + + +from nesi.softbox.base_resources import credentials, base +from nesi.softbox.base_resources.box import BoxCollection, Box, logging LOG = logging.getLogger(__name__) @@ -25,6 +27,18 @@ class KeyMileBox(Box): """ # Define Keymile Properties + @property + def channels(self): + """Return `CpePortCollection` object.""" + return keymile_channel.KeyMileChannelCollection( + self._conn, base.get_sub_resource_path_by(self, 'channels')) + + @property + def interfaces(self): + """Return `CpePortCollection` object.""" + return keymile_interface.KeyMileInterfaceCollection( + self._conn, base.get_sub_resource_path_by(self, 'interfaces')) + @property def credentials(self): """Return `CredentialsCollection` object.""" @@ -39,6 +53,53 @@ def cards(self): self._conn, base.get_sub_resource_path_by( self, 'cards')) + def get_card(self, field, value): + """Get specific card object.""" + return keymile_card.KeyMileCardCollection( + self._conn, base.get_sub_resource_path_by(self, 'cards'), + params={field: value}).find_by_field_value(field, value) + + def get_cards(self, field, value): + """Get all cards.""" + return keymile_card.KeyMileCardCollection( + self._conn, base.get_sub_resource_path_by(self, 'cards'), + params={field: value}) + + def get_port(self, field, value): + """Get specific port object.""" + return keymile_port.KeyMilePortCollection( + self._conn, base.get_sub_resource_path_by(self, 'ports'), + params={field: value}).find_by_field_value(field, value) + + def get_ports(self, field, value): + """Get specific port object.""" + return keymile_port.KeyMilePortCollection( + self._conn, base.get_sub_resource_path_by(self, 'ports'), + params={field: value}) + + def get_chan(self, field, value): + """Get specific channel object.""" + return keymile_channel.KeyMileChannelCollection( + self._conn, base.get_sub_resource_path_by(self, 'channels'), + params={field: value}).find_by_field_value(field, value) + + def get_chans(self, field, value): + return keymile_channel.KeyMileChannelCollection( + self._conn, base.get_sub_resource_path_by(self, 'channels'), + params={field: value}) + + def get_interface(self, field, value): + """Get specific interface object.""" + return keymile_interface.KeyMileInterfaceCollection( + self._conn, base.get_sub_resource_path_by(self, 'interfaces'), + params={field: value}).find_by_field_value(field, value) + + def get_interfaces(self, field, value): + """Get specific interface object.""" + return keymile_interface.KeyMileInterfaceCollection( + self._conn, base.get_sub_resource_path_by(self, 'interfaces'), + params={field: value}) + class KeyMileBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/keymile/keymile_resources/keymile_channel.py b/nesi/keymile/keymile_resources/keymile_channel.py new file mode 100644 index 0000000..18e4a80 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_channel.py @@ -0,0 +1,34 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import logging + +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class KeyMileChannel(base.Resource): + """Represent logical channel resource.""" + + id = base.Field('id') + port_id = base.Field('port_id') + name = base.Field('name') + description = base.Field('description') + + +class KeyMileChannelCollection(base.ResourceCollection): + """Represent a collection of channels.""" + + @property + def _resource_type(self): + return KeyMileChannel diff --git a/nesi/keymile/keymile_resources/keymile_interface.py b/nesi/keymile/keymile_resources/keymile_interface.py new file mode 100644 index 0000000..24c8b82 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_interface.py @@ -0,0 +1,34 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import logging + +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class KeyMileInterface(base.Resource): + """Represent logical interface resource.""" + + id = base.Field('id') + port_id = base.Field('port_id') + name = base.Field('name') + description = base.Field('description') + + +class KeyMileInterfaceCollection(base.ResourceCollection): + """Represent a collection of interfaces.""" + + @property + def _resource_type(self): + return KeyMileInterface diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py new file mode 100644 index 0000000..c84be0b --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -0,0 +1,27 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.port import PortCollection, Port, logging, base + +LOG = logging.getLogger(__name__) + + +class KeyMilePort(Port): + """Represent physical port resource.""" + + +class KeyMilePortCollection(PortCollection): + """Represent a collection of ports.""" + + @property + def _resource_type(self): + return KeyMilePort \ No newline at end of file diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index dcb31d3..f4f7002 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -27,6 +27,7 @@ from .route_models import Route from .emu_models import Emu from .user_models import User +from .channel_models import Channel class Box(db.Model): @@ -56,6 +57,8 @@ class Box(db.Model): subrack_details = db.relationship('Subrack', backref='subracks', lazy='dynamic') cards = db.relationship('Card', backref='Box', lazy='dynamic') ports = db.relationship('Port', backref='Box', lazy='dynamic') + channels = db.relationship('Channel', backref='Box', lazy='dynamic') + interfaces = db.relationship('Interface', backref='Box', lazy='dynamic') cpes = db.relationship('Cpe', backref='Box', lazy='dynamic') cpe_ports = db.relationship('CpePort', backref='Box', lazy='dynamic') onts = db.relationship('Ont', backref='Box', lazy='dynamic') diff --git a/nesi/softbox/api/models/channel_models.py b/nesi/softbox/api/models/channel_models.py new file mode 100644 index 0000000..4837c8f --- /dev/null +++ b/nesi/softbox/api/models/channel_models.py @@ -0,0 +1,23 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import db +from ..models.interface_models import Interface + + +class Channel(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + description = db.Column(db.String()) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + port_id = db.Column(db.Integer, db.ForeignKey('port.id')) + interfaces = db.relationship('Interface', backref='Channel', lazy='dynamic') diff --git a/nesi/softbox/api/models/interface_models.py b/nesi/softbox/api/models/interface_models.py new file mode 100644 index 0000000..38dc722 --- /dev/null +++ b/nesi/softbox/api/models/interface_models.py @@ -0,0 +1,22 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import db + + +class Interface(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + description = db.Column(db.String()) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + chan_id = db.Column(db.Integer, db.ForeignKey('channel.id')) + port_id = db.Column(db.Integer, db.ForeignKey('port.id')) diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index f6d5ab1..17c9bbe 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -14,6 +14,8 @@ from nesi.softbox.api import db from .ont_models import Ont from .cpe_models import Cpe +from .channel_models import Channel +from .interface_models import Interface class Port(db.Model): @@ -305,3 +307,7 @@ class Port(db.Model): vectoring_group = db.Column(db.Integer(), default=None) vectoring_profile_id = db.Column(db.Integer(), default=None) template_name = db.Column(db.String(), default=None) + + # KeyMile + channels = db.relationship('Channel', backref='Port', lazy='dynamic') + interfaces = db.relationship('Interface', backref='Port', lazy='dynamic') diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index af4a27b..fb7d67d 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -30,10 +30,10 @@ class BoxSchema(ma.ModelSchema): class Meta: model = Box fields = ('id', 'vendor', 'model', 'version', 'software_version', 'network_protocol', 'network_address', - 'network_port', 'uuid', 'description', + 'network_port', 'uuid', 'description', 'interfaces', 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', - 'subracks', 'subrack_details', 'cards', 'ports', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', + 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') @@ -61,6 +61,14 @@ class Meta: {'_links': { 'self': ma.URLFor('show_ports', box_id='')}}) + channels = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_channels', box_id='')}}) + + interfaces = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_interfaces', box_id='')}}) + service_ports = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_service_ports', box_id='')}}) diff --git a/nesi/softbox/api/schemas/channel_schemas.py b/nesi/softbox/api/schemas/channel_schemas.py new file mode 100644 index 0000000..d496e3a --- /dev/null +++ b/nesi/softbox/api/schemas/channel_schemas.py @@ -0,0 +1,52 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.channel_models import Channel +from ..schemas.interface_schemas import InterfacesSchema + + +class ChannelSchema(ma.ModelSchema): + class Meta: + model = Channel + fields = ('id', 'box_id', 'box', 'port_id', 'interfaces', + 'name', 'description', '_links') + + interfaces = ma.Nested(InterfacesSchema.InterfaceSchema, many=True) + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_channel', box_id='', id='')}) + + +class ChannelsSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class ChannelSchema(ma.ModelSchema): + class Meta: + model = Channel + fields = ('id', 'name', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_channel', box_id='', id='')}) + + members = ma.Nested(ChannelSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_channels', box_id='')}) + + diff --git a/nesi/softbox/api/schemas/interface_schemas.py b/nesi/softbox/api/schemas/interface_schemas.py new file mode 100644 index 0000000..a98b4a5 --- /dev/null +++ b/nesi/softbox/api/schemas/interface_schemas.py @@ -0,0 +1,49 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.interface_models import Interface + + +class InterfaceSchema(ma.ModelSchema): + class Meta: + model = Interface + fields = ('id', 'box_id', 'box', 'chan_id', 'port_id', + 'name', 'description', '_links') + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_interface', box_id='', id='')}) + + +class InterfacesSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class InterfaceSchema(ma.ModelSchema): + class Meta: + model = Interface + fields = ('id', 'name', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_interface', box_id='', id='')}) + + members = ma.Nested(InterfaceSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_interfaces', box_id='')}) + + diff --git a/nesi/softbox/api/schemas/port_schemas.py b/nesi/softbox/api/schemas/port_schemas.py index b2cced5..83679f3 100644 --- a/nesi/softbox/api/schemas/port_schemas.py +++ b/nesi/softbox/api/schemas/port_schemas.py @@ -14,18 +14,24 @@ from ..models.port_models import Port from ..schemas.cpe_schemas import CpesSchema from ..schemas.ont_schemas import OntsSchema +from ..schemas.channel_schemas import ChannelsSchema +from ..schemas.interface_schemas import InterfacesSchema class PortSchema(ma.ModelSchema): class Meta: model = Port - fields = ('id', 'box_id', 'box', 'card_id', 'cpes', 'onts', 'loopback', 'name', + fields = ('id', 'box_id', 'box', 'card_id', 'cpes', 'onts', 'channels', 'loopback', 'name', 'interfaces', 'description', 'admin_state', 'operational_state', '_links') cpes = ma.Nested(CpesSchema.CpeSchema, many=True) onts = ma.Nested(OntsSchema.OntSchema, many=True) + channels = ma.Nested(ChannelsSchema.ChannelSchema, many=True) + + interfaces = ma.Nested(InterfacesSchema.InterfaceSchema, many=True) + box = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_box', id='')}}) diff --git a/nesi/softbox/api/views/__init__.py b/nesi/softbox/api/views/__init__.py index c37245d..cf9f0df 100644 --- a/nesi/softbox/api/views/__init__.py +++ b/nesi/softbox/api/views/__init__.py @@ -1,4 +1,4 @@ __all__ = ["box_views", "credential_views", "route_views", "subrack_views", "card_views", "port_views", "ont_views", "ontport_views", "cpe_views", "cpeport_views", "vlan_views", "portprofile_views", "emu_views", "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", - "qos_interface_views", "vlan_interface_views", "user_views"] + "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views"] diff --git a/nesi/softbox/api/views/channel_views.py b/nesi/softbox/api/views/channel_views.py new file mode 100644 index 0000000..ca37c4d --- /dev/null +++ b/nesi/softbox/api/views/channel_views.py @@ -0,0 +1,59 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from ..models.port_models import Port +from ..schemas.channel_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//channels', methods=['GET']) +def show_channels(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(ChannelsSchema(), Channel, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//channels/', methods=['GET']) +def show_channel(box_id, id): + response = show_component(Channel, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//channels', methods=['POST']) +def new_channel(box_id): + req = flask.request.json + + if 'name' not in req or req['name'] == "": + if 'port_id' in req: + port = json.loads(show_component(Port, box_id, req['port_id']).data.decode('utf-8')) + req['name'] = port['name'] + "/" + str(len(port['channels']) + 1) + response = new_component(ChannelSchema(), Channel, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//channels/', methods=['PUT']) +def update_channel(box_id, id): + req = flask.request.json + update_component(Channel, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//channels/', methods=['DELETE']) +def del_channel(box_id, id): + del_component(Channel, box_id, id) + return flask.Response(status=204) diff --git a/nesi/softbox/api/views/interface_views.py b/nesi/softbox/api/views/interface_views.py new file mode 100644 index 0000000..9987f5a --- /dev/null +++ b/nesi/softbox/api/views/interface_views.py @@ -0,0 +1,65 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from ..models.port_models import Port +from ..models.channel_models import Channel +from ..schemas.interface_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//interfaces', methods=['GET']) +def show_interfaces(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(InterfacesSchema(), Interface, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//interfaces/', methods=['GET']) +def show_interface(box_id, id): + response = show_component(Interface, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//interfaces', methods=['POST']) +def new_interface(box_id): + req = flask.request.json + + if 'name' not in req or req['name'] == "": + if 'port_id' in req: + port = json.loads(show_component(Port, box_id, req['port_id']).data.decode('utf-8')) + req['name'] = port['name'] + "/" + str(len(port['interfaces']) + 1) + elif 'chan_id' in req: + channel = json.loads(show_component(Channel, box_id, req['chan_id']).data.decode('utf-8')) + req['name'] = channel['name'] + "/" + str(len(channel['interfaces']) + 1) + else: + raise exceptions.Forbidden('can not have port and channel as parent') + response = new_component(InterfaceSchema(), Interface, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//interfaces/', methods=['PUT']) +def update_interface(box_id, id): + req = flask.request.json + update_component(Interface, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//interfaces/', methods=['DELETE']) +def del_interface(box_id, id): + del_component(Interface, box_id, id) + return flask.Response(status=204) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index f1a1f42..0efe85a 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -350,9 +350,9 @@ def loop(self, context=None, return_to=None, command=None): try: self.process_command(line, context) - except exceptions.CommandSyntaxError as exc: - self.line_buffer = [] # manually clear buffer in case of exception - self.on_error(dict(context, command=exc.command)) + except (exceptions.CommandExecutionError, exceptions.CommandSyntaxError) as exc: + self.line_buffer = [] + self.write_error_message(context, exc.template, *exc.template_scopes) except exceptions.TerminalExitError as exc: self.line_buffer = [] # manually clear buffer in case of exception @@ -364,12 +364,19 @@ def loop(self, context=None, return_to=None, command=None): # set prompt_len anew in case of prompt_len change in command-processor beneath self.set_prompt_end_pos(context) + if exc.command is not None: + command = exc.command + continue + # This is the first instance of the desired # CommandProcessor to unwind to, continuing self.on_cycle(context) self.on_exit(context) + def _terminate(self, command=None): + del self + def get_prompt_len(self): text = self._render('on_cycle', context=dict(), ignore_errors=True) @@ -411,6 +418,13 @@ def on_error(self, context): if text is not None: self._write(text) + def write_error_message(self, context, template, *scopes): + if template is None: + template = 'on_error' + text = self._render(template, context=context, *scopes, ignore_errors=True) + if text is not None: + self._write(text) + @property def comment(self): return '!' diff --git a/templates/KeyMile/login/base/execution_errors/invalid_address_error.j2 b/templates/KeyMile/login/base/execution_errors/invalid_address_error.j2 new file mode 100644 index 0000000..e9423d2 --- /dev/null +++ b/templates/KeyMile/login/base/execution_errors/invalid_address_error.j2 @@ -0,0 +1,2 @@ +error: invalid address + diff --git a/templates/KeyMile/login/mainloop/on_error.j2 b/templates/KeyMile/login/base/execution_errors/invalid_management_function_error.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/on_error.j2 rename to templates/KeyMile/login/base/execution_errors/invalid_management_function_error.j2 diff --git a/templates/KeyMile/login/mainloop/help.j2 b/templates/KeyMile/login/base/help/help.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help.j2 rename to templates/KeyMile/login/base/help/help.j2 diff --git a/templates/KeyMile/login/mainloop/help_cd.j2 b/templates/KeyMile/login/base/help/help_cd.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_cd.j2 rename to templates/KeyMile/login/base/help/help_cd.j2 diff --git a/templates/KeyMile/login/mainloop/help_download.j2 b/templates/KeyMile/login/base/help/help_download.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_download.j2 rename to templates/KeyMile/login/base/help/help_download.j2 diff --git a/templates/KeyMile/login/mainloop/help_exit.j2 b/templates/KeyMile/login/base/help/help_exit.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_exit.j2 rename to templates/KeyMile/login/base/help/help_exit.j2 diff --git a/templates/KeyMile/login/mainloop/help_ftpserver.j2 b/templates/KeyMile/login/base/help/help_ftpserver.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_ftpserver.j2 rename to templates/KeyMile/login/base/help/help_ftpserver.j2 diff --git a/templates/KeyMile/login/mainloop/help_get.j2 b/templates/KeyMile/login/base/help/help_get.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_get.j2 rename to templates/KeyMile/login/base/help/help_get.j2 diff --git a/templates/KeyMile/login/mainloop/help_help.j2 b/templates/KeyMile/login/base/help/help_help.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_help.j2 rename to templates/KeyMile/login/base/help/help_help.j2 diff --git a/templates/KeyMile/login/mainloop/help_ls.j2 b/templates/KeyMile/login/base/help/help_ls.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_ls.j2 rename to templates/KeyMile/login/base/help/help_ls.j2 diff --git a/templates/KeyMile/login/mainloop/help_mode.j2 b/templates/KeyMile/login/base/help/help_mode.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_mode.j2 rename to templates/KeyMile/login/base/help/help_mode.j2 diff --git a/templates/KeyMile/login/mainloop/help_profile.j2 b/templates/KeyMile/login/base/help/help_profile.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_profile.j2 rename to templates/KeyMile/login/base/help/help_profile.j2 diff --git a/templates/KeyMile/login/mainloop/help_pwd.j2 b/templates/KeyMile/login/base/help/help_pwd.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_pwd.j2 rename to templates/KeyMile/login/base/help/help_pwd.j2 diff --git a/templates/KeyMile/login/mainloop/help_set.j2 b/templates/KeyMile/login/base/help/help_set.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_set.j2 rename to templates/KeyMile/login/base/help/help_set.j2 diff --git a/templates/KeyMile/login/mainloop/help_show.j2 b/templates/KeyMile/login/base/help/help_show.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_show.j2 rename to templates/KeyMile/login/base/help/help_show.j2 diff --git a/templates/KeyMile/login/mainloop/help_upload.j2 b/templates/KeyMile/login/base/help/help_upload.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_upload.j2 rename to templates/KeyMile/login/base/help/help_upload.j2 diff --git a/templates/KeyMile/login/mainloop/on_enter.j2 b/templates/KeyMile/login/base/login_message.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/on_enter.j2 rename to templates/KeyMile/login/base/login_message.j2 diff --git a/templates/KeyMile/login/base/ls/ls_ap_list.j2 b/templates/KeyMile/login/base/ls/ls_ap_list.j2 new file mode 100644 index 0000000..c514d30 --- /dev/null +++ b/templates/KeyMile/login/base/ls/ls_ap_list.j2 @@ -0,0 +1,3 @@ + +AP List: + diff --git a/templates/KeyMile/login/mainloop/ls_header.j2 b/templates/KeyMile/login/base/ls/ls_header.j2 similarity index 70% rename from templates/KeyMile/login/mainloop/ls_header.j2 rename to templates/KeyMile/login/base/ls/ls_header.j2 index 6080a9f..e0a8150 100644 --- a/templates/KeyMile/login/mainloop/ls_header.j2 +++ b/templates/KeyMile/login/base/ls/ls_header.j2 @@ -1,4 +1,4 @@ -Infos of AP: / +Infos of AP: {{ context.path }} Name : MileGate 2200 Main Mode : Equipment State : Ok @@ -8,16 +8,3 @@ Infos of AP: / Service Label : Description : -MF List: - main - cfgm - fm - status - -AP List: - eoam - fan - multicast - services - tdmConnections - diff --git a/templates/KeyMile/login/base/ls/ls_list_body.j2 b/templates/KeyMile/login/base/ls/ls_list_body.j2 new file mode 100644 index 0000000..325772f --- /dev/null +++ b/templates/KeyMile/login/base/ls/ls_list_body.j2 @@ -0,0 +1,2 @@ + {{ context.list_entry }} + diff --git a/templates/KeyMile/login/base/ls/ls_mf_body.j2 b/templates/KeyMile/login/base/ls/ls_mf_body.j2 new file mode 100644 index 0000000..4cbc7f7 --- /dev/null +++ b/templates/KeyMile/login/base/ls/ls_mf_body.j2 @@ -0,0 +1,2 @@ +{{ context.prop_type }}: {{ context.prop_name }} {{ context.prop_rw_rights }} + diff --git a/templates/KeyMile/login/base/ls/ls_mf_header.j2 b/templates/KeyMile/login/base/ls/ls_mf_header.j2 new file mode 100644 index 0000000..f245922 --- /dev/null +++ b/templates/KeyMile/login/base/ls/ls_mf_header.j2 @@ -0,0 +1,2 @@ +{{ context.mf_layer }} + diff --git a/templates/KeyMile/login/base/ls/ls_mf_list.j2 b/templates/KeyMile/login/base/ls/ls_mf_list.j2 new file mode 100644 index 0000000..e7c6651 --- /dev/null +++ b/templates/KeyMile/login/base/ls/ls_mf_list.j2 @@ -0,0 +1,3 @@ + +MF List: + diff --git a/templates/KeyMile/login/base/on_cycle.j2 b/templates/KeyMile/login/base/on_cycle.j2 new file mode 100644 index 0000000..aa3921f --- /dev/null +++ b/templates/KeyMile/login/base/on_cycle.j2 @@ -0,0 +1 @@ +{{ context.path }}> diff --git a/templates/KeyMile/login/base/on_error.j2 b/templates/KeyMile/login/base/on_error.j2 new file mode 100644 index 0000000..c36472c --- /dev/null +++ b/templates/KeyMile/login/base/on_error.j2 @@ -0,0 +1,2 @@ +error: invalid management function + diff --git a/templates/KeyMile/login/base/pwd.j2 b/templates/KeyMile/login/base/pwd.j2 new file mode 100644 index 0000000..b598ab2 --- /dev/null +++ b/templates/KeyMile/login/base/pwd.j2 @@ -0,0 +1,2 @@ +{{ context.path }}{{ context.spacer }}\ # current directory + diff --git a/templates/KeyMile/login/base/syntax_errors/syntax_error.j2 b/templates/KeyMile/login/base/syntax_errors/syntax_error.j2 new file mode 100644 index 0000000..314c72f --- /dev/null +++ b/templates/KeyMile/login/base/syntax_errors/syntax_error.j2 @@ -0,0 +1,2 @@ +error: syntax error + diff --git a/templates/KeyMile/login/mainloop/ls_body.j2 b/templates/KeyMile/login/mainloop/ls_body.j2 deleted file mode 100644 index 75c88ef..0000000 --- a/templates/KeyMile/login/mainloop/ls_body.j2 +++ /dev/null @@ -1,2 +0,0 @@ - unit-{{ context.card.name }} - diff --git a/templates/KeyMile/login/mainloop/on_cycle.j2 b/templates/KeyMile/login/mainloop/on_cycle.j2 deleted file mode 100644 index 050587e..0000000 --- a/templates/KeyMile/login/mainloop/on_cycle.j2 +++ /dev/null @@ -1 +0,0 @@ -/> diff --git a/templates/KeyMile/login/on_exit.j2 b/templates/KeyMile/login/on_exit.j2 deleted file mode 100644 index e69de29..0000000 diff --git a/templates/KeyMile/on_enter.j2 b/templates/KeyMile/on_enter.j2 deleted file mode 100644 index e69de29..0000000 diff --git a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py new file mode 100644 index 0000000..e7cb30f --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py @@ -0,0 +1,29 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class EoamCommandProcessor(BaseCommandProcessor): + __name__ = 'eoam' + management_functions = ('main', 'cfgm', 'status') + access_points = () + + main = {} + + cfgm = {} + + status = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py new file mode 100644 index 0000000..08cd8e3 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py @@ -0,0 +1,29 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class FanAlarmCommandProcessor(BaseCommandProcessor): + __name__ = 'fanAlarm' + management_functions = ('main', 'cfgm', 'fm') + access_points = () + + main = {} + + cfgm = {} + + fm = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py new file mode 100644 index 0000000..240ecdc --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py @@ -0,0 +1,29 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class FanCommandProcessor(BaseCommandProcessor): + __name__ = 'fan' + management_functions = ('main', 'cfgm', 'fm') + access_points = () + + main = {} + + cfgm = {} + + fm = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py new file mode 100644 index 0000000..c88ccd2 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py @@ -0,0 +1,33 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class MulticastCommandProcessor(BaseCommandProcessor): + __name__ = 'multicast' + management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') + access_points = () + + main = {} + + cfgm = {} + + fm = {} + + pm = {} + + status = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py new file mode 100644 index 0000000..838df63 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -0,0 +1,80 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class RootCommandProcessor(BaseCommandProcessor): + __name__ = 'root' + management_functions = {'main', 'cfgm', 'fm', 'status'} + access_points = ('eoam', 'fan', 'multicast', 'services', 'tdmConnections') + + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + }, + 'Logbooks': { + 'Cmd': ( + 'GetAllLogbooks', + 'GetAlarmLogbook', + 'GetEventLogbook', + 'GetConfigLogbook', + 'GetEquipmentLogbook', + 'GetSessionLogbook' + ) + }, + 'NESoftwareDownload': { + 'Cmd': ( + 'StartEsw', + ) + } + } + + cfgm = {} + + fm = {} + + status = { + 'DateAndTime': { + 'Time': { + 'Cmd': ( + 'SetDateAndTime', + ), + 'Prop': { + 'Summary': 'r-' + } + }, + 'SNTPClient': { + 'Prop': { + 'PrimaryServerState': 'r-' + } + } + } + } + + def _init_access_points(self, context=None): + for card in self._model.cards: + if 'unit-' + card.name in self.access_points: + continue + self.access_points += ('unit-' + card.name,) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py new file mode 100644 index 0000000..b758126 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -0,0 +1,29 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class ServicesCommandProcessor(BaseCommandProcessor): + __name__ = 'services' + management_functions = ('main', 'fm', 'status') + access_points = () + + main = {} + + fm = {} + + status = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py new file mode 100644 index 0000000..2d84a49 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py @@ -0,0 +1,31 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class ServicesMacAccessCtrlCommandProcessor(BaseCommandProcessor): + __name__ = 'servicesMacAccessCtrl' + management_functions = ('main', 'cfgm', 'fm', 'status') + access_points = () + + main = {} + + cfgm = {} + + fm = {} + + status = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py new file mode 100644 index 0000000..af77c82 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py @@ -0,0 +1,25 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class ServicesPacketCommandProcessor(BaseCommandProcessor): + __name__ = 'servicesPacket' + management_functions = ('main',) + access_points = ('1to1DoubleTag', '1to1SingeTag', 'mcast', 'nto1', 'pls', 'tls') + + main = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py new file mode 100644 index 0000000..7992aa8 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py @@ -0,0 +1,27 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class TdmConnectionsCommandProcessor(BaseCommandProcessor): + __name__ = 'tdmConnections' + management_functions = ('main', 'cfgm') + access_points = () + + main = {} + + cfgm = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py new file mode 100644 index 0000000..9e891c3 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -0,0 +1,47 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class ChanCommandProcessor(BaseCommandProcessor): + __name__ = 'chan' + management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') + access_points = () + + main = {} + + cfgm = {} + + fm = {} + + pm = {} + + status = {} + + def _init_access_points(self, context=None): + chan = self._model.get_chan('name', context['unit'] + '/' + context['port'] + '/' + context['chan']) + card = self._model.get_card('name', context['unit']) + + for interface in self._model.get_interfaces('chan_id', chan.id): + if card.product != 'adsl': + ap_name = 'interface-' + else: + ap_name = 'vcc-' + identifier = ap_name + interface.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py new file mode 100644 index 0000000..17666ca --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py @@ -0,0 +1,23 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class VccCommandProcessor(BaseCommandProcessor): + __name__ = 'port' + management_functions = ('main', 'cfgm', 'pm', 'status') + access_points = () + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py new file mode 100644 index 0000000..0d3ad9d --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -0,0 +1,34 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class InterfaceCommandProcessor(BaseCommandProcessor): + __name__ = 'interface' + management_functions = ('main', 'cfgm', 'pm', 'status') + access_points = () + + main = {} + + cfgm = {} + + pm = {} + + status = {} + + def _init_access_points(self, context=None): + pass + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py new file mode 100644 index 0000000..d267ae8 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -0,0 +1,42 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class PortCommandProcessor(BaseCommandProcessor): + __name__ = 'port' + management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') + access_points = () + + main = {} + + cfgm = {} + + fm = {} + + pm = {} + + status = {} + + def _init_access_points(self, context=None): + port = self._model.get_port('name', context['unit'] + '/' + context['port']) + + for chan in self._model.get_chans('port_id', port.id): + identifier = 'chan-' + chan.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py new file mode 100644 index 0000000..5c2dfd7 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -0,0 +1,44 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class UnitCommandProcessor(BaseCommandProcessor): + __name__ = 'unit' + management_functions = ('main', 'cfgm', 'fm', 'status') + access_points = () #'internalPorts', only on certain cards + + main = {} + + cfgm = {} + + fm = {} + + status = {} + + def _init_access_points(self, context=None): + card = self._model.get_card('name', context['unit']) + + #if card.type == ?: + # self.access_points += ('internalPorts',) + # + + for port in self._model.get_ports('card_id', card.id): + identifier = 'port-' + port.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 6edfcdd..7e51d77 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -12,7 +12,271 @@ from nesi import exceptions from nesi.softbox.cli import base +import re class BaseCommandProcessor(base.CommandProcessor): """Create CLI REPR loop for example switch.""" + + management_functions = () + access_points = () + + def create_spacers(self, positions, args): + spacers = [] + previous_pos = 0 + i = 0 + for position in positions: + spacer = position - (previous_pos + len(str(args[i]))) + spacers.append(spacer) + previous_pos = position + i += 1 + + return spacers + + def do_help(self, command, *args, context=None): + help_scopes = ('login', 'base', 'help') + if self._validate(args, str): + help_arg, = self._dissect(args, str) + + if help_arg == 'cd': + self._write(self._render('help_cd', *help_scopes, context=context)) + elif help_arg == 'pwd': + self._write(self._render('help_pwd', *help_scopes, context=context)) + elif help_arg == 'ls': + self._write(self._render('help_ls', *help_scopes, context=context)) + elif help_arg == 'show': + self._write(self._render('help_show', *help_scopes, context=context)) + elif help_arg == 'mode': + self._write(self._render('help_mode', *help_scopes, context=context)) + elif help_arg == 'ftpserver': + self._write(self._render('help_ftpserver', *help_scopes, context=context)) + elif help_arg == 'upload': + self._write(self._render('help_upload', *help_scopes, context=context)) + elif help_arg == 'download': + self._write(self._render('help_download', *help_scopes, context=context)) + elif help_arg == 'get': + self._write(self._render('help_get', *help_scopes, context=context)) + elif help_arg == 'set': + self._write(self._render('help_set', *help_scopes, context=context)) + elif help_arg == 'profile': + self._write(self._render('help_profile', *help_scopes, context=context)) + elif help_arg == 'help': + self._write(self._render('help_help', *help_scopes, context=context)) + elif help_arg == 'exit': + self._write(self._render('help_exit', *help_scopes, context=context)) + else: + raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args,): + self._write(self._render('help', *help_scopes, context=context)) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_pwd(self, command, *args, context=None): + context['spacer'] = self.create_spacers((67,), (context['path'],))[0] * ' ' + self._write(self._render('pwd', 'login', 'base', context=context)) + + def do_cd(self, command, *args, context=None): + if args[0] == '/': + context['path'] = '/' + from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor + exc = exceptions.TerminalExitError + exc.return_to = RootCommandProcessor + + raise exc + + components = [x for x in args[0].split('/') if x] + + if not re.search( + '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', + components[0]): + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + + if args[0] == '.': + return # dot does nothing + + if args[0].startswith('./'): + if args[0] == './': + return + + self.do_cd(command, args[0][2:], context=context) + return + + if re.search('\.\./(?:[^.]+/)+\.\.', args[0]): + if args[0].endswith('..'): + raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + else: + raise exceptions.CommandExecutionError(template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + + if args[0].startswith('..'): + splitted_path = [x for x in context['path'].split('/') if x] + exit_component = None + if len(splitted_path) != 0: + exit_component = splitted_path.pop() + context['path'] = '/' + '/'.join(splitted_path) + + if exit_component in ('main', 'cfgm', 'fm', 'pm', 'status'): + self.set_prompt_end_pos(context=context) + if args[0] != '..': + self.do_cd('cd', args[0][3:], context=context) + return + + if args[0] == '..': + raise exceptions.TerminalExitError() + + exc = exceptions.TerminalExitError() + exc.command = 'cd ' + args[0][3:] + raise exc + + if args[0].startswith('/'): + if 'unit-' not in components[0] and components[0] not in ('eoam', 'fan', 'multicast', 'services', 'tdmConnection', 'main', 'cfgm', 'fm', 'pm', 'status'): + raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + + context['path'] = '/' + + if self.__name__ != 'root': + exc = exceptions.TerminalExitError() + from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor + exc.return_to = RootCommandProcessor + exc.command = 'cd ' + args[0].lstrip('/') + raise exc + + self.do_cd('cd', args[0].lstrip('/'), context=context) + else: + remaining_args = '/'.join(components[1:]) + + component_type = None + component_number = None + if '-' in components[0]: + component_type = components[0].split('-')[0] + component_number = components[0].split('-')[1] + command_processor = component_type.capitalize() + 'CommandProcessor' + else: + command_processor = self.__name__.capitalize() + components[0].capitalize() + 'CommandProcessor' + + if component_type == 'unit': + if self.__name__ != 'root': + raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + + context['unit'] = component_number + elif component_type == 'port': + if self.__name__ != 'unit': + raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + + context['port'] = component_number + elif component_type == 'chan': + if self.__name__ != 'port': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + context['chan'] = component_number + elif component_type == 'interface': + if self.__name__ != 'port' and self.__name__ != 'chan': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + context['chan'] = component_number + + if components[0] in ('main', 'cfgm', 'fm', 'pm', 'status'): + if re.search('(main|cfgm|fm|pm|status)', context['path']): + return + if context['path'] == '/': + new_path = components[0] + else: + new_path = '/' + components[0] + context['path'] += new_path + self.set_prompt_end_pos(context=context) + return + + from vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor import UnitCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.chan.chanCommandProcessor import ChanCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor import InterfaceCommandProcessor + subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') + + if len(remaining_args) > 0: + command = 'cd ' + remaining_args + else: + command = None + + if context['path'] == '/': + new_path = components[0] + else: + new_path = '/' + components[0] + + context['path'] += new_path + subprocessor.loop(context=context, return_to=self.__class__, command=command) + + def do_exit(self, command, *args, context=None): + exc = exceptions.TerminalExitError() + exc.return_to = 'sysexit' + raise exc + + def do_ls(self, command, *args, context=None): + if self._validate(args,): + scopes = ('login', 'base', 'ls') + if re.search('(pm|fm|status|main|cfgm)', context['path']): + mf_type = context['path'].split('/')[-1] + + mf_layers = None + if mf_type == 'status': + mf_layers = self.status + elif mf_type == 'cfgm': + mf_layers = self.cfgm + elif mf_type == 'fm': + mf_layers = self.fm + elif mf_type == 'pm': + mf_layers = self.pm + elif mf_type == 'main': + mf_layers = self.main + + def generate_ls_text(layers, depth): + text = '' + for layer in layers: + if layer not in ('Cmd', 'Prop', 'File'): + context['mf_layer'] = depth * ' ' + layer + text += self._render('ls_mf_header', *scopes, context=context) + depth += 1 + text += generate_ls_text(layers[layer], depth) + depth -= 1 + else: + if layer == 'Cmd': + prop_type = layer + ' ' + else: + prop_type = layer + + context['prop_type'] = depth * ' ' + prop_type + + for property in layers[layer]: + context['prop_name'] = property + + if prop_type in ('File', 'Prop'): + context['prop_rw_rights'] = layers[layer].get(property, '') + else: + context['prop_rw_rights'] = '' + text += self._render('ls_mf_body', *scopes, context=context) + return text + + text = generate_ls_text(mf_layers, 0) + self._write(text) + + else: + text = self._render('ls_header', *scopes, context=context) + + text += self._render('ls_mf_list', *scopes, context=context) + for management_function in self.management_functions: + context['list_entry'] = management_function + text += self._render('ls_list_body', *scopes, context=context) + + text += self._render('ls_ap_list', *scopes, context=context) + + self._init_access_points(context=context) + + for access_point in self.access_points: + context['list_entry'] = access_point + text += self._render('ls_list_body', *scopes, context=context) + + self._write(text) + else: + raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=command) + + def _init_access_points(self, context=None): + raise exceptions.SoftboxenError(message='Abstract method not implemented.') diff --git a/vendors/KeyMile/main.py b/vendors/KeyMile/main.py index b3dcf3f..21561dc 100644 --- a/vendors/KeyMile/main.py +++ b/vendors/KeyMile/main.py @@ -11,19 +11,11 @@ # License: https://github.com/inexio/NESi/LICENSE.rst from nesi.softbox.cli import base +from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor from nesi import exceptions -from vendors.KeyMile.rootCommandProcessor import RootCommandProcessor -class ReadInputCommandProcessor(base.CommandProcessor): - """Create CLI REPR loop for example switch.""" - - VENDOR = 'KeyMile' - MODEL = 'MG2200' - VERSION = '1' - - -class PreLoginCommandProcessor(ReadInputCommandProcessor): +class PreLoginCommandProcessor(base.CommandProcessor): def on_unknown_command(self, command, *args, context=None): subprocessor = self._create_subprocessor( @@ -43,7 +35,7 @@ def on_unknown_command(self, command, *args, context=None): raise exc -class LoginCommandProcessor(ReadInputCommandProcessor): +class LoginCommandProcessor(base.CommandProcessor): def on_unknown_command(self, command, *args, context=None): username = context.pop('username') @@ -59,8 +51,12 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.TerminalExitError() subprocessor = self._create_subprocessor( - RootCommandProcessor, 'login', 'mainloop') + RootCommandProcessor, 'login', 'base') + + context['path'] = '/' + + self._write(self._render('login_message', 'login', 'base', context=context)) - subprocessor.loop(context=context) + subprocessor.loop(context=context, return_to=RootCommandProcessor) self.on_exit(context) diff --git a/vendors/KeyMile/rootCommandProcessor.py b/vendors/KeyMile/rootCommandProcessor.py deleted file mode 100644 index 71c0edf..0000000 --- a/vendors/KeyMile/rootCommandProcessor.py +++ /dev/null @@ -1,74 +0,0 @@ -# This file is part of the NESi software. -# -# Copyright (c) 2020 -# Original Software Design by Ilya Etingof . -# -# Software adapted by inexio . -# - Janis Groß -# - Philip Konrath -# - Alexander Dincher -# -# License: https://github.com/inexio/NESi/LICENSE.rst - -from nesi import exceptions -from .baseCommandProcessor import BaseCommandProcessor -from .changeDirectoryProcessor import ChangeDirectoryProcessor - - -class RootCommandProcessor(BaseCommandProcessor, ChangeDirectoryProcessor): - - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - - def do_help(self, command, *args, context=None): - if self._validate(args, str): - help_arg, = self._dissect(args, str) - - if help_arg == 'cd': - self._write(self._render('help_cd', context=context)) - elif help_arg == 'pwd': - self._write(self._render('help_pwd', context=context)) - elif help_arg == 'ls': - self._write(self._render('help_ls', context=context)) - elif help_arg == 'show': - self._write(self._render('help_show', context=context)) - elif help_arg == 'mode': - self._write(self._render('help_mode', context=context)) - elif help_arg == 'ftpserver': - self._write(self._render('help_ftpserver', context=context)) - elif help_arg == 'upload': - self._write(self._render('help_upload', context=context)) - elif help_arg == 'download': - self._write(self._render('help_download', context=context)) - elif help_arg == 'get': - self._write(self._render('help_get', context=context)) - elif help_arg == 'set': - self._write(self._render('help_set', context=context)) - elif help_arg == 'profile': - self._write(self._render('help_profile', context=context)) - elif help_arg == 'help': - self._write(self._render('help_help', context=context)) - elif help_arg == 'exit': - self._write(self._render('help_exit', context=context)) - else: - raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args,): - self._write(self._render('help', context=context)) - else: - raise exceptions.CommandSyntaxError(command=command) - - def do_exit(self, command, *args, context=None): - exc = exceptions.TerminalExitError() - exc.return_to = 'sysexit' - raise exc - - def do_ls(self, command, *args, context=None): - if self._validate(args,): - text = self._render('ls_header', context=context) - - for card in self._model.cards: - text += self._render('ls_body', context=dict(context, card=card)) - - self._write(text) - else: - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file From 66a47ca05b0f86e571fcc61564534cb4c3bd3d8d Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 2 Oct 2020 09:38:37 +0200 Subject: [PATCH 075/318] Added management function jsons --- .../accessPoints/root/eoamCommandProcessor.py | 53 ++- .../root/fan/fanAlarmCommandProcessor.py | 33 +- .../root/fan/fanCommandProcessor.py | 43 ++- .../root/multicastCommandProcessor.py | 162 ++++++++- .../root/services/servicesCommandProcessor.py | 31 +- .../servicesMacAccessCtrlCommandProcessor.py | 62 +++- .../servicesPacketCommandProcessor.py | 9 +- .../root/tdmConnectionsCommandProcessor.py | 34 +- .../unit/port/chan/chanCommandProcessor.py | 101 +++++- .../unit/port/chan/vcc/vccCommandProcessor.py | 105 ++++++ .../interface/interfaceCommandProcessor.py | 105 +++++- .../root/unit/port/portCommandProcessor.py | 335 +++++++++++++++++- 12 files changed, 1035 insertions(+), 38 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py index e7cb30f..0f9d2f1 100644 --- a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py @@ -19,11 +19,58 @@ class EoamCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'status') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'DefaultMdLevel': { + 'Prop': { + 'DefaultMdSettings': 'rw' + } + }, + 'ContextMap': { + 'Prop': { + 'Mapping': 'rw' + } + }, + 'Aggregation': { + 'Prop': { + 'Role': 'rw', + 'Address': 'rw' + } + }, + 'Md': { + 'Cmd': ( + 'CreateMd', + 'DeleteMd' + ) + } + } - status = {} + status = { + 'DefaultMdMips': { + 'Prop': { + 'Mips': 'r-' + } + }, + 'ConfigurationErrors': { + 'Prop': { + 'InterfacesInError': 'r-' + } + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py index 08cd8e3..78cb692 100644 --- a/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py @@ -19,11 +19,38 @@ class FanAlarmCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'General': { + 'Prop': { + 'Polarity': 'rw' + } + } + } - fm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py index 240ecdc..3e10c68 100644 --- a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py @@ -19,11 +19,48 @@ class FanCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'Equipment': { + 'Prop': { + 'CurrentStatus': 'r-' + } + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'General': { + 'Prop': { + 'Option': 'rw' + } + } + } - fm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py index c88ccd2..8ec0162 100644 --- a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py @@ -19,15 +19,167 @@ class MulticastCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'Multicast': { + 'General': { + 'Prop': { + 'SnoopingMode': 'rw', + 'LocalIPAddressForIGMPGeneration': 'rw', + 'IPSourceAddressOfQueries': 'rw', + 'portGroupInactivityTimeout': 'rw' + }, + 'Cmd': ( + 'CreateVlan', + 'DeleteVlan' + ) + }, + 'PreJoin': { + 'Prop': { + 'preJoinIntervalPeriod': 'rw' + } + }, + 'PostLeave': { + 'Prop': { + 'postLeaveDelayPeriod': 'rw' + } + }, + 'Preview': { + 'Prop': { + 'previewSettings': 'rw' + } + }, + 'Bandwidth': { + 'Prop': { + 'defaultBandwidthPerStream': 'rw' + } + }, + 'Alarms': { + 'Prop': { + 'configuredMulticastStreamsThreshold': 'rw' + } - fm = {} + } + } + } - pm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } - status = {} + pm = { + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + }, + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + } + } + + status = { + 'multicast': { + 'activeStreams': { + 'Dynamic': { + 'Prop': { + 'activeMulticastStreams': 'r-', + 'NumberOfActiveStreams': 'r-' + }, + 'Cmd': ( + 'clearAllStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticMulticastStreams': 'r-', + 'NumberOfStaticStreams': 'r-' + } + }, + }, + + 'unitConfiguration': { + 'Prop': { + 'multicastUnitConfigurationStatus': 'r-' + } + }, + 'portSummary': { + 'Prop': { + 'CoreUnitFrontPorts': 'r-', + 'CapableServiceUnits': 'r-' + } + }, + 'Router': { + 'Prop': { + 'learnedIpRouterSourceAddress': 'r-' + } + + } + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py index b758126..dcede08 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -19,11 +19,36 @@ class ServicesCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'fm', 'status') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } - fm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } - status = {} + status = { + 'Prop': { + 'conflictList': 'r-' + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py index 2d84a49..aea38f2 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py @@ -19,13 +19,67 @@ class ServicesMacAccessCtrlCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'status') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'General': { + 'Prop': { + 'Blacklist': 'rw' + } + } + } - fm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + }, + 'DuplicatedMac': { + 'Prop': { + 'DuplicatedMacAccessList': 'r-' + }, + 'Cmd': ( + 'FlushMacAccessDuplicatedList', + ) + } + } - status = {} + status = { + 'DynamicList': { + 'Prop': { + 'DynamicList': 'r-' + }, + 'Cmd': ( + 'FlushMacAccessDynamicList', + 'DeleteMacAccessDynamicListEntry' + ) + }, + 'UNIBlacklist': { + 'Prop': { + 'Blacklist': 'r-', + 'BNGlist': 'r-' + }, + 'Cmd': ( + 'DeleteMacAccessBNGlistEntry', + ) + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py index af77c82..e2bf785 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py @@ -19,7 +19,14 @@ class ServicesPacketCommandProcessor(BaseCommandProcessor): management_functions = ('main',) access_points = ('1to1DoubleTag', '1to1SingeTag', 'mcast', 'nto1', 'pls', 'tls') - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py index 7992aa8..905a06a 100644 --- a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py @@ -19,9 +19,39 @@ class TdmConnectionsCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'Connections': { + 'Cmd': ( + 'CreateConnection', + 'CreateBulkConnection', + 'CreateAdvancedConnection', + 'DeleteConnection', + 'DeleteMultipleConnections', + 'ShowConnections', + 'SetLabel1', + 'SetLabel2' + ) + }, + 'Ctps': { + 'Cmd': ( + 'ShowCtps', + ) + }, + 'Pbus': { + 'Prop': { + 'PbusUsage': 'r-' + } + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 9e891c3..e0d8ea3 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -19,15 +19,106 @@ class ChanCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'Profile': { + 'Prop': { + 'ChanProfile': 'rw' + } + }, + 'subinterface': { + 'Cmd': ( + 'CreateInterface', + 'DeleteInterface' + ) + } + } - fm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } - pm = {} + pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } + } - status = {} + status = { + 'General': { + 'Prop': { + 'Status': 'r-' + } + } + } def _init_access_points(self, context=None): chan = self._model.get_chan('name', context['unit'] + '/' + context['port'] + '/' + context['chan']) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py index 17666ca..8873005 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py @@ -19,5 +19,110 @@ class VccCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'pm', 'status') access_points = () + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } + + cfgm = { + 'Traceability': { + 'Prop': { + 'AutomaticAgentCircuitId': 'rw', + 'AgentCircuitId': 'rw' + } + }, + 'Filter': { + 'Prop': { + 'MACSourceFilteringMode': 'rw', + 'MacAccessWhitelist': 'rw', + 'NumberOfMacForFloodingPrev': 'rw', + 'L2CPFilter': 'rw', + 'DestMacBlacklistProfile': 'rw', + 'SrcMacBlacklist': 'rw' + } + }, + 'IfRateLimiter': { + 'Prop': { + 'IfRateLimiting': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'configuredProfiles': 'rw' + } + } + } + + pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } + } + + status = { + 'ServiceInfo': { + 'Prop': { + 'ServiceStatus': 'r-' + } + }, + 'UserConnection': { + 'Prop': { + 'CurrentPppConnectionState': 'r-' + } + } + } + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index 0d3ad9d..1e53469 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -19,13 +19,110 @@ class InterfaceCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'pm', 'status') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'Traceability': { + 'Prop': { + 'AutomaticAgentCircuitId': 'rw', + 'AgentCircuitId': 'rw' + } + }, + 'Filter': { + 'Prop': { + 'MACSourceFilteringMode': 'rw', + 'MacAccessWhitelist': 'rw', + 'NumberOfMacForFloodingPrev': 'rw', + 'L2CPFilter': 'rw', + 'DestMacBlacklistProfile': 'rw', + 'SrcMacBlacklist': 'rw' + } + }, + 'IfRateLimiter': { + 'Prop': { + 'IfRateLimiting': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'configuredProfiles': 'rw' + } + } + } - pm = {} + pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } + } - status = {} + status = { + 'ServiceInfo': { + 'Prop': { + 'ServiceStatus': 'r-' + } + }, + 'UserConnection': { + 'Prop': { + 'CurrentPppConnectionState': 'r-' + } + } + } def _init_access_points(self, context=None): pass diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index d267ae8..54ee05d 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -19,15 +19,340 @@ class PortCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'Multicast': { + 'Prop': { + 'MaxNumberOfMulticastStreams': 'rw', + 'EnableIgmpClassifier': 'rw', + 'AllowStaticStreams': 'rw', + 'EnableFastLeave': 'rw', + 'GroupManagement': 'rw', + 'Bandwidth': 'rw' + }, + 'Cmd': ( + 'GetGroupList', + ) + }, + 'Traceability': { + 'Prop': { + 'AgentRemoteId': 'rw' + } + }, + 'Security': { + 'Prop': { + 'ServiceOptions': 'rw', + 'MaxNumberOfMac': 'rw' + } + }, + 'AccessControl': { + 'Prop': { + 'ClassificationKey': 'rw', + 'MAT': 'rw' + } + }, + 'RateLimiter': { + 'Prop': { + 'RateLimiting': 'rw', + 'RateLimitingCoS': 'rw' + } + }, + 'Qos': { + 'Prop': { + 'WfqProfile': 'rw' + } + }, + 'Wire': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'PortProfiles': 'rw' + } + }, + 'Misc': { + 'Prop': { + 'SpecificDPBO': 'rw', + 'SpecificUPBO': 'rw' + } + } + } - fm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } - pm = {} + pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } + } - status = {} + status = { + 'General': { + 'Prop': { + 'Standard': 'r-', + 'PowerMgmStatus': 'r-', + 'Vdsl2Parameters': 'r-', + 'EstUPBOElectricalLength': 'r-', + 'LineRate': 'r-', + 'LineSnrMargin': 'r-', + 'AttainableNetDataRate': 'r-', + 'AttainableRate': 'r-', + 'OutputPower': 'r-', + 'BandStatus': 'r-' + } + }, + 'statistics': { + 'Prop': { + 'counters': 'r-', + 'PolicingCounters': 'r-' + }, + 'Cmd': ( + 'ResetPortCounters', + ) + }, + 'Nto1MacAccessDynamicList': { + 'Prop': { + 'UnicastList': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters', + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + }, + }, + 'TLSMacForwardingList': { + 'Prop': { + 'MacForwardingList': 'r-' + }, + 'Cmd': ( + 'FlushMacForwardingList', + ) + }, + '1to1MacForwardingList': { + 'Prop': { + 'One2OneMacForwardingList': 'r-' + } + }, + 'Qos': { + 'Prop': { + 'wfqueues': 'r-' + } + }, + 'Multicast': { + 'stream': { + 'Dynamic': { + 'Prop': { + 'ActiveStreams': 'r-' + }, + 'Cmd': ( + 'ClearActiveStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticStreams': 'r-' + } + }, + }, + + 'Vlan': { + 'Prop': { + 'AttachedVlans': 'r-' + } + }, + 'Preview': { + 'Cmd': ( + 'ResetPreviewSettings', + ) + }, + 'Bandwidth': { + 'Prop': { + 'bandwidthStatus': 'r-' + } + }, + }, + 'LineTest': { + 'MELT': { + 'Prop': { + 'MeltResults': 'r-' + }, + 'Cmd': ( + 'StartMeltMeasurement', + ) + }, + 'Delt': { + 'Prop': { + 'DeltMeasurementStatus': 'r-', + 'RecordedDeltMeasurements': 'r-' + }, + 'Cmd': ( + 'StartDeltMeasurement', + ) + }, + 'Selt': { + 'Prop': { + 'SeltMeasurementStatus': 'r-', + 'RecordedSeltMeasurements': 'r-', + 'CableType': 'rw', + 'BandplanProfile': 'rw', + 'TargetSnrm': 'rw' + }, + 'Cmd': ( + 'StartSeltMeasurement', + ) + }, + }, + 'Defects': { + 'Prop': { + 'Defects': 'r-' + } + }, + 'LineInventory': { + 'Prop': { + 'VendorId': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'DslOperationStatus': 'r-' + } + }, + 'Subcarrier': { + 'Cmd': ( + 'ShowBitAllocation', + ) + }, + 'RfiBands': { + 'Prop': { + 'NotchStatus': 'r-' + } + } + } def _init_access_points(self, context=None): port = self._model.get_port('name', context['unit'] + '/' + context['port']) From 7c88ec02b86d2ed08c155d896e1958d029215af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp-Noah=20Gro=C3=9F?= Date: Fri, 2 Oct 2020 10:09:15 +0200 Subject: [PATCH 076/318] Implemented Mgmt_Cards and Mgmt_Ports. --- nesi/softbox/api/models/card_models.py | 1 + nesi/softbox/api/models/mgmt_card_models.py | 27 +++++++ nesi/softbox/api/models/mgmt_port_models.py | 23 ++++++ nesi/softbox/api/models/subrack_models.py | 2 + nesi/softbox/api/schemas/mgmt_card_schemas.py | 51 ++++++++++++ nesi/softbox/api/schemas/mgmt_port_schemas.py | 49 ++++++++++++ nesi/softbox/api/schemas/subrack_schemas.py | 4 +- nesi/softbox/api/views/__init__.py | 2 +- nesi/softbox/api/views/base_views.py | 1 + nesi/softbox/api/views/card_views.py | 1 + nesi/softbox/api/views/mgmt_card_views.py | 78 +++++++++++++++++++ nesi/softbox/api/views/mgmt_port_views.py | 66 ++++++++++++++++ nesi/softbox/base_resources/card.py | 1 + nesi/softbox/base_resources/mgmt_card.py | 35 +++++++++ nesi/softbox/base_resources/mgmt_port.py | 55 +++++++++++++ 15 files changed, 394 insertions(+), 2 deletions(-) create mode 100644 nesi/softbox/api/models/mgmt_card_models.py create mode 100644 nesi/softbox/api/models/mgmt_port_models.py create mode 100644 nesi/softbox/api/schemas/mgmt_card_schemas.py create mode 100644 nesi/softbox/api/schemas/mgmt_port_schemas.py create mode 100644 nesi/softbox/api/views/mgmt_card_views.py create mode 100644 nesi/softbox/api/views/mgmt_port_views.py create mode 100644 nesi/softbox/base_resources/mgmt_card.py create mode 100644 nesi/softbox/base_resources/mgmt_port.py diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index c132fb4..f190760 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst import uuid diff --git a/nesi/softbox/api/models/mgmt_card_models.py b/nesi/softbox/api/models/mgmt_card_models.py new file mode 100644 index 0000000..80cd845 --- /dev/null +++ b/nesi/softbox/api/models/mgmt_card_models.py @@ -0,0 +1,27 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst +import uuid + +from nesi.softbox.api import db +from .mgmt_port_models import MgmtPort + + +class MgmtCard(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + description = db.Column(db.String(), default='None') + subrack_id = db.Column(db.Integer, db.ForeignKey('subrack.id')) + admin_state = db.Column(db.Enum('0', '1'), default='0') + operational_state = db.Column(db.Enum('0', '1'), default='0') + mgmt_ports = db.relationship('MgmtPort', backref='MgmtCard', lazy='dynamic') diff --git a/nesi/softbox/api/models/mgmt_port_models.py b/nesi/softbox/api/models/mgmt_port_models.py new file mode 100644 index 0000000..5fa2437 --- /dev/null +++ b/nesi/softbox/api/models/mgmt_port_models.py @@ -0,0 +1,23 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst +from nesi.softbox.api import db + +class MgmtPort(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + mgmt_card_id = db.Column(db.Integer, db.ForeignKey('mgmt_card.id')) + admin_state = db.Column(db.Enum('0', '1'), default='0') + operational_state = db.Column(db.Enum('0', '1'), default='0') + + description = db.Column(db.String(64)) diff --git a/nesi/softbox/api/models/subrack_models.py b/nesi/softbox/api/models/subrack_models.py index a4cfa6e..46f207b 100644 --- a/nesi/softbox/api/models/subrack_models.py +++ b/nesi/softbox/api/models/subrack_models.py @@ -13,6 +13,7 @@ from nesi.softbox.api import db from .card_models import Card +from .mgmt_card_models import MgmtCard class Subrack(db.Model): @@ -20,6 +21,7 @@ class Subrack(db.Model): name = db.Column(db.String(64), default='test') box_id = db.Column(db.Integer, db.ForeignKey('box.id')) cards = db.relationship('Card', backref='Subrack', lazy='dynamic') + mgmt_cards = db.relationship('MgmtCard', backref='Subrack', lazy='dynamic') # data description = db.Column(db.String(), default='') planned_type = db.Column(db.Enum('rvxs-a', 'not-planned', 'planned', 'nfxs-f'), default='not-planned') diff --git a/nesi/softbox/api/schemas/mgmt_card_schemas.py b/nesi/softbox/api/schemas/mgmt_card_schemas.py new file mode 100644 index 0000000..5d7e4f0 --- /dev/null +++ b/nesi/softbox/api/schemas/mgmt_card_schemas.py @@ -0,0 +1,51 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.mgmt_card_models import MgmtCard +from ..schemas.mgmt_port_schemas import MgmtPortsSchema + + +class MgmtCardSchema(ma.ModelSchema): + class Meta: + model = MgmtCard + fields = ('id', 'box_id', 'box', 'name', 'subrack_id', 'admin_state', 'operational_state', 'description', 'mgmt_ports') + + mgmt_ports = ma.Nested(MgmtPortsSchema.MgmtPortSchema, many=True) + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_mgmt_card', box_id='', id=''), + 'collection': ma.URLFor('show_mgmt_cards', box_id='')}) + + +class MgmtCardsSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class MgmtCardSchema(ma.ModelSchema): + class Meta: + model = MgmtCard + fields = ('id', 'name', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_mgmt_card', box_id='', id='')}) + + members = ma.Nested(MgmtCardSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_mgmt_cards', box_id='')}) diff --git a/nesi/softbox/api/schemas/mgmt_port_schemas.py b/nesi/softbox/api/schemas/mgmt_port_schemas.py new file mode 100644 index 0000000..0cdbae4 --- /dev/null +++ b/nesi/softbox/api/schemas/mgmt_port_schemas.py @@ -0,0 +1,49 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.mgmt_port_models import MgmtPort + + +class MgmtPortSchema(ma.ModelSchema): + class Meta: + model = MgmtPort + fields = ('id', 'box_id', 'box', 'mgmt_card_id', 'name', + 'description', 'admin_state', 'operational_state', '_links') + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_mgmt_port', box_id='', id=''), + 'collection': ma.URLFor('show_mgmt_ports', box_id='')}) + + +class MgmtPortsSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class MgmtPortSchema(ma.ModelSchema): + class Meta: + model = MgmtPort + fields = ('id', 'name', 'operational_state', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_mgmt_port', box_id='', id='')}) + + members = ma.Nested(MgmtPortSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_mgmt_ports', box_id='')}) diff --git a/nesi/softbox/api/schemas/subrack_schemas.py b/nesi/softbox/api/schemas/subrack_schemas.py index dc42f7d..7a6c773 100644 --- a/nesi/softbox/api/schemas/subrack_schemas.py +++ b/nesi/softbox/api/schemas/subrack_schemas.py @@ -13,15 +13,17 @@ from nesi.softbox.api import ma from ..models.subrack_models import Subrack from ..schemas.card_schemas import CardsSchema +from ..schemas.mgmt_card_schemas import MgmtCardsSchema class SubrackSchema(ma.ModelSchema): class Meta: model = Subrack - fields = ('id', 'box_id', 'box', 'cards', + fields = ('id', 'box_id', 'box', 'cards', 'mgmt_cards', 'name', 'description', '_links') cards = ma.Nested(CardsSchema.CardSchema, many=True) + mgmt_cards = ma.Nested(MgmtCardsSchema.MgmtCardSchema, many=True) box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/views/__init__.py b/nesi/softbox/api/views/__init__.py index cf9f0df..e6e1f95 100644 --- a/nesi/softbox/api/views/__init__.py +++ b/nesi/softbox/api/views/__init__.py @@ -1,4 +1,4 @@ __all__ = ["box_views", "credential_views", "route_views", "subrack_views", "card_views", "port_views", "ont_views", "ontport_views", "cpe_views", "cpeport_views", "vlan_views", "portprofile_views", "emu_views", "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", - "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views"] + "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views", "mgmt_card_views", "mgmt_port_views"] diff --git a/nesi/softbox/api/views/base_views.py b/nesi/softbox/api/views/base_views.py index aef71de..ac46d02 100644 --- a/nesi/softbox/api/views/base_views.py +++ b/nesi/softbox/api/views/base_views.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst diff --git a/nesi/softbox/api/views/card_views.py b/nesi/softbox/api/views/card_views.py index c063e89..5374f92 100644 --- a/nesi/softbox/api/views/card_views.py +++ b/nesi/softbox/api/views/card_views.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst diff --git a/nesi/softbox/api/views/mgmt_card_views.py b/nesi/softbox/api/views/mgmt_card_views.py new file mode 100644 index 0000000..9167f9a --- /dev/null +++ b/nesi/softbox/api/views/mgmt_card_views.py @@ -0,0 +1,78 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import re + +from .base_views import * +from .box_views import show_box +from ..models.mgmt_card_models import MgmtCard +from ..models.subrack_models import Subrack +from ..schemas.mgmt_card_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//mgmt_cards', methods=['GET']) +def show_mgmt_cards(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(MgmtCardsSchema(), MgmtCard, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//mgmt_cards/', methods=['GET']) +def show_mgmt_card(box_id, id): + response = show_component(MgmtCard, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//mgmt_cards', methods=['POST']) +def new_mgmt_card(box_id): + req = flask.request.json + + box = json.loads(show_box(box_id)[0].data.decode('utf-8')) + subrack = json.loads(show_component(Subrack, box_id, req['subrack_id']).data.decode('utf-8')) + if 'name' not in req or req['name'] == '' or req['name'] not in ('11', '13'): + if box['vendor'] == 'KeyMile': + card11_exists = False + card13_exists = False + for card in subrack['mgmt_cards']: + if card['name'] == '11': + card11_exists = True + elif card['name'] == '13': + card13_exists = True + if not card11_exists: + req['name'] = '11' + elif not card13_exists: + req['name'] = '13' + else: + return flask.Response(status=500) + + response = new_component(MgmtCardSchema(), MgmtCard, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//mgmt_cards/', methods=['PUT']) +def update_mgmt_card(box_id, id): + req = flask.request.json + update_component(MgmtCard, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//mgmt_cards/', methods=['DELETE']) +def del_mgmt_card(box_id, id): + del_component(MgmtCard, box_id, id) + return flask.Response(status=204) diff --git a/nesi/softbox/api/views/mgmt_port_views.py b/nesi/softbox/api/views/mgmt_port_views.py new file mode 100644 index 0000000..b7ec236 --- /dev/null +++ b/nesi/softbox/api/views/mgmt_port_views.py @@ -0,0 +1,66 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from .box_views import show_box +from ..models.mgmt_card_models import MgmtCard +from ..schemas.mgmt_port_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//mgmt_ports', methods=['GET']) +def show_mgmt_ports(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(MgmtPortsSchema(), MgmtPort, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//mgmt_ports/', methods=['GET']) +def show_mgmt_port(box_id, id): + response = show_component(MgmtPort, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//mgmt_ports', methods=['POST']) +def new_mgmt_port(box_id): + req = flask.request.json + + mgmt_card = json.loads(show_component(MgmtCard, box_id, req['mgmt_card_id']).data.decode('utf-8')) + box = json.loads(show_box(box_id)[0].data.decode('utf-8')) + + if 'name' not in req or req['name'] == "": #TODO evtl. noch zu bearbeiten + if box['vendor'] == 'Huawei': + req['name'] = mgmt_card['name'] + "/" + str(len(mgmt_card['mgmt_ports'])) + else: + req['name'] = mgmt_card['name'] + "/" + str(len(mgmt_card['mgmt_ports']) + 1) + + response = new_component(MgmtPortSchema(), MgmtPort, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//mgmt_ports/', methods=['PUT']) +def update_mgmt_port(box_id, id): + req = flask.request.json + update_component(MgmtPort, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//mgmt_ports/', methods=['DELETE']) +def del_mgmt_port(box_id, id): + del_component(MgmtPort, box_id, id) + return flask.Response(status=204) diff --git a/nesi/softbox/base_resources/card.py b/nesi/softbox/base_resources/card.py index 2de330b..93df665 100644 --- a/nesi/softbox/base_resources/card.py +++ b/nesi/softbox/base_resources/card.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst diff --git a/nesi/softbox/base_resources/mgmt_card.py b/nesi/softbox/base_resources/mgmt_card.py new file mode 100644 index 0000000..feef2d0 --- /dev/null +++ b/nesi/softbox/base_resources/mgmt_card.py @@ -0,0 +1,35 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import logging + +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class MgmtCard(base.Resource): + """Represent physical shelf resource.""" + id = base.Field('id') + name = base.Field('name') + box_id = base.Field('box_id') + description = base.Field('description') + subrack_id = base.Field('subrack_id') + + +class MgmtCardCollection(base.ResourceCollection): + """Represent a collection of cards.""" + + @property + def _resource_type(self): + return MgmtCard diff --git a/nesi/softbox/base_resources/mgmt_port.py b/nesi/softbox/base_resources/mgmt_port.py new file mode 100644 index 0000000..176e161 --- /dev/null +++ b/nesi/softbox/base_resources/mgmt_port.py @@ -0,0 +1,55 @@ + +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import logging + +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class MgmtPort(base.Resource): + """Represent physical port resource.""" + + id = base.Field('id') + name = base.Field('name') + box_id = base.Field('box_id') + card_id = base.Field('card_id') + description = base.Field('description') + admin_state = base.Field('admin_state') + operational_state = base.Field('operational_state') + + def admin_up(self): + """Set the admin port state to up""" + self.update(admin_state='1') + + def admin_down(self): + """Set the admin port state to down""" + self.update(admin_state='0') + + def down(self): + """Set the port state to down""" + self.update(operational_state='0') + + def up(self): + """Set the port state to up""" + self.update(operational_state='1') + + +class MgmtPortCollection(base.ResourceCollection): + """Represent a collection of management ports.""" + + @property + def _resource_type(self): + return MgmtPort From 55966d1e87a0d177ff36e13187f76a35d2292b5c Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 2 Oct 2020 10:45:58 +0200 Subject: [PATCH 077/318] Implemented get commands for first few properties --- .../base/execution_errors/invalid_property.j2 | 2 + .../login/base/get/administrative_status.j2 | 3 + .../KeyMile/login/base/get/attainable_rate.j2 | 4 + .../KeyMile/login/base/get/chan_profile.j2 | 3 + .../login/base/get/operational_status.j2 | 3 + ...dProcessor.py => alarmCommandProcessor.py} | 4 +- .../root/fan/fanCommandProcessor.py | 9 +- .../accessPoints/root/rootCommandProcessor.py | 297 +++++++++++++++++- .../unit/port/chan/vcc/vccCommandProcessor.py | 2 +- .../interface/interfaceCommandProcessor.py | 3 - .../root/unit/port/portCommandProcessor.py | 19 ++ .../root/unit/unitCommandProcessor.py | 195 +++++++++++- vendors/KeyMile/baseCommandProcessor.py | 59 +++- 13 files changed, 570 insertions(+), 33 deletions(-) create mode 100644 templates/KeyMile/login/base/execution_errors/invalid_property.j2 create mode 100644 templates/KeyMile/login/base/get/administrative_status.j2 create mode 100644 templates/KeyMile/login/base/get/attainable_rate.j2 create mode 100644 templates/KeyMile/login/base/get/chan_profile.j2 create mode 100644 templates/KeyMile/login/base/get/operational_status.j2 rename vendors/KeyMile/accessPoints/root/fan/{fanAlarmCommandProcessor.py => alarmCommandProcessor.py} (94%) diff --git a/templates/KeyMile/login/base/execution_errors/invalid_property.j2 b/templates/KeyMile/login/base/execution_errors/invalid_property.j2 new file mode 100644 index 0000000..af8470b --- /dev/null +++ b/templates/KeyMile/login/base/execution_errors/invalid_property.j2 @@ -0,0 +1,2 @@ +error: invalid property + diff --git a/templates/KeyMile/login/base/get/administrative_status.j2 b/templates/KeyMile/login/base/get/administrative_status.j2 new file mode 100644 index 0000000..62715fa --- /dev/null +++ b/templates/KeyMile/login/base/get/administrative_status.j2 @@ -0,0 +1,3 @@ + \ # AdministrativeStatus +{{ context.port.admin_state }}{{ context.spacer }}\ # State + diff --git a/templates/KeyMile/login/base/get/attainable_rate.j2 b/templates/KeyMile/login/base/get/attainable_rate.j2 new file mode 100644 index 0000000..dc5e135 --- /dev/null +++ b/templates/KeyMile/login/base/get/attainable_rate.j2 @@ -0,0 +1,4 @@ + \ # AttainableRate +{{ context.port.downstream_max }}{{ context.spacer1 }}\ # Downstream +{{ context.port.upstream_max }}{{ context.spacer2 }}\ # Upstream + diff --git a/templates/KeyMile/login/base/get/chan_profile.j2 b/templates/KeyMile/login/base/get/chan_profile.j2 new file mode 100644 index 0000000..7691f6d --- /dev/null +++ b/templates/KeyMile/login/base/get/chan_profile.j2 @@ -0,0 +1,3 @@ + \ # ChannelProfile +{{ context.port_profile.name }}{{ context.spacer }}\ # Name + diff --git a/templates/KeyMile/login/base/get/operational_status.j2 b/templates/KeyMile/login/base/get/operational_status.j2 new file mode 100644 index 0000000..ea79363 --- /dev/null +++ b/templates/KeyMile/login/base/get/operational_status.j2 @@ -0,0 +1,3 @@ + \ # OperationalStatus +{{ context.port.operational_state }}{{ context.spacer }}\ # State + diff --git a/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py similarity index 94% rename from vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py rename to vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py index 78cb692..e2f83a8 100644 --- a/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py @@ -14,8 +14,8 @@ from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor -class FanAlarmCommandProcessor(BaseCommandProcessor): - __name__ = 'fanAlarm' +class AlarmCommandProcessor(BaseCommandProcessor): + __name__ = 'alarm' management_functions = ('main', 'cfgm', 'fm') access_points = () diff --git a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py index 3e10c68..efb61a5 100644 --- a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py @@ -62,5 +62,12 @@ class FanCommandProcessor(BaseCommandProcessor): } } + def _init_access_points(self, context=None): + for i in range(1, 12): + identifier = 'alarm-' + str(i) + if identifier in self.access_points: + continue + self.access_points += (identifier,) + def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 838df63..4dd4cf4 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -48,25 +48,308 @@ class RootCommandProcessor(BaseCommandProcessor): } } - cfgm = {} + cfgm = { + 'ConfigurationManagement': { + 'Prop': { + 'ConfigurationStatus': 'r-', + 'BackupDescription': 'r-' + }, + 'Cmd': ( + 'Load', + 'Save', + 'Initialize', + 'ChangeDescription' + ), + 'File': { + 'Configuration': 'rw' + } + }, + 'ManagementInterface': { + 'Prop': { + 'IP_Address': 'rw', + 'VlanId': 'rw', + 'ManagementVlanCoS': 'rw' + } + }, + 'Packet': { + 'Prop': { + 'Bridge': 'rw', + 'MACMovement': 'rw', + 'Traceability': 'rw', + 'PPPoA': 'rw' + } + }, + 'SessionManagement': { + 'Prop': { + 'TelnetEnabled': 'r-', + 'SshEnabled': 'r-', + 'UsbEnabled': 'r-', + 'RetryTime': 'r-', + 'SessionmanagerTime': 'r-', + 'AuthenticationManagementInterfaces': 'r-', + 'LocalAuthenticationFallback': 'r-', + 'RadiusDefaultUserclass': 'r-' + } + }, + 'RadiusClient': { + 'Prop': { + 'CommonRadius': 'r-', + 'PrimaryRadiusServer': 'r-', + 'AlternateRadiusServer': 'r-' + } + }, + 'DateAndTime': { + 'SNTPClient': { + 'Prop': { + 'OperationMode': 'rw', + 'PrimaryServer': 'rw', + 'SecondaryServer': 'rw', + 'PollingInterval': 'rw', + 'BroadcastDelay': 'rw' + } + }, + 'TimeZone': { + 'Prop': { + 'TimeZone': 'rw', + 'DaylightSaving': 'r-' + } + }, + }, + 'ProfileManagement': { + 'Prop': { + 'ProfileCpsTable': 'r-' + }, + 'Cmd': ( + 'Check', + 'Delete' + ), + 'File': { + 'Profile': 'rw', + 'Cps': 'rw' + } + }, + 'QoS': { + 'Prop': { + 'PriorityMapping': 'rw', + 'QueueMode': 'rw' + } + }, + 'SNMP': { + 'General': { + 'Prop': { + 'SNMPSupport': 'rw', + 'SNMPParameters': 'r-' + }, + 'Cmd': ( + 'SetDefaultSNMPConfigurationTables' + ) + }, + 'USM': { + 'Prop': { + 'LocalUserTable': 'rw', + 'RemoteUserTable': 'rw' + } + }, + }, + 'SyslogDestinations': { + 'Destination1': { + 'Prop': { + 'SyslogDestination1': 'rw' + } + }, + 'Destination2': { + 'Prop': { + 'SyslogDestination2': 'rw' + } + }, + 'Destination3': { + 'Prop': { + 'SyslogDestination3': 'rw' + } + }, + 'Destination4': { + 'Prop': { + 'SyslogDestination4': 'rw' + } + }, + 'Destination5': { + 'Prop': { + 'SyslogDestination5': 'rw' + } + }, + 'Destination6': { + 'Prop': { + 'SyslogDestination6': 'rw' + } + }, + 'Destination7': { + 'Prop': { + 'SyslogDestination7': 'rw' + } + }, + 'Destination8': { + 'Prop': { + 'SyslogDestination8': 'rw' + } + }, + 'Destination9': { + 'Prop': { + 'SyslogDestination9': 'rw' + } + }, + 'Destination10': { + 'Prop': { + 'SyslogDestination10': 'rw' + } + }, + }, + 'SyslogSources': { + 'Prop': { + 'SyslogSourceConfiguration': 'rw' + } + }, + 'BatteryPowerSaving': { + 'Prop': { + 'PowerSavingEnabled': 'rw', + 'PowerSavingAlarm': 'rw', + 'PowerSavingThresholds': 'rw', + 'PowerSavingUnits': 'r-' + }, + 'Cmd': ( + 'PowerSavingAddUnit', + 'PowerSavingRemoveUnit' + ) + }, + 'Ipsec': { + 'Prop': { + 'Ipsec': 'rw' + } + }, + 'TemeratureLimits': { + 'Prop': { + 'ThresholdExceed': 'rw', + 'ThresholdWarning': 'rw' + } + }, + 'ESO': { + 'Prop': { + 'Eso1ClockSources': 'rw', + 'Eso2ClockSource': 'rw' + } + }, + 'PETS': { + 'Prop': { + 'ClockSources': 'rw', + 'PetsClockPriority': 'rw' + } + } + } - fm = {} + fm = { + 'ActiveFailures': { + 'Prop': { + 'ActiveFailureTable': 'r-' + } + }, + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge' + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } status = { 'DateAndTime': { 'Time': { - 'Cmd': ( - 'SetDateAndTime', - ), 'Prop': { 'Summary': 'r-' - } + }, + 'Cmd': ( + 'SetDateAndTime' + ) }, 'SNTPClient': { 'Prop': { - 'PrimaryServerState': 'r-' + 'PrimaryServerState': 'r-', + 'SecondaryServerState': 'r-', + 'LastResponseTime': 'r-', + 'LastJumpTime': 'r-', + 'LastAdjustmentTime': 'r-' } + }, + }, + 'ManagementInterface': { + 'Prop': { + 'SshFingerprint': 'r-' + }, + 'Cmd': ( + 'Ping' + ) + }, + 'SessionManagement': { + 'Cmd': ( + 'ShowSessions' + ) + }, + 'RadiusClient': { + 'Prop': { + 'PrimaryRadiusServerStatus': 'r-', + 'AlternateRadiusServerStatus': 'r-' } + }, + 'Ipsec': { + 'Prop': { + 'IpsecSAStatus': 'r-' + }, + 'Cmd': ( + 'GetIpsecLogbook' + ) + }, + 'Redundancy': { + 'Prop': { + 'NeConfigurationStatus': 'r-', + 'RedundancyRoles': 'r-', + 'RedundancyStatus': 'r-' + }, + 'Cmd': ( + 'ManualSwitchOver', + 'ForcedSwitchOver', + 'IsolateUnits', + 'JoinUnits' + ) + }, + 'Temperature': { + 'Prop': { + 'CurrTemperature': 'r-', + 'MaxTemperature': 'r-', + 'MinTemperature': 'r-' + }, + 'Cmd': ( + 'ResetMinMax' + ) + }, + 'ESO': { + 'Prop': { + 'ClockOutputEso1': 'r-', + 'ClockOutputEso2': 'r-' + } + }, + 'PETS': { + 'Prop': { + 'PetsClockSources': 'r-', + 'PetsOperationStatus': 'r-' + }, + 'Cmd': ( + 'PetsClockOperation' + ) } } diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py index 8873005..21d96b0 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py @@ -15,7 +15,7 @@ class VccCommandProcessor(BaseCommandProcessor): - __name__ = 'port' + __name__ = 'vcc' management_functions = ('main', 'cfgm', 'pm', 'status') access_points = () diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index 1e53469..d8638a1 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -124,8 +124,5 @@ class InterfaceCommandProcessor(BaseCommandProcessor): } } - def _init_access_points(self, context=None): - pass - def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 54ee05d..beadf56 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -354,6 +354,25 @@ class PortCommandProcessor(BaseCommandProcessor): } } + def do_get(self, command, *args, context=None): + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + if self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': + text = self._render('attainable_rate', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': + text = self._render('administrative_status', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': + text = self._render('operational_status', *scopes, context=context) + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + def _init_access_points(self, context=None): port = self._model.get_port('name', context['unit'] + '/' + context['port']) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 5c2dfd7..9c218de 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -19,13 +19,200 @@ class UnitCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'status') access_points = () #'internalPorts', only on certain cards - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'Equipment': { + 'Prop': { + 'AssignmentStatus': 'r-', + 'CurrentStatus': 'r-' + }, + 'Cmd': ( + 'Assign', + 'Unassign', + 'Restart', + 'StopInBoot' + ) + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + }, + 'Logbooks': { + 'Cmd': ( + 'GetAlarmLogbook', + 'GetEventLogbook', + 'GetEquipmentLogbook' + ) + }, + 'Software': { + 'Prop': { + 'DiskSpace': 'r-', + 'SoftwareOnUnit': 'r-', + 'HardwareAndSoftware': 'r-', + 'Status': 'r-', + 'Configuration': 'rw' + }, + 'Cmd': ( + 'DeleteSoftware', + 'StartSoftware' + ), + 'File': { + 'Software': 'rw' + } + } + } - cfgm = {} + cfgm = { + 'Vlan': { + 'Prop': { + 'VlanCosTable': 'r-' + } + }, + 'Security': { + 'Prop': { + 'filtering': 'rw', + 'EoamMode': 'rw' + } + }, + 'Logon': { + 'Prop': { + 'LogonOptions': 'rw', + 'OneToOneOptions': 'rw' + } + }, + 'Mac': { + 'Prop': { + 'MacServiceBased': 'rw' + } + }, + 'HostPort': { + 'Prop': { + 'PolicerProfile': 'rw', + 'TrunkPolicerProfile': 'rw', + 'ProtRateLimiter': 'rw' + } + }, + 'QoS': { + 'Prop': { + 'ColorMarking': 'rw' + } + }, + 'Wire': { + 'General': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Thresholds': { + 'Prop': { + 'MeltAlarmThresholds': 'rw' + } + } + } + } - fm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge' + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } - status = {} + status = { + 'MacAllocationTable': { + 'Prop': { + 'MacAllocationTableEntries': 'r-' + } + }, + 'SwitchPort': { + 'Prop': { + 'Mac': 'r-', + 'MacStatus': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters' + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters' + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters' + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters' + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters' + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters' + ) + }, + }, + }, + 'BufferManagement': { + 'Prop': { + 'BufferMgmtStatus': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'MeltLineTestStatus': 'r-', + 'SearchTone': 'rw' + }, + 'Cmd': ( + 'StartMeltAll', + 'StopMeltAll' + ) + } + } def _init_access_points(self, context=None): card = self._model.get_card('name', context['unit']) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 7e51d77..185e14a 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -21,17 +21,30 @@ class BaseCommandProcessor(base.CommandProcessor): management_functions = () access_points = () - def create_spacers(self, positions, args): - spacers = [] - previous_pos = 0 - i = 0 - for position in positions: - spacer = position - (previous_pos + len(str(args[i]))) - spacers.append(spacer) - previous_pos = position - i += 1 - - return spacers + main = {} + + cfgm = {} + + fm = {} + + pm = {} + + status = {} + + def map_states(self, object, type): + if object.admin_state == '0': + if type == 'port': + object.admin_state = 'Down' + elif object.admin_state == '1': + if type == 'port': + object.admin_state = 'Down' + + if object.operational_state == '0': + if type == 'port': + object.operational_state = 'Down' + elif object.operational_state == '1': + if type == 'port': + object.operational_state = 'Down' def do_help(self, command, *args, context=None): help_scopes = ('login', 'base', 'help') @@ -76,10 +89,16 @@ def do_pwd(self, command, *args, context=None): self._write(self._render('pwd', 'login', 'base', context=context)) def do_cd(self, command, *args, context=None): + if len(args) == 0: + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + if args[0] == '/': context['path'] = '/' from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor - exc = exceptions.TerminalExitError + exc = exceptions.TerminalExitError() exc.return_to = RootCommandProcessor raise exc @@ -87,7 +106,7 @@ def do_cd(self, command, *args, context=None): components = [x for x in args[0].split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', components[0]): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty @@ -152,7 +171,7 @@ def do_cd(self, command, *args, context=None): component_number = components[0].split('-')[1] command_processor = component_type.capitalize() + 'CommandProcessor' else: - command_processor = self.__name__.capitalize() + components[0].capitalize() + 'CommandProcessor' + command_processor = components[0].capitalize() + 'CommandProcessor' if component_type == 'unit': if self.__name__ != 'root': @@ -175,6 +194,10 @@ def do_cd(self, command, *args, context=None): template_scopes=()) # TODO: fix exception to not require all fields as empty context['chan'] = component_number + if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): + if self.__name__ != 'root': + raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + if components[0] in ('main', 'cfgm', 'fm', 'pm', 'status'): if re.search('(main|cfgm|fm|pm|status)', context['path']): return @@ -190,6 +213,12 @@ def do_cd(self, command, *args, context=None): from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor from vendors.KeyMile.accessPoints.root.unit.port.chan.chanCommandProcessor import ChanCommandProcessor from vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor import InterfaceCommandProcessor + from vendors.KeyMile.accessPoints.root.fan.fanCommandProcessor import FanCommandProcessor + from vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor import AlarmCommandProcessor + from vendors.KeyMile.accessPoints.root.eoamCommandProcessor import EoamCommandProcessor + from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor + from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor + from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if len(remaining_args) > 0: @@ -279,4 +308,4 @@ def generate_ls_text(layers, depth): raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=command) def _init_access_points(self, context=None): - raise exceptions.SoftboxenError(message='Abstract method not implemented.') + pass # Abstract method not implemented From 34ee7d9f1fcc483030466350f91e5b5171aa4ba3 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 2 Oct 2020 13:00:22 +0200 Subject: [PATCH 078/318] Extracted management function dicts into external files for every command processor --- .../accessPoints/root/eoamCommandProcessor.py | 55 +-- .../root/eoamManagementFunctions.py | 52 +++ .../root/fan/alarmCommandProcessor.py | 35 +- .../root/fan/alarmManagementFunctions.py | 32 ++ .../root/fan/fanCommandProcessor.py | 45 +-- .../root/fan/fanManagementFunctions.py | 42 +++ .../root/multicastCommandProcessor.py | 166 +-------- .../root/multicastManagementFunctions.py | 161 +++++++++ .../accessPoints/root/rootCommandProcessor.py | 337 +---------------- .../root/rootManagementFunctions.py | 333 +++++++++++++++++ .../services/macAccessCtrlCommandProcessor.py | 28 ++ .../macAccessCtrlManagementFunctions.py | 61 ++++ ...Processor.py => packetCommandProcessor.py} | 13 +- .../services/packetManagementFunctions.py | 8 + .../root/services/servicesCommandProcessor.py | 33 +- .../servicesMacAccessCtrlCommandProcessor.py | 85 ----- .../services/servicesManagementFunctions.py | 30 ++ .../root/tdmConnectionsCommandProcessor.py | 35 +- .../root/tdmConnectionsManagementFunctions.py | 33 ++ .../unit/port/chan/chanCommandProcessor.py | 105 +----- .../unit/port/chan/chanManagementFunctions.py | 100 ++++++ .../unit/port/chan/vcc/vccCommandProcessor.py | 108 +----- .../port/chan/vcc/vccManagementFunctions.py | 104 ++++++ .../interface/interfaceCommandProcessor.py | 108 +----- .../interface/interfaceManagementFunctions.py | 104 ++++++ .../root/unit/port/portCommandProcessor.py | 339 +----------------- .../root/unit/port/portManagementFunctions.py | 334 +++++++++++++++++ .../root/unit/unitCommandProcessor.py | 198 +--------- .../root/unit/unitManagementFunctions.py | 194 ++++++++++ 29 files changed, 1664 insertions(+), 1614 deletions(-) create mode 100644 vendors/KeyMile/accessPoints/root/eoamManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/fan/alarmManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/fan/fanManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/multicastManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/rootManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/services/macAccessCtrlManagementFunctions.py rename vendors/KeyMile/accessPoints/root/services/{servicesPacketCommandProcessor.py => packetCommandProcessor.py} (75%) create mode 100644 vendors/KeyMile/accessPoints/root/services/packetManagementFunctions.py delete mode 100644 vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/services/servicesManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/tdmConnectionsManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/chan/chanManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/portManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/unitManagementFunctions.py diff --git a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py index 0f9d2f1..d6888f5 100644 --- a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py @@ -19,58 +19,9 @@ class EoamCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'status') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'AdminAndOperStatus': { - 'Prop': { - 'AdministrativeStatus': 'rw', - 'OperationalStatus': 'r-' - } - } - } - - cfgm = { - 'DefaultMdLevel': { - 'Prop': { - 'DefaultMdSettings': 'rw' - } - }, - 'ContextMap': { - 'Prop': { - 'Mapping': 'rw' - } - }, - 'Aggregation': { - 'Prop': { - 'Role': 'rw', - 'Address': 'rw' - } - }, - 'Md': { - 'Cmd': ( - 'CreateMd', - 'DeleteMd' - ) - } - } - - status = { - 'DefaultMdMips': { - 'Prop': { - 'Mips': 'r-' - } - }, - 'ConfigurationErrors': { - 'Prop': { - 'InterfacesInError': 'r-' - } - } - } + from .eoamManagementFunctions import main + from .eoamManagementFunctions import cfgm + from .eoamManagementFunctions import status def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/eoamManagementFunctions.py b/vendors/KeyMile/accessPoints/root/eoamManagementFunctions.py new file mode 100644 index 0000000..c669d81 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/eoamManagementFunctions.py @@ -0,0 +1,52 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + } +} + +cfgm = { + 'DefaultMdLevel': { + 'Prop': { + 'DefaultMdSettings': 'rw' + } + }, + 'ContextMap': { + 'Prop': { + 'Mapping': 'rw' + } + }, + 'Aggregation': { + 'Prop': { + 'Role': 'rw', + 'Address': 'rw' + } + }, + 'Md': { + 'Cmd': ( + 'CreateMd', + 'DeleteMd' + ) + } +} + +status = { + 'DefaultMdMips': { + 'Prop': { + 'Mips': 'r-' + } + }, + 'ConfigurationErrors': { + 'Prop': { + 'InterfacesInError': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py index e2f83a8..a88d5ef 100644 --- a/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py @@ -19,38 +19,9 @@ class AlarmCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - cfgm = { - 'General': { - 'Prop': { - 'Polarity': 'rw' - } - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } + from .alarmManagementFunctions import main + from .alarmManagementFunctions import cfgm + from .alarmManagementFunctions import fm def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/fan/alarmManagementFunctions.py b/vendors/KeyMile/accessPoints/root/fan/alarmManagementFunctions.py new file mode 100644 index 0000000..7ecdd32 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/fan/alarmManagementFunctions.py @@ -0,0 +1,32 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'General': { + 'Prop': { + 'Polarity': 'rw' + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py index efb61a5..cd8dff8 100644 --- a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py @@ -19,48 +19,9 @@ class FanCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'Equipment': { - 'Prop': { - 'CurrentStatus': 'r-' - } - }, - 'Inventory': { - 'Prop': { - 'EquipmentInventory': 'r-' - } - } - } - - cfgm = { - 'General': { - 'Prop': { - 'Option': 'rw' - } - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } + from .fanManagementFunctions import main + from .fanManagementFunctions import cfgm + from .fanManagementFunctions import fm def _init_access_points(self, context=None): for i in range(1, 12): diff --git a/vendors/KeyMile/accessPoints/root/fan/fanManagementFunctions.py b/vendors/KeyMile/accessPoints/root/fan/fanManagementFunctions.py new file mode 100644 index 0000000..3a7049a --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/fan/fanManagementFunctions.py @@ -0,0 +1,42 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'Equipment': { + 'Prop': { + 'CurrentStatus': 'r-' + } + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + } +} + +cfgm = { + 'General': { + 'Prop': { + 'Option': 'rw' + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py index 8ec0162..43b31cf 100644 --- a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py @@ -19,167 +19,11 @@ class MulticastCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - cfgm = { - 'Multicast': { - 'General': { - 'Prop': { - 'SnoopingMode': 'rw', - 'LocalIPAddressForIGMPGeneration': 'rw', - 'IPSourceAddressOfQueries': 'rw', - 'portGroupInactivityTimeout': 'rw' - }, - 'Cmd': ( - 'CreateVlan', - 'DeleteVlan' - ) - }, - 'PreJoin': { - 'Prop': { - 'preJoinIntervalPeriod': 'rw' - } - }, - 'PostLeave': { - 'Prop': { - 'postLeaveDelayPeriod': 'rw' - } - }, - 'Preview': { - 'Prop': { - 'previewSettings': 'rw' - } - }, - 'Bandwidth': { - 'Prop': { - 'defaultBandwidthPerStream': 'rw' - } - }, - 'Alarms': { - 'Prop': { - 'configuredMulticastStreamsThreshold': 'rw' - } - - } - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } - - pm = { - 'UserCounter': { - 'Prop': { - 'UserCounterDisplayMode': 'rw', - 'UserCounterTable': 'r-' - }, - 'Cmd': ( - 'UserCounterReset', - ) - }, - 'History15min': { - 'Prop': { - 'History15minDisplayMode': 'rw', - 'History15minTable': 'r-' - } - }, - 'History24h': { - 'Prop': { - 'History24hDisplayMode': 'rw', - 'History24hTable': 'r-' - } - }, - 'Alarm15min': { - 'Prop': { - 'Alarm15minDisplayMode': 'rw', - 'Alarm15minTable': 'r-' - }, - 'Cmd': ( - 'Alarm15minReset', - ) - }, - 'Alarm24h': { - 'Prop': { - 'Alarm24hDisplayMode': 'rw', - 'Alarm24hTable': 'r-' - }, - 'Cmd': ( - 'Alarm24hReset', - ) - }, - 'PerformanceMonitoring': { - 'Cmd': ( - 'UserCounter', - 'GetHistory15min', - 'GetHistory24h', - 'GetAlarm15min', - 'GetAlarm24hRecursive', - 'ResetUserCounter', - 'ResetAlarm15min', - 'ResetAlarm24h' - ) - } - } - - status = { - 'multicast': { - 'activeStreams': { - 'Dynamic': { - 'Prop': { - 'activeMulticastStreams': 'r-', - 'NumberOfActiveStreams': 'r-' - }, - 'Cmd': ( - 'clearAllStreams', - ) - }, - 'Static': { - 'Prop': { - 'StaticMulticastStreams': 'r-', - 'NumberOfStaticStreams': 'r-' - } - }, - }, - - 'unitConfiguration': { - 'Prop': { - 'multicastUnitConfigurationStatus': 'r-' - } - }, - 'portSummary': { - 'Prop': { - 'CoreUnitFrontPorts': 'r-', - 'CapableServiceUnits': 'r-' - } - }, - 'Router': { - 'Prop': { - 'learnedIpRouterSourceAddress': 'r-' - } - - } - } - } + from .multicastManagementFunctions import main + from .multicastManagementFunctions import cfgm + from .multicastManagementFunctions import fm + from .multicastManagementFunctions import pm + from .multicastManagementFunctions import status def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/multicastManagementFunctions.py b/vendors/KeyMile/accessPoints/root/multicastManagementFunctions.py new file mode 100644 index 0000000..0b5c804 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/multicastManagementFunctions.py @@ -0,0 +1,161 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'Multicast': { + 'General': { + 'Prop': { + 'SnoopingMode': 'rw', + 'LocalIPAddressForIGMPGeneration': 'rw', + 'IPSourceAddressOfQueries': 'rw', + 'portGroupInactivityTimeout': 'rw' + }, + 'Cmd': ( + 'CreateVlan', + 'DeleteVlan' + ) + }, + 'PreJoin': { + 'Prop': { + 'preJoinIntervalPeriod': 'rw' + } + }, + 'PostLeave': { + 'Prop': { + 'postLeaveDelayPeriod': 'rw' + } + }, + 'Preview': { + 'Prop': { + 'previewSettings': 'rw' + } + }, + 'Bandwidth': { + 'Prop': { + 'defaultBandwidthPerStream': 'rw' + } + }, + 'Alarms': { + 'Prop': { + 'configuredMulticastStreamsThreshold': 'rw' + } + + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +pm = { + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + }, + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + } +} + +status = { + 'multicast': { + 'activeStreams': { + 'Dynamic': { + 'Prop': { + 'activeMulticastStreams': 'r-', + 'NumberOfActiveStreams': 'r-' + }, + 'Cmd': ( + 'clearAllStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticMulticastStreams': 'r-', + 'NumberOfStaticStreams': 'r-' + } + }, + }, + + 'unitConfiguration': { + 'Prop': { + 'multicastUnitConfigurationStatus': 'r-' + } + }, + 'portSummary': { + 'Prop': { + 'CoreUnitFrontPorts': 'r-', + 'CapableServiceUnits': 'r-' + } + }, + 'Router': { + 'Prop': { + 'learnedIpRouterSourceAddress': 'r-' + } + + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 4dd4cf4..81725fc 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -19,339 +19,10 @@ class RootCommandProcessor(BaseCommandProcessor): management_functions = {'main', 'cfgm', 'fm', 'status'} access_points = ('eoam', 'fan', 'multicast', 'services', 'tdmConnections') - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'Inventory': { - 'Prop': { - 'EquipmentInventory': 'r-' - } - }, - 'Logbooks': { - 'Cmd': ( - 'GetAllLogbooks', - 'GetAlarmLogbook', - 'GetEventLogbook', - 'GetConfigLogbook', - 'GetEquipmentLogbook', - 'GetSessionLogbook' - ) - }, - 'NESoftwareDownload': { - 'Cmd': ( - 'StartEsw', - ) - } - } - - cfgm = { - 'ConfigurationManagement': { - 'Prop': { - 'ConfigurationStatus': 'r-', - 'BackupDescription': 'r-' - }, - 'Cmd': ( - 'Load', - 'Save', - 'Initialize', - 'ChangeDescription' - ), - 'File': { - 'Configuration': 'rw' - } - }, - 'ManagementInterface': { - 'Prop': { - 'IP_Address': 'rw', - 'VlanId': 'rw', - 'ManagementVlanCoS': 'rw' - } - }, - 'Packet': { - 'Prop': { - 'Bridge': 'rw', - 'MACMovement': 'rw', - 'Traceability': 'rw', - 'PPPoA': 'rw' - } - }, - 'SessionManagement': { - 'Prop': { - 'TelnetEnabled': 'r-', - 'SshEnabled': 'r-', - 'UsbEnabled': 'r-', - 'RetryTime': 'r-', - 'SessionmanagerTime': 'r-', - 'AuthenticationManagementInterfaces': 'r-', - 'LocalAuthenticationFallback': 'r-', - 'RadiusDefaultUserclass': 'r-' - } - }, - 'RadiusClient': { - 'Prop': { - 'CommonRadius': 'r-', - 'PrimaryRadiusServer': 'r-', - 'AlternateRadiusServer': 'r-' - } - }, - 'DateAndTime': { - 'SNTPClient': { - 'Prop': { - 'OperationMode': 'rw', - 'PrimaryServer': 'rw', - 'SecondaryServer': 'rw', - 'PollingInterval': 'rw', - 'BroadcastDelay': 'rw' - } - }, - 'TimeZone': { - 'Prop': { - 'TimeZone': 'rw', - 'DaylightSaving': 'r-' - } - }, - }, - 'ProfileManagement': { - 'Prop': { - 'ProfileCpsTable': 'r-' - }, - 'Cmd': ( - 'Check', - 'Delete' - ), - 'File': { - 'Profile': 'rw', - 'Cps': 'rw' - } - }, - 'QoS': { - 'Prop': { - 'PriorityMapping': 'rw', - 'QueueMode': 'rw' - } - }, - 'SNMP': { - 'General': { - 'Prop': { - 'SNMPSupport': 'rw', - 'SNMPParameters': 'r-' - }, - 'Cmd': ( - 'SetDefaultSNMPConfigurationTables' - ) - }, - 'USM': { - 'Prop': { - 'LocalUserTable': 'rw', - 'RemoteUserTable': 'rw' - } - }, - }, - 'SyslogDestinations': { - 'Destination1': { - 'Prop': { - 'SyslogDestination1': 'rw' - } - }, - 'Destination2': { - 'Prop': { - 'SyslogDestination2': 'rw' - } - }, - 'Destination3': { - 'Prop': { - 'SyslogDestination3': 'rw' - } - }, - 'Destination4': { - 'Prop': { - 'SyslogDestination4': 'rw' - } - }, - 'Destination5': { - 'Prop': { - 'SyslogDestination5': 'rw' - } - }, - 'Destination6': { - 'Prop': { - 'SyslogDestination6': 'rw' - } - }, - 'Destination7': { - 'Prop': { - 'SyslogDestination7': 'rw' - } - }, - 'Destination8': { - 'Prop': { - 'SyslogDestination8': 'rw' - } - }, - 'Destination9': { - 'Prop': { - 'SyslogDestination9': 'rw' - } - }, - 'Destination10': { - 'Prop': { - 'SyslogDestination10': 'rw' - } - }, - }, - 'SyslogSources': { - 'Prop': { - 'SyslogSourceConfiguration': 'rw' - } - }, - 'BatteryPowerSaving': { - 'Prop': { - 'PowerSavingEnabled': 'rw', - 'PowerSavingAlarm': 'rw', - 'PowerSavingThresholds': 'rw', - 'PowerSavingUnits': 'r-' - }, - 'Cmd': ( - 'PowerSavingAddUnit', - 'PowerSavingRemoveUnit' - ) - }, - 'Ipsec': { - 'Prop': { - 'Ipsec': 'rw' - } - }, - 'TemeratureLimits': { - 'Prop': { - 'ThresholdExceed': 'rw', - 'ThresholdWarning': 'rw' - } - }, - 'ESO': { - 'Prop': { - 'Eso1ClockSources': 'rw', - 'Eso2ClockSource': 'rw' - } - }, - 'PETS': { - 'Prop': { - 'ClockSources': 'rw', - 'PetsClockPriority': 'rw' - } - } - } - - fm = { - 'ActiveFailures': { - 'Prop': { - 'ActiveFailureTable': 'r-' - } - }, - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge' - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } - - status = { - 'DateAndTime': { - 'Time': { - 'Prop': { - 'Summary': 'r-' - }, - 'Cmd': ( - 'SetDateAndTime' - ) - }, - 'SNTPClient': { - 'Prop': { - 'PrimaryServerState': 'r-', - 'SecondaryServerState': 'r-', - 'LastResponseTime': 'r-', - 'LastJumpTime': 'r-', - 'LastAdjustmentTime': 'r-' - } - }, - }, - 'ManagementInterface': { - 'Prop': { - 'SshFingerprint': 'r-' - }, - 'Cmd': ( - 'Ping' - ) - }, - 'SessionManagement': { - 'Cmd': ( - 'ShowSessions' - ) - }, - 'RadiusClient': { - 'Prop': { - 'PrimaryRadiusServerStatus': 'r-', - 'AlternateRadiusServerStatus': 'r-' - } - }, - 'Ipsec': { - 'Prop': { - 'IpsecSAStatus': 'r-' - }, - 'Cmd': ( - 'GetIpsecLogbook' - ) - }, - 'Redundancy': { - 'Prop': { - 'NeConfigurationStatus': 'r-', - 'RedundancyRoles': 'r-', - 'RedundancyStatus': 'r-' - }, - 'Cmd': ( - 'ManualSwitchOver', - 'ForcedSwitchOver', - 'IsolateUnits', - 'JoinUnits' - ) - }, - 'Temperature': { - 'Prop': { - 'CurrTemperature': 'r-', - 'MaxTemperature': 'r-', - 'MinTemperature': 'r-' - }, - 'Cmd': ( - 'ResetMinMax' - ) - }, - 'ESO': { - 'Prop': { - 'ClockOutputEso1': 'r-', - 'ClockOutputEso2': 'r-' - } - }, - 'PETS': { - 'Prop': { - 'PetsClockSources': 'r-', - 'PetsOperationStatus': 'r-' - }, - 'Cmd': ( - 'PetsClockOperation' - ) - } - } + from .rootManagementFunctions import main + from .rootManagementFunctions import cfgm + from .rootManagementFunctions import fm + from .rootManagementFunctions import status def _init_access_points(self, context=None): for card in self._model.cards: diff --git a/vendors/KeyMile/accessPoints/root/rootManagementFunctions.py b/vendors/KeyMile/accessPoints/root/rootManagementFunctions.py new file mode 100644 index 0000000..479c920 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/rootManagementFunctions.py @@ -0,0 +1,333 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + }, + 'Logbooks': { + 'Cmd': ( + 'GetAllLogbooks', + 'GetAlarmLogbook', + 'GetEventLogbook', + 'GetConfigLogbook', + 'GetEquipmentLogbook', + 'GetSessionLogbook' + ) + }, + 'NESoftwareDownload': { + 'Cmd': ( + 'StartEsw', + ) + } +} + +cfgm = { + 'ConfigurationManagement': { + 'Prop': { + 'ConfigurationStatus': 'r-', + 'BackupDescription': 'r-' + }, + 'Cmd': ( + 'Load', + 'Save', + 'Initialize', + 'ChangeDescription' + ), + 'File': { + 'Configuration': 'rw' + } + }, + 'ManagementInterface': { + 'Prop': { + 'IP_Address': 'rw', + 'VlanId': 'rw', + 'ManagementVlanCoS': 'rw' + } + }, + 'Packet': { + 'Prop': { + 'Bridge': 'rw', + 'MACMovement': 'rw', + 'Traceability': 'rw', + 'PPPoA': 'rw' + } + }, + 'SessionManagement': { + 'Prop': { + 'TelnetEnabled': 'r-', + 'SshEnabled': 'r-', + 'UsbEnabled': 'r-', + 'RetryTime': 'r-', + 'SessionmanagerTime': 'r-', + 'AuthenticationManagementInterfaces': 'r-', + 'LocalAuthenticationFallback': 'r-', + 'RadiusDefaultUserclass': 'r-' + } + }, + 'RadiusClient': { + 'Prop': { + 'CommonRadius': 'r-', + 'PrimaryRadiusServer': 'r-', + 'AlternateRadiusServer': 'r-' + } + }, + 'DateAndTime': { + 'SNTPClient': { + 'Prop': { + 'OperationMode': 'rw', + 'PrimaryServer': 'rw', + 'SecondaryServer': 'rw', + 'PollingInterval': 'rw', + 'BroadcastDelay': 'rw' + } + }, + 'TimeZone': { + 'Prop': { + 'TimeZone': 'rw', + 'DaylightSaving': 'r-' + } + }, + }, + 'ProfileManagement': { + 'Prop': { + 'ProfileCpsTable': 'r-' + }, + 'Cmd': ( + 'Check', + 'Delete' + ), + 'File': { + 'Profile': 'rw', + 'Cps': 'rw' + } + }, + 'QoS': { + 'Prop': { + 'PriorityMapping': 'rw', + 'QueueMode': 'rw' + } + }, + 'SNMP': { + 'General': { + 'Prop': { + 'SNMPSupport': 'rw', + 'SNMPParameters': 'r-' + }, + 'Cmd': ( + 'SetDefaultSNMPConfigurationTables', + ) + }, + 'USM': { + 'Prop': { + 'LocalUserTable': 'rw', + 'RemoteUserTable': 'rw' + } + }, + }, + 'SyslogDestinations': { + 'Destination1': { + 'Prop': { + 'SyslogDestination1': 'rw' + } + }, + 'Destination2': { + 'Prop': { + 'SyslogDestination2': 'rw' + } + }, + 'Destination3': { + 'Prop': { + 'SyslogDestination3': 'rw' + } + }, + 'Destination4': { + 'Prop': { + 'SyslogDestination4': 'rw' + } + }, + 'Destination5': { + 'Prop': { + 'SyslogDestination5': 'rw' + } + }, + 'Destination6': { + 'Prop': { + 'SyslogDestination6': 'rw' + } + }, + 'Destination7': { + 'Prop': { + 'SyslogDestination7': 'rw' + } + }, + 'Destination8': { + 'Prop': { + 'SyslogDestination8': 'rw' + } + }, + 'Destination9': { + 'Prop': { + 'SyslogDestination9': 'rw' + } + }, + 'Destination10': { + 'Prop': { + 'SyslogDestination10': 'rw' + } + }, + }, + 'SyslogSources': { + 'Prop': { + 'SyslogSourceConfiguration': 'rw' + } + }, + 'BatteryPowerSaving': { + 'Prop': { + 'PowerSavingEnabled': 'rw', + 'PowerSavingAlarm': 'rw', + 'PowerSavingThresholds': 'rw', + 'PowerSavingUnits': 'r-' + }, + 'Cmd': ( + 'PowerSavingAddUnit', + 'PowerSavingRemoveUnit' + ) + }, + 'Ipsec': { + 'Prop': { + 'Ipsec': 'rw' + } + }, + 'TemeratureLimits': { + 'Prop': { + 'ThresholdExceed': 'rw', + 'ThresholdWarning': 'rw' + } + }, + 'ESO': { + 'Prop': { + 'Eso1ClockSources': 'rw', + 'Eso2ClockSource': 'rw' + } + }, + 'PETS': { + 'Prop': { + 'ClockSources': 'rw', + 'PetsClockPriority': 'rw' + } + } +} + +fm = { + 'ActiveFailures': { + 'Prop': { + 'ActiveFailureTable': 'r-' + } + }, + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +status = { + 'DateAndTime': { + 'Time': { + 'Prop': { + 'Summary': 'r-' + }, + 'Cmd': ( + 'SetDateAndTime', + ) + }, + 'SNTPClient': { + 'Prop': { + 'PrimaryServerState': 'r-', + 'SecondaryServerState': 'r-', + 'LastResponseTime': 'r-', + 'LastJumpTime': 'r-', + 'LastAdjustmentTime': 'r-' + } + }, + }, + 'ManagementInterface': { + 'Prop': { + 'SshFingerprint': 'r-' + }, + 'Cmd': ( + 'Ping', + ) + }, + 'SessionManagement': { + 'Cmd': ( + 'ShowSessions', + ) + }, + 'RadiusClient': { + 'Prop': { + 'PrimaryRadiusServerStatus': 'r-', + 'AlternateRadiusServerStatus': 'r-' + } + }, + 'Ipsec': { + 'Prop': { + 'IpsecSAStatus': 'r-' + }, + 'Cmd': ( + 'GetIpsecLogbook', + ) + }, + 'Redundancy': { + 'Prop': { + 'NeConfigurationStatus': 'r-', + 'RedundancyRoles': 'r-', + 'RedundancyStatus': 'r-' + }, + 'Cmd': ( + 'ManualSwitchOver', + 'ForcedSwitchOver', + 'IsolateUnits', + 'JoinUnits' + ) + }, + 'Temperature': { + 'Prop': { + 'CurrTemperature': 'r-', + 'MaxTemperature': 'r-', + 'MinTemperature': 'r-' + }, + 'Cmd': ( + 'ResetMinMax', + ) + }, + 'ESO': { + 'Prop': { + 'ClockOutputEso1': 'r-', + 'ClockOutputEso2': 'r-' + } + }, + 'PETS': { + 'Prop': { + 'PetsClockSources': 'r-', + 'PetsOperationStatus': 'r-' + }, + 'Cmd': ( + 'PetsClockOperation', + ) + } +} diff --git a/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py new file mode 100644 index 0000000..d93320a --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py @@ -0,0 +1,28 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class MacAccessCtrlCommandProcessor(BaseCommandProcessor): + __name__ = 'macAccessCtrl' + management_functions = ('main', 'cfgm', 'fm', 'status') + access_points = () + + from .macAccessCtrlManagementFunctions import main + from .macAccessCtrlManagementFunctions import cfgm + from .macAccessCtrlManagementFunctions import fm + from .macAccessCtrlManagementFunctions import status + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/macAccessCtrlManagementFunctions.py b/vendors/KeyMile/accessPoints/root/services/macAccessCtrlManagementFunctions.py new file mode 100644 index 0000000..4ec41f2 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/macAccessCtrlManagementFunctions.py @@ -0,0 +1,61 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'General': { + 'Prop': { + 'Blacklist': 'rw' + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + }, + 'DuplicatedMac': { + 'Prop': { + 'DuplicatedMacAccessList': 'r-' + }, + 'Cmd': ( + 'FlushMacAccessDuplicatedList', + ) + } +} + +status = { + 'DynamicList': { + 'Prop': { + 'DynamicList': 'r-' + }, + 'Cmd': ( + 'FlushMacAccessDynamicList', + 'DeleteMacAccessDynamicListEntry' + ) + }, + 'UNIBlacklist': { + 'Prop': { + 'Blacklist': 'r-', + 'BNGlist': 'r-' + }, + 'Cmd': ( + 'DeleteMacAccessBNGlistEntry', + ) + } +} diff --git a/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py similarity index 75% rename from vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py rename to vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py index e2bf785..96d4113 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py @@ -14,19 +14,12 @@ from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor -class ServicesPacketCommandProcessor(BaseCommandProcessor): - __name__ = 'servicesPacket' +class PacketCommandProcessor(BaseCommandProcessor): + __name__ = 'packet' management_functions = ('main',) access_points = ('1to1DoubleTag', '1to1SingeTag', 'mcast', 'nto1', 'pls', 'tls') - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } + from .packetManagementFunctions import main def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/packetManagementFunctions.py b/vendors/KeyMile/accessPoints/root/services/packetManagementFunctions.py new file mode 100644 index 0000000..ebb0f2f --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/packetManagementFunctions.py @@ -0,0 +1,8 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py index dcede08..253a74f 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -19,36 +19,9 @@ class ServicesCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'fm', 'status') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } - - status = { - 'Prop': { - 'conflictList': 'r-' - } - } + from .servicesManagementFunctions import main + from .servicesManagementFunctions import fm + from .servicesManagementFunctions import status def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py deleted file mode 100644 index aea38f2..0000000 --- a/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py +++ /dev/null @@ -1,85 +0,0 @@ -# This file is part of the NESi software. -# -# Copyright (c) 2020 -# Original Software Design by Ilya Etingof . -# -# Software adapted by inexio . -# - Janis Groß -# - Philip Konrath -# - Alexander Dincher -# -# License: https://github.com/inexio/NESi/LICENSE.rst - -from nesi import exceptions -from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor - - -class ServicesMacAccessCtrlCommandProcessor(BaseCommandProcessor): - __name__ = 'servicesMacAccessCtrl' - management_functions = ('main', 'cfgm', 'fm', 'status') - access_points = () - - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - cfgm = { - 'General': { - 'Prop': { - 'Blacklist': 'rw' - } - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - }, - 'DuplicatedMac': { - 'Prop': { - 'DuplicatedMacAccessList': 'r-' - }, - 'Cmd': ( - 'FlushMacAccessDuplicatedList', - ) - } - } - - status = { - 'DynamicList': { - 'Prop': { - 'DynamicList': 'r-' - }, - 'Cmd': ( - 'FlushMacAccessDynamicList', - 'DeleteMacAccessDynamicListEntry' - ) - }, - 'UNIBlacklist': { - 'Prop': { - 'Blacklist': 'r-', - 'BNGlist': 'r-' - }, - 'Cmd': ( - 'DeleteMacAccessBNGlistEntry', - ) - } - } - - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesManagementFunctions.py b/vendors/KeyMile/accessPoints/root/services/servicesManagementFunctions.py new file mode 100644 index 0000000..b1bccfc --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/servicesManagementFunctions.py @@ -0,0 +1,30 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +status = { + 'Prop': { + 'conflictList': 'r-' + } +} diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py index 905a06a..12b4d77 100644 --- a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py @@ -19,39 +19,8 @@ class TdmConnectionsCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - cfgm = { - 'Connections': { - 'Cmd': ( - 'CreateConnection', - 'CreateBulkConnection', - 'CreateAdvancedConnection', - 'DeleteConnection', - 'DeleteMultipleConnections', - 'ShowConnections', - 'SetLabel1', - 'SetLabel2' - ) - }, - 'Ctps': { - 'Cmd': ( - 'ShowCtps', - ) - }, - 'Pbus': { - 'Prop': { - 'PbusUsage': 'r-' - } - } - } + from .tdmConnectionsManagementFunctions import main + from .tdmConnectionsManagementFunctions import cfgm def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsManagementFunctions.py b/vendors/KeyMile/accessPoints/root/tdmConnectionsManagementFunctions.py new file mode 100644 index 0000000..894d3f3 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/tdmConnectionsManagementFunctions.py @@ -0,0 +1,33 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'Connections': { + 'Cmd': ( + 'CreateConnection', + 'CreateBulkConnection', + 'CreateAdvancedConnection', + 'DeleteConnection', + 'DeleteMultipleConnections', + 'ShowConnections', + 'SetLabel1', + 'SetLabel2' + ) + }, + 'Ctps': { + 'Cmd': ( + 'ShowCtps', + ) + }, + 'Pbus': { + 'Prop': { + 'PbusUsage': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index e0d8ea3..2f4b9b9 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -19,106 +19,11 @@ class ChanCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - cfgm = { - 'Profile': { - 'Prop': { - 'ChanProfile': 'rw' - } - }, - 'subinterface': { - 'Cmd': ( - 'CreateInterface', - 'DeleteInterface' - ) - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } - - pm = { - 'PerformanceMonitoring': { - 'Cmd': ( - 'UserCounter', - 'GetHistory15min', - 'GetHistory24h', - 'GetAlarm15min', - 'GetAlarm24hRecursive', - 'ResetUserCounter', - 'ResetAlarm15min', - 'ResetAlarm24h' - ) - }, - 'UserCounter': { - 'Prop': { - 'UserCounterDisplayMode': 'rw', - 'UserCounterTable': 'r-' - }, - 'Cmd': ( - 'UserCounterReset', - ) - }, - 'History15min': { - 'Prop': { - 'History15minDisplayMode': 'rw', - 'History15minTable': 'r-' - } - }, - 'History24h': { - 'Prop': { - 'History24hDisplayMode': 'rw', - 'History24hTable': 'r-' - } - }, - 'Alarm15min': { - 'Prop': { - 'Alarm15minDisplayMode': 'rw', - 'Alarm15minTable': 'r-' - }, - 'Cmd': ( - 'Alarm15minReset', - ) - }, - 'Alarm24h': { - 'Prop': { - 'Alarm24hDisplayMode': 'rw', - 'Alarm24hTable': 'r-' - }, - 'Cmd': ( - 'Alarm24hReset', - ) - } - } - - status = { - 'General': { - 'Prop': { - 'Status': 'r-' - } - } - } + from .chanManagementFunctions import main + from .chanManagementFunctions import cfgm + from .chanManagementFunctions import fm + from .chanManagementFunctions import pm + from .chanManagementFunctions import status def _init_access_points(self, context=None): chan = self._model.get_chan('name', context['unit'] + '/' + context['port'] + '/' + context['chan']) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanManagementFunctions.py new file mode 100644 index 0000000..ab83570 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanManagementFunctions.py @@ -0,0 +1,100 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'Profile': { + 'Prop': { + 'ChanProfile': 'rw' + } + }, + 'subinterface': { + 'Cmd': ( + 'CreateInterface', + 'DeleteInterface' + ) + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } +} + +status = { + 'General': { + 'Prop': { + 'Status': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py index 21d96b0..40d569a 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py @@ -19,110 +19,10 @@ class VccCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'pm', 'status') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - cfgm = { - 'Traceability': { - 'Prop': { - 'AutomaticAgentCircuitId': 'rw', - 'AgentCircuitId': 'rw' - } - }, - 'Filter': { - 'Prop': { - 'MACSourceFilteringMode': 'rw', - 'MacAccessWhitelist': 'rw', - 'NumberOfMacForFloodingPrev': 'rw', - 'L2CPFilter': 'rw', - 'DestMacBlacklistProfile': 'rw', - 'SrcMacBlacklist': 'rw' - } - }, - 'IfRateLimiter': { - 'Prop': { - 'IfRateLimiting': 'rw' - } - }, - 'Profiles': { - 'Prop': { - 'configuredProfiles': 'rw' - } - } - } - - pm = { - 'PerformanceMonitoring': { - 'Cmd': ( - 'UserCounter', - 'GetHistory15min', - 'GetHistory24h', - 'GetAlarm15min', - 'GetAlarm24hRecursive', - 'ResetUserCounter', - 'ResetAlarm15min', - 'ResetAlarm24h' - ) - }, - 'UserCounter': { - 'Prop': { - 'UserCounterDisplayMode': 'rw', - 'UserCounterTable': 'r-' - }, - 'Cmd': ( - 'UserCounterReset', - ) - }, - 'History15min': { - 'Prop': { - 'History15minDisplayMode': 'rw', - 'History15minTable': 'r-' - } - }, - 'History24h': { - 'Prop': { - 'History24hDisplayMode': 'rw', - 'History24hTable': 'r-' - } - }, - 'Alarm15min': { - 'Prop': { - 'Alarm15minDisplayMode': 'rw', - 'Alarm15minTable': 'r-' - }, - 'Cmd': ( - 'Alarm15minReset', - ) - }, - 'Alarm24h': { - 'Prop': { - 'Alarm24hDisplayMode': 'rw', - 'Alarm24hTable': 'r-' - }, - 'Cmd': ( - 'Alarm24hReset', - ) - } - } - - status = { - 'ServiceInfo': { - 'Prop': { - 'ServiceStatus': 'r-' - } - }, - 'UserConnection': { - 'Prop': { - 'CurrentPppConnectionState': 'r-' - } - } - } + from .vccManagementFunctions import main + from .vccManagementFunctions import cfgm + from .vccManagementFunctions import pm + from .vccManagementFunctions import status def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py new file mode 100644 index 0000000..9278f33 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py @@ -0,0 +1,104 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'Traceability': { + 'Prop': { + 'AutomaticAgentCircuitId': 'rw', + 'AgentCircuitId': 'rw' + } + }, + 'Filter': { + 'Prop': { + 'MACSourceFilteringMode': 'rw', + 'MacAccessWhitelist': 'rw', + 'NumberOfMacForFloodingPrev': 'rw', + 'L2CPFilter': 'rw', + 'DestMacBlacklistProfile': 'rw', + 'SrcMacBlacklist': 'rw' + } + }, + 'IfRateLimiter': { + 'Prop': { + 'IfRateLimiting': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'configuredProfiles': 'rw' + } + } +} + +pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } +} + +status = { + 'ServiceInfo': { + 'Prop': { + 'ServiceStatus': 'r-' + } + }, + 'UserConnection': { + 'Prop': { + 'CurrentPppConnectionState': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index d8638a1..5bbae5d 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -19,110 +19,10 @@ class InterfaceCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'pm', 'status') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - cfgm = { - 'Traceability': { - 'Prop': { - 'AutomaticAgentCircuitId': 'rw', - 'AgentCircuitId': 'rw' - } - }, - 'Filter': { - 'Prop': { - 'MACSourceFilteringMode': 'rw', - 'MacAccessWhitelist': 'rw', - 'NumberOfMacForFloodingPrev': 'rw', - 'L2CPFilter': 'rw', - 'DestMacBlacklistProfile': 'rw', - 'SrcMacBlacklist': 'rw' - } - }, - 'IfRateLimiter': { - 'Prop': { - 'IfRateLimiting': 'rw' - } - }, - 'Profiles': { - 'Prop': { - 'configuredProfiles': 'rw' - } - } - } - - pm = { - 'PerformanceMonitoring': { - 'Cmd': ( - 'UserCounter', - 'GetHistory15min', - 'GetHistory24h', - 'GetAlarm15min', - 'GetAlarm24hRecursive', - 'ResetUserCounter', - 'ResetAlarm15min', - 'ResetAlarm24h' - ) - }, - 'UserCounter': { - 'Prop': { - 'UserCounterDisplayMode': 'rw', - 'UserCounterTable': 'r-' - }, - 'Cmd': ( - 'UserCounterReset', - ) - }, - 'History15min': { - 'Prop': { - 'History15minDisplayMode': 'rw', - 'History15minTable': 'r-' - } - }, - 'History24h': { - 'Prop': { - 'History24hDisplayMode': 'rw', - 'History24hTable': 'r-' - } - }, - 'Alarm15min': { - 'Prop': { - 'Alarm15minDisplayMode': 'rw', - 'Alarm15minTable': 'r-' - }, - 'Cmd': ( - 'Alarm15minReset', - ) - }, - 'Alarm24h': { - 'Prop': { - 'Alarm24hDisplayMode': 'rw', - 'Alarm24hTable': 'r-' - }, - 'Cmd': ( - 'Alarm24hReset', - ) - } - } - - status = { - 'ServiceInfo': { - 'Prop': { - 'ServiceStatus': 'r-' - } - }, - 'UserConnection': { - 'Prop': { - 'CurrentPppConnectionState': 'r-' - } - } - } + from .interfaceManagementFunctions import main + from .interfaceManagementFunctions import cfgm + from .interfaceManagementFunctions import pm + from .interfaceManagementFunctions import status def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceManagementFunctions.py new file mode 100644 index 0000000..9278f33 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceManagementFunctions.py @@ -0,0 +1,104 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'Traceability': { + 'Prop': { + 'AutomaticAgentCircuitId': 'rw', + 'AgentCircuitId': 'rw' + } + }, + 'Filter': { + 'Prop': { + 'MACSourceFilteringMode': 'rw', + 'MacAccessWhitelist': 'rw', + 'NumberOfMacForFloodingPrev': 'rw', + 'L2CPFilter': 'rw', + 'DestMacBlacklistProfile': 'rw', + 'SrcMacBlacklist': 'rw' + } + }, + 'IfRateLimiter': { + 'Prop': { + 'IfRateLimiting': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'configuredProfiles': 'rw' + } + } +} + +pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } +} + +status = { + 'ServiceInfo': { + 'Prop': { + 'ServiceStatus': 'r-' + } + }, + 'UserConnection': { + 'Prop': { + 'CurrentPppConnectionState': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index beadf56..e9b392e 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -19,340 +19,11 @@ class PortCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'AdminAndOperStatus': { - 'Prop': { - 'AdministrativeStatus': 'rw', - 'OperationalStatus': 'r-' - } - } - } - - cfgm = { - 'Multicast': { - 'Prop': { - 'MaxNumberOfMulticastStreams': 'rw', - 'EnableIgmpClassifier': 'rw', - 'AllowStaticStreams': 'rw', - 'EnableFastLeave': 'rw', - 'GroupManagement': 'rw', - 'Bandwidth': 'rw' - }, - 'Cmd': ( - 'GetGroupList', - ) - }, - 'Traceability': { - 'Prop': { - 'AgentRemoteId': 'rw' - } - }, - 'Security': { - 'Prop': { - 'ServiceOptions': 'rw', - 'MaxNumberOfMac': 'rw' - } - }, - 'AccessControl': { - 'Prop': { - 'ClassificationKey': 'rw', - 'MAT': 'rw' - } - }, - 'RateLimiter': { - 'Prop': { - 'RateLimiting': 'rw', - 'RateLimitingCoS': 'rw' - } - }, - 'Qos': { - 'Prop': { - 'WfqProfile': 'rw' - } - }, - 'Wire': { - 'Prop': { - 'MeltConfiguration': 'rw' - } - }, - 'Profiles': { - 'Prop': { - 'PortProfiles': 'rw' - } - }, - 'Misc': { - 'Prop': { - 'SpecificDPBO': 'rw', - 'SpecificUPBO': 'rw' - } - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } - - pm = { - 'PerformanceMonitoring': { - 'Cmd': ( - 'UserCounter', - 'GetHistory15min', - 'GetHistory24h', - 'GetAlarm15min', - 'GetAlarm24hRecursive', - 'ResetUserCounter', - 'ResetAlarm15min', - 'ResetAlarm24h' - ) - }, - 'UserCounter': { - 'Prop': { - 'UserCounterDisplayMode': 'rw', - 'UserCounterTable': 'r-' - }, - 'Cmd': ( - 'UserCounterReset', - ) - }, - 'History15min': { - 'Prop': { - 'History15minDisplayMode': 'rw', - 'History15minTable': 'r-' - } - }, - 'History24h': { - 'Prop': { - 'History24hDisplayMode': 'rw', - 'History24hTable': 'r-' - } - }, - 'Alarm15min': { - 'Prop': { - 'Alarm15minDisplayMode': 'rw', - 'Alarm15minTable': 'r-' - }, - 'Cmd': ( - 'Alarm15minReset', - ) - }, - 'Alarm24h': { - 'Prop': { - 'Alarm24hDisplayMode': 'rw', - 'Alarm24hTable': 'r-' - }, - 'Cmd': ( - 'Alarm24hReset', - ) - } - } - - status = { - 'General': { - 'Prop': { - 'Standard': 'r-', - 'PowerMgmStatus': 'r-', - 'Vdsl2Parameters': 'r-', - 'EstUPBOElectricalLength': 'r-', - 'LineRate': 'r-', - 'LineSnrMargin': 'r-', - 'AttainableNetDataRate': 'r-', - 'AttainableRate': 'r-', - 'OutputPower': 'r-', - 'BandStatus': 'r-' - } - }, - 'statistics': { - 'Prop': { - 'counters': 'r-', - 'PolicingCounters': 'r-' - }, - 'Cmd': ( - 'ResetPortCounters', - ) - }, - 'Nto1MacAccessDynamicList': { - 'Prop': { - 'UnicastList': 'r-' - } - }, - 'HostPortStatistics': { - 'GeneralCounters': { - 'Prop': { - 'GeneralList': 'r-' - }, - 'Cmd': ( - 'ResetGeneralCounters', - ) - }, - 'ProtocolCounters': { - 'IgmpCounters': { - 'Prop': { - 'IgmpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetIgmpCounters', - ) - }, - 'DhcpCounters': { - 'Prop': { - 'DhcpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetDhcpCounters', - ) - }, - 'ArpCounters': { - 'Prop': { - 'ArpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetArpCounters', - ) - }, - 'PPPoECounters': { - 'Prop': { - 'PPPoEProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetPPPoECounters', - ) - }, - 'UnknownSourceMACCounters': { - 'Prop': { - 'UnknownSrcMACProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetUnknownSrcMACCounters', - ) - }, - }, - }, - 'TLSMacForwardingList': { - 'Prop': { - 'MacForwardingList': 'r-' - }, - 'Cmd': ( - 'FlushMacForwardingList', - ) - }, - '1to1MacForwardingList': { - 'Prop': { - 'One2OneMacForwardingList': 'r-' - } - }, - 'Qos': { - 'Prop': { - 'wfqueues': 'r-' - } - }, - 'Multicast': { - 'stream': { - 'Dynamic': { - 'Prop': { - 'ActiveStreams': 'r-' - }, - 'Cmd': ( - 'ClearActiveStreams', - ) - }, - 'Static': { - 'Prop': { - 'StaticStreams': 'r-' - } - }, - }, - - 'Vlan': { - 'Prop': { - 'AttachedVlans': 'r-' - } - }, - 'Preview': { - 'Cmd': ( - 'ResetPreviewSettings', - ) - }, - 'Bandwidth': { - 'Prop': { - 'bandwidthStatus': 'r-' - } - }, - }, - 'LineTest': { - 'MELT': { - 'Prop': { - 'MeltResults': 'r-' - }, - 'Cmd': ( - 'StartMeltMeasurement', - ) - }, - 'Delt': { - 'Prop': { - 'DeltMeasurementStatus': 'r-', - 'RecordedDeltMeasurements': 'r-' - }, - 'Cmd': ( - 'StartDeltMeasurement', - ) - }, - 'Selt': { - 'Prop': { - 'SeltMeasurementStatus': 'r-', - 'RecordedSeltMeasurements': 'r-', - 'CableType': 'rw', - 'BandplanProfile': 'rw', - 'TargetSnrm': 'rw' - }, - 'Cmd': ( - 'StartSeltMeasurement', - ) - }, - }, - 'Defects': { - 'Prop': { - 'Defects': 'r-' - } - }, - 'LineInventory': { - 'Prop': { - 'VendorId': 'r-' - } - }, - 'Maintenance': { - 'Prop': { - 'DslOperationStatus': 'r-' - } - }, - 'Subcarrier': { - 'Cmd': ( - 'ShowBitAllocation', - ) - }, - 'RfiBands': { - 'Prop': { - 'NotchStatus': 'r-' - } - } - } + from .portManagementFunctions import main + from .portManagementFunctions import cfgm + from .portManagementFunctions import fm + from .portManagementFunctions import pm + from .portManagementFunctions import status def do_get(self, command, *args, context=None): scopes = ('login', 'base', 'get') diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/port/portManagementFunctions.py new file mode 100644 index 0000000..9529dba --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/portManagementFunctions.py @@ -0,0 +1,334 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + } +} + +cfgm = { + 'Multicast': { + 'Prop': { + 'MaxNumberOfMulticastStreams': 'rw', + 'EnableIgmpClassifier': 'rw', + 'AllowStaticStreams': 'rw', + 'EnableFastLeave': 'rw', + 'GroupManagement': 'rw', + 'Bandwidth': 'rw' + }, + 'Cmd': ( + 'GetGroupList', + ) + }, + 'Traceability': { + 'Prop': { + 'AgentRemoteId': 'rw' + } + }, + 'Security': { + 'Prop': { + 'ServiceOptions': 'rw', + 'MaxNumberOfMac': 'rw' + } + }, + 'AccessControl': { + 'Prop': { + 'ClassificationKey': 'rw', + 'MAT': 'rw' + } + }, + 'RateLimiter': { + 'Prop': { + 'RateLimiting': 'rw', + 'RateLimitingCoS': 'rw' + } + }, + 'Qos': { + 'Prop': { + 'WfqProfile': 'rw' + } + }, + 'Wire': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'PortProfiles': 'rw' + } + }, + 'Misc': { + 'Prop': { + 'SpecificDPBO': 'rw', + 'SpecificUPBO': 'rw' + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } +} + +status = { + 'General': { + 'Prop': { + 'Standard': 'r-', + 'PowerMgmStatus': 'r-', + 'Vdsl2Parameters': 'r-', + 'EstUPBOElectricalLength': 'r-', + 'LineRate': 'r-', + 'LineSnrMargin': 'r-', + 'AttainableNetDataRate': 'r-', + 'AttainableRate': 'r-', + 'OutputPower': 'r-', + 'BandStatus': 'r-' + } + }, + 'statistics': { + 'Prop': { + 'counters': 'r-', + 'PolicingCounters': 'r-' + }, + 'Cmd': ( + 'ResetPortCounters', + ) + }, + 'Nto1MacAccessDynamicList': { + 'Prop': { + 'UnicastList': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters', + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + }, + }, + 'TLSMacForwardingList': { + 'Prop': { + 'MacForwardingList': 'r-' + }, + 'Cmd': ( + 'FlushMacForwardingList', + ) + }, + '1to1MacForwardingList': { + 'Prop': { + 'One2OneMacForwardingList': 'r-' + } + }, + 'Qos': { + 'Prop': { + 'wfqueues': 'r-' + } + }, + 'Multicast': { + 'stream': { + 'Dynamic': { + 'Prop': { + 'ActiveStreams': 'r-' + }, + 'Cmd': ( + 'ClearActiveStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticStreams': 'r-' + } + }, + }, + + 'Vlan': { + 'Prop': { + 'AttachedVlans': 'r-' + } + }, + 'Preview': { + 'Cmd': ( + 'ResetPreviewSettings', + ) + }, + 'Bandwidth': { + 'Prop': { + 'bandwidthStatus': 'r-' + } + }, + }, + 'LineTest': { + 'MELT': { + 'Prop': { + 'MeltResults': 'r-' + }, + 'Cmd': ( + 'StartMeltMeasurement', + ) + }, + 'Delt': { + 'Prop': { + 'DeltMeasurementStatus': 'r-', + 'RecordedDeltMeasurements': 'r-' + }, + 'Cmd': ( + 'StartDeltMeasurement', + ) + }, + 'Selt': { + 'Prop': { + 'SeltMeasurementStatus': 'r-', + 'RecordedSeltMeasurements': 'r-', + 'CableType': 'rw', + 'BandplanProfile': 'rw', + 'TargetSnrm': 'rw' + }, + 'Cmd': ( + 'StartSeltMeasurement', + ) + }, + }, + 'Defects': { + 'Prop': { + 'Defects': 'r-' + } + }, + 'LineInventory': { + 'Prop': { + 'VendorId': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'DslOperationStatus': 'r-' + } + }, + 'Subcarrier': { + 'Cmd': ( + 'ShowBitAllocation', + ) + }, + 'RfiBands': { + 'Prop': { + 'NotchStatus': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 9c218de..368a108 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -19,200 +19,10 @@ class UnitCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'status') access_points = () #'internalPorts', only on certain cards - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'Equipment': { - 'Prop': { - 'AssignmentStatus': 'r-', - 'CurrentStatus': 'r-' - }, - 'Cmd': ( - 'Assign', - 'Unassign', - 'Restart', - 'StopInBoot' - ) - }, - 'Inventory': { - 'Prop': { - 'EquipmentInventory': 'r-' - } - }, - 'Logbooks': { - 'Cmd': ( - 'GetAlarmLogbook', - 'GetEventLogbook', - 'GetEquipmentLogbook' - ) - }, - 'Software': { - 'Prop': { - 'DiskSpace': 'r-', - 'SoftwareOnUnit': 'r-', - 'HardwareAndSoftware': 'r-', - 'Status': 'r-', - 'Configuration': 'rw' - }, - 'Cmd': ( - 'DeleteSoftware', - 'StartSoftware' - ), - 'File': { - 'Software': 'rw' - } - } - } - - cfgm = { - 'Vlan': { - 'Prop': { - 'VlanCosTable': 'r-' - } - }, - 'Security': { - 'Prop': { - 'filtering': 'rw', - 'EoamMode': 'rw' - } - }, - 'Logon': { - 'Prop': { - 'LogonOptions': 'rw', - 'OneToOneOptions': 'rw' - } - }, - 'Mac': { - 'Prop': { - 'MacServiceBased': 'rw' - } - }, - 'HostPort': { - 'Prop': { - 'PolicerProfile': 'rw', - 'TrunkPolicerProfile': 'rw', - 'ProtRateLimiter': 'rw' - } - }, - 'QoS': { - 'Prop': { - 'ColorMarking': 'rw' - } - }, - 'Wire': { - 'General': { - 'Prop': { - 'MeltConfiguration': 'rw' - } - }, - 'Thresholds': { - 'Prop': { - 'MeltAlarmThresholds': 'rw' - } - } - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge' - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } - - status = { - 'MacAllocationTable': { - 'Prop': { - 'MacAllocationTableEntries': 'r-' - } - }, - 'SwitchPort': { - 'Prop': { - 'Mac': 'r-', - 'MacStatus': 'r-' - } - }, - 'HostPortStatistics': { - 'GeneralCounters': { - 'Prop': { - 'GeneralList': 'r-' - }, - 'Cmd': ( - 'ResetGeneralCounters' - ) - }, - 'ProtocolCounters': { - 'IgmpCounters': { - 'Prop': { - 'IgmpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetIgmpCounters' - ) - }, - 'DhcpCounters': { - 'Prop': { - 'DhcpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetDhcpCounters' - ) - }, - 'ArpCounters': { - 'Prop': { - 'ArpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetArpCounters' - ) - }, - 'PPPoECounters': { - 'Prop': { - 'PPPoEProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetPPPoECounters' - ) - }, - 'UnknownSourceMACCounters': { - 'Prop': { - 'UnknownSrcMACProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetUnknownSrcMACCounters' - ) - }, - }, - }, - 'BufferManagement': { - 'Prop': { - 'BufferMgmtStatus': 'r-' - } - }, - 'Maintenance': { - 'Prop': { - 'MeltLineTestStatus': 'r-', - 'SearchTone': 'rw' - }, - 'Cmd': ( - 'StartMeltAll', - 'StopMeltAll' - ) - } - } + from .unitManagementFunctions import main + from .unitManagementFunctions import cfgm + from .unitManagementFunctions import fm + from .unitManagementFunctions import status def _init_access_points(self, context=None): card = self._model.get_card('name', context['unit']) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/unitManagementFunctions.py new file mode 100644 index 0000000..0a5adbd --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/unitManagementFunctions.py @@ -0,0 +1,194 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'Equipment': { + 'Prop': { + 'AssignmentStatus': 'r-', + 'CurrentStatus': 'r-' + }, + 'Cmd': ( + 'Assign', + 'Unassign', + 'Restart', + 'StopInBoot' + ) + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + }, + 'Logbooks': { + 'Cmd': ( + 'GetAlarmLogbook', + 'GetEventLogbook', + 'GetEquipmentLogbook' + ) + }, + 'Software': { + 'Prop': { + 'DiskSpace': 'r-', + 'SoftwareOnUnit': 'r-', + 'HardwareAndSoftware': 'r-', + 'Status': 'r-', + 'Configuration': 'rw' + }, + 'Cmd': ( + 'DeleteSoftware', + 'StartSoftware' + ), + 'File': { + 'Software': 'rw' + } + } +} + +cfgm = { + 'Vlan': { + 'Prop': { + 'VlanCosTable': 'r-' + } + }, + 'Security': { + 'Prop': { + 'filtering': 'rw', + 'EoamMode': 'rw' + } + }, + 'Logon': { + 'Prop': { + 'LogonOptions': 'rw', + 'OneToOneOptions': 'rw' + } + }, + 'Mac': { + 'Prop': { + 'MacServiceBased': 'rw' + } + }, + 'HostPort': { + 'Prop': { + 'PolicerProfile': 'rw', + 'TrunkPolicerProfile': 'rw', + 'ProtRateLimiter': 'rw' + } + }, + 'QoS': { + 'Prop': { + 'ColorMarking': 'rw' + } + }, + 'Wire': { + 'General': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Thresholds': { + 'Prop': { + 'MeltAlarmThresholds': 'rw' + } + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +status = { + 'MacAllocationTable': { + 'Prop': { + 'MacAllocationTableEntries': 'r-' + } + }, + 'SwitchPort': { + 'Prop': { + 'Mac': 'r-', + 'MacStatus': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters', + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + }, + }, + 'BufferManagement': { + 'Prop': { + 'BufferMgmtStatus': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'MeltLineTestStatus': 'r-', + 'SearchTone': 'rw' + }, + 'Cmd': ( + 'StartMeltAll', + 'StopMeltAll' + ) + } +} From 6072944fa3a62e0189944e4fdd1b3ada59726532 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 2 Oct 2020 14:29:32 +0200 Subject: [PATCH 079/318] Added create_spacers function again --- vendors/KeyMile/baseCommandProcessor.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 185e14a..d6463c9 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -46,6 +46,18 @@ def map_states(self, object, type): if type == 'port': object.operational_state = 'Down' + def create_spacers(self, positions, args): + spacers = [] + previous_pos = 0 + i = 0 + for position in positions: + spacer = position - (previous_pos + len(str(args[i]))) + spacers.append(spacer) + previous_pos = position + i += 1 + + return spacers + def do_help(self, command, *args, context=None): help_scopes = ('login', 'base', 'help') if self._validate(args, str): @@ -88,6 +100,9 @@ def do_pwd(self, command, *args, context=None): context['spacer'] = self.create_spacers((67,), (context['path'],))[0] * ' ' self._write(self._render('pwd', 'login', 'base', context=context)) + def exec_in_path(self, path, command, *args, context=None): + pass + def do_cd(self, command, *args, context=None): if len(args) == 0: exc = exceptions.CommandSyntaxError(command=command) @@ -304,6 +319,12 @@ def generate_ls_text(layers, depth): text += self._render('ls_list_body', *scopes, context=context) self._write(text) + elif self._validate(args, '-e'): + pass + elif self._validate([args[0]], str): + path = args[0] + + self.do_cd('cd', path, context=context) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=command) From b6ab25466c27509f2894029ea9bb15f29e38a9d6 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 5 Oct 2020 12:29:31 +0200 Subject: [PATCH 080/318] Fixed base_views to handle new keymile schemas --- nesi/keymile/api/schemas/__init__.py | 17 +++++++++++++++++ nesi/softbox/api/views/base_views.py | 1 + 2 files changed, 18 insertions(+) diff --git a/nesi/keymile/api/schemas/__init__.py b/nesi/keymile/api/schemas/__init__.py index e69de29..04e408d 100644 --- a/nesi/keymile/api/schemas/__init__.py +++ b/nesi/keymile/api/schemas/__init__.py @@ -0,0 +1,17 @@ +from inspect import isclass +from pkgutil import iter_modules +from pathlib import Path +from importlib import import_module + +# iterate through the modules in the current package +package_dir = Path(__file__).resolve().parent +for (_, module_name, _) in iter_modules([package_dir]): + + # import the module and iterate through its attributes + module = import_module(f"{__name__}.{module_name}") + for attribute_name in dir(module): + attribute = getattr(module, attribute_name) + + if isclass(attribute): + # Add the class to this package's variables + globals()[attribute_name] = attribute \ No newline at end of file diff --git a/nesi/softbox/api/views/base_views.py b/nesi/softbox/api/views/base_views.py index ac46d02..4259e94 100644 --- a/nesi/softbox/api/views/base_views.py +++ b/nesi/softbox/api/views/base_views.py @@ -20,6 +20,7 @@ from nesi.softbox.api.schemas import * from nesi.alcatel.api.schemas import * from nesi.huawei.api.schemas import * +from nesi.keymile.api.schemas import * # important for other view classes from nesi.softbox.api import db From 29127760e0f3562495ea24e8e45e5a659a9fc1bb Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 6 Oct 2020 09:45:34 +0200 Subject: [PATCH 081/318] Initialize Keymile testsetup --- .../integration_tests/keymile/backup.txt | 3 ++ .../integration_tests/keymile/getDslam4.txt | 3 ++ .../keymile/getInventory2.txt | 3 ++ .../integration_tests/keymile/getIpsx7.txt | 3 ++ .../keymile/getMonitoring3.txt | 3 ++ .../integration_tests/keymile/getState1.txt | 3 ++ .../keymile/getSubscriber6.txt | 3 ++ .../integration_tests/keymile/getVoice5.txt | 3 ++ .../keymile/setChannelProfile14.txt | 3 ++ .../keymile/setDslProfile8.txt | 3 ++ .../keymile/setInterface16.txt | 3 ++ .../integration_tests/keymile/setIpAddr6.txt | 3 ++ .../keymile/setPortProfile13.txt | 3 ++ .../integration_tests/keymile/setProfile7.txt | 3 ++ .../keymile/setSIPDomain12.txt | 3 ++ .../integration_tests/keymile/setTraffic1.txt | 3 ++ .../integration_tests/keymile/setVCC15.txt | 3 ++ .../integration_tests/keymile/setconfDsl2.txt | 3 ++ .../keymile/setconfVoice9.txt | 3 ++ .../keymile/setdeconfVoicePort11.txt | 3 ++ .../keymile/setdeconfVoicePort17.txt | 3 ++ .../keymile/setportaktiv4.txt | 3 ++ .../keymile/setportdeactiv5.txt | 3 ++ .../keymile/setunconfDsl3.txt | 3 ++ .../keymile/setunconfVoice10.txt | 3 ++ .../keymile/test Loopback3.txt | 3 ++ .../keymile/testVoicePort2.txt | 3 ++ .../integration_tests/keymile/testmelt1.txt | 3 ++ .../keymile/testmelting4.txt | 3 ++ test_cases/unit_tests/keymile/test_keymile.py | 41 ++++++++++++------- 30 files changed, 113 insertions(+), 15 deletions(-) create mode 100644 test_cases/integration_tests/keymile/backup.txt create mode 100644 test_cases/integration_tests/keymile/getDslam4.txt create mode 100644 test_cases/integration_tests/keymile/getInventory2.txt create mode 100644 test_cases/integration_tests/keymile/getIpsx7.txt create mode 100644 test_cases/integration_tests/keymile/getMonitoring3.txt create mode 100644 test_cases/integration_tests/keymile/getState1.txt create mode 100644 test_cases/integration_tests/keymile/getSubscriber6.txt create mode 100644 test_cases/integration_tests/keymile/getVoice5.txt create mode 100644 test_cases/integration_tests/keymile/setChannelProfile14.txt create mode 100644 test_cases/integration_tests/keymile/setDslProfile8.txt create mode 100644 test_cases/integration_tests/keymile/setInterface16.txt create mode 100644 test_cases/integration_tests/keymile/setIpAddr6.txt create mode 100644 test_cases/integration_tests/keymile/setPortProfile13.txt create mode 100644 test_cases/integration_tests/keymile/setProfile7.txt create mode 100644 test_cases/integration_tests/keymile/setSIPDomain12.txt create mode 100644 test_cases/integration_tests/keymile/setTraffic1.txt create mode 100644 test_cases/integration_tests/keymile/setVCC15.txt create mode 100644 test_cases/integration_tests/keymile/setconfDsl2.txt create mode 100644 test_cases/integration_tests/keymile/setconfVoice9.txt create mode 100644 test_cases/integration_tests/keymile/setdeconfVoicePort11.txt create mode 100644 test_cases/integration_tests/keymile/setdeconfVoicePort17.txt create mode 100644 test_cases/integration_tests/keymile/setportaktiv4.txt create mode 100644 test_cases/integration_tests/keymile/setportdeactiv5.txt create mode 100644 test_cases/integration_tests/keymile/setunconfDsl3.txt create mode 100644 test_cases/integration_tests/keymile/setunconfVoice10.txt create mode 100644 test_cases/integration_tests/keymile/test Loopback3.txt create mode 100644 test_cases/integration_tests/keymile/testVoicePort2.txt create mode 100644 test_cases/integration_tests/keymile/testmelt1.txt create mode 100644 test_cases/integration_tests/keymile/testmelting4.txt diff --git a/test_cases/integration_tests/keymile/backup.txt b/test_cases/integration_tests/keymile/backup.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/backup.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getDslam4.txt b/test_cases/integration_tests/keymile/getDslam4.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/getDslam4.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getInventory2.txt b/test_cases/integration_tests/keymile/getInventory2.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/getInventory2.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getIpsx7.txt b/test_cases/integration_tests/keymile/getIpsx7.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/getIpsx7.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getMonitoring3.txt b/test_cases/integration_tests/keymile/getMonitoring3.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/getMonitoring3.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getState1.txt b/test_cases/integration_tests/keymile/getState1.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/getState1.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getSubscriber6.txt b/test_cases/integration_tests/keymile/getSubscriber6.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/getSubscriber6.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getVoice5.txt b/test_cases/integration_tests/keymile/getVoice5.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/getVoice5.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setChannelProfile14.txt b/test_cases/integration_tests/keymile/setChannelProfile14.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setChannelProfile14.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setDslProfile8.txt b/test_cases/integration_tests/keymile/setDslProfile8.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setDslProfile8.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setInterface16.txt b/test_cases/integration_tests/keymile/setInterface16.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setInterface16.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setIpAddr6.txt b/test_cases/integration_tests/keymile/setIpAddr6.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setIpAddr6.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setPortProfile13.txt b/test_cases/integration_tests/keymile/setPortProfile13.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setPortProfile13.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setProfile7.txt b/test_cases/integration_tests/keymile/setProfile7.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setProfile7.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setSIPDomain12.txt b/test_cases/integration_tests/keymile/setSIPDomain12.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setSIPDomain12.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setTraffic1.txt b/test_cases/integration_tests/keymile/setTraffic1.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setTraffic1.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setVCC15.txt b/test_cases/integration_tests/keymile/setVCC15.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setVCC15.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfDsl2.txt b/test_cases/integration_tests/keymile/setconfDsl2.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setconfDsl2.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfVoice9.txt b/test_cases/integration_tests/keymile/setconfVoice9.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setconfVoice9.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setportaktiv4.txt b/test_cases/integration_tests/keymile/setportaktiv4.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setportaktiv4.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setportdeactiv5.txt b/test_cases/integration_tests/keymile/setportdeactiv5.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setportdeactiv5.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setunconfDsl3.txt b/test_cases/integration_tests/keymile/setunconfDsl3.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setunconfDsl3.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setunconfVoice10.txt b/test_cases/integration_tests/keymile/setunconfVoice10.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setunconfVoice10.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/test Loopback3.txt b/test_cases/integration_tests/keymile/test Loopback3.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/test Loopback3.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/testVoicePort2.txt b/test_cases/integration_tests/keymile/testVoicePort2.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/testVoicePort2.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/testmelt1.txt b/test_cases/integration_tests/keymile/testmelt1.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/testmelt1.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/testmelting4.txt b/test_cases/integration_tests/keymile/testmelting4.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/testmelting4.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/unit_tests/keymile/test_keymile.py b/test_cases/unit_tests/keymile/test_keymile.py index db82172..e5a171a 100644 --- a/test_cases/unit_tests/keymile/test_keymile.py +++ b/test_cases/unit_tests/keymile/test_keymile.py @@ -11,23 +11,34 @@ # License: https://github.com/inexio/NESi/LICENSE.rst from test_cases.unit_tests.test_core import TestCore +import pytest +from os import listdir +from os.path import isfile, join class TestKeymile(TestCore): + PATH = 'test_cases/integration_tests/keymile/' + DATA = [f for f in listdir('test_cases/integration_tests/keymile/') if + isfile(join('test_cases/integration_tests/keymile/', f)) and f != 'output.txt'] - def test_portup_portdown(self): - port = self.model.get_port("name", '1/1/1/1') - assert(self.model.get_port("name", '1/1/1/1').admin_state == '0') - port.admin_up() - assert(self.model.get_port("name", '1/1/1/1').admin_state == '1') - port.admin_down() - assert(self.model.get_port("name", '1/1/1/1').admin_state == '0') - - def test_ontportup_portdown(self): - port = self.model.get_ont_port("name", '1/1/4/1/1/1/1') - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '0') - port.admin_up() - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '1') - port.admin_down() - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '0') + def test_box(self): + assert True + def test_card(self): + assert True + + def test_channel(self): + assert True + + def test_interface(self): + assert True + + def test_port(self): + assert True + + def test_subrack(self): + assert True + + @pytest.mark.parametrize("path", DATA) + def test_integration(self, path): + self.run(self.PATH + path, self.PATH + 'output.txt') From 2ab68d4104af5964d0ef25b18b6b8d497de1d31b Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 6 Oct 2020 09:47:39 +0200 Subject: [PATCH 082/318] Updated gitignore --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c38ccac..00d2735 100644 --- a/.gitignore +++ b/.gitignore @@ -134,4 +134,8 @@ dmypy.json # Tests /test_cases/integration_tests/alcatel/output.txt -/test_cases/integration_tests/huawei/output.txt \ No newline at end of file +/test_cases/integration_tests/huawei/output.txt +/test_cases/integration_tests/keymile/output.txt +/test_cases/integration_tests/edgecore/output.txt +/test_cases/integration_tests/pbn/output.txt +/test_cases/integration_tests/zhone/output.txt \ No newline at end of file From 8b146b78f140457fab8605110f40e2a9fed1cb2d Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 6 Oct 2020 15:25:02 +0200 Subject: [PATCH 083/318] Added case sensitivity for command processors --- nesi/softbox/cli/base.py | 19 +++++++++++++++++-- vendors/KeyMile/main.py | 2 ++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 0efe85a..04cbce4 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -45,11 +45,12 @@ class CommandProcessor: """ def __init__(self, model, input_stream, output_stream, history, - template_root=None, scopes=(), daemon=False): + template_root=None, scopes=(), daemon=False, parent=None, case_sensitive=True): self._model = model self._input = input_stream self._output = output_stream self._scopes = scopes + self._parent = parent self._template_root = template_root self._template_dir = os.path.join( template_root, *scopes) @@ -61,6 +62,7 @@ def __init__(self, model, input_stream, output_stream, history, self.daemon = daemon # CLI specific attributes + self.case_sensitive = case_sensitive self.line_buffer = [] self.history_enabled = True self.hide_input = False @@ -279,6 +281,9 @@ def _get_command_func(self, line): command = args[0] args = args[1:] + if self.case_sensitive is False: + command = command.lower() + if command == self.negation: command += "_" + args.pop(0) @@ -318,7 +323,7 @@ def _create_subprocessor(self, subprocessor, *scopes): return subprocessor( self._model, self._input, self._output, self.history, template_root=self._template_root, - scopes=scopes, daemon=self.daemon) + scopes=scopes, daemon=self.daemon, parent=self, case_sensitive=self.case_sensitive) def process_command(self, line, context): self._parse_and_execute_command(line, context) @@ -443,6 +448,11 @@ def _dissect(self, args, *tokens): except IndexError: raise exceptions.CommandSyntaxError(command=' '.join(args)) + if self.case_sensitive is False: + arg = arg.lower() + if not isinstance(token, type): + token = token.lower() + if type(token) == type: values.append(arg) @@ -461,6 +471,11 @@ def _validate(self, args, *tokens): except IndexError: return False + if self.case_sensitive is False: + arg = arg.lower() + if not isinstance(token, type): + token = token.lower() + if arg != token and type(token) != type: return False diff --git a/vendors/KeyMile/main.py b/vendors/KeyMile/main.py index 21561dc..ff9abd4 100644 --- a/vendors/KeyMile/main.py +++ b/vendors/KeyMile/main.py @@ -50,6 +50,8 @@ def on_unknown_command(self, command, *args, context=None): self._write(text) raise exceptions.TerminalExitError() + self.case_sensitive = False + subprocessor = self._create_subprocessor( RootCommandProcessor, 'login', 'base') From 1b976e5fd25183c37ac99f5d5ca30ba452d64bf1 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 7 Oct 2020 10:04:39 +0200 Subject: [PATCH 084/318] Added subscriber classes and portgroupCommandProcessor --- .../conf/bootstraps/create-keymile-MG2200.sh | 20 +- nesi/keymile/keymile_resources/__init__.py | 3 +- nesi/keymile/keymile_resources/keymile_box.py | 18 ++ .../keymile_resources/keymile_subscriber.py | 36 +++ nesi/softbox/api/models/box_models.py | 2 + nesi/softbox/api/models/card_models.py | 2 +- nesi/softbox/api/models/subscriber_models.py | 13 + nesi/softbox/api/schemas/box_schemas.py | 6 +- .../softbox/api/schemas/subscriber_schemas.py | 47 ++++ nesi/softbox/api/views/__init__.py | 3 +- nesi/softbox/api/views/subscriber_views.py | 53 ++++ templates/KeyMile/login/base/get/ip.j2 | 5 + templates/KeyMile/login/base/get/sip.j2 | 17 ++ .../login/base/get/subscriberList_bottom.j2 | 2 + .../login/base/get/subscriberList_item.j2 | 7 + .../login/base/get/subscriberList_item2.j2 | 6 + .../login/base/get/subscriberList_top.j2 | 3 + .../root/unit/port/portCommandProcessor.py | 2 +- .../port/portgroupportCommandProcessor.py | 66 +++++ .../port/portgroupportManagementFunctions.py | 264 ++++++++++++++++++ .../portgroup/portgroupCommandProcessor.py | 37 +++ .../portgroup/portgroupManagementFunctions.py | 17 ++ .../root/unit/unitCommandProcessor.py | 40 ++- 23 files changed, 662 insertions(+), 7 deletions(-) create mode 100644 nesi/keymile/keymile_resources/keymile_subscriber.py create mode 100644 nesi/softbox/api/models/subscriber_models.py create mode 100644 nesi/softbox/api/schemas/subscriber_schemas.py create mode 100644 nesi/softbox/api/views/subscriber_views.py create mode 100644 templates/KeyMile/login/base/get/ip.j2 create mode 100644 templates/KeyMile/login/base/get/sip.j2 create mode 100644 templates/KeyMile/login/base/get/subscriberList_bottom.j2 create mode 100644 templates/KeyMile/login/base/get/subscriberList_item.j2 create mode 100644 templates/KeyMile/login/base/get/subscriberList_item2.j2 create mode 100644 templates/KeyMile/login/base/get/subscriberList_top.j2 create mode 100644 vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupManagementFunctions.py diff --git a/bootup/conf/bootstraps/create-keymile-MG2200.sh b/bootup/conf/bootstraps/create-keymile-MG2200.sh index 7bd564b..0b64ca8 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2200.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2200.sh @@ -44,6 +44,24 @@ req='{ root_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) +# test subscriber +req='{ + "name": "tester", + "number": 9023, + "type": "unit" +}' + +subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) + +# test subscriber +req='{ + "name": "tester2", + "number": 90223, + "type": "unit" +}' + +subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) + ### Subrack 0 ### # Create a physical subrack at the network device (admin operation) @@ -59,7 +77,7 @@ subrack_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "xdsl" + "product": "analog" }' unit_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) diff --git a/nesi/keymile/keymile_resources/__init__.py b/nesi/keymile/keymile_resources/__init__.py index e6be87c..17f26e0 100644 --- a/nesi/keymile/keymile_resources/__init__.py +++ b/nesi/keymile/keymile_resources/__init__.py @@ -1 +1,2 @@ -__all__ = ["keymile_card", "keymile_port", "keymile_subrack", "keymile_channel", "keymile_interface"] +__all__ = ["keymile_card", "keymile_port", "keymile_subrack", "keymile_channel", "keymile_interface", + "keymile_subscriber"] diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 87586b3..178a817 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -53,6 +53,12 @@ def cards(self): self._conn, base.get_sub_resource_path_by( self, 'cards')) + @property + def subscribers(self): + """Return `SubscriberCollection` object.""" + return keymile_subscriber.KeymileSubscriberCollection( + self._conn, base.get_sub_resource_path_by(self, 'subscribers')) + def get_card(self, field, value): """Get specific card object.""" return keymile_card.KeyMileCardCollection( @@ -100,6 +106,18 @@ def get_interfaces(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'interfaces'), params={field: value}) + def get_subscriber(self, field, value): + """Get specific subscriber object.""" + return keymile_subscriber.KeymileSubscriberCollection( + self._conn, base.get_sub_resource_path_by(self, 'subscribers'), + params={field: value}).find_by_field_value(field, value) + + def get_subscribers(self, field, value): + """Get specific subscribers object.""" + return keymile_subscriber.KeymileSubscriberCollection( + self._conn, base.get_sub_resource_path_by(self, 'subscribers'), + params={field: value}) + class KeyMileBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/keymile/keymile_resources/keymile_subscriber.py b/nesi/keymile/keymile_resources/keymile_subscriber.py new file mode 100644 index 0000000..5dc324d --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_subscriber.py @@ -0,0 +1,36 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.service_port import logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class KeymileSubscriber(base.Resource): + """Represent logical subscriber resource.""" + + # fields + id = base.Field('id') + number = base.Field('number') + name = base.Field('name') + type = base.Field('type') + address = base.Field('address') + registration_state = base.Field('registration_state') + + +class KeymileSubscriberCollection(base.ResourceCollection): + """Represent a collection of logical subscribers.""" + + @property + def _resource_type(self): + return KeymileSubscriber diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index f4f7002..3540487 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -28,6 +28,7 @@ from .emu_models import Emu from .user_models import User from .channel_models import Channel +from .subscriber_models import Subscriber class Box(db.Model): @@ -70,6 +71,7 @@ class Box(db.Model): vlan_interfaces = db.relationship('VlanInterface', backref='Box', lazy='dynamic') routes = db.relationship('Route', backref='Box', lazy='dynamic') emus = db.relationship('Emu', backref='Box', lazy='dynamic') + subscribers = db.relationship('Subscriber', backref='Box', lazy='dynamic') board_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_instl_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_init_reporting_logging = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index f190760..7433116 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -23,7 +23,7 @@ class Card(db.Model): subrack_id = db.Column(db.Integer, db.ForeignKey('subrack.id')) ports = db.relationship('Port', backref='Card', lazy='dynamic') ppc = db.Column(db.Enum('8', '16', '32', '48', '64'), default='32') - product = db.Column(db.Enum('xdsl', 'vdsl', 'adsl', 'sdsl', 'ftth-pon', 'ftth', 'mgnt'), + product = db.Column(db.Enum('xdsl', 'vdsl', 'adsl', 'sdsl', 'ftth-pon', 'ftth', 'mgnt', 'analog', 'isdn'), nullable=False, default='vdsl') # Alcatel specific data diff --git a/nesi/softbox/api/models/subscriber_models.py b/nesi/softbox/api/models/subscriber_models.py new file mode 100644 index 0000000..1dc9cd1 --- /dev/null +++ b/nesi/softbox/api/models/subscriber_models.py @@ -0,0 +1,13 @@ +from nesi.softbox.api import db + + +class Subscriber(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + + number = db.Column(db.Integer(), nullable=False, unique=True) + type = db.Column(db.Enum('unit', 'port'), default='port') + address = db.Column(db.String(), default='') + registration_state = db.Column(db.Enum('registered'), default='registered') + diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index fb7d67d..b28a8e1 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -32,7 +32,7 @@ class Meta: fields = ('id', 'vendor', 'model', 'version', 'software_version', 'network_protocol', 'network_address', 'network_port', 'uuid', 'description', 'interfaces', 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', - 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', + 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') @@ -77,6 +77,10 @@ class Meta: {'_links': { 'self': ma.URLFor('show_emus', box_id='')}}) + subscribers = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_subscribers', box_id='')}}) + onts = ma.Hyperlinks({'_links': { 'self': ma.URLFor('show_onts', box_id='')}}) diff --git a/nesi/softbox/api/schemas/subscriber_schemas.py b/nesi/softbox/api/schemas/subscriber_schemas.py new file mode 100644 index 0000000..d788063 --- /dev/null +++ b/nesi/softbox/api/schemas/subscriber_schemas.py @@ -0,0 +1,47 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.subscriber_models import Subscriber + + +class SubscriberSchema(ma.ModelSchema): + class Meta: + model = Subscriber + fields = ('id', 'name', 'box', 'number', 'type', 'address', 'registration_state', '_links') + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_subscriber', box_id='', id=''), + 'collection': ma.URLFor('show_subscribers', box_id='')}) + + +class SubscribersSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class EmuSchema(ma.ModelSchema): + class Meta: + model = Subscriber + fields = ('id', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_subscriber', box_id='', id='')}) + + members = ma.Nested(SubscriberSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_subscribers', box_id='')}) diff --git a/nesi/softbox/api/views/__init__.py b/nesi/softbox/api/views/__init__.py index e6e1f95..edde876 100644 --- a/nesi/softbox/api/views/__init__.py +++ b/nesi/softbox/api/views/__init__.py @@ -1,4 +1,5 @@ __all__ = ["box_views", "credential_views", "route_views", "subrack_views", "card_views", "port_views", "ont_views", "ontport_views", "cpe_views", "cpeport_views", "vlan_views", "portprofile_views", "emu_views", "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", - "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views", "mgmt_card_views", "mgmt_port_views"] + "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views", + "mgmt_card_views", "mgmt_port_views", "subscriber_views"] diff --git a/nesi/softbox/api/views/subscriber_views.py b/nesi/softbox/api/views/subscriber_views.py new file mode 100644 index 0000000..4b46e43 --- /dev/null +++ b/nesi/softbox/api/views/subscriber_views.py @@ -0,0 +1,53 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from ..schemas.subscriber_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//subscribers', methods=['GET']) +def show_subscribers(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(SubscribersSchema(), Subscriber, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//subscribers/', methods=['GET']) +def show_subscriber(box_id, id): + response = show_component(Subscriber, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//subscribers/', methods=['PUT']) +def update_subscriber(box_id, id): + req = flask.request.json + update_component(Subscriber, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//subscribers', methods=['POST']) +def new_subscriber(box_id): + req = flask.request.json + response = new_component(SubscriberSchema(), Subscriber, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//subscribers/', methods=['DELETE']) +def del_subscriber(box_id, id): + del_component(Subscriber, box_id, id) + return flask.Response(status=204) diff --git a/templates/KeyMile/login/base/get/ip.j2 b/templates/KeyMile/login/base/get/ip.j2 new file mode 100644 index 0000000..c5d5e83 --- /dev/null +++ b/templates/KeyMile/login/base/get/ip.j2 @@ -0,0 +1,5 @@ + \ # Ip +10.16.12.14 \ # GatewayIpAddress +255.255.255.0 \ # SubnetMask +10.16.12.1 \ # DefaultGateway + diff --git a/templates/KeyMile/login/base/get/sip.j2 b/templates/KeyMile/login/base/get/sip.j2 new file mode 100644 index 0000000..fa1eed3 --- /dev/null +++ b/templates/KeyMile/login/base/get/sip.j2 @@ -0,0 +1,17 @@ + \ # sip +"Name" \ # GatewayName +"hab.dich.loieb.net" \ # HomeDomain +500 \ # SipPortNumber +"+49" \ # CountryCode +"6567" \ # AreaCode +500 \ # RetransmissionTimerT1 +4 \ # MaxRetransmissionIntervalT2 +false \ # SipExtension100relRequired +None \ # assertedIdentityMode +true \ # OverlapSignalling +30 \ # OverlapT10timer + \ # SessionTimer +false \ # UacRequestSessionTimer +false \ # UasRequestSessionTimer +1800 \ # SessionExpiration + diff --git a/templates/KeyMile/login/base/get/subscriberList_bottom.j2 b/templates/KeyMile/login/base/get/subscriberList_bottom.j2 new file mode 100644 index 0000000..7d2b463 --- /dev/null +++ b/templates/KeyMile/login/base/get/subscriberList_bottom.j2 @@ -0,0 +1,2 @@ +} \ + diff --git a/templates/KeyMile/login/base/get/subscriberList_item.j2 b/templates/KeyMile/login/base/get/subscriberList_item.j2 new file mode 100644 index 0000000..189f50a --- /dev/null +++ b/templates/KeyMile/login/base/get/subscriberList_item.j2 @@ -0,0 +1,7 @@ + \ # [{{ context.i }}] # + \ # Subscriber + "{{ context.subscriber.number }}"{{ context.spacer1 }}\ # SubscriberNumber + "{{ context.subscriber.registration_state }}"{{ context.spacer2 }}\ # RegistrationStatus + "{{ context.subscriber.address }}"{{ context.spacer3 }}\ # Address +; \ + diff --git a/templates/KeyMile/login/base/get/subscriberList_item2.j2 b/templates/KeyMile/login/base/get/subscriberList_item2.j2 new file mode 100644 index 0000000..733e082 --- /dev/null +++ b/templates/KeyMile/login/base/get/subscriberList_item2.j2 @@ -0,0 +1,6 @@ + \ # [{{ context.i }}] # + \ # Subscriber + "{{ context.subscriber.number }}"{{ context.spacer1 }}\ # SubscriberNumber + "{{ context.subscriber.registration_state }}"{{ context.spacer2 }}\ # RegistrationStatus +; \ + diff --git a/templates/KeyMile/login/base/get/subscriberList_top.j2 b/templates/KeyMile/login/base/get/subscriberList_top.j2 new file mode 100644 index 0000000..2e483ea --- /dev/null +++ b/templates/KeyMile/login/base/get/subscriberList_top.j2 @@ -0,0 +1,3 @@ + \ # Registration +{ \ # UnregisteredSubscriberList + diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index e9b392e..b4ad848 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -32,7 +32,7 @@ def do_get(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - if self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': + elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py new file mode 100644 index 0000000..dcbb3be --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -0,0 +1,66 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor + + +class PortgroupPortCommandProcessor(PortCommandProcessor): + __name__ = 'portgroupport' + management_functions = ('main', 'cfgm', 'status') + access_points = () + + from .portgroupportManagementFunctions import main + from .portgroupportManagementFunctions import cfgm + from .portgroupportManagementFunctions import fm + from .portgroupportManagementFunctions import pm + from .portgroupportManagementFunctions import status + + def do_get(self, command, *args, context=None): + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': + text = self._render('attainable_rate', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ + self._model.get_card('name', context['unit']).product == 'isdn': + text = self._render('subscriberList_top', *scopes, context=context) + i = 0 + for subscriber in self._model.subscribers: + if subscriber.type == 'port': # TODO: show only subscriber of this port + + context['i'] = i + context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' + context['spacer2'] = self.create_spacers((63,), (subscriber.registration_state,))[0] * ' ' + i += 1 + text += self._render('subscriberList_item2', *scopes, context=dict(context, subscriber=subscriber)) + text += self._render('subscriberList_bottom', *scopes, context=context) + + self._write(text) + elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': + text = self._render('administrative_status', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': + text = self._render('operational_status', *scopes, context=context) + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + + def _init_access_points(self, context=None): + port = self._model.get_port('name', context['unit'] + '/' + context['portgroup'] + '/' + context['port']) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportManagementFunctions.py new file mode 100644 index 0000000..5add929 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportManagementFunctions.py @@ -0,0 +1,264 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + } +} + +cfgm = { + 'Multicast': { + 'Prop': { + 'MaxNumberOfMulticastStreams': 'rw', + 'EnableIgmpClassifier': 'rw', + 'AllowStaticStreams': 'rw', + 'EnableFastLeave': 'rw', + 'GroupManagement': 'rw', + 'Bandwidth': 'rw' + }, + 'Cmd': ( + 'GetGroupList', + ) + }, + 'Traceability': { + 'Prop': { + 'AgentRemoteId': 'rw' + } + }, + 'Security': { + 'Prop': { + 'ServiceOptions': 'rw', + 'MaxNumberOfMac': 'rw' + } + }, + 'AccessControl': { + 'Prop': { + 'ClassificationKey': 'rw', + 'MAT': 'rw' + } + }, + 'RateLimiter': { + 'Prop': { + 'RateLimiting': 'rw', + 'RateLimitingCoS': 'rw' + } + }, + 'Qos': { + 'Prop': { + 'WfqProfile': 'rw' + } + }, + 'Wire': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'PortProfiles': 'rw' + } + }, + 'Misc': { + 'Prop': { + 'SpecificDPBO': 'rw', + 'SpecificUPBO': 'rw' + } + } +} + +status = { + 'General': { + 'Prop': { + 'Standard': 'r-', + 'PowerMgmStatus': 'r-', + 'Vdsl2Parameters': 'r-', + 'EstUPBOElectricalLength': 'r-', + 'LineRate': 'r-', + 'LineSnrMargin': 'r-', + 'AttainableNetDataRate': 'r-', + 'AttainableRate': 'r-', + 'OutputPower': 'r-', + 'BandStatus': 'r-' + } + }, + 'statistics': { + 'Prop': { + 'counters': 'r-', + 'PolicingCounters': 'r-' + }, + 'Cmd': ( + 'ResetPortCounters', + ) + }, + 'Nto1MacAccessDynamicList': { + 'Prop': { + 'UnicastList': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters', + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + }, + }, + 'TLSMacForwardingList': { + 'Prop': { + 'MacForwardingList': 'r-' + }, + 'Cmd': ( + 'FlushMacForwardingList', + ) + }, + '1to1MacForwardingList': { + 'Prop': { + 'One2OneMacForwardingList': 'r-' + } + }, + 'Qos': { + 'Prop': { + 'wfqueues': 'r-' + } + }, + 'Multicast': { + 'stream': { + 'Dynamic': { + 'Prop': { + 'ActiveStreams': 'r-' + }, + 'Cmd': ( + 'ClearActiveStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticStreams': 'r-' + } + }, + }, + + 'Vlan': { + 'Prop': { + 'AttachedVlans': 'r-' + } + }, + 'Preview': { + 'Cmd': ( + 'ResetPreviewSettings', + ) + }, + 'Bandwidth': { + 'Prop': { + 'bandwidthStatus': 'r-' + } + }, + }, + 'LineTest': { + 'MELT': { + 'Prop': { + 'MeltResults': 'r-' + }, + 'Cmd': ( + 'StartMeltMeasurement', + ) + }, + 'Delt': { + 'Prop': { + 'DeltMeasurementStatus': 'r-', + 'RecordedDeltMeasurements': 'r-' + }, + 'Cmd': ( + 'StartDeltMeasurement', + ) + }, + 'Selt': { + 'Prop': { + 'SeltMeasurementStatus': 'r-', + 'RecordedSeltMeasurements': 'r-', + 'CableType': 'rw', + 'BandplanProfile': 'rw', + 'TargetSnrm': 'rw' + }, + 'Cmd': ( + 'StartSeltMeasurement', + ) + }, + }, + 'Defects': { + 'Prop': { + 'Defects': 'r-' + } + }, + 'LineInventory': { + 'Prop': { + 'VendorId': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'DslOperationStatus': 'r-' + } + }, + 'Subcarrier': { + 'Cmd': ( + 'ShowBitAllocation', + ) + }, + 'RfiBands': { + 'Prop': { + 'NotchStatus': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py new file mode 100644 index 0000000..47cf9f2 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -0,0 +1,37 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class PortgroupCommandProcessor(BaseCommandProcessor): + __name__ = 'portgroup' + management_functions = ('main', 'cfgm') + access_points = () + + from .portgroupManagementFunctions import main + from .portgroupManagementFunctions import cfgm + + def _init_access_points(self, context=None): # work in progress + card = self._model.get_card('name', context['unit']) + portgroup = context['portgroup'] + + for port in self._model.get_ports('card_id', card.id): + if port.name.count('/') == 2 and port.name.strip('/')[1] == 'portgroup-' + portgroup: + identifier = 'port-' + port.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupManagementFunctions.py new file mode 100644 index 0000000..d281df9 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupManagementFunctions.py @@ -0,0 +1,17 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'General': { + 'Cmd': { + 'CreatePort', + 'DeletePort' + } + } +} \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 368a108..1a5dc5a 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -37,5 +37,43 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) + # todo: add portgroup to access_points + + def do_get(self, command, *args, context=None): + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ + (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', context['unit']).product == 'analog'): + text = self._render('subscriberList_top', *scopes, context=context) + i = 0 + for subscriber in self._model.subscribers: + if subscriber.type == 'unit': + context['i'] = i + context['spacer1'] = self.create_spacers((63,), (subscriber.number, ))[0] * ' ' + context['spacer2'] = self.create_spacers((63,), (subscriber.registration_state, ))[0] * ' ' + context['spacer3'] = self.create_spacers((63,), (subscriber.address, ))[0] * ' ' + + i += 1 + text += self._render('subscriberList_item', *scopes, context=dict(context, subscriber=subscriber)) + text += self._render('subscriberList_bottom', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'SIP') and context['path'].split('/')[-1] == 'cfgm' and \ + (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', context['unit']).product == 'analog'): + # TODO: dynamic fields + text = self._render('sip', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'IP') and context['path'].split('/')[-1] == 'cfgm' and \ + (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', context['unit']).product == 'analog'): + # TODO: dynamic fields + text = self._render('ip', *scopes, context=context) + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) From d5aa610783dcffdabec12f2e69bd2ca62ea9bce2 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Wed, 7 Oct 2020 10:48:56 +0200 Subject: [PATCH 085/318] Added new card fields --- .../conf/bootstraps/create-keymile-MG2200.sh | 177 +++++++++++++++++- nesi/huawei/huawei_resources/huawei_card.py | 1 - .../api/schemas/keymile_card_schemas.py | 23 +++ .../keymile/keymile_resources/keymile_card.py | 25 ++- nesi/softbox/api/models/card_models.py | 21 +++ .../KeyMile/login/base/get/current_status.j2 | 8 + .../login/base/get/equipment_inventory.j2 | 16 ++ .../login/base/get/hardware_and_software.j2 | 9 + .../root/services/packetCommandProcessor.py | 4 +- .../root/services/servicesCommandProcessor.py | 4 +- .../root/unit/unitCommandProcessor.py | 118 +++++++++++- vendors/KeyMile/baseCommandProcessor.py | 4 +- 12 files changed, 385 insertions(+), 25 deletions(-) create mode 100644 nesi/keymile/api/schemas/keymile_card_schemas.py create mode 100644 templates/KeyMile/login/base/get/current_status.j2 create mode 100644 templates/KeyMile/login/base/get/equipment_inventory.j2 create mode 100644 templates/KeyMile/login/base/get/hardware_and_software.j2 diff --git a/bootup/conf/bootstraps/create-keymile-MG2200.sh b/bootup/conf/bootstraps/create-keymile-MG2200.sh index 0b64ca8..abc2883 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2200.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2200.sh @@ -77,7 +77,24 @@ subrack_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "analog" + "product": "adsl", + "board_name": "SUAD2", + "supplier_build_state": "R3D", + "board_id": "305", + "hardware_key": 102, + "software": "suad2_r5c01.esw", + "software_name": "SUAD2", + "software_revision": "R5C01", + "state": "Ok", + "serial_number": "4363507882", + "manufacturer_name": "KEYMILE", + "model_name": "37900030", + "short_text": "MG SUSE1 SHDSL EFM 32-port", + "manufacturer_id": "100989", + "manufacturer_part_number": "09862706", + "manufacturer_build_state": "02", + "boot_loader": "BLSU1_R1G01/CT23337", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -117,7 +134,24 @@ interface_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "xdsl" + "product": "sdsl", + "board_name": "SUSE1", + "supplier_build_state": "R1A", + "board_id": "330", + "hardware_key": 1, + "software": "suse1_r4d02_t01.esw", + "software_name": "SUSE1", + "software_revision": "R4D02_T01", + "state": "Ok", + "serial_number": "6973180458", + "manufacturer_name": "KEYMILE", + "model_name": "37900196", + "short_text": "MG SUAD2 ADSL2+ AnnexB 32-port", + "manufacturer_id": "100989", + "manufacturer_part_number": "09860762", + "manufacturer_build_state": "05", + "boot_loader": "BLSU1_R1F01/CT18388", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -149,7 +183,24 @@ port_2_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "xdsl" + "product": "sdsl", + "board_name": "SUSE1", + "supplier_build_state": "R1A", + "board_id": "330", + "hardware_key": 3, + "software": "suse1_r4d02_t01.esw", + "software_name": "SUSE1", + "software_revision": "R4D02_T01", + "state": "Ok", + "serial_number": "3383369557", + "manufacturer_name": "KEYMILE", + "model_name": "37900196", + "short_text": "MG SUSE1 SHDSL EFM 32-port", + "manufacturer_id": "100989", + "manufacturer_part_number": "09862706", + "manufacturer_build_state": "02", + "boot_loader": "BLSU1_R1G01/CT23337", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -179,7 +230,24 @@ interface_3_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "xdsl" + "product": "adsl", + "board_name": "SUAD2", + "supplier_build_state": "R3D", + "board_id": "305", + "hardware_key": 104, + "software": "suad2_r5c01.esw", + "software_name": "SUAD2", + "software_revision": "R5C01", + "state": "Ok", + "serial_number": "4810312946", + "manufacturer_name": "KEYMILE", + "model_name": "37900030", + "short_text": "MG SUAD2 ADSL2+ AnnexB 32-port", + "manufacturer_id": "100989", + "manufacturer_part_number": "09860762", + "manufacturer_build_state": "05", + "boot_loader": "BLSU1_R1F01/CT18388", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -189,7 +257,24 @@ unit_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "vdsl" + "product": "vdsl", + "board_name": "SUVM4", + "supplier_build_state": "R1G", + "board_id": "345", + "hardware_key": 1, + "software": "suvm4_r3c02_01.esw", + "software_name": "SUVM4", + "software_revision": "R3C02_01", + "state": "Ok", + "serial_number": "6702369850", + "manufacturer_name": "KEYMILE", + "model_name": "37900293", + "short_text": "MG SUVM4 VDSL2 ISDN 32-port", + "manufacturer_id": "100989", + "manufacturer_part_number": "09866094", + "manufacturer_build_state": "01", + "boot_loader": "BPSUVM4_R1B03/CT0", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_5=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -199,7 +284,24 @@ unit_5=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "vdsl" + "product": "vdsl", + "board_name": "SUVM6", + "supplier_build_state": "R1K", + "board_id": "377", + "hardware_key": 25, + "software": "suvm6_r3e10_01.esw", + "software_name": "SUVM6", + "software_revision": "R3E10_01", + "state": "Ok", + "serial_number": "1283288279", + "manufacturer_name": "KEYMILE", + "model_name": "37900528", + "short_text": "MG SUVM6 VDSL2/17MHz ISDN 48pt", + "manufacturer_id": "100989", + "manufacturer_part_number": "09869778", + "manufacturer_build_state": "20", + "boot_loader": "BPSUVM6_R1B02/CT0", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_6=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -209,7 +311,24 @@ unit_6=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "vdsl" + "product": "vdsl", + "board_name": "SUVM6", + "supplier_build_state": "R1K", + "board_id": "377", + "hardware_key": 14, + "software": "suvm6_r3e10_01.esw", + "software_name": "SUVM6", + "software_revision": "R3E10_01", + "state": "Ok", + "serial_number": "6135149854", + "manufacturer_name": "KEYMILE", + "model_name": "37900528", + "short_text": "MG SUVM6 VDSL2/17MHz ISDN 48pt", + "manufacturer_id": "100989", + "manufacturer_part_number": "09869778", + "manufacturer_build_state": "20", + "boot_loader": "BPSUVM6_R1B02/CT0", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_7=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -219,7 +338,47 @@ unit_7=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "vdsl" + "product": "vdsl", + "board_name": "SUVM6", + "supplier_build_state": "R1K", + "board_id": "377", + "hardware_key": 104, + "software": "suvm6_r3e10_01.esw", + "software_name": "SUVM6", + "software_revision": "R3E10_01", + "state": "Ok", + "serial_number": "8781619728", + "manufacturer_name": "KEYMILE", + "model_name": "37900528", + "short_text": "MG SUVM6 VDSL2/17MHz ISDN 48pt", + "manufacturer_id": "100989", + "manufacturer_part_number": "09869778", + "manufacturer_build_state": "20", + "boot_loader": "BPSUVM6_R1B02/CT0", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' -unit_8=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) \ No newline at end of file +unit_8=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-19 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "isdn", + "name": "19" +}' + +unit_19=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_19', + "admin_state": "1", + "operational_state": "1", + "name": "19/1/1" +}' + +port_19_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) \ No newline at end of file diff --git a/nesi/huawei/huawei_resources/huawei_card.py b/nesi/huawei/huawei_resources/huawei_card.py index 30c1ffa..6670ea2 100644 --- a/nesi/huawei/huawei_resources/huawei_card.py +++ b/nesi/huawei/huawei_resources/huawei_card.py @@ -35,4 +35,3 @@ class HuaweiCardCollection(CardCollection): @property def _resource_type(self): return HuaweiCard - diff --git a/nesi/keymile/api/schemas/keymile_card_schemas.py b/nesi/keymile/api/schemas/keymile_card_schemas.py new file mode 100644 index 0000000..eb4344d --- /dev/null +++ b/nesi/keymile/api/schemas/keymile_card_schemas.py @@ -0,0 +1,23 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.card_schemas import * + + +class KeyMileCardSchema(CardSchema): + class Meta: + model = Card + fields = CardSchema.Meta.fields + ('board_name', 'supplier_build_state', 'board_id', 'hardware_key', 'software', + 'software_name', 'software_revision', 'state', 'serial_number', + 'manufacturer_name', 'model_name', 'short_text', 'manufacturer_id', + 'manufacturer_part_number', 'manufacturer_build_state', 'customer_id', + 'customer_product_id', 'boot_loader', 'processor') diff --git a/nesi/keymile/keymile_resources/keymile_card.py b/nesi/keymile/keymile_resources/keymile_card.py index 3870bc6..8370b93 100644 --- a/nesi/keymile/keymile_resources/keymile_card.py +++ b/nesi/keymile/keymile_resources/keymile_card.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.card import CardCollection, Card, logging, base +from nesi.softbox.base_resources.card import CardCollection, Card, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) @@ -18,10 +19,30 @@ class KeyMileCard(Card): """Represent physical shelf resource.""" + board_name = base.Field('board_name') + supplier_build_state = base.Field('supplier_build_state') + board_id = base.Field('board_id') + hardware_key = base.Field('hardware_key') + software = base.Field('software') + software_name = base.Field('software_name') + software_revision = base.Field('software_revision') + state = base.Field('state') + serial_number = base.Field('serial_number') + manufacturer_name = base.Field('manufacturer_name') + model_name = base.Field('model_name') + short_text = base.Field('short_text') + manufacturer_id = base.Field('manufacturer_id') + manufacturer_part_number = base.Field('manufacturer_part_number') + manufacturer_build_state = base.Field('manufacturer_build_state') + customer_id = base.Field('customer_id') + customer_product_id = base.Field('customer_product_id') + boot_loader = base.Field('boot_loader') + processor = base.Field('processor') + class KeyMileCardCollection(CardCollection): """Represent a collection of cards.""" @property def _resource_type(self): - return KeyMileCard \ No newline at end of file + return KeyMileCard diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index 7433116..2d0a4d7 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -80,3 +80,24 @@ class Card(db.Model): power_off_cause = db.Column(db.String(), default='-') power_off_time = db.Column(db.String(), default='-') temperature = db.Column(db.String(), default='68C') + + # Keymile specific data + supplier_build_state = db.Column(db.Enum('R1G', 'R1D', 'R2B', 'R2A', 'R1K', 'R1H', 'R2B', 'R1E', 'R3D', 'R1C', + 'R1A', ''), default='') + board_id = db.Column(db.Enum('345', '332', '303', '308', '377', '356', '305', '307', '330', '0'), default='0') + hardware_key = db.Column(db.Integer(), default=0) + software = db.Column(db.String(), default='') + software_name = db.Column(db.String(), default='') + software_revision = db.Column(db.String(), default='') + state = db.Column(db.Enum('Ok', 'Empty'), default='Empty') + serial_number = db.Column(db.String(), default='') + manufacturer_name = db.Column(db.String(), default='') + model_name = db.Column(db.String(), default='') + short_text = db.Column(db.String(), default='') + manufacturer_id = db.Column(db.String(), default='') + manufacturer_part_number = db.Column(db.String(), default='') + manufacturer_build_state = db.Column(db.String(), default='') + customer_id = db.Column(db.String(), default='') + customer_product_id = db.Column(db.String(), default='') + boot_loader = db.Column(db.String(), default='') + processor = db.Column(db.String(), default='') diff --git a/templates/KeyMile/login/base/get/current_status.j2 b/templates/KeyMile/login/base/get/current_status.j2 new file mode 100644 index 0000000..2ea3cef --- /dev/null +++ b/templates/KeyMile/login/base/get/current_status.j2 @@ -0,0 +1,8 @@ + \ # EquipmentStatus +{{ context.unit_state }}{{ context.spacer_1 }}\ # State +{{ context.unit_hardware | safe }}{{ context.spacer_2 }}\ # Hardware +{{ context.unit_software | safe }}{{ context.spacer_3 }}\ # Software +{{ context.unit_serial_number | safe }}{{ context.spacer_4 }}\ # SerialNumber +{{ context.unit_manufacturer_name | safe }}{{ context.spacer_5 }}\ # ManufacturerName +{{ context.unit_model_name | safe }}{{ context.spacer_6 }}\ # ModelName + diff --git a/templates/KeyMile/login/base/get/equipment_inventory.j2 b/templates/KeyMile/login/base/get/equipment_inventory.j2 new file mode 100644 index 0000000..6780cd1 --- /dev/null +++ b/templates/KeyMile/login/base/get/equipment_inventory.j2 @@ -0,0 +1,16 @@ + \ # EquipmentInventory +{{ context.unit_symbol | safe }}{{ context.spacer_1 }}\ # Symbol +{{ context.unit_short_text | safe }}{{ context.spacer_2 }}\ # ShortText +{{ context.unit_board_id }}{{ context.spacer_3 }}\ # BoardId +{{ context.unit_hardware_key }}{{ context.spacer_4 }}\ # HardwareKey +{{ context.unit_manufacturer_id | safe }}{{ context.spacer_5 }}\ # ManufacturerId +{{ context.unit_serial_number | safe }}{{ context.spacer_6 }}\ # ManufacturerSerialNumber +{{ context.unit_manufacturer_part_number | safe }}{{ context.spacer_7 }}\ # ManufacturerPartNumber +{{ context.unit_manufacturer_build_state | safe }}{{ context.spacer_8 }}\ # ManufacturerBuildState +{{ context.unit_supplier_part_number | safe }}{{ context.spacer_9 }}\ # SupplierPartNumber +{{ context.unit_supplier_build_state | safe }}{{ context.spacer_10 }}\ # SupplierBuildState +{{ context.unit_customer_id | safe }}{{ context.spacer_11 }}\ # CustomerId +{{ context.unit_customer_product_id | safe }}{{ context.spacer_12 }}\ # CustomerProductId +{{ context.unit_boot_loader | safe }}{{ context.spacer_13 }}\ # Bootloader +{{ context.unit_processor | safe }}{{ context.spacer_14 }}\ # Processor + diff --git a/templates/KeyMile/login/base/get/hardware_and_software.j2 b/templates/KeyMile/login/base/get/hardware_and_software.j2 new file mode 100644 index 0000000..0ac56c1 --- /dev/null +++ b/templates/KeyMile/login/base/get/hardware_and_software.j2 @@ -0,0 +1,9 @@ + \ # HardwareAndSoftware +{{ context.unit_hardware | safe }}{{ context.spacer_1 }}\ # Hardware +{{ context.unit_supplier_build_state | safe }}{{ context.spacer_2 }}\ # SupplierBuildState +{{ context.unit_board_id | safe }}{{ context.spacer_3 }}\ # BoardId +{{ context.unit_hardware_key | safe }}{{ context.spacer_4 }}\ # HardwareKey +{{ context.unit_software | safe }}{{ context.spacer_5 }}\ # Software +{{ context.unit_software_name | safe }}{{ context.spacer_6 }}\ # SoftwareName +{{ context.unit_software_revision | safe }}{{ context.spacer_7 }}\ # SoftwareRevision + diff --git a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py index 96d4113..1413d30 100644 --- a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py @@ -17,9 +17,9 @@ class PacketCommandProcessor(BaseCommandProcessor): __name__ = 'packet' management_functions = ('main',) - access_points = ('1to1DoubleTag', '1to1SingeTag', 'mcast', 'nto1', 'pls', 'tls') + access_points = ('1to1DoubleTag', '1to1SingleTag', 'mcast', 'nto1', 'pls', 'tls') from .packetManagementFunctions import main def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py index 253a74f..98da567 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -17,11 +17,11 @@ class ServicesCommandProcessor(BaseCommandProcessor): __name__ = 'services' management_functions = ('main', 'fm', 'status') - access_points = () + access_points = ('packet', 'macAccessCtrl') from .servicesManagementFunctions import main from .servicesManagementFunctions import fm from .servicesManagementFunctions import status def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 1a5dc5a..2e6bb75 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -17,7 +17,7 @@ class UnitCommandProcessor(BaseCommandProcessor): __name__ = 'unit' management_functions = ('main', 'cfgm', 'fm', 'status') - access_points = () #'internalPorts', only on certain cards + access_points = () # 'internalPorts', only on certain cards from .unitManagementFunctions import main from .unitManagementFunctions import cfgm @@ -27,7 +27,7 @@ class UnitCommandProcessor(BaseCommandProcessor): def _init_access_points(self, context=None): card = self._model.get_card('name', context['unit']) - #if card.type == ?: + # if card.type == ?: # self.access_points += ('internalPorts',) # @@ -40,37 +40,139 @@ def _init_access_points(self, context=None): # todo: add portgroup to access_points def do_get(self, command, *args, context=None): + card = self._model.get_card('name', context['unit']) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ - (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', context['unit']).product == 'analog'): + (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', + context[ + 'unit']).product == 'analog'): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: if subscriber.type == 'unit': context['i'] = i - context['spacer1'] = self.create_spacers((63,), (subscriber.number, ))[0] * ' ' - context['spacer2'] = self.create_spacers((63,), (subscriber.registration_state, ))[0] * ' ' - context['spacer3'] = self.create_spacers((63,), (subscriber.address, ))[0] * ' ' + context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' + context['spacer2'] = self.create_spacers((63,), (subscriber.registration_state,))[0] * ' ' + context['spacer3'] = self.create_spacers((63,), (subscriber.address,))[0] * ' ' i += 1 text += self._render('subscriberList_item', *scopes, context=dict(context, subscriber=subscriber)) text += self._render('subscriberList_bottom', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'SIP') and context['path'].split('/')[-1] == 'cfgm' and \ - (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', context['unit']).product == 'analog'): + (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', + context[ + 'unit']).product == 'analog'): # TODO: dynamic fields text = self._render('sip', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'IP') and context['path'].split('/')[-1] == 'cfgm' and \ - (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', context['unit']).product == 'analog'): + (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', + context[ + 'unit']).product == 'analog'): # TODO: dynamic fields text = self._render('ip', *scopes, context=context) self._write(text) + + elif self._validate((args[0],), 'HardwareAndSoftware'): + unit_hardware = '"' + card.board_name + '"' + context['unit_hardware'] = unit_hardware + context['spacer_1'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' + unit_supplier_build_state = '"' + card.supplier_build_state + '"' + context['unit_supplier_build_state'] = unit_supplier_build_state + context['spacer_2'] = self.create_spacers((67,), (unit_supplier_build_state,))[0] * ' ' + unit_board_id = card.board_id + context['unit_board_id'] = unit_board_id + context['spacer_3'] = self.create_spacers((67,), (unit_board_id,))[0] * ' ' + unit_hardware_key = card.hardware_key + context['unit_hardware_key'] = unit_hardware_key + context['spacer_4'] = self.create_spacers((67,), (unit_hardware_key,))[0] * ' ' + unit_software = '"' + card.software + '"' + context['unit_software'] = unit_software + context['spacer_5'] = self.create_spacers((67,), (unit_software,))[0] * ' ' + unit_software_name = '"' + card.software_name + '"' + context['unit_software_name'] = unit_software_name + context['spacer_6'] = self.create_spacers((67,), (unit_software_name,))[0] * ' ' + unit_software_revision = '"' + card.software_revision + '"' + context['unit_software_revision'] = unit_software_revision + context['spacer_7'] = self.create_spacers((67,), (unit_software_revision,))[0] * ' ' + text = self._render('hardware_and_software', *scopes, context=context) + self._write(text) + + elif self._validate((args[0],), 'CurrentStatus'): + unit_state = card.state + context['unit_state'] = unit_state + context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' + unit_hardware = '"' + card.board_name + ' ' + card.supplier_build_state + '"' + context['unit_hardware'] = unit_hardware + context['spacer_2'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' + unit_software = '"' + card.software[:-4] + '"' + context['unit_software'] = unit_software + context['spacer_3'] = self.create_spacers((67,), (unit_software,))[0] * ' ' + unit_serial_number = '"' + card.serial_number + '"' + context['unit_serial_number'] = unit_serial_number + context['spacer_4'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' + unit_manufacturer_name = '"' + card.manufacturer_name + '"' + context['unit_manufacturer_name'] = unit_manufacturer_name + context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_name,))[0] * ' ' + unit_model_name = '"' + card.model_name + '"' + context['unit_model_name'] = unit_model_name + context['spacer_6'] = self.create_spacers((67,), (unit_model_name,))[0] * ' ' + text = self._render('current_status', *scopes, context=context) + self._write(text) + + elif self._validate((args[0],), 'EquipmentInventory'): + unit_symbol = '"' + card.board_name + '"' + context['unit_symbol'] = unit_symbol + context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' + unit_short_text = '"' + card.short_text + '"' + context['unit_short_text'] = unit_short_text + context['spacer_2'] = self.create_spacers((67,), (unit_short_text,))[0] * ' ' + unit_board_id = card.board_id + context['unit_board_id'] = unit_board_id + context['spacer_3'] = self.create_spacers((67,), (unit_board_id,))[0] * ' ' + unit_hardware_key = card.hardware_key + context['unit_hardware_key'] = unit_hardware_key + context['spacer_4'] = self.create_spacers((67,), (unit_hardware_key,))[0] * ' ' + unit_manufacturer_id = '"' + card.manufacturer_id + '"' + context['unit_manufacturer_id'] = unit_manufacturer_id + context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_id,))[0] * ' ' + unit_serial_number = '"' + card.serial_number + '"' + context['unit_serial_number'] = unit_serial_number + context['spacer_6'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' + unit_manufacturer_part_number = '"' + card.manufacturer_part_number + '"' + context['unit_manufacturer_part_number'] = unit_manufacturer_part_number + context['spacer_7'] = self.create_spacers((67,), (unit_manufacturer_part_number,))[0] * ' ' + unit_manufacturer_build_state = '"' + card.manufacturer_build_state + '"' + context['unit_manufacturer_build_state'] = unit_manufacturer_build_state + context['spacer_8'] = self.create_spacers((67,), (unit_manufacturer_build_state,))[0] * ' ' + unit_supplier_part_number = '"' + card.model_name + '"' + context['unit_supplier_part_number'] = unit_supplier_part_number + context['spacer_9'] = self.create_spacers((67,), (unit_supplier_part_number,))[0] * ' ' + unit_supplier_build_state = '"' + card.supplier_build_state + '"' + context['unit_supplier_build_state'] = unit_supplier_build_state + context['spacer_10'] = self.create_spacers((67,), (unit_supplier_build_state,))[0] * ' ' + unit_customer_id = '"' + card.customer_id + '"' + context['unit_customer_id'] = unit_customer_id + context['spacer_11'] = self.create_spacers((67,), (unit_customer_id,))[0] * ' ' + unit_customer_product_id = '"' + card.customer_product_id + '"' + context['unit_customer_product_id'] = unit_customer_product_id + context['spacer_12'] = self.create_spacers((67,), (unit_customer_product_id,))[0] * ' ' + unit_boot_loader = '"' + card.boot_loader + '"' + context['unit_boot_loader'] = unit_boot_loader + context['spacer_13'] = self.create_spacers((67,), (unit_boot_loader,))[0] * ' ' + unit_processor = '"' + card.processor + '"' + context['unit_processor'] = unit_processor + context['spacer_14'] = self.create_spacers((67,), (unit_processor,))[0] * ' ' + text = self._render('equipment_inventory', *scopes, context=context) + self._write(text) + else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index d6463c9..afce2fd 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -121,7 +121,7 @@ def do_cd(self, command, *args, context=None): components = [x for x in args[0].split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|packet|macAccessCtrl|\.|\.\.)$', components[0]): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty @@ -234,6 +234,8 @@ def do_cd(self, command, *args, context=None): from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor + from vendors.KeyMile.accessPoints.root.services.packetCommandProcessor import PacketCommandProcessor + from vendors.KeyMile.accessPoints.root.services.macAccessCtrlCommandProcessor import MacAccessCtrlCommandProcessor as MacaccessctrlCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if len(remaining_args) > 0: From 275025370cc205f8a1c8030fb3ffbf8ed480cb12 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 7 Oct 2020 11:10:25 +0200 Subject: [PATCH 086/318] added context to get Integration tests --- .../integration_tests/keymile/getDslam4.txt | 1 + .../keymile/getInventory2.txt | 15 +++ .../integration_tests/keymile/getIpsx7.txt | 5 + .../keymile/getMonitoring3.txt | 18 ++++ .../integration_tests/keymile/getState1.txt | 101 ++++++++++++++++++ .../keymile/getSubscriber6.txt | 2 + .../integration_tests/keymile/getVoice5.txt | 6 ++ 7 files changed, 148 insertions(+) diff --git a/test_cases/integration_tests/keymile/getDslam4.txt b/test_cases/integration_tests/keymile/getDslam4.txt index 6f999b9..a36c092 100644 --- a/test_cases/integration_tests/keymile/getDslam4.txt +++ b/test_cases/integration_tests/keymile/getDslam4.txt @@ -1,3 +1,4 @@ admin secret +ls exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getInventory2.txt b/test_cases/integration_tests/keymile/getInventory2.txt index 6f999b9..c45e0e0 100644 --- a/test_cases/integration_tests/keymile/getInventory2.txt +++ b/test_cases/integration_tests/keymile/getInventory2.txt @@ -1,3 +1,18 @@ admin secret +ls +cd /services/packet/nto1/ +ls +cd /services/packet/nto1/srvc-{$match}/cfgm +get Service +cd /unit-{$slot} +ls +cd /unit-{$slot}/mai +get HardwareAndSoftware +get CurrentStatus +get EquipmentInventory +cd /unit-{$slot}/port-{$port} +ls +cd /unit-{$slot}/port-{$port}/main +get OperationalStatus exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getIpsx7.txt b/test_cases/integration_tests/keymile/getIpsx7.txt index 6f999b9..dead751 100644 --- a/test_cases/integration_tests/keymile/getIpsx7.txt +++ b/test_cases/integration_tests/keymile/getIpsx7.txt @@ -1,3 +1,8 @@ admin secret +cd /unit-19/status +get SubscriberList +cd /unit-19/cfgm +get SIP +get IP exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getMonitoring3.txt b/test_cases/integration_tests/keymile/getMonitoring3.txt index 6f999b9..6338665 100644 --- a/test_cases/integration_tests/keymile/getMonitoring3.txt +++ b/test_cases/integration_tests/keymile/getMonitoring3.txt @@ -1,3 +1,21 @@ admin secret +ls +cd status +get CurrTemperature +cd .. +cd fan +ls +cd .. +cd unit-1 +ls +cd .. + + + + + + + + exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getState1.txt b/test_cases/integration_tests/keymile/getState1.txt index 6f999b9..cdfab20 100644 --- a/test_cases/integration_tests/keymile/getState1.txt +++ b/test_cases/integration_tests/keymile/getState1.txt @@ -1,3 +1,104 @@ admin secret +#adsl SUAD2 +cd /unit-{$card}/port-{$port}/status +get AttainableRate +cd /unit-{$card}/port-{$port}/main +get AdministrativeStatus +get OperationalStatus +cd /unit-{$card}/port-{$port}/chan-1/cfgm +get ProfileName +get ChanProfile +cd /unit-{$card}/port-{$port}/chan-1/status +get status +cd /unit-{$card}/port-{$port}/chan-1/vcc-1/cfgm +get configuredProfiles +cd /unit-{$card}/port-{$port}/chan-1/vcc-1/status +get ServiceStatus +cd /unit-11 +ls +cd /unit-{$slotIpss} +ls +#vdsl SUVD2 +cd /unit-{$card}/port-{$port}/status +get AttainableRate +cd /unit-{$card}/port-{$port}/main +get AdministrativeStatus +get OperationalStatus +cd /unit-{$card}/port-{$port}/chan-1/cfgm +get ChanProfile +cd /unit-{$card}/port-{$port}/chan-1/status +get status +cd /unit-{$card}/port-{$port}/chan-1/interface-1/cfgm +get configuredProfiles +get vlanProfile +cd /unit-{$card}/port-{$port}/chan-1/interface-1/status +get ServiceStatus +cd /unit-11 +ls +cd /unit-{$card}/port-{$port} +get status/VendorId +cd /unit-{$slotIpss} +ls +#xdsl +cd /unit-{$card}/port-{$port}/status +get AttainableRate +get UnicastList +cd /unit-{$card}/port-{$port}/main +get AdministrativeStatus +get OperationalStatus +cd /unit-{$card}/port-{$port} +ls +cd /unit-{$card}/port-{$port}/chan-1/cfgm +get ChanProfile +cd /unit-{$card}/port-{$port}/chan-1/status +get status +cd /unit-{$card}/port-{$port}/chan-1/interface-1/cfgm +get configuredProfiles +cd /unit-{$card}/port-{$port}/chan-1/interface-1/status +get ServiceStatus +cd /unit-{$card} +ls +cd /unit-11 +ls +cd /unit-{$card}/port-{$port} +get status/VendorId +#ftth +cd /unit-{$card}/port-{$port}/main +get AdministrativeStatus +get OperationalStatus +cd /unit-{$card}/port-{$port} +ls +cd /unit-{$card}/port-{$port}/status +get PortMacStatus +get PortGeneralStatus +cd /unit-{$card}/port-{$port}/interface-1/cfgm +get configuredProfiles +get vlanProfile +get IfRateLimiting +cd /unit-{$card}/port-{$port}/interface-1/status +get ServiceStatus +cd /unit-{$card}/port-{$port}/status +get DDMStatus +#sdsl +cd /unit-{$card}/port-{$port}/main +ls +cd /unit-{$card}/port-{$port}/status +ls +get LineActualState +get LineOperationState +cd /unit-{$card}/logports/logport-{$port}/status +get ActualStatus +get OperationalWireState +cd /unit-{$card}/logports/logport-{$port}/main +get AdministrativeStatus +get OperationalStatus +cd /unit-{$card}/logports/logport-{$port}/cfgm +get SpanProfiles +cd /unit-{$card}/logports/logport-{$port}/interface-1/cfgm +get configuredProfiles +get vlanProfile +cd /unit-{$card}/logports/logport-{$port}/interface-1/status +get ServiceStatus +ls exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getSubscriber6.txt b/test_cases/integration_tests/keymile/getSubscriber6.txt index 6f999b9..1a0f1b4 100644 --- a/test_cases/integration_tests/keymile/getSubscriber6.txt +++ b/test_cases/integration_tests/keymile/getSubscriber6.txt @@ -1,3 +1,5 @@ admin secret +cd /unit-19/portgroup-1/port-1/status +get SubscriberList exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getVoice5.txt b/test_cases/integration_tests/keymile/getVoice5.txt index 6f999b9..e3318fa 100644 --- a/test_cases/integration_tests/keymile/getVoice5.txt +++ b/test_cases/integration_tests/keymile/getVoice5.txt @@ -1,3 +1,9 @@ admin secret +#analog +cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm +get pstnport +#isdn +cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm +get isdnport exit \ No newline at end of file From 12da00ac65e747db8d28ba65ed3ae5fad403de53 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 7 Oct 2020 13:38:55 +0200 Subject: [PATCH 087/318] added context to set Integration tests --- .../keymile/setChannelProfile14.txt | 8 +++++++ .../keymile/setInterface16.txt | 12 ++++++++++ .../integration_tests/keymile/setIpAddr6.txt | 14 +++++++++++ .../keymile/setPortProfile13.txt | 7 ++++++ .../integration_tests/keymile/setProfile7.txt | 3 --- .../keymile/setSIPDomain12.txt | 9 ++++++++ .../integration_tests/keymile/setTraffic1.txt | 13 +++++++++++ .../integration_tests/keymile/setVCC15.txt | 3 +++ .../integration_tests/keymile/setconfDsl2.txt | 23 +++++++++++++++++++ .../keymile/setconfVoice9.txt | 16 +++++++++++++ .../keymile/setdeconfVoicePort11.txt | 4 ++++ .../keymile/setdeconfVoicePort17.txt | 23 +++++++++++++++++++ .../keymile/setportaktiv4.txt | 15 ++++++++++++ .../keymile/setportdeactiv5.txt | 15 ++++++++++++ .../keymile/setunconfDsl3.txt | 23 +++++++++++++++++++ .../keymile/setunconfVoice10.txt | 3 --- 16 files changed, 185 insertions(+), 6 deletions(-) delete mode 100644 test_cases/integration_tests/keymile/setProfile7.txt delete mode 100644 test_cases/integration_tests/keymile/setunconfVoice10.txt diff --git a/test_cases/integration_tests/keymile/setChannelProfile14.txt b/test_cases/integration_tests/keymile/setChannelProfile14.txt index 6f999b9..3ad57dd 100644 --- a/test_cases/integration_tests/keymile/setChannelProfile14.txt +++ b/test_cases/integration_tests/keymile/setChannelProfile14.txt @@ -1,3 +1,11 @@ admin secret +cd /unit-$card/port-$port/chan-1/cfgm +#SUVM6/4 +set chanprofile $profile +set chanprofile default +#else +cd /unit-$card/port-$port/chan-1/cfgm +set ProfileName $profile +set ProfileName default exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setInterface16.txt b/test_cases/integration_tests/keymile/setInterface16.txt index 6f999b9..16a5569 100644 --- a/test_cases/integration_tests/keymile/setInterface16.txt +++ b/test_cases/integration_tests/keymile/setInterface16.txt @@ -1,3 +1,15 @@ admin secret +#SUSE1 +cd /unit-$card/logports/logport-$port/cfgm +#SUEN4 +cd /unit-$card/port-$port/cfgm +#SUE16 +cd /unit-$card/port-$port/cfgm +#ftth +cd /unit-$card/port-$port/cfgm +#else +cd /unit-$card/port-$port/chan-1/cfgm +CreateInterface default VCC_1_32_10100 +DeleteInterface all exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setIpAddr6.txt b/test_cases/integration_tests/keymile/setIpAddr6.txt index 6f999b9..e4e5a91 100644 --- a/test_cases/integration_tests/keymile/setIpAddr6.txt +++ b/test_cases/integration_tests/keymile/setIpAddr6.txt @@ -1,3 +1,17 @@ admin secret +cd /services/packet/1to1SingleTag/srvc-1/cfgm +set Service /unit-{$managementSlot}/control {$input->vlan_voice_new} CoS0 Add +cd /services/packet/1to1SingleTag/srvc-2/cfgm +set Service /unit-{$managementSlot}/media {$input->vlan_voice_new} CoS0 Add +cd /unit-{$managementSlot}/cfgm +set Ip {$input->ip_voice} 255.255.255.0 {$input->gateway_voice} +cd /cfgm +save +cd /unit-{$managementSlot}/main +restart +set /cfgm/IP_Address {$input->ip_new} 255.255.255.0 {$input->gateway} +/cfgm/Save +/unit-11/main/restart +set /cfgm/VlanId {$input->vlan_new} exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setPortProfile13.txt b/test_cases/integration_tests/keymile/setPortProfile13.txt index 6f999b9..ed42302 100644 --- a/test_cases/integration_tests/keymile/setPortProfile13.txt +++ b/test_cases/integration_tests/keymile/setPortProfile13.txt @@ -1,3 +1,10 @@ admin secret + +cd /unit-$card/port-$port/cfgm +#SUVM6 posibilities +set portprofiles true $vdslProfile 0 false default 0 false default 0 false default Priority +set portprofiles true " . $vdslProfile . " 0 false default 0 false default 0 false default Priority +set portprofiles false default 0 false default 0 false default 0 true " . $adslProfile . " Priority +set portprofiles true default 0 false default 0 false default 0 true default Priority exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setProfile7.txt b/test_cases/integration_tests/keymile/setProfile7.txt deleted file mode 100644 index 6f999b9..0000000 --- a/test_cases/integration_tests/keymile/setProfile7.txt +++ /dev/null @@ -1,3 +0,0 @@ -admin -secret -exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setSIPDomain12.txt b/test_cases/integration_tests/keymile/setSIPDomain12.txt index 6f999b9..d465075 100644 --- a/test_cases/integration_tests/keymile/setSIPDomain12.txt +++ b/test_cases/integration_tests/keymile/setSIPDomain12.txt @@ -1,3 +1,12 @@ admin secret +#analog or isdn +cd /unit-{$slotIpss}/cfgm +get Sip +set Proxy PrimaryOnly $domain 5060 "" 0 true Options 10 "" 0 true Options 10 +set Registrar $domain 5060 OneByOneRegistration 1 +set Sip $name $domain 5060 +49 $area 500 4 false None true 30 false false 1800 +set digitmap {sip "xxx" $domain 0 ""; sip "*xx*x.#" $domain 0 ""; sip "*xx*" $domain 0 ""; sip "*xx#" $domain 0 ""; sip "#xx#" $domain 0 ""; } +cd /cfgm +save exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setTraffic1.txt b/test_cases/integration_tests/keymile/setTraffic1.txt index 6f999b9..a9cc539 100644 --- a/test_cases/integration_tests/keymile/setTraffic1.txt +++ b/test_cases/integration_tests/keymile/setTraffic1.txt @@ -1,3 +1,16 @@ admin secret +#ftth +cd /unit-$card +ls +#SUEN4 +cd /unit-$card/port-$port/cfgm +Set Mode "Speed1000 Autoneg On" +Set FlowControl false +CreateInterface VLAN_$trafficVlan +#else +cd /unit-$card/port-$port/cfgm +Set Mode "1000MbitsFullDuplex" +Set FlowControl false +CreateInterface VLAN_$trafficVlan exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setVCC15.txt b/test_cases/integration_tests/keymile/setVCC15.txt index 6f999b9..cd9305b 100644 --- a/test_cases/integration_tests/keymile/setVCC15.txt +++ b/test_cases/integration_tests/keymile/setVCC15.txt @@ -1,3 +1,6 @@ admin secret +cd /unit-$card/port-$port/chan-1/cfgm +CreateVcc $profile default +DeleteVcc all exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfDsl2.txt b/test_cases/integration_tests/keymile/setconfDsl2.txt index 6f999b9..c2e2afc 100644 --- a/test_cases/integration_tests/keymile/setconfDsl2.txt +++ b/test_cases/integration_tests/keymile/setconfDsl2.txt @@ -1,3 +1,26 @@ admin secret +#adsl +cd /unit-$card/port-$port/main +Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" +set AdministrativeStatus up +#vdsl +cd /unit-$card/port-$port/main +Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" +set AdministrativeStatus up +#xdsl +cd /unit-$card/port-$port/main +Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" +set AdministrativeStatus up +#ftth +cd /unit-$card/port-$port/main +Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" +set AdministrativeStatus up +#sdsl +cd /unit-$card/logports/cfgm +create $bonding_port $profile +cd /unit-$card/logports/logport-$port/cfgm +CreateInterface name $servicetype +cd /unit-$card/logports/logport-$port/main +set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfVoice9.txt b/test_cases/integration_tests/keymile/setconfVoice9.txt index 6f999b9..60f70f6 100644 --- a/test_cases/integration_tests/keymile/setconfVoice9.txt +++ b/test_cases/integration_tests/keymile/setconfVoice9.txt @@ -1,3 +1,19 @@ admin secret +#analog +cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm +set pstnport true {$numbers} true false none none none none none +cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/main +Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" +cd /unit-$voiceCard/port-$voicePort/main +set AdministrativeStatus up +Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" +#isdn +cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm +set isdnport true {$numbers} true false none none none none none +cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/main +Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" +cd /unit-$voiceCard/port-$voicePort/main +set AdministrativeStatus up +Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt index 6f999b9..6704e55 100644 --- a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt @@ -1,3 +1,7 @@ admin secret +#isdn or analog +cd /unit-$ipsxSlot/portgroup-$card/port-$port/cfgm +get pstnport +cd / exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt index 6f999b9..d82cfe2 100644 --- a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt @@ -1,3 +1,26 @@ admin secret +#analog +cd /unit-$card/port-$port/main +set AdministrativeStatus down +Set Labels "" "" "" +cd /unit-$ipsxSlot/portgroup-$card/port-$port/cfgm +Set pstnport false {} true false none none none none none +cd /unit-$ipsxSlot/portgroup-$card/port-$port/main +Set Labels "" "" "" +#isdn +cd /unit-$card/port-$port/main +set AdministrativeStatus down +Set Labels "" "" "" +cd /unit-$ipsxSlot/portgroup-$card/port-$port/cfgm +Set isdnport false {} true false false none none none none +cd /unit-$ipsxSlot/portgroup-$card/port-$port/main +Set Labels "" "" "" + + + + + + + exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setportaktiv4.txt b/test_cases/integration_tests/keymile/setportaktiv4.txt index 6f999b9..c917fa5 100644 --- a/test_cases/integration_tests/keymile/setportaktiv4.txt +++ b/test_cases/integration_tests/keymile/setportaktiv4.txt @@ -1,3 +1,18 @@ admin secret +#adsl +cd /unit-$card/port-$port/main +set AdministrativeStatus up +#vdsl +cd /unit-$card/port-$port/main +set AdministrativeStatus up +#xdsl +cd /unit-$card/port-$port/main +set AdministrativeStatus up +#ftth +cd /unit-$card/port-$port/main +set AdministrativeStatus up +#sdsl +cd /unit-$card/logports/logport-$port/main +set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setportdeactiv5.txt b/test_cases/integration_tests/keymile/setportdeactiv5.txt index 6f999b9..041cd8d 100644 --- a/test_cases/integration_tests/keymile/setportdeactiv5.txt +++ b/test_cases/integration_tests/keymile/setportdeactiv5.txt @@ -1,3 +1,18 @@ admin secret +#adsl +cd /unit-$card/port-$port/main +set AdministrativeStatus down +#vdsl +cd /unit-$card/port-$port/main +set AdministrativeStatus down +#xdsl +cd /unit-$card/port-$port/main +set AdministrativeStatus down +#ftth +cd /unit-$card/port-$port/main +set AdministrativeStatus down +#sdsl +cd /unit-$card/logports/logport-$port/main +set AdministrativeStatus down exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setunconfDsl3.txt b/test_cases/integration_tests/keymile/setunconfDsl3.txt index 6f999b9..7213e54 100644 --- a/test_cases/integration_tests/keymile/setunconfDsl3.txt +++ b/test_cases/integration_tests/keymile/setunconfDsl3.txt @@ -1,3 +1,26 @@ admin secret +#adsl +cd /unit-$card/port-$port/main +set AdministrativeStatus down +Set Labels "" "" "" +#vdsl +cd /unit-$card/port-$port/main +set AdministrativeStatus down +Set Labels "" "" "" +#xdsl +cd /unit-$card/port-$port/main +set AdministrativeStatus down +Set Labels "" "" "" +#ftth +cd /unit-$card/port-$port/main +set AdministrativeStatus down +Set Labels "" "" "" +#sdsl +cd /unit-$card/logports/logport-$port/main +set AdministrativeStatus down +Set Labels "" "" "" +cd /unit-$card/logports/logport-$port/main +cd /unit-$card/logports/cfgm +Delete logport-$port exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setunconfVoice10.txt b/test_cases/integration_tests/keymile/setunconfVoice10.txt deleted file mode 100644 index 6f999b9..0000000 --- a/test_cases/integration_tests/keymile/setunconfVoice10.txt +++ /dev/null @@ -1,3 +0,0 @@ -admin -secret -exit \ No newline at end of file From 2b09c9aa27ee558cf788855b28a111c0aeea1842 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 7 Oct 2020 13:53:09 +0200 Subject: [PATCH 088/318] added logportCommandProcessor and refactored do_get functionality --- .../unit/logport/logportsCommandProcessor.py | 37 +++ .../logport/logportsManagementFunctions.py | 17 ++ .../logport/port/logportCommandProcessor.py | 43 +++ .../port/logportManagementFunctions.py | 264 ++++++++++++++++++ .../port/portgroupportCommandProcessor.py | 56 ++-- 5 files changed, 384 insertions(+), 33 deletions(-) create mode 100644 vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py new file mode 100644 index 0000000..1f28568 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -0,0 +1,37 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class LogPortsCommandProcessor(BaseCommandProcessor): + __name__ = 'logports' + management_functions = ('main', 'cfgm') + access_points = () + + from .logportsManagementFunctions import main + from .logportsManagementFunctions import cfgm + + def _init_access_points(self, context=None): # work in progress + card = self._model.get_card('name', context['unit']) + logports = context['logports'] + + for port in self._model.get_ports('card_id', card.id): + if port.name.count('/') == 2 and port.name.strip('/')[1] == 'logports-' + logports: + identifier = 'port-' + port.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py new file mode 100644 index 0000000..d281df9 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py @@ -0,0 +1,17 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'General': { + 'Cmd': { + 'CreatePort', + 'DeletePort' + } + } +} \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py new file mode 100644 index 0000000..1df5208 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -0,0 +1,43 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor + + +class LogPortCommandProcessor(PortCommandProcessor): + __name__ = 'logport' + management_functions = ('main', 'cfgm', 'status') + access_points = () + + from .logportManagementFunctions import main + from .logportManagementFunctions import cfgm + from .logportManagementFunctions import status + + def do_get(self, command, *args, context=None): + scopes = ('login', 'base', 'get') + try: + super().do_get(command, *args, context=None) + except exceptions.CommandExecutionError: + #TODO: example + if self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': + text = self._render('attainable_rate', *scopes, context=context) + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + + def _init_access_points(self, context=None): + port = self._model.get_port('name', context['unit'] + '/' + context['portgroup'] + '/' + context['port']) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py new file mode 100644 index 0000000..5add929 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py @@ -0,0 +1,264 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + } +} + +cfgm = { + 'Multicast': { + 'Prop': { + 'MaxNumberOfMulticastStreams': 'rw', + 'EnableIgmpClassifier': 'rw', + 'AllowStaticStreams': 'rw', + 'EnableFastLeave': 'rw', + 'GroupManagement': 'rw', + 'Bandwidth': 'rw' + }, + 'Cmd': ( + 'GetGroupList', + ) + }, + 'Traceability': { + 'Prop': { + 'AgentRemoteId': 'rw' + } + }, + 'Security': { + 'Prop': { + 'ServiceOptions': 'rw', + 'MaxNumberOfMac': 'rw' + } + }, + 'AccessControl': { + 'Prop': { + 'ClassificationKey': 'rw', + 'MAT': 'rw' + } + }, + 'RateLimiter': { + 'Prop': { + 'RateLimiting': 'rw', + 'RateLimitingCoS': 'rw' + } + }, + 'Qos': { + 'Prop': { + 'WfqProfile': 'rw' + } + }, + 'Wire': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'PortProfiles': 'rw' + } + }, + 'Misc': { + 'Prop': { + 'SpecificDPBO': 'rw', + 'SpecificUPBO': 'rw' + } + } +} + +status = { + 'General': { + 'Prop': { + 'Standard': 'r-', + 'PowerMgmStatus': 'r-', + 'Vdsl2Parameters': 'r-', + 'EstUPBOElectricalLength': 'r-', + 'LineRate': 'r-', + 'LineSnrMargin': 'r-', + 'AttainableNetDataRate': 'r-', + 'AttainableRate': 'r-', + 'OutputPower': 'r-', + 'BandStatus': 'r-' + } + }, + 'statistics': { + 'Prop': { + 'counters': 'r-', + 'PolicingCounters': 'r-' + }, + 'Cmd': ( + 'ResetPortCounters', + ) + }, + 'Nto1MacAccessDynamicList': { + 'Prop': { + 'UnicastList': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters', + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + }, + }, + 'TLSMacForwardingList': { + 'Prop': { + 'MacForwardingList': 'r-' + }, + 'Cmd': ( + 'FlushMacForwardingList', + ) + }, + '1to1MacForwardingList': { + 'Prop': { + 'One2OneMacForwardingList': 'r-' + } + }, + 'Qos': { + 'Prop': { + 'wfqueues': 'r-' + } + }, + 'Multicast': { + 'stream': { + 'Dynamic': { + 'Prop': { + 'ActiveStreams': 'r-' + }, + 'Cmd': ( + 'ClearActiveStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticStreams': 'r-' + } + }, + }, + + 'Vlan': { + 'Prop': { + 'AttachedVlans': 'r-' + } + }, + 'Preview': { + 'Cmd': ( + 'ResetPreviewSettings', + ) + }, + 'Bandwidth': { + 'Prop': { + 'bandwidthStatus': 'r-' + } + }, + }, + 'LineTest': { + 'MELT': { + 'Prop': { + 'MeltResults': 'r-' + }, + 'Cmd': ( + 'StartMeltMeasurement', + ) + }, + 'Delt': { + 'Prop': { + 'DeltMeasurementStatus': 'r-', + 'RecordedDeltMeasurements': 'r-' + }, + 'Cmd': ( + 'StartDeltMeasurement', + ) + }, + 'Selt': { + 'Prop': { + 'SeltMeasurementStatus': 'r-', + 'RecordedSeltMeasurements': 'r-', + 'CableType': 'rw', + 'BandplanProfile': 'rw', + 'TargetSnrm': 'rw' + }, + 'Cmd': ( + 'StartSeltMeasurement', + ) + }, + }, + 'Defects': { + 'Prop': { + 'Defects': 'r-' + } + }, + 'LineInventory': { + 'Prop': { + 'VendorId': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'DslOperationStatus': 'r-' + } + }, + 'Subcarrier': { + 'Cmd': ( + 'ShowBitAllocation', + ) + }, + 'RfiBands': { + 'Prop': { + 'NotchStatus': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index dcbb3be..0c4258f 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -21,43 +21,33 @@ class PortgroupPortCommandProcessor(PortCommandProcessor): from .portgroupportManagementFunctions import main from .portgroupportManagementFunctions import cfgm - from .portgroupportManagementFunctions import fm - from .portgroupportManagementFunctions import pm from .portgroupportManagementFunctions import status def do_get(self, command, *args, context=None): scopes = ('login', 'base', 'get') - if self._validate(args, *()): - exc = exceptions.CommandSyntaxError(command=command) - exc.template = 'syntax_error' - exc.template_scopes = ('login', 'base', 'syntax_errors') - raise exc - elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': - text = self._render('attainable_rate', *scopes, context=context) - self._write(text) - elif self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ - self._model.get_card('name', context['unit']).product == 'isdn': - text = self._render('subscriberList_top', *scopes, context=context) - i = 0 - for subscriber in self._model.subscribers: - if subscriber.type == 'port': # TODO: show only subscriber of this port - - context['i'] = i - context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' - context['spacer2'] = self.create_spacers((63,), (subscriber.registration_state,))[0] * ' ' - i += 1 - text += self._render('subscriberList_item2', *scopes, context=dict(context, subscriber=subscriber)) - text += self._render('subscriberList_bottom', *scopes, context=context) - - self._write(text) - elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': - text = self._render('administrative_status', *scopes, context=context) - self._write(text) - elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': - text = self._render('operational_status', *scopes, context=context) - self._write(text) - else: - raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + try: + super().do_get(command, *args, context=None) + except exceptions.CommandExecutionError: + # TODO: example + if self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ + self._model.get_card('name', context['unit']).product == 'isdn': + text = self._render('subscriberList_top', *scopes, context=context) + i = 0 + for subscriber in self._model.subscribers: + if subscriber.type == 'port': # TODO: show only subscriber of this port + + context['i'] = i + context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' + context['spacer2'] = self.create_spacers((63,), (subscriber.registration_state,))[0] * ' ' + i += 1 + text += self._render('subscriberList_item2', *scopes, + context=dict(context, subscriber=subscriber)) + text += self._render('subscriberList_bottom', *scopes, context=context) + + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) def _init_access_points(self, context=None): port = self._model.get_port('name', context['unit'] + '/' + context['portgroup'] + '/' + context['port']) From 330dfcb583e3c6e4107bd44b0a6e77c1351c8e88 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 7 Oct 2020 13:53:54 +0200 Subject: [PATCH 089/318] deleted obsolete TODOS --- .../root/unit/logport/port/logportCommandProcessor.py | 1 - .../root/unit/portgroup/port/portgroupportCommandProcessor.py | 1 - 2 files changed, 2 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 1df5208..200467b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -28,7 +28,6 @@ def do_get(self, command, *args, context=None): try: super().do_get(command, *args, context=None) except exceptions.CommandExecutionError: - #TODO: example if self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 0c4258f..4c86300 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -28,7 +28,6 @@ def do_get(self, command, *args, context=None): try: super().do_get(command, *args, context=None) except exceptions.CommandExecutionError: - # TODO: example if self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ self._model.get_card('name', context['unit']).product == 'isdn': text = self._render('subscriberList_top', *scopes, context=context) From 0ad8ea0ab745bc9bd2d7a6272b0ca69306a2920e Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Wed, 7 Oct 2020 14:39:02 +0200 Subject: [PATCH 090/318] Small fixes for units, ports, and some schemas + filled 3 testfiles --- nesi/softbox/api/schemas/credential_schemas.py | 2 +- nesi/softbox/api/schemas/emu_schemas.py | 2 +- nesi/softbox/api/schemas/mgmt_card_schemas.py | 3 ++- nesi/softbox/api/schemas/qos_interface_schemas.py | 2 +- nesi/softbox/api/schemas/route_schemas.py | 2 +- nesi/softbox/api/schemas/service_port_schemas.py | 2 +- nesi/softbox/api/schemas/service_vlan_schemas.py | 2 +- nesi/softbox/api/schemas/subscriber_schemas.py | 2 +- nesi/softbox/api/schemas/user_schemas.py | 2 +- nesi/softbox/api/schemas/vlan_interface_schemas.py | 2 +- nesi/softbox/api/schemas/vlan_schemas.py | 2 +- templates/KeyMile/login/base/get/operational_status.j2 | 2 +- .../integration_tests/keymile/test Loopback3.txt | 6 ++++++ .../integration_tests/keymile/testVoicePort2.txt | 7 +++++++ test_cases/integration_tests/keymile/testmelt1.txt | 3 --- test_cases/integration_tests/keymile/testmelting4.txt | 10 ++++++++++ .../root/unit/port/portCommandProcessor.py | 6 ++++++ .../accessPoints/root/unit/unitCommandProcessor.py | 6 +++--- vendors/KeyMile/baseCommandProcessor.py | 4 ++-- 19 files changed, 47 insertions(+), 20 deletions(-) delete mode 100644 test_cases/integration_tests/keymile/testmelt1.txt diff --git a/nesi/softbox/api/schemas/credential_schemas.py b/nesi/softbox/api/schemas/credential_schemas.py index c60f477..7259d53 100644 --- a/nesi/softbox/api/schemas/credential_schemas.py +++ b/nesi/softbox/api/schemas/credential_schemas.py @@ -18,7 +18,7 @@ class CredentialSchema(ma.ModelSchema): class Meta: model = Credential fields = ('id', 'protocol', 'credential', 'username', 'password', - 'box', '_links') + 'box', 'box_id', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/emu_schemas.py b/nesi/softbox/api/schemas/emu_schemas.py index aad1347..7d4fb13 100644 --- a/nesi/softbox/api/schemas/emu_schemas.py +++ b/nesi/softbox/api/schemas/emu_schemas.py @@ -17,7 +17,7 @@ class EmuSchema(ma.ModelSchema): class Meta: model = Emu - fields = ('id', 'name', 'box', '_links') + fields = ('id', 'name', 'box', 'box_id', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/mgmt_card_schemas.py b/nesi/softbox/api/schemas/mgmt_card_schemas.py index 5d7e4f0..c03f1c5 100644 --- a/nesi/softbox/api/schemas/mgmt_card_schemas.py +++ b/nesi/softbox/api/schemas/mgmt_card_schemas.py @@ -19,7 +19,8 @@ class MgmtCardSchema(ma.ModelSchema): class Meta: model = MgmtCard - fields = ('id', 'box_id', 'box', 'name', 'subrack_id', 'admin_state', 'operational_state', 'description', 'mgmt_ports') + fields = ('id', 'box_id', 'box', 'name', 'subrack_id', 'admin_state', 'operational_state', 'description', + 'mgmt_ports') mgmt_ports = ma.Nested(MgmtPortsSchema.MgmtPortSchema, many=True) diff --git a/nesi/softbox/api/schemas/qos_interface_schemas.py b/nesi/softbox/api/schemas/qos_interface_schemas.py index 0743d85..02dd33f 100644 --- a/nesi/softbox/api/schemas/qos_interface_schemas.py +++ b/nesi/softbox/api/schemas/qos_interface_schemas.py @@ -17,7 +17,7 @@ class QosInterfaceSchema(ma.ModelSchema): class Meta: model = QosInterface - fields = ('id', 'name', 'description', 'box', + fields = ('id', 'name', 'description', 'box', 'box_id', '_links') _links = ma.Hyperlinks({ diff --git a/nesi/softbox/api/schemas/route_schemas.py b/nesi/softbox/api/schemas/route_schemas.py index da0b85e..41db76f 100644 --- a/nesi/softbox/api/schemas/route_schemas.py +++ b/nesi/softbox/api/schemas/route_schemas.py @@ -17,7 +17,7 @@ class RouteSchema(ma.ModelSchema): class Meta: model = Route - fields = ('id', 'dst', 'gw', 'metric', 'box', '_links') + fields = ('id', 'dst', 'gw', 'metric', 'box', 'box_id', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/service_port_schemas.py b/nesi/softbox/api/schemas/service_port_schemas.py index ae33609..251d7ef 100644 --- a/nesi/softbox/api/schemas/service_port_schemas.py +++ b/nesi/softbox/api/schemas/service_port_schemas.py @@ -17,7 +17,7 @@ class ServicePortSchema(ma.ModelSchema): class Meta: model = ServicePort - fields = ('id', 'name', 'box', 'connected_id', 'connected_type', 'admin_state', 'operational_state', + fields = ('id', 'name', 'box', 'box_id', 'connected_id', 'connected_type', 'admin_state', 'operational_state', '_links') box = ma.Hyperlinks( diff --git a/nesi/softbox/api/schemas/service_vlan_schemas.py b/nesi/softbox/api/schemas/service_vlan_schemas.py index d9c0e2a..1354f95 100644 --- a/nesi/softbox/api/schemas/service_vlan_schemas.py +++ b/nesi/softbox/api/schemas/service_vlan_schemas.py @@ -17,7 +17,7 @@ class ServiceVlanSchema(ma.ModelSchema): class Meta: model = ServiceVlan - fields = ('id', 'name', 'service_port_id', 'vlan_id', 'box', 'card_id', '_links') + fields = ('id', 'name', 'service_port_id', 'vlan_id', 'box', 'box_id', 'card_id', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/subscriber_schemas.py b/nesi/softbox/api/schemas/subscriber_schemas.py index d788063..25b65d6 100644 --- a/nesi/softbox/api/schemas/subscriber_schemas.py +++ b/nesi/softbox/api/schemas/subscriber_schemas.py @@ -17,7 +17,7 @@ class SubscriberSchema(ma.ModelSchema): class Meta: model = Subscriber - fields = ('id', 'name', 'box', 'number', 'type', 'address', 'registration_state', '_links') + fields = ('id', 'name', 'box', 'box_id', 'number', 'type', 'address', 'registration_state', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/user_schemas.py b/nesi/softbox/api/schemas/user_schemas.py index f2f93e5..6341cd0 100644 --- a/nesi/softbox/api/schemas/user_schemas.py +++ b/nesi/softbox/api/schemas/user_schemas.py @@ -17,7 +17,7 @@ class UserSchema(ma.ModelSchema): class Meta: model = User - fields = ('id', 'box', 'credentials_id', 'name', '_links') + fields = ('id', 'box', 'box_id', 'credentials_id', 'name', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/vlan_interface_schemas.py b/nesi/softbox/api/schemas/vlan_interface_schemas.py index ff335dc..aa67183 100644 --- a/nesi/softbox/api/schemas/vlan_interface_schemas.py +++ b/nesi/softbox/api/schemas/vlan_interface_schemas.py @@ -17,7 +17,7 @@ class VlanInterfaceSchema(ma.ModelSchema): class Meta: model = VlanInterface - fields = ('id', 'name', 'box', 'vlan_id', '_links') + fields = ('id', 'name', 'box', 'box_id', 'vlan_id', '_links') _links = ma.Hyperlinks({ 'self': ma.URLFor( diff --git a/nesi/softbox/api/schemas/vlan_schemas.py b/nesi/softbox/api/schemas/vlan_schemas.py index 96d608a..49ca8d7 100644 --- a/nesi/softbox/api/schemas/vlan_schemas.py +++ b/nesi/softbox/api/schemas/vlan_schemas.py @@ -17,7 +17,7 @@ class VlanSchema(ma.ModelSchema): class Meta: model = Vlan - fields = ('id', 'box_id', 'number', 'mtu', + fields = ('id', 'box_id', 'number', 'mtu', 'box' '_links') box = ma.Hyperlinks( diff --git a/templates/KeyMile/login/base/get/operational_status.j2 b/templates/KeyMile/login/base/get/operational_status.j2 index ea79363..167d462 100644 --- a/templates/KeyMile/login/base/get/operational_status.j2 +++ b/templates/KeyMile/login/base/get/operational_status.j2 @@ -1,3 +1,3 @@ \ # OperationalStatus -{{ context.port.operational_state }}{{ context.spacer }}\ # State +{{ context.port_operational_state }}{{ context.spacer }}\ # State diff --git a/test_cases/integration_tests/keymile/test Loopback3.txt b/test_cases/integration_tests/keymile/test Loopback3.txt index 6f999b9..a4c19e2 100644 --- a/test_cases/integration_tests/keymile/test Loopback3.txt +++ b/test_cases/integration_tests/keymile/test Loopback3.txt @@ -1,3 +1,9 @@ admin secret +#isdn +cd /unit-$voiceCard/port-$voicePort/status +Lock +StartQuickLoopbackTest +get QuickLoopbackTest +Unlock exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/testVoicePort2.txt b/test_cases/integration_tests/keymile/testVoicePort2.txt index 6f999b9..0602971 100644 --- a/test_cases/integration_tests/keymile/testVoicePort2.txt +++ b/test_cases/integration_tests/keymile/testVoicePort2.txt @@ -1,3 +1,10 @@ admin secret +cd /unit-{$voice_card}/main +get HardwareAndSoftware +/unit-$voice_card/port-$voice_port/status/StartLineTest +get /unit-$voice_card/port-$voice_port/status/LineTestResults +#SUVM6 +cd /unit-$card/port-$port/main +set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/testmelt1.txt b/test_cases/integration_tests/keymile/testmelt1.txt deleted file mode 100644 index 6f999b9..0000000 --- a/test_cases/integration_tests/keymile/testmelt1.txt +++ /dev/null @@ -1,3 +0,0 @@ -admin -secret -exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/testmelting4.txt b/test_cases/integration_tests/keymile/testmelting4.txt index 6f999b9..a526c37 100644 --- a/test_cases/integration_tests/keymile/testmelting4.txt +++ b/test_cases/integration_tests/keymile/testmelting4.txt @@ -1,3 +1,13 @@ admin secret +#voiceport +/unit-$voice_card/port-$voice_port/status/StartLineTest +get /unit-$voice_card/port-$voice_port/status/LineTestResults +#else +/unit-$card/port-$port/status/StartMeltMeasurement +get /unit-$card/port-$port/status/MeltResults + +#SUVM6 +cd /unit-$card/port-$port/main +set AdministrativeStatus up exit \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index b4ad848..69ba6b0 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -26,6 +26,8 @@ class PortCommandProcessor(BaseCommandProcessor): from .portManagementFunctions import status def do_get(self, command, *args, context=None): + port_name = context['unit'] + '/' + context['port'] + port = self._model.get_port('name', port_name) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -39,6 +41,10 @@ def do_get(self, command, *args, context=None): text = self._render('administrative_status', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': + self.map_states(port, 'port') + port_operational_state = port.operational_state + context['port_operational_state'] = port_operational_state + context['spacer'] = self.create_spacers((67,), (port_operational_state,))[0] * ' ' text = self._render('operational_status', *scopes, context=context) self._write(text) else: diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 2e6bb75..0deccb2 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -80,7 +80,7 @@ def do_get(self, command, *args, context=None): text = self._render('ip', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'HardwareAndSoftware'): + elif self._validate((args[0],), 'HardwareAndSoftware') and context['path'].split('/')[-1] == 'main': unit_hardware = '"' + card.board_name + '"' context['unit_hardware'] = unit_hardware context['spacer_1'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' @@ -105,7 +105,7 @@ def do_get(self, command, *args, context=None): text = self._render('hardware_and_software', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'CurrentStatus'): + elif self._validate((args[0],), 'CurrentStatus') and context['path'].split('/')[-1] == 'main': unit_state = card.state context['unit_state'] = unit_state context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' @@ -127,7 +127,7 @@ def do_get(self, command, *args, context=None): text = self._render('current_status', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'EquipmentInventory'): + elif self._validate((args[0],), 'EquipmentInventory') and context['path'].split('/')[-1] == 'main': unit_symbol = '"' + card.board_name + '"' context['unit_symbol'] = unit_symbol context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index afce2fd..21d6af9 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -37,14 +37,14 @@ def map_states(self, object, type): object.admin_state = 'Down' elif object.admin_state == '1': if type == 'port': - object.admin_state = 'Down' + object.admin_state = 'Up' if object.operational_state == '0': if type == 'port': object.operational_state = 'Down' elif object.operational_state == '1': if type == 'port': - object.operational_state = 'Down' + object.operational_state = 'Up' def create_spacers(self, positions, args): spacers = [] From 545349146521b24831141b13057dde25a46381fd Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 7 Oct 2020 16:02:22 +0200 Subject: [PATCH 091/318] offer parent and child relation in baseCommandProcessor --- vendors/KeyMile/baseCommandProcessor.py | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 21d6af9..4c4ed07 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -103,6 +103,44 @@ def do_pwd(self, command, *args, context=None): def exec_in_path(self, path, command, *args, context=None): pass + ''' + search := string keyword like "unit" or "port" + node := contains the dict tree or + None for default tree structure + parent := None or contains parent dict (should be None / important for rekursive call) + return := Tuple of ParentList, ChildList + ''' + def get_parent_and_child_relation(self, search, node=None, parent=None): + if node is None: + node = { + "root": { + "unit": { + "control": {}, + "media": {}, + "port": { + "chanel": { + "interfaces": {} + }, + "interfaces": {} + }, + "portgroups": {"portgroupports": {}}, + "logports": {"logport": {}}, + "vectoringports": {"vectorport": {}}, + "internalports": {"internalport": {}} + }, + "eoam": {}, + "tdmConnections": {}, + "services": {}, + "multicast": {} + }} + for x, y in node.items(): + if y.get(search) is not None: + pp = list(parent.keys()) + pc = list(y[search].keys()) + return (pp, pc) + else: + return self.get_parent_and_child_relation(search=search, node=y, parent=node) + def do_cd(self, command, *args, context=None): if len(args) == 0: exc = exceptions.CommandSyntaxError(command=command) From 3891b8b4876c8a47acd1596a6f4af4b17ea8ebdf Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 7 Oct 2020 16:43:35 +0200 Subject: [PATCH 092/318] First set structure --- .../accessPoints/root/eoamCommandProcessor.py | 11 ++++++++++- .../root/multicastCommandProcessor.py | 11 ++++++++++- .../accessPoints/root/rootCommandProcessor.py | 10 ++++++++++ .../root/tdmConnectionsCommandProcessor.py | 11 ++++++++++- .../unit/logport/logportsCommandProcessor.py | 11 ++++++++++- .../unit/logport/port/logportCommandProcessor.py | 16 +++++++++++++++- .../root/unit/port/chan/chanCommandProcessor.py | 11 ++++++++++- .../unit/port/chan/vcc/vccCommandProcessor.py | 11 ++++++++++- .../port/interface/interfaceCommandProcessor.py | 9 +++++++++ .../root/unit/port/portCommandProcessor.py | 12 +++++++++++- .../port/portgroupportCommandProcessor.py | 16 +++++++++++++++- .../unit/portgroup/portgroupCommandProcessor.py | 11 ++++++++++- .../root/unit/unitCommandProcessor.py | 9 +++++++++ vendors/KeyMile/baseCommandProcessor.py | 8 ++++++++ 14 files changed, 147 insertions(+), 10 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py index d6888f5..cf866dc 100644 --- a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py @@ -24,4 +24,13 @@ class EoamCommandProcessor(BaseCommandProcessor): from .eoamManagementFunctions import status def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py index 43b31cf..5cad2b8 100644 --- a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py @@ -26,4 +26,13 @@ class MulticastCommandProcessor(BaseCommandProcessor): from .multicastManagementFunctions import status def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 81725fc..1fd5799 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -30,5 +30,15 @@ def _init_access_points(self, context=None): continue self.access_points += ('unit-' + card.name,) + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py index 12b4d77..b230d5c 100644 --- a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py @@ -23,4 +23,13 @@ class TdmConnectionsCommandProcessor(BaseCommandProcessor): from .tdmConnectionsManagementFunctions import cfgm def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 1f28568..cee387f 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -34,4 +34,13 @@ def _init_access_points(self, context=None): # work in progress self.access_points += (identifier,) def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 200467b..382a1e0 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -39,4 +39,18 @@ def _init_access_points(self, context=None): port = self._model.get_port('name', context['unit'] + '/' + context['portgroup'] + '/' + context['port']) def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + try: + super().set(command, *args, context=None) + except exceptions.CommandExecutionError: + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 2f4b9b9..1029469 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -40,4 +40,13 @@ def _init_access_points(self, context=None): self.access_points += (identifier,) def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py index 40d569a..c0e0842 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py @@ -25,4 +25,13 @@ class VccCommandProcessor(BaseCommandProcessor): from .vccManagementFunctions import status def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index 5bbae5d..4deae4d 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -26,3 +26,12 @@ class InterfaceCommandProcessor(BaseCommandProcessor): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 69ba6b0..79bfeb5 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -60,4 +60,14 @@ def _init_access_points(self, context=None): self.access_points += (identifier,) def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 4c86300..f603a08 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -52,4 +52,18 @@ def _init_access_points(self, context=None): port = self._model.get_port('name', context['unit'] + '/' + context['portgroup'] + '/' + context['port']) def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + try: + super().set(command, *args, context=None) + except exceptions.CommandExecutionError: + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index 47cf9f2..f2fa5dc 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -34,4 +34,13 @@ def _init_access_points(self, context=None): # work in progress self.access_points += (identifier,) def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 0deccb2..f4ff360 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -179,3 +179,12 @@ def do_get(self, command, *args, context=None): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 4c4ed07..3eca771 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -141,6 +141,14 @@ def get_parent_and_child_relation(self, search, node=None, parent=None): else: return self.get_parent_and_child_relation(search=search, node=y, parent=node) + def do_set(self, command, *args, context=None): + self.set(command, args, context) + return + + def set(self, command, *args, context=None): + #interface method + return + def do_cd(self, command, *args, context=None): if len(args) == 0: exc = exceptions.CommandSyntaxError(command=command) From 021f3e068edd60648e41769efa496feeddced427 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 8 Oct 2020 09:52:58 +0200 Subject: [PATCH 093/318] Refactored do_cd and added generic function to switch between directories --- ...ile-MG2200.sh => create-keymile-MG2500.sh} | 84 +++- bootup/restapi.sh | 2 +- templates/KeyMile/login/base/ls/ls_header.j2 | 2 +- .../unit/port/chan/chanCommandProcessor.py | 4 +- .../root/unit/port/portCommandProcessor.py | 2 +- .../portgroup/portgroupCommandProcessor.py | 5 +- .../root/unit/unitCommandProcessor.py | 2 +- vendors/KeyMile/baseCommandProcessor.py | 448 ++++++++++-------- vendors/KeyMile/main.py | 1 + 9 files changed, 345 insertions(+), 205 deletions(-) rename bootup/conf/bootstraps/{create-keymile-MG2200.sh => create-keymile-MG2500.sh} (83%) diff --git a/bootup/conf/bootstraps/create-keymile-MG2200.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh similarity index 83% rename from bootup/conf/bootstraps/create-keymile-MG2200.sh rename to bootup/conf/bootstraps/create-keymile-MG2500.sh index abc2883..6a0d3e4 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2200.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -22,12 +22,12 @@ path="`dirname \"$0\"`" # Create a network device (admin operation) req='{ "vendor": "KeyMile", - "model": "MG2200", + "model": "MG2500", "version": "1", "description": "Example Switch", - "hostname": "KeyMileMG2200", + "hostname": "KeyMileMG2500", "mgmt_address": "10.0.0.12", - "software_version": "MG2200V800R016C00", + "software_version": "MG2500V800R016C00", "network_protocol": "telnet", "network_address": "127.0.0.1", "network_port": 9023, @@ -36,13 +36,85 @@ req='{ box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 -# Admin credentials +# Sessionmanager credentials req='{ - "username": "admin", + "username": "sessionmanager", "password": "secret" }' -root_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) +sessionmanager_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# Sessionmanager user +req='{ + "name": "sessionmanager", + "credentials_id": '$sessionmanager_credential_id', + "level": "Super", + "profile": "root", + "append_info": "Sessionmanager", + "lock_status": "Unlocked" +}' + +sessionmanager_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) + +# Manager credentials +req='{ + "username": "manager", + "password": "secret" +}' + +manager_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# Manager user +req='{ + "name": "manager", + "credentials_id": '$manager_credential_id', + "level": "Admin", + "profile": "admin", + "append_info": "Manager", + "lock_status": "Unlocked" +}' + +manager_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) + +# Maintenance credentials +req='{ + "username": "maintenance", + "password": "secret" +}' + +maintenance_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# Manager user +req='{ + "name": "maintenance", + "credentials_id": '$maintenance_credential_id', + "level": "Operator", + "profile": "operator", + "append_info": "Maintenance", + "lock_status": "Unlocked" +}' + +maintenance_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) + +# Information credentials +req='{ + "username": "information", + "password": "secret" +}' + +information_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# Manager user +req='{ + "name": "information", + "credentials_id": '$information_credential_id', + "level": "User", + "profile": "commonuser", + "append_info": "Information", + "lock_status": "Unlocked" +}' + +information_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) # test subscriber req='{ diff --git a/bootup/restapi.sh b/bootup/restapi.sh index d14d657..7071288 100755 --- a/bootup/restapi.sh +++ b/bootup/restapi.sh @@ -181,7 +181,7 @@ if [ $recreate_db = "yes" ]; then #bash bootup/conf/bootstraps/create-box-port-vlan.sh #bash bootup/conf/bootstraps/create-alcatel-7360.sh #bash bootup/conf/bootstraps/create-huawei-5623.sh - bash bootup/conf/bootstraps/create-keymile-MG2200.sh + bash bootup/conf/bootstraps/create-keymile-MG2500.sh fi if [ $alcatel_api = "yes" ]; then diff --git a/templates/KeyMile/login/base/ls/ls_header.j2 b/templates/KeyMile/login/base/ls/ls_header.j2 index e0a8150..2f31160 100644 --- a/templates/KeyMile/login/base/ls/ls_header.j2 +++ b/templates/KeyMile/login/base/ls/ls_header.j2 @@ -1,4 +1,4 @@ -Infos of AP: {{ context.path }} +Infos of AP: {{ context.ls_path }} Name : MileGate 2200 Main Mode : Equipment State : Ok diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 1029469..c3f3e2b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -26,8 +26,8 @@ class ChanCommandProcessor(BaseCommandProcessor): from .chanManagementFunctions import status def _init_access_points(self, context=None): - chan = self._model.get_chan('name', context['unit'] + '/' + context['port'] + '/' + context['chan']) - card = self._model.get_card('name', context['unit']) + chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + card = self._model.get_card('name', self._parent._parent.component_id) for interface in self._model.get_interfaces('chan_id', chan.id): if card.product != 'adsl': diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 79bfeb5..585ac74 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -51,7 +51,7 @@ def do_get(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) def _init_access_points(self, context=None): - port = self._model.get_port('name', context['unit'] + '/' + context['port']) + port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) for chan in self._model.get_chans('port_id', port.id): identifier = 'chan-' + chan.name.split('/')[-1] diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index f2fa5dc..b9dfef6 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -23,11 +23,10 @@ class PortgroupCommandProcessor(BaseCommandProcessor): from .portgroupManagementFunctions import cfgm def _init_access_points(self, context=None): # work in progress - card = self._model.get_card('name', context['unit']) - portgroup = context['portgroup'] + card = self._model.get_card('name', self._parent.component_id) for port in self._model.get_ports('card_id', card.id): - if port.name.count('/') == 2 and port.name.strip('/')[1] == 'portgroup-' + portgroup: + if port.name.count('/') == 2 and port.name.strip('/')[1] == 'portgroup-' + self.component_id: identifier = 'port-' + port.name.split('/')[-1] if identifier in self.access_points: continue diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index f4ff360..1fe5609 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -25,7 +25,7 @@ class UnitCommandProcessor(BaseCommandProcessor): from .unitManagementFunctions import status def _init_access_points(self, context=None): - card = self._model.get_card('name', context['unit']) + card = self._model.get_card('name', self.component_id) # if card.type == ?: # self.access_points += ('internalPorts',) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 3eca771..5b588d3 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -21,6 +21,11 @@ class BaseCommandProcessor(base.CommandProcessor): management_functions = () access_points = () + component_id = None + + def set_component_id(self, id): + self.component_id = id + main = {} cfgm = {} @@ -100,281 +105,344 @@ def do_pwd(self, command, *args, context=None): context['spacer'] = self.create_spacers((67,), (context['path'],))[0] * ' ' self._write(self._render('pwd', 'login', 'base', context=context)) - def exec_in_path(self, path, command, *args, context=None): - pass + def ls(self, context=None, path_type='path'): + scopes = ('login', 'base', 'ls') + context['ls_path'] = context[path_type] + if re.search('(pm|fm|status|main|cfgm)', context['ls_path']): + mf_type = context['ls_path'].split('/')[-1] + + mf_layers = None + if mf_type == 'status': + mf_layers = self.status + elif mf_type == 'cfgm': + mf_layers = self.cfgm + elif mf_type == 'fm': + mf_layers = self.fm + elif mf_type == 'pm': + mf_layers = self.pm + elif mf_type == 'main': + mf_layers = self.main + + def generate_ls_text(layers, depth): + text = '' + for layer in layers: + if layer not in ('Cmd', 'Prop', 'File'): + context['mf_layer'] = depth * ' ' + layer + text += self._render('ls_mf_header', *scopes, context=context) + depth += 1 + text += generate_ls_text(layers[layer], depth) + depth -= 1 + else: + if layer == 'Cmd': + prop_type = layer + ' ' + else: + prop_type = layer - ''' - search := string keyword like "unit" or "port" - node := contains the dict tree or - None for default tree structure - parent := None or contains parent dict (should be None / important for rekursive call) - return := Tuple of ParentList, ChildList - ''' - def get_parent_and_child_relation(self, search, node=None, parent=None): - if node is None: - node = { - "root": { - "unit": { - "control": {}, - "media": {}, - "port": { - "chanel": { - "interfaces": {} - }, - "interfaces": {} - }, - "portgroups": {"portgroupports": {}}, - "logports": {"logport": {}}, - "vectoringports": {"vectorport": {}}, - "internalports": {"internalport": {}} - }, - "eoam": {}, - "tdmConnections": {}, - "services": {}, - "multicast": {} - }} - for x, y in node.items(): - if y.get(search) is not None: - pp = list(parent.keys()) - pc = list(y[search].keys()) - return (pp, pc) - else: - return self.get_parent_and_child_relation(search=search, node=y, parent=node) + context['prop_type'] = depth * ' ' + prop_type - def do_set(self, command, *args, context=None): - self.set(command, args, context) - return + for property in layers[layer]: + context['prop_name'] = property - def set(self, command, *args, context=None): - #interface method - return + if prop_type in ('File', 'Prop'): + context['prop_rw_rights'] = layers[layer].get(property, '') + else: + context['prop_rw_rights'] = '' + text += self._render('ls_mf_body', *scopes, context=context) + return text - def do_cd(self, command, *args, context=None): - if len(args) == 0: - exc = exceptions.CommandSyntaxError(command=command) - exc.template = 'syntax_error' - exc.template_scopes = ('login', 'base', 'syntax_errors') - raise exc + text = generate_ls_text(mf_layers, 0) + self._write(text) - if args[0] == '/': - context['path'] = '/' - from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor - exc = exceptions.TerminalExitError() - exc.return_to = RootCommandProcessor + else: + text = self._render('ls_header', *scopes, context=context) + + text += self._render('ls_mf_list', *scopes, context=context) + for management_function in self.management_functions: + context['list_entry'] = management_function + text += self._render('ls_list_body', *scopes, context=context) + + text += self._render('ls_ap_list', *scopes, context=context) + + self._init_access_points(context=context) + + for access_point in self.access_points: + context['list_entry'] = access_point + text += self._render('ls_list_body', *scopes, context=context) - raise exc + self._write(text) - components = [x for x in args[0].split('/') if x] + def do_ls(self, command, *args, context=None): + if self._validate(args, ): + self.ls(context=context) + elif self._validate(args, '-e'): + pass + elif self._validate(args, str): + path = args[0] + + try: + tmp_cmdproc = self.change_directory(path, context=context) + tmp_cmdproc.ls(context=context, path_type='component_path') + except exceptions.CommandExecutionError: + raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + context['component_path'] = context['path'] + else: + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=command) + + def change_directory(self, path, context=None): + path = path.lower() + if path == '/': + if self.__name__ != 'root': + self._parent.change_directory(path, context=context) + else: + context['component_path'] = '/' + return self + + components = [x for x in path.split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|packet|macAccessCtrl|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', components[0]): - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty + raise exceptions.SoftboxenError() - if args[0] == '.': - return # dot does nothing + if path == '.': + return self - if args[0].startswith('./'): - if args[0] == './': - return + if path.startswith('./'): + if path == './': + return self - self.do_cd(command, args[0][2:], context=context) - return + return self.change_directory(path[2:], context=context) - if re.search('\.\./(?:[^.]+/)+\.\.', args[0]): - if args[0].endswith('..'): + if re.search('\.\./(?:[^.]+/)+\.\.', path): + if path.endswith('..'): raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) else: raise exceptions.CommandExecutionError(template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors'), command=None) - if args[0].startswith('..'): - splitted_path = [x for x in context['path'].split('/') if x] + if path.startswith('..'): + splitted_path = [x for x in context['component_path'].split('/') if x] exit_component = None if len(splitted_path) != 0: exit_component = splitted_path.pop() - context['path'] = '/' + '/'.join(splitted_path) + context['component_path'] = '/' + '/'.join(splitted_path) if exit_component in ('main', 'cfgm', 'fm', 'pm', 'status'): self.set_prompt_end_pos(context=context) - if args[0] != '..': - self.do_cd('cd', args[0][3:], context=context) - return + if path != '..': + return self._parent.change_directory(path[3:], context=context) + return self - if args[0] == '..': - raise exceptions.TerminalExitError() + if path == '..': + return self._parent - exc = exceptions.TerminalExitError() - exc.command = 'cd ' + args[0][3:] - raise exc - - if args[0].startswith('/'): + return self._parent.change_directory(path[3:], context=context) + if path.startswith('/'): if 'unit-' not in components[0] and components[0] not in ('eoam', 'fan', 'multicast', 'services', 'tdmConnection', 'main', 'cfgm', 'fm', 'pm', 'status'): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - context['path'] = '/' - if self.__name__ != 'root': - exc = exceptions.TerminalExitError() - from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor - exc.return_to = RootCommandProcessor - exc.command = 'cd ' + args[0].lstrip('/') - raise exc - - self.do_cd('cd', args[0].lstrip('/'), context=context) + subprocessor = self._parent.change_directory(path, context=context) + else: + context['component_path'] = '/' + subprocessor = self.change_directory(path.lstrip('/'), context=context) else: remaining_args = '/'.join(components[1:]) component_type = None - component_number = None + component_id = None if '-' in components[0]: component_type = components[0].split('-')[0] - component_number = components[0].split('-')[1] + component_id = components[0].split('-')[1] command_processor = component_type.capitalize() + 'CommandProcessor' else: command_processor = components[0].capitalize() + 'CommandProcessor' if component_type == 'unit': if self.__name__ != 'root': - raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - - context['unit'] = component_number - elif component_type == 'port': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'portgroup' or component_type == 'logports' or component_type == 'huntgroup': if self.__name__ != 'unit': - raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - - context['port'] = component_number + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'port': + if self.__name__ != 'unit' and self.__name__ != 'portgroup': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'chan': if self.__name__ != 'port': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - context['chan'] = component_number elif component_type == 'interface': if self.__name__ != 'port' and self.__name__ != 'chan': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - context['chan'] = component_number - if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): if self.__name__ != 'root': - raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty if components[0] in ('main', 'cfgm', 'fm', 'pm', 'status'): if re.search('(main|cfgm|fm|pm|status)', context['path']): - return - if context['path'] == '/': + return self + if context['component_path'] == '/': new_path = components[0] else: new_path = '/' + components[0] - context['path'] += new_path - self.set_prompt_end_pos(context=context) - return + context['component_path'] += new_path + return self from vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor import UnitCommandProcessor from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor from vendors.KeyMile.accessPoints.root.unit.port.chan.chanCommandProcessor import ChanCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor import InterfaceCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor import \ + InterfaceCommandProcessor from vendors.KeyMile.accessPoints.root.fan.fanCommandProcessor import FanCommandProcessor from vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor import AlarmCommandProcessor from vendors.KeyMile.accessPoints.root.eoamCommandProcessor import EoamCommandProcessor from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor - from vendors.KeyMile.accessPoints.root.services.packetCommandProcessor import PacketCommandProcessor - from vendors.KeyMile.accessPoints.root.services.macAccessCtrlCommandProcessor import MacAccessCtrlCommandProcessor as MacaccessctrlCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import PortgroupCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import PortgroupPortCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') - if len(remaining_args) > 0: - command = 'cd ' + remaining_args - else: - command = None + if component_id is not None: + subprocessor.set_component_id(component_id) - if context['path'] == '/': + if context['component_path'] == '/': new_path = components[0] else: new_path = '/' + components[0] + context['component_path'] += new_path - context['path'] += new_path - subprocessor.loop(context=context, return_to=self.__class__, command=command) - - def do_exit(self, command, *args, context=None): - exc = exceptions.TerminalExitError() - exc.return_to = 'sysexit' - raise exc - - def do_ls(self, command, *args, context=None): - if self._validate(args,): - scopes = ('login', 'base', 'ls') - if re.search('(pm|fm|status|main|cfgm)', context['path']): - mf_type = context['path'].split('/')[-1] - - mf_layers = None - if mf_type == 'status': - mf_layers = self.status - elif mf_type == 'cfgm': - mf_layers = self.cfgm - elif mf_type == 'fm': - mf_layers = self.fm - elif mf_type == 'pm': - mf_layers = self.pm - elif mf_type == 'main': - mf_layers = self.main - - def generate_ls_text(layers, depth): - text = '' - for layer in layers: - if layer not in ('Cmd', 'Prop', 'File'): - context['mf_layer'] = depth * ' ' + layer - text += self._render('ls_mf_header', *scopes, context=context) - depth += 1 - text += generate_ls_text(layers[layer], depth) - depth -= 1 - else: - if layer == 'Cmd': - prop_type = layer + ' ' - else: - prop_type = layer - - context['prop_type'] = depth * ' ' + prop_type - - for property in layers[layer]: - context['prop_name'] = property - - if prop_type in ('File', 'Prop'): - context['prop_rw_rights'] = layers[layer].get(property, '') - else: - context['prop_rw_rights'] = '' - text += self._render('ls_mf_body', *scopes, context=context) - return text + if len(remaining_args) > 0: + subprocessor = subprocessor.change_directory(remaining_args, context=context) - text = generate_ls_text(mf_layers, 0) - self._write(text) + return subprocessor + ''' + search := string keyword like "unit" or "port" + node := contains the dict tree or + None for default tree structure + parent := None or contains parent dict (should be None / important for rekursive call) + return := Tuple of ParentList, ChildList + ''' + def get_parent_and_child_relation(self, search, node=None, parent=None): + if node is None: + node = { + "root": { + "unit": { + "control": {}, + "media": {}, + "port": { + "chanel": { + "interfaces": {} + }, + "interfaces": {} + }, + "portgroups": {"portgroupports": {}}, + "logports": {"logport": {}}, + "vectoringports": {"vectorport": {}}, + "internalports": {"internalport": {}} + }, + "eoam": {}, + "tdmConnections": {}, + "services": {}, + "multicast": {} + }} + for x, y in node.items(): + if y.get(search) is not None: + pp = list(parent.keys()) + pc = list(y[search].keys()) + return (pp, pc) else: - text = self._render('ls_header', *scopes, context=context) - - text += self._render('ls_mf_list', *scopes, context=context) - for management_function in self.management_functions: - context['list_entry'] = management_function - text += self._render('ls_list_body', *scopes, context=context) - - text += self._render('ls_ap_list', *scopes, context=context) + return self.get_parent_and_child_relation(search=search, node=y, parent=node) - self._init_access_points(context=context) + def do_set(self, command, *args, context=None): + self.set(command, args, context) + return - for access_point in self.access_points: - context['list_entry'] = access_point - text += self._render('ls_list_body', *scopes, context=context) + def set(self, command, *args, context=None): + #interface method + return - self._write(text) - elif self._validate(args, '-e'): - pass - elif self._validate([args[0]], str): + def do_cd(self, command, *args, context=None): + if self._validate(args, ): + raise exceptions.CommandSyntaxError() + elif self._validate(args, str): path = args[0] - self.do_cd('cd', path, context=context) + try: + subprocessor = self.change_directory(path, context=context) + return_to = self.get_command_processor(subprocessor) + except: + context['component_path'] = context['path'] + raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + context['path'] = context['component_path'] + subprocessor.loop(context=context, return_to=return_to) else: - raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=command) + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=command) + + def get_command_processor(self, current_processor, component_type=None): + from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor import UnitCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.chan.chanCommandProcessor import ChanCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor import \ + InterfaceCommandProcessor + from vendors.KeyMile.accessPoints.root.fan.fanCommandProcessor import FanCommandProcessor + from vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor import AlarmCommandProcessor + from vendors.KeyMile.accessPoints.root.eoamCommandProcessor import EoamCommandProcessor + from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor + from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor + from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor + if current_processor.__class__ == RootCommandProcessor: + return_to = RootCommandProcessor + if component_type not in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services', 'unit') and component_type is not None: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif current_processor.__class__ == UnitCommandProcessor: + return_to = RootCommandProcessor + if component_type != 'port' and component_type is not None: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif current_processor.__class__ == PortCommandProcessor: + return_to = UnitCommandProcessor + if component_type != 'chan' and component_type is not None: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif current_processor.__class__ == ChanCommandProcessor: + return_to = PortCommandProcessor + if component_type != 'interface' and component_type is not None: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif current_processor.__class__ == InterfaceCommandProcessor: + return_to = ChanCommandProcessor + return_to = PortCommandProcessor + elif current_processor.__class__ == FanCommandProcessor: + return_to = RootCommandProcessor + elif current_processor.__class__ == AlarmCommandProcessor: + return_to = FanCommandProcessor + elif current_processor.__class__ == EoamCommandProcessor: + return_to = RootCommandProcessor + elif current_processor.__class__ == MulticastCommandProcessor: + return_to = RootCommandProcessor + elif current_processor.__class__ == TdmConnectionsCommandProcessor: + return_to = RootCommandProcessor + elif current_processor.__class__ == ServicesCommandProcessor: + return_to = RootCommandProcessor + + return return_to + + def do_exit(self, command, *args, context=None): + exc = exceptions.TerminalExitError() + exc.return_to = 'sysexit' + raise exc def _init_access_points(self, context=None): pass # Abstract method not implemented diff --git a/vendors/KeyMile/main.py b/vendors/KeyMile/main.py index ff9abd4..95e03f6 100644 --- a/vendors/KeyMile/main.py +++ b/vendors/KeyMile/main.py @@ -56,6 +56,7 @@ def on_unknown_command(self, command, *args, context=None): RootCommandProcessor, 'login', 'base') context['path'] = '/' + context['component_path'] = '/' self._write(self._render('login_message', 'login', 'base', context=context)) From a567e4f2674f5d77831bf5893aa6ec3e9e03b869 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 8 Oct 2020 10:51:03 +0200 Subject: [PATCH 094/318] refactored parent child function --- vendors/KeyMile/baseCommandProcessor.py | 70 ++++++++++++++++--------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 5b588d3..aa52ce2 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -325,44 +325,62 @@ def change_directory(self, path, context=None): ''' search := string keyword like "unit" or "port" + parent := string keyword to describe the parent of search like "root" node := contains the dict tree or None for default tree structure - parent := None or contains parent dict (should be None / important for rekursive call) - return := Tuple of ParentList, ChildList + parent_keys := should be None / important for rekursive call + return := Tuple of (ParentList, ChildList) or ([],[]) ''' - def get_parent_and_child_relation(self, search, node=None, parent=None): + + def get_parent_and_child_relation(self, search, parent=None, node=None, parent_keys=None): + if parent == "": + return ([], []) if node is None: node = { - "root": { - "unit": { - "control": {}, - "media": {}, - "port": { - "chanel": { - "interfaces": {} + "root": { + "unit": { + "control": {}, + "media": {}, + "port": { + "chanel": { + "interfaces": { + "hell": {} + } + }, + "interfaces": { + "hell2": {} + } }, - "interfaces": {} + "portgroups": {"portgroupports": {}}, + "logports": {"logport": {}}, + "vectoringports": {"vectorport": {}}, + "internalports": {"internalport": {}} }, - "portgroups": {"portgroupports": {}}, - "logports": {"logport": {}}, - "vectoringports": {"vectorport": {}}, - "internalports": {"internalport": {}} - }, - "eoam": {}, - "tdmConnections": {}, - "services": {}, - "multicast": {} - }} + "eoam": {}, + "tdmConnections": {}, + "services": {}, + "multicast": {} + }} for x, y in node.items(): - if y.get(search) is not None: - pp = list(parent.keys()) - pc = list(y[search].keys()) + if x == search and (parent is None or parent_keys.__contains__(parent)): + if parent is not None: + pp = [parent] + elif parent_keys is None: + pp = [] + else: + pp = [parent_keys] + pc = list(y.keys()) return (pp, pc) else: - return self.get_parent_and_child_relation(search=search, node=y, parent=node) + (pp, pc) = self.get_parent_and_child_relation(search=search, parent=parent, node=y, parent_keys=x) + if pp == [] and pc == []: + pass + else: + return (pp, pc) + else: + return ([], []) def do_set(self, command, *args, context=None): - self.set(command, args, context) return def set(self, command, *args, context=None): From 739d6cd6065cab8696115a83781ad48ef12a8113 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 8 Oct 2020 11:25:36 +0200 Subject: [PATCH 095/318] Added restrictions for card names if keymile version is a certain one --- .../conf/bootstraps/create-keymile-MG2500.sh | 4 +-- nesi/softbox/api/views/card_views.py | 14 ++++++++++- .../root/unit/unitCommandProcessor.py | 25 ++++++++++--------- vendors/KeyMile/baseCommandProcessor.py | 9 ++++--- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 6a0d3e4..06f1a66 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -22,8 +22,8 @@ path="`dirname \"$0\"`" # Create a network device (admin operation) req='{ "vendor": "KeyMile", - "model": "MG2500", - "version": "1", + "model": "MileGate", + "version": "2500", "description": "Example Switch", "hostname": "KeyMileMG2500", "mgmt_address": "10.0.0.12", diff --git a/nesi/softbox/api/views/card_views.py b/nesi/softbox/api/views/card_views.py index 5374f92..9852947 100644 --- a/nesi/softbox/api/views/card_views.py +++ b/nesi/softbox/api/views/card_views.py @@ -58,11 +58,16 @@ def new_card(box_id): else: p = re.compile('^([0-9]+)?/?([0-9]+)?/?([0-9]+)?$') match_groups = p.match(last_card['name']).groups() - filtered_match_groups = [x for x in match_groups if x is not None] # filter out None values + filtered_match_groups = [x for x in match_groups if x is not None] # filter out None values last_card_index = filtered_match_groups[len(filtered_match_groups) - 1] if subrack['name'] != "": req['name'] = subrack['name'] + "/" + str(int(last_card_index) + 1) else: + if vendor == 'KeyMile': + if int(last_card_index) + 1 in (11, 13): + return flask.Response(status=500) # MgmtCard slots are reserved + if (box['version'] == '2500' and int(last_card_index) + 1 > 21) or (box['version'] == '2300' and int(last_card_index) + 1 > 14) or (box['version'] == '2200' and int(last_card_index) + 1 > 12): + return flask.Response(status=500) req['name'] = str(int(last_card_index) + 1) else: if subrack['name'] != "": @@ -73,6 +78,13 @@ def new_card(box_id): else: if vendor == 'Huawei': req['name'] = "0" + if vendor == 'KeyMile': + if box['version'] == '2500': + req['name'] = "1" + elif box['version'] == '2300': + req['name'] = "7" + elif box['version'] == '2200': + req['name'] = "9" else: req['name'] = "1" diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 1fe5609..ecf05a1 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -16,7 +16,7 @@ class UnitCommandProcessor(BaseCommandProcessor): __name__ = 'unit' - management_functions = ('main', 'cfgm', 'fm', 'status') + management_functions = ('main', 'fm') access_points = () # 'internalPorts', only on certain cards from .unitManagementFunctions import main @@ -25,17 +25,18 @@ class UnitCommandProcessor(BaseCommandProcessor): from .unitManagementFunctions import status def _init_access_points(self, context=None): - card = self._model.get_card('name', self.component_id) - - # if card.type == ?: - # self.access_points += ('internalPorts',) - # - - for port in self._model.get_ports('card_id', card.id): - identifier = 'port-' + port.name.split('/')[-1] - if identifier in self.access_points: - continue - self.access_points += (identifier,) + try: + card = self._model.get_card('name', self.component_id) + + self.management_functions = ('main', 'cfgm', 'fm', 'status') + + for port in self._model.get_ports('card_id', card.id): + identifier = 'port-' + port.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + except exceptions.InvalidInputError: + pass # todo: add portgroup to access_points diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index aa52ce2..33041c3 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -156,6 +156,8 @@ def generate_ls_text(layers, depth): else: text = self._render('ls_header', *scopes, context=context) + self._init_access_points(context=context) + text += self._render('ls_mf_list', *scopes, context=context) for management_function in self.management_functions: context['list_entry'] = management_function @@ -163,8 +165,6 @@ def generate_ls_text(layers, depth): text += self._render('ls_ap_list', *scopes, context=context) - self._init_access_points(context=context) - for access_point in self.access_points: context['list_entry'] = access_point text += self._render('ls_list_body', *scopes, context=context) @@ -194,7 +194,7 @@ def change_directory(self, path, context=None): path = path.lower() if path == '/': if self.__name__ != 'root': - self._parent.change_directory(path, context=context) + return self._parent.change_directory(path, context=context) else: context['component_path'] = '/' return self @@ -260,6 +260,9 @@ def change_directory(self, path, context=None): command_processor = components[0].capitalize() + 'CommandProcessor' if component_type == 'unit': + if (self._model.version == '2200' and not 9 <= int(component_id) <= 12) or (self._model.version == '2300' and not 7 <= int(component_id) <= 14) or (self._model.version == '2500' and not 1 <= int(component_id) <= 21): + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty# if self.__name__ != 'root': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty From 4c0d2df9d3e94ea75ecd586ad29bde436c4267cd Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 8 Oct 2020 11:35:54 +0200 Subject: [PATCH 096/318] updated set function --- .../accessPoints/root/eoamCommandProcessor.py | 4 ++++ .../root/multicastCommandProcessor.py | 4 ++++ .../accessPoints/root/rootCommandProcessor.py | 4 ++++ .../services/macAccessCtrlCommandProcessor.py | 20 ++++++++++++++++++- .../root/services/packetCommandProcessor.py | 18 +++++++++++++++++ .../root/services/servicesCommandProcessor.py | 18 +++++++++++++++++ .../root/tdmConnectionsCommandProcessor.py | 4 ++++ .../unit/logport/logportsCommandProcessor.py | 4 ++++ .../logport/port/logportCommandProcessor.py | 4 ++++ .../unit/port/chan/chanCommandProcessor.py | 4 ++++ .../interface/interfaceCommandProcessor.py | 4 ++++ .../root/unit/port/portCommandProcessor.py | 4 ++++ .../port/portgroupportCommandProcessor.py | 4 ++++ .../portgroup/portgroupCommandProcessor.py | 4 ++++ .../root/unit/unitCommandProcessor.py | 4 ++++ vendors/KeyMile/baseCommandProcessor.py | 10 ++++++++++ 16 files changed, 113 insertions(+), 1 deletion(-) diff --git a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py index cf866dc..ea461fb 100644 --- a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py @@ -32,5 +32,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py index 5cad2b8..c724daf 100644 --- a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py @@ -34,5 +34,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 1fd5799..3b245f4 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -36,6 +36,10 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py index d93320a..42dbfba 100644 --- a/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py @@ -25,4 +25,22 @@ class MacAccessCtrlCommandProcessor(BaseCommandProcessor): from .macAccessCtrlManagementFunctions import status def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + try: + super().set(command, *args, context=None) + except exceptions.CommandExecutionError: + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + # TODO test case + return + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py index 1413d30..a8dffac 100644 --- a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py @@ -23,3 +23,21 @@ class PacketCommandProcessor(BaseCommandProcessor): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + try: + super().set(command, *args, context=None) + except exceptions.CommandExecutionError: + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + # TODO test case + return + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py index 98da567..47ca719 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -25,3 +25,21 @@ class ServicesCommandProcessor(BaseCommandProcessor): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + try: + super().set(command, *args, context=None) + except exceptions.CommandExecutionError: + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + # TODO test case + return + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py index b230d5c..15fe3fd 100644 --- a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py @@ -31,5 +31,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index cee387f..9e76d86 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -42,5 +42,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 382a1e0..193cfe5 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -51,6 +51,10 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + # TODO test case + return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index c3f3e2b..288e2db 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -48,5 +48,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index 4deae4d..1073477 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -33,5 +33,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 585ac74..e620c73 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -69,5 +69,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index f603a08..eee4a76 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -64,6 +64,10 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + # TODO test case + return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index b9dfef6..a129baa 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -41,5 +41,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index ecf05a1..f798367 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -187,5 +187,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 33041c3..4777e1d 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -384,6 +384,16 @@ def get_parent_and_child_relation(self, search, parent=None, node=None, parent_k return ([], []) def do_set(self, command, *args, context=None): + if len(args) == 0: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + elif args[0].count('/') > 0 or args[0].count('.') > 0: + proc = self.change_directory(args[0], context=context) + # ToDO: is set ../properties true possible?? + proc.set(command, *args[1:], context=context) + elif args[0].count('/') == 0: + self.set(command, *args, context=context) + return def set(self, command, *args, context=None): From fcfb4685b5a3d0faa0f574276fd8d7bab00fde4d Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 8 Oct 2020 13:42:35 +0200 Subject: [PATCH 097/318] Empty cards now get displayed when ls'ing on root layer, if no port is underneath a card there is no longer the option to cd into a non existing port --- .../accessPoints/root/rootCommandProcessor.py | 21 +++++++++++++++++++ vendors/KeyMile/baseCommandProcessor.py | 7 +++++++ 2 files changed, 28 insertions(+) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 3b245f4..9ecee4d 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -30,6 +30,27 @@ def _init_access_points(self, context=None): continue self.access_points += ('unit-' + card.name,) + first_unit = 0 + unit_count = 0 + if self._model.version == '2500': + first_unit = 1 + unit_count = 21 + elif self._model.version == '2300': + first_unit = 7 + unit_count = 8 + elif self._model.version == '2200': + first_unit = 9 + unit_count = 4 + + for i in range(first_unit, first_unit + unit_count): + if 'unit-' + str(i) in self.access_points: + continue + + if 'unit-' + str(i - 1) not in self.access_points: + self.access_points += (i,) + else: + self.access_points = self.access_points[:self.access_points.index('unit-' + str(i - 1)) + 1] + ('unit-' + str(i),) + self.access_points[self.access_points.index('unit-' + str(i - 1)) + 1:] + def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 4777e1d..07b96a5 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -183,6 +183,7 @@ def do_ls(self, command, *args, context=None): tmp_cmdproc = self.change_directory(path, context=context) tmp_cmdproc.ls(context=context, path_type='component_path') except exceptions.CommandExecutionError: + context['component_path'] = context['path'] raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) context['component_path'] = context['path'] else: @@ -271,6 +272,12 @@ def change_directory(self, path, context=None): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'port': + try: + self._model.get_port('name', self.component_id + '/' + component_id) + except exceptions.InvalidInputError: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if self.__name__ != 'unit' and self.__name__ != 'portgroup': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty From 92bbe690e246ca906a9ac3598a86474504246382 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 8 Oct 2020 14:18:05 +0200 Subject: [PATCH 098/318] added first set functionality for up down --- .../root/unit/port/portCommandProcessor.py | 28 ++++++++++++++----- .../root/unit/unitCommandProcessor.py | 18 ++++-------- vendors/KeyMile/baseCommandProcessor.py | 14 +++++++--- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index e620c73..1f3aa64 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -26,8 +26,7 @@ class PortCommandProcessor(BaseCommandProcessor): from .portManagementFunctions import status def do_get(self, command, *args, context=None): - port_name = context['unit'] + '/' + context['port'] - port = self._model.get_port('name', port_name) + port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -38,7 +37,9 @@ def do_get(self, command, *args, context=None): text = self._render('attainable_rate', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': - text = self._render('administrative_status', *scopes, context=context) + self.map_states(port, 'port') + context['spacer'] = self.create_spacers((67,), (port.admin_state,))[0] * ' ' + text = self._render('administrative_status', *scopes, context=dict(context, port=port)) self._write(text) elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': self.map_states(port, 'port') @@ -62,16 +63,29 @@ def _init_access_points(self, context=None): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + def get_port_component(self): + return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') + print(context['path']) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return + elif self._validate(args, 'AdministrativeStatus', str) and context['path'].split('/')[-1] == 'main': + state, = self._dissect(args, 'AdministrativeStatus', str) + try: + port = self.get_port_component() + if state == 'up': + port.admin_up() + elif state == 'down': + port.admin_down() + else: + raise exceptions.SoftboxenError() + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index f798367..6e3cf72 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -41,7 +41,7 @@ def _init_access_points(self, context=None): # todo: add portgroup to access_points def do_get(self, command, *args, context=None): - card = self._model.get_card('name', context['unit']) + card = self._model.get_card('name', self.component_id) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -50,9 +50,7 @@ def do_get(self, command, *args, context=None): raise exc elif self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ - (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', - context[ - 'unit']).product == 'analog'): + (card.product == 'isdn' or card.product == 'analog'): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: @@ -67,16 +65,12 @@ def do_get(self, command, *args, context=None): text += self._render('subscriberList_bottom', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'SIP') and context['path'].split('/')[-1] == 'cfgm' and \ - (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', - context[ - 'unit']).product == 'analog'): + (card.product == 'isdn' or card.product == 'analog'): # TODO: dynamic fields text = self._render('sip', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'IP') and context['path'].split('/')[-1] == 'cfgm' and \ - (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', - context[ - 'unit']).product == 'analog'): + (card.product == 'isdn' or card.product == 'analog'): # TODO: dynamic fields text = self._render('ip', *scopes, context=context) self._write(text) @@ -187,8 +181,8 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) + elif self._validate(args, 'CurrentStatus', 'test', str): + ip, = self._dissect(args, 'CurrentStatus', 'test', str) #TODO test case return else: diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 07b96a5..fdda854 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -319,6 +319,9 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import PortgroupPortCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') + if component_id is not None and self.component_id is not None: + subprocessor.set_component_id(self.component_id + '/' + component_id) + if component_id is not None: subprocessor.set_component_id(component_id) @@ -394,10 +397,13 @@ def do_set(self, command, *args, context=None): if len(args) == 0: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif args[0].count('/') > 0 or args[0].count('.') > 0: - proc = self.change_directory(args[0], context=context) - # ToDO: is set ../properties true possible?? - proc.set(command, *args[1:], context=context) + elif args[0].count('/') > 0: + path = '' + for el in args[0].split('/')[:-1]: + path += el + '/' + proc = self.change_directory(str(path[:-1]), context=context) + res =(args[0].split('/')[-1],) + args[1:] + proc.set(command, *res, context=context) elif args[0].count('/') == 0: self.set(command, *args, context=context) From e86a83f8e00ddc1e03a59119cde858d787500432 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Thu, 8 Oct 2020 15:49:54 +0200 Subject: [PATCH 099/318] Sneakily removing some prints out of Huawei command processors --- vendors/Huawei/configCommandProcessor.py | 1 - vendors/Huawei/vlanSrvprofCommandProcessor.py | 1 - 2 files changed, 2 deletions(-) diff --git a/vendors/Huawei/configCommandProcessor.py b/vendors/Huawei/configCommandProcessor.py index 2427165..2b8821f 100644 --- a/vendors/Huawei/configCommandProcessor.py +++ b/vendors/Huawei/configCommandProcessor.py @@ -1029,7 +1029,6 @@ def do_port(self, command, *args, context=None): def do_xdsl(self, command, *args, context=None): if self._validate(args, 'vectoring-group', 'link', 'add', str, str): profile_idx, port_idx = self._dissect(args, 'vectoring-group', 'link', 'add', str, str) - print(port_idx) portname = port_idx[0:3] + '/' + port_idx[4] try: diff --git a/vendors/Huawei/vlanSrvprofCommandProcessor.py b/vendors/Huawei/vlanSrvprofCommandProcessor.py index 0677d3d..0a46789 100644 --- a/vendors/Huawei/vlanSrvprofCommandProcessor.py +++ b/vendors/Huawei/vlanSrvprofCommandProcessor.py @@ -100,7 +100,6 @@ def do_igmp(self, command, *args, context=None): def do_pitp(self, command, *args, context=None): if self._validate(args, 'enable'): self._model.set_pitp('enable') - print(context['srvprof'].vlan_mac) text = self._render('please_wait_commit', context=context) self._write(text) From 352c7e0f4cdcef91b596357fa48df3b4809a7f05 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Thu, 8 Oct 2020 15:50:34 +0200 Subject: [PATCH 100/318] Added global get function --- .../accessPoints/root/rootCommandProcessor.py | 6 +- .../root/unit/port/portCommandProcessor.py | 17 +++-- .../root/unit/unitCommandProcessor.py | 26 +++++--- vendors/KeyMile/baseCommandProcessor.py | 66 +++++++++++++++---- 4 files changed, 84 insertions(+), 31 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 9ecee4d..0e465c6 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -66,4 +66,8 @@ def set(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors')) def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def get_property(self, command, *args, context=None): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 1f3aa64..3fa69b0 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -25,23 +25,27 @@ class PortCommandProcessor(BaseCommandProcessor): from .portManagementFunctions import pm from .portManagementFunctions import status - def do_get(self, command, *args, context=None): - port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + def get_property(self, command, *args, context=None): + port_name = self._parent.component_id + '/' + self.component_id + port = self._model.get_port('name', port_name) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': + elif self._validate(args, 'AttainableRate') and (context['path'].split('/')[-1] == 'status' + or context['component_path'].split('/')[-1] == 'status'): text = self._render('attainable_rate', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': + elif self._validate(args, 'AdministrativeStatus') and (context['path'].split('/')[-1] == 'main' + or context['component_path'].split('/')[-1] == 'main'): self.map_states(port, 'port') context['spacer'] = self.create_spacers((67,), (port.admin_state,))[0] * ' ' text = self._render('administrative_status', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': + elif self._validate(args, 'OperationalStatus') and (context['path'].split('/')[-1] == 'main' + or context['component_path'].split('/')[-1] == 'main'): self.map_states(port, 'port') port_operational_state = port.operational_state context['port_operational_state'] = port_operational_state @@ -49,7 +53,8 @@ def do_get(self, command, *args, context=None): text = self._render('operational_status', *scopes, context=context) self._write(text) else: - raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) def _init_access_points(self, context=None): port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 6e3cf72..21aa15c 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -40,7 +40,7 @@ def _init_access_points(self, context=None): # todo: add portgroup to access_points - def do_get(self, command, *args, context=None): + def get_property(self, command, *args, context=None): card = self._model.get_card('name', self.component_id) scopes = ('login', 'base', 'get') if self._validate(args, *()): @@ -49,8 +49,9 @@ def do_get(self, command, *args, context=None): exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ - (card.product == 'isdn' or card.product == 'analog'): + elif self._validate(args, 'SubscriberList') and (context['path'].split('/')[-1] == 'status' + or context['component_path'].split('/')[-1] == 'status') \ + and (card.product == 'isdn' or card.product == 'analog'): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: @@ -64,18 +65,21 @@ def do_get(self, command, *args, context=None): text += self._render('subscriberList_item', *scopes, context=dict(context, subscriber=subscriber)) text += self._render('subscriberList_bottom', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'SIP') and context['path'].split('/')[-1] == 'cfgm' and \ - (card.product == 'isdn' or card.product == 'analog'): + elif self._validate(args, 'SIP') and (context['path'].split('/')[-1] == 'cfgm' + or context['component_path'].split('/')[-1] == 'cfgm') \ + and (card.product == 'isdn' or card.product == 'analog'): # TODO: dynamic fields text = self._render('sip', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'IP') and context['path'].split('/')[-1] == 'cfgm' and \ - (card.product == 'isdn' or card.product == 'analog'): + elif self._validate(args, 'IP') and (context['path'].split('/')[-1] == 'cfgm' + or context['component_path'].split('/')[-1] == 'cfgm') \ + and (card.product == 'isdn' or card.product == 'analog'): # TODO: dynamic fields text = self._render('ip', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'HardwareAndSoftware') and context['path'].split('/')[-1] == 'main': + elif self._validate(args, 'HardwareAndSoftware') and (context['path'].split('/')[-1] == 'main' + or context['component_path'].split('/')[-1] == 'main'): unit_hardware = '"' + card.board_name + '"' context['unit_hardware'] = unit_hardware context['spacer_1'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' @@ -100,7 +104,8 @@ def do_get(self, command, *args, context=None): text = self._render('hardware_and_software', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'CurrentStatus') and context['path'].split('/')[-1] == 'main': + elif self._validate(args, 'CurrentStatus') and (context['path'].split('/')[-1] == 'main' + or context['component_path'].split('/')[-1] == 'main'): unit_state = card.state context['unit_state'] = unit_state context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' @@ -122,7 +127,8 @@ def do_get(self, command, *args, context=None): text = self._render('current_status', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'EquipmentInventory') and context['path'].split('/')[-1] == 'main': + elif self._validate(args, 'EquipmentInventory') and (context['path'].split('/')[-1] == 'main' + or context['component_path'].split('/')[-1] == 'main'): unit_symbol = '"' + card.board_name + '"' context['unit_symbol'] = unit_symbol context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index fdda854..d0d4078 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -96,7 +96,7 @@ def do_help(self, command, *args, context=None): self._write(self._render('help_exit', *help_scopes, context=context)) else: raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args,): + elif self._validate(args, ): self._write(self._render('help', *help_scopes, context=context)) else: raise exceptions.CommandSyntaxError(command=command) @@ -142,7 +142,6 @@ def generate_ls_text(layers, depth): for property in layers[layer]: context['prop_name'] = property - if prop_type in ('File', 'Prop'): context['prop_rw_rights'] = layers[layer].get(property, '') else: @@ -184,7 +183,10 @@ def do_ls(self, command, *args, context=None): tmp_cmdproc.ls(context=context, path_type='component_path') except exceptions.CommandExecutionError: context['component_path'] = context['path'] - raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + context['component_path'] = context['path'] else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', @@ -218,9 +220,13 @@ def change_directory(self, path, context=None): if re.search('\.\./(?:[^.]+/)+\.\.', path): if path.endswith('..'): - raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) else: - raise exceptions.CommandExecutionError(template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + raise exceptions.CommandExecutionError(template='invalid_address_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) if path.startswith('..'): splitted_path = [x for x in context['component_path'].split('/') if x] @@ -240,8 +246,10 @@ def change_directory(self, path, context=None): return self._parent.change_directory(path[3:], context=context) if path.startswith('/'): - if 'unit-' not in components[0] and components[0] not in ('eoam', 'fan', 'multicast', 'services', 'tdmConnection', 'main', 'cfgm', 'fm', 'pm', 'status'): - raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + if 'unit-' not in components[0] and components[0] not in ( + 'eoam', 'fan', 'multicast', 'services', 'tdmConnection', 'main', 'cfgm', 'fm', 'pm', 'status'): + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty if self.__name__ != 'root': subprocessor = self._parent.change_directory(path, context=context) @@ -315,8 +323,10 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import PortgroupCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import PortgroupPortCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import \ + PortgroupCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import \ + PortgroupPortCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if component_id is not None and self.component_id is not None: @@ -393,6 +403,31 @@ def get_parent_and_child_relation(self, search, parent=None, node=None, parent_k else: return ([], []) + def do_get(self, command, *args, context=None): + if len(args) >= 1: + if '/' in args[0]: + path = '' + for component in args[0].split('/')[:-1]: + path += component + '/' + prop = args[0].split('/')[-1] + try: + tmp_cmdproc = self.change_directory(path, context=context) + tmp_cmdproc.get_property(command, prop, context=context) + except exceptions.CommandExecutionError: + raise exceptions.CommandExecutionError(template='syntax_error', + template_scopes=('login', 'base', 'syntax_errors'), + command=None) + else: + self.get_property(command, args[0], context=context) + else: + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + + def get_property(self, command, *args, context=None): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + def do_set(self, command, *args, context=None): if len(args) == 0: raise exceptions.CommandExecutionError(command=command, template='invalid_property', @@ -402,7 +437,7 @@ def do_set(self, command, *args, context=None): for el in args[0].split('/')[:-1]: path += el + '/' proc = self.change_directory(str(path[:-1]), context=context) - res =(args[0].split('/')[-1],) + args[1:] + res = (args[0].split('/')[-1],) + args[1:] proc.set(command, *res, context=context) elif args[0].count('/') == 0: self.set(command, *args, context=context) @@ -410,7 +445,7 @@ def do_set(self, command, *args, context=None): return def set(self, command, *args, context=None): - #interface method + # interface method return def do_cd(self, command, *args, context=None): @@ -424,7 +459,9 @@ def do_cd(self, command, *args, context=None): return_to = self.get_command_processor(subprocessor) except: context['component_path'] = context['path'] - raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) context['path'] = context['component_path'] subprocessor.loop(context=context, return_to=return_to) else: @@ -447,7 +484,8 @@ def get_command_processor(self, current_processor, component_type=None): from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor if current_processor.__class__ == RootCommandProcessor: return_to = RootCommandProcessor - if component_type not in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services', 'unit') and component_type is not None: + if component_type not in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services', 'unit') \ + and component_type is not None: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif current_processor.__class__ == UnitCommandProcessor: @@ -489,4 +527,4 @@ def do_exit(self, command, *args, context=None): raise exc def _init_access_points(self, context=None): - pass # Abstract method not implemented + pass # Abstract method not implemented From 810140071973e4002e2afc374f2d9c176911651c Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 8 Oct 2020 16:36:03 +0200 Subject: [PATCH 101/318] added set and get functionality for labels on ports and units --- .../api/schemas/keymile_card_schemas.py | 2 +- .../api/schemas/keymile_port_schemas.py | 4 +- .../keymile/keymile_resources/keymile_card.py | 7 ++++ .../keymile/keymile_resources/keymile_port.py | 7 ++++ nesi/softbox/api/models/card_models.py | 4 +- nesi/softbox/api/models/port_models.py | 4 +- templates/KeyMile/login/base/get/labels.j2 | 5 +++ .../root/unit/port/portCommandProcessor.py | 26 +++++++++---- .../port/portgroupportCommandProcessor.py | 6 +-- .../root/unit/unitCommandProcessor.py | 37 ++++++++++++------- 10 files changed, 73 insertions(+), 29 deletions(-) create mode 100644 templates/KeyMile/login/base/get/labels.j2 diff --git a/nesi/keymile/api/schemas/keymile_card_schemas.py b/nesi/keymile/api/schemas/keymile_card_schemas.py index eb4344d..7b658b8 100644 --- a/nesi/keymile/api/schemas/keymile_card_schemas.py +++ b/nesi/keymile/api/schemas/keymile_card_schemas.py @@ -20,4 +20,4 @@ class Meta: 'software_name', 'software_revision', 'state', 'serial_number', 'manufacturer_name', 'model_name', 'short_text', 'manufacturer_id', 'manufacturer_part_number', 'manufacturer_build_state', 'customer_id', - 'customer_product_id', 'boot_loader', 'processor') + 'customer_product_id', 'boot_loader', 'processor', 'label1', 'label2') diff --git a/nesi/keymile/api/schemas/keymile_port_schemas.py b/nesi/keymile/api/schemas/keymile_port_schemas.py index 667b9c6..c8a1f07 100644 --- a/nesi/keymile/api/schemas/keymile_port_schemas.py +++ b/nesi/keymile/api/schemas/keymile_port_schemas.py @@ -16,6 +16,6 @@ class KeyMilePortSchema(PortSchema): class Meta: model = Port - fields = PortSchema.Meta.fields + ('channels',) + fields = PortSchema.Meta.fields + ('channels', 'label1', 'label2') - channels = ma.Nested(CpesSchema.CpeSchema, many=True) \ No newline at end of file + channels = ma.Nested(CpesSchema.CpeSchema, many=True) diff --git a/nesi/keymile/keymile_resources/keymile_card.py b/nesi/keymile/keymile_resources/keymile_card.py index 8370b93..7680fbc 100644 --- a/nesi/keymile/keymile_resources/keymile_card.py +++ b/nesi/keymile/keymile_resources/keymile_card.py @@ -38,6 +38,13 @@ class KeyMileCard(Card): customer_product_id = base.Field('customer_product_id') boot_loader = base.Field('boot_loader') processor = base.Field('processor') + label1 = base.Field('label1') + label2 = base.Field('label2') + + def set_label(self, l1, l2, desc): + self.update(label1=l1) + self.update(label2=l2) + self.update(description=desc) class KeyMileCardCollection(CardCollection): diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py index c84be0b..ea36140 100644 --- a/nesi/keymile/keymile_resources/keymile_port.py +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -17,6 +17,13 @@ class KeyMilePort(Port): """Represent physical port resource.""" + label1 = base.Field('label1') + label2 = base.Field('label2') + + def set_label(self, l1, l2, desc): + self.update(label1=l1) + self.update(label2=l2) + self.update(description=desc) class KeyMilePortCollection(PortCollection): diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index 2d0a4d7..aa1855f 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -27,7 +27,7 @@ class Card(db.Model): nullable=False, default='vdsl') # Alcatel specific data - description = db.Column(db.String(), default='None') + description = db.Column(db.String(), default='""') position = db.Column(db.String()) entry_vlan_number = db.Column(db.Integer()) planned_type = db.Column(db.Enum('rdlt-c', 'rant-a', 'nant-a', 'nrnt-a', 'fant-f', 'relt-a', 'nelt-b', 'fglt-b', @@ -101,3 +101,5 @@ class Card(db.Model): customer_product_id = db.Column(db.String(), default='') boot_loader = db.Column(db.String(), default='') processor = db.Column(db.String(), default='') + label1 = db.Column(db.String(), default='""') + label2 = db.Column(db.String(), default='""') diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 17c9bbe..1705e0c 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -27,7 +27,7 @@ class Port(db.Model): cpes = db.relationship('Cpe', backref='Port', lazy='dynamic') # Alcatel data - description = db.Column(db.String()) + description = db.Column(db.String(), default='') type = db.Column(db.Enum('pon', 'ethernet-line'), default='pon') shutdown = db.Column(db.Boolean(), default=False) speed = db.Column(db.Enum('10M', '1G', '10G'), default='1G') @@ -311,3 +311,5 @@ class Port(db.Model): # KeyMile channels = db.relationship('Channel', backref='Port', lazy='dynamic') interfaces = db.relationship('Interface', backref='Port', lazy='dynamic') + label1 = db.Column(db.String(), default='""') + label2 = db.Column(db.String(), default='""') diff --git a/templates/KeyMile/login/base/get/labels.j2 b/templates/KeyMile/login/base/get/labels.j2 new file mode 100644 index 0000000..d8b257f --- /dev/null +++ b/templates/KeyMile/login/base/get/labels.j2 @@ -0,0 +1,5 @@ + \ # Labels +{{ context.port.label1 | safe }}{{ context.spacer1 }}\ # Label1 +{{ context.port.label2 | safe }}{{ context.spacer2 }}\ # Label2 +{{ context.port.description | safe }}{{ context.spacer3 }}\ # Description + diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 3fa69b0..0363cef 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -34,18 +34,21 @@ def get_property(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'AttainableRate') and (context['path'].split('/')[-1] == 'status' - or context['component_path'].split('/')[-1] == 'status'): + elif self._validate((args[0],), 'AttainableRate') and context['component_path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) - elif self._validate(args, 'AdministrativeStatus') and (context['path'].split('/')[-1] == 'main' - or context['component_path'].split('/')[-1] == 'main'): + elif self._validate((args[0],), 'AdministrativeStatus') and context['component_path'].split('/')[-1] == 'main': self.map_states(port, 'port') context['spacer'] = self.create_spacers((67,), (port.admin_state,))[0] * ' ' text = self._render('administrative_status', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate(args, 'OperationalStatus') and (context['path'].split('/')[-1] == 'main' - or context['component_path'].split('/')[-1] == 'main'): + elif self._validate(args, 'Labels') and context['component_path'].split('/')[-1] == 'main': + context['spacer1'] = self.create_spacers((67,), (port.label1,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (port.label2,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (port.description,))[0] * ' ' + text = self._render('labels', *scopes, context=dict(context, port=port)) + self._write(text) + elif self._validate((args[0],), 'OperationalStatus') and context['component_path'].split('/')[-1] == 'main': self.map_states(port, 'port') port_operational_state = port.operational_state context['port_operational_state'] = port_operational_state @@ -73,13 +76,12 @@ def get_port_component(self): def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') - print(context['path']) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'AdministrativeStatus', str) and context['path'].split('/')[-1] == 'main': + elif self._validate(args, 'AdministrativeStatus', str) and context['component_path'].split('/')[-1] == 'main': state, = self._dissect(args, 'AdministrativeStatus', str) try: port = self.get_port_component() @@ -92,5 +94,13 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'Labels', str, str, str) and context['component_path'].split('/')[-1] == 'main': + label1, label2, description = self._dissect(args, 'Labels', str, str, str) + try: + port = self.get_port_component() + port.set_label(label1, label2, description) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index eee4a76..d0a5072 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -28,8 +28,8 @@ def do_get(self, command, *args, context=None): try: super().do_get(command, *args, context=None) except exceptions.CommandExecutionError: - if self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ - self._model.get_card('name', context['unit']).product == 'isdn': + if self._validate((args[0],), 'SubscriberList') and context['component_path'].split('/')[-1] == 'status' and \ + self._model.get_card('name', self._parent._parent.component_id).product == 'isdn': text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: @@ -49,7 +49,7 @@ def do_get(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors')) def _init_access_points(self, context=None): - port = self._model.get_port('name', context['unit'] + '/' + context['portgroup'] + '/' + context['port']) + port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 21aa15c..1b1dbdb 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -49,9 +49,8 @@ def get_property(self, command, *args, context=None): exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'SubscriberList') and (context['path'].split('/')[-1] == 'status' - or context['component_path'].split('/')[-1] == 'status') \ - and (card.product == 'isdn' or card.product == 'analog'): + elif self._validate(args, 'SubscriberList') and context['component_path'].split('/')[-1] == 'status' and \ + (card.product == 'isdn' or card.product == 'analog'): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: @@ -65,19 +64,24 @@ def get_property(self, command, *args, context=None): text += self._render('subscriberList_item', *scopes, context=dict(context, subscriber=subscriber)) text += self._render('subscriberList_bottom', *scopes, context=context) self._write(text) - elif self._validate(args, 'SIP') and (context['path'].split('/')[-1] == 'cfgm' - or context['component_path'].split('/')[-1] == 'cfgm') \ - and (card.product == 'isdn' or card.product == 'analog'): + elif self._validate(args, 'SIP') and context['component_path'].split('/')[-1] == 'cfgm' and \ + (card.product == 'isdn' or card.product == 'analog'): # TODO: dynamic fields text = self._render('sip', *scopes, context=context) self._write(text) - elif self._validate(args, 'IP') and (context['path'].split('/')[-1] == 'cfgm' - or context['component_path'].split('/')[-1] == 'cfgm') \ - and (card.product == 'isdn' or card.product == 'analog'): + elif self._validate(args, 'IP') and context['component_path'].split('/')[-1] == 'cfgm' and \ + (card.product == 'isdn' or card.product == 'analog'): # TODO: dynamic fields text = self._render('ip', *scopes, context=context) self._write(text) + elif self._validate(args, 'Labels') and context['component_path'].split('/')[-1] == 'main': + context['spacer1'] = self.create_spacers((67,), (card.label1,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (card.label2,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (card.description,))[0] * ' ' + text = self._render('labels', *scopes, context=dict(context, port=card)) + self._write(text) + elif self._validate(args, 'HardwareAndSoftware') and (context['path'].split('/')[-1] == 'main' or context['component_path'].split('/')[-1] == 'main'): unit_hardware = '"' + card.board_name + '"' @@ -181,15 +185,22 @@ def get_property(self, command, *args, context=None): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + def get_component(self): + return self._model.get_card('name', self.component_id) + def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'CurrentStatus', 'test', str): - ip, = self._dissect(args, 'CurrentStatus', 'test', str) - #TODO test case - return + elif self._validate(args, 'Labels', str, str, str) and context['component_path'].split('/')[-1] == 'main': + label1, label2, description = self._dissect(args, 'Labels', str, str, str) + try: + component = self.get_component() + component.set_label(label1, label2, description) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) else: raise exceptions.CommandSyntaxError(command=command) From 452a50813e53a66dca9415d01c01967c6e79dbf8 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 9 Oct 2020 10:36:21 +0200 Subject: [PATCH 102/318] Minor code adjustments --- .../accessPoints/root/unit/unitCommandProcessor.py | 9 +++------ vendors/KeyMile/baseCommandProcessor.py | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 1b1dbdb..ef7afcd 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -82,8 +82,7 @@ def get_property(self, command, *args, context=None): text = self._render('labels', *scopes, context=dict(context, port=card)) self._write(text) - elif self._validate(args, 'HardwareAndSoftware') and (context['path'].split('/')[-1] == 'main' - or context['component_path'].split('/')[-1] == 'main'): + elif self._validate(args, 'HardwareAndSoftware') and context['component_path'].split('/')[-1] == 'main': unit_hardware = '"' + card.board_name + '"' context['unit_hardware'] = unit_hardware context['spacer_1'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' @@ -108,8 +107,7 @@ def get_property(self, command, *args, context=None): text = self._render('hardware_and_software', *scopes, context=context) self._write(text) - elif self._validate(args, 'CurrentStatus') and (context['path'].split('/')[-1] == 'main' - or context['component_path'].split('/')[-1] == 'main'): + elif self._validate(args, 'CurrentStatus') and context['component_path'].split('/')[-1] == 'main': unit_state = card.state context['unit_state'] = unit_state context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' @@ -131,8 +129,7 @@ def get_property(self, command, *args, context=None): text = self._render('current_status', *scopes, context=context) self._write(text) - elif self._validate(args, 'EquipmentInventory') and (context['path'].split('/')[-1] == 'main' - or context['component_path'].split('/')[-1] == 'main'): + elif self._validate(args, 'EquipmentInventory') and context['component_path'].split('/')[-1] == 'main': unit_symbol = '"' + card.board_name + '"' context['unit_symbol'] = unit_symbol context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index d0d4078..9238279 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -351,7 +351,7 @@ def change_directory(self, path, context=None): parent := string keyword to describe the parent of search like "root" node := contains the dict tree or None for default tree structure - parent_keys := should be None / important for rekursive call + parent_keys := should be None / important for recursive call return := Tuple of (ParentList, ChildList) or ([],[]) ''' From 8fe3db1afd4279aed48e18db88ccb7c0e6e95712 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 13 Oct 2020 10:54:35 +0200 Subject: [PATCH 103/318] create portgroupports --- .../conf/bootstraps/create-keymile-MG2500.sh | 15 +---- nesi/keymile/keymile_resources/__init__.py | 2 +- nesi/keymile/keymile_resources/keymile_box.py | 18 ++++++ .../keymile_portgroupport.py | 58 +++++++++++++++++++ nesi/softbox/api/models/box_models.py | 2 + .../api/models/portgroupport_models.py | 13 +++++ .../api/schemas/portgroupport_schemas.py | 48 +++++++++++++++ .../softbox/api/schemas/subscriber_schemas.py | 2 +- nesi/softbox/api/views/__init__.py | 2 +- nesi/softbox/api/views/portgroupport_views.py | 53 +++++++++++++++++ 10 files changed, 198 insertions(+), 15 deletions(-) create mode 100644 nesi/keymile/keymile_resources/keymile_portgroupport.py create mode 100644 nesi/softbox/api/models/portgroupport_models.py create mode 100644 nesi/softbox/api/schemas/portgroupport_schemas.py create mode 100644 nesi/softbox/api/views/portgroupport_views.py diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 06f1a66..8f992ab 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -125,15 +125,6 @@ req='{ subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) -# test subscriber -req='{ - "name": "tester2", - "number": 90223, - "type": "unit" -}' - -subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) - ### Subrack 0 ### # Create a physical subrack at the network device (admin operation) @@ -443,14 +434,14 @@ req='{ unit_19=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) -### Port-1 ### +### PortGroupPort-1 ### # Create a physical port at the network device (admin operation) req='{ "card_id": '$unit_19', "admin_state": "1", "operational_state": "1", - "name": "19/1/1" + "name": "19/G1/1" }' -port_19_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) \ No newline at end of file +port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) \ No newline at end of file diff --git a/nesi/keymile/keymile_resources/__init__.py b/nesi/keymile/keymile_resources/__init__.py index 17f26e0..fcea829 100644 --- a/nesi/keymile/keymile_resources/__init__.py +++ b/nesi/keymile/keymile_resources/__init__.py @@ -1,2 +1,2 @@ __all__ = ["keymile_card", "keymile_port", "keymile_subrack", "keymile_channel", "keymile_interface", - "keymile_subscriber"] + "keymile_subscriber", "keymile_portgroupport"] diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 178a817..d800261 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -59,6 +59,12 @@ def subscribers(self): return keymile_subscriber.KeymileSubscriberCollection( self._conn, base.get_sub_resource_path_by(self, 'subscribers')) + @property + def portgroupsports(self): + """Return `PortgrouportCollection` object.""" + return keymile_portgroupport.KeymilePortGroupPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'portgrouports')) + def get_card(self, field, value): """Get specific card object.""" return keymile_card.KeyMileCardCollection( @@ -118,6 +124,18 @@ def get_subscribers(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'subscribers'), params={field: value}) + def get_portgroupport(self, field, value): + """Get specific portgroupport object.""" + return keymile_portgroupport.KeymilePortGroupPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'portgroupports'), + params={field: value}).find_by_field_value(field, value) + + def get_portgroupports(self, field, value): + """Get specific portgroupports object.""" + return keymile_portgroupport.KeymilePortGroupPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'portgroupports'), + params={field: value}) + class KeyMileBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/keymile/keymile_resources/keymile_portgroupport.py b/nesi/keymile/keymile_resources/keymile_portgroupport.py new file mode 100644 index 0000000..fa976d3 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_portgroupport.py @@ -0,0 +1,58 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.service_port import logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class KeymilePortGroupPort(base.Resource): + """Represent logical subscriber resource.""" + + # fields + id = base.Field('id') + name = base.Field('name') + operational_state = base.Field('operational_state') + admin_state = base.Field('admin_state') + description = base.Field('description') + label1 = base.Field('label1') + label2 = base.Field('label2') + + def set_label(self, l1, l2, desc): + self.update(label1=l1) + self.update(label2=l2) + self.update(description=desc) + + def admin_up(self): + """Set the admin port state to up""" + self.update(admin_state='1') + + def admin_down(self): + """Set the admin port state to down""" + self.update(admin_state='0') + + def down(self): + """Set the port state to down""" + self.update(operational_state='0') + + def up(self): + """Set the port state to down""" + self.update(operational_state='1') + + +class KeymilePortGroupPortCollection(base.ResourceCollection): + """Represent a collection of logical subscribers.""" + + @property + def _resource_type(self): + return KeymilePortGroupPort diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 3540487..af447ad 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -29,6 +29,7 @@ from .user_models import User from .channel_models import Channel from .subscriber_models import Subscriber +from .portgroupport_models import PortGroupPort class Box(db.Model): @@ -72,6 +73,7 @@ class Box(db.Model): routes = db.relationship('Route', backref='Box', lazy='dynamic') emus = db.relationship('Emu', backref='Box', lazy='dynamic') subscribers = db.relationship('Subscriber', backref='Box', lazy='dynamic') + portgroupports = db.relationship('PortGroupPort', backref='Box', lazy='dynamic') board_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_instl_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_init_reporting_logging = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/models/portgroupport_models.py b/nesi/softbox/api/models/portgroupport_models.py new file mode 100644 index 0000000..24811ba --- /dev/null +++ b/nesi/softbox/api/models/portgroupport_models.py @@ -0,0 +1,13 @@ +from nesi.softbox.api import db + + +class PortGroupPort(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + operational_state = db.Column(db.Enum('1', '0'), default='0') # 0 => down, 1 => up + admin_state = db.Column(db.Enum('1', '0'), default='0') + description = db.Column(db.String(), default='') + label1 = db.Column(db.String(), default='""') + label2 = db.Column(db.String(), default='""') + card_id = db.Column(db.Integer, db.ForeignKey('card.id')) diff --git a/nesi/softbox/api/schemas/portgroupport_schemas.py b/nesi/softbox/api/schemas/portgroupport_schemas.py new file mode 100644 index 0000000..932f44b --- /dev/null +++ b/nesi/softbox/api/schemas/portgroupport_schemas.py @@ -0,0 +1,48 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.portgroupport_models import PortGroupPort + + +class PortGroupPortSchema(ma.ModelSchema): + class Meta: + model = PortGroupPort + fields = ('id', 'name', 'box_id', 'card_id', 'operational_state', 'admin_state', 'description', 'label1', + 'label2', '_links') + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_portgroupport', box_id='', id=''), + 'collection': ma.URLFor('show_portgroupports', box_id='')}) + + +class PortGroupPortsSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class PortGroupPortSchema(ma.ModelSchema): + class Meta: + model = PortGroupPort + fields = ('id', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_portgroupport', box_id='', id='')}) + + members = ma.Nested(PortGroupPortSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_portgroupports', box_id='')}) diff --git a/nesi/softbox/api/schemas/subscriber_schemas.py b/nesi/softbox/api/schemas/subscriber_schemas.py index 25b65d6..3efa31c 100644 --- a/nesi/softbox/api/schemas/subscriber_schemas.py +++ b/nesi/softbox/api/schemas/subscriber_schemas.py @@ -32,7 +32,7 @@ class SubscribersSchema(ma.ModelSchema): class Meta: fields = ('members', 'count', '_links') - class EmuSchema(ma.ModelSchema): + class SubscriberSchema(ma.ModelSchema): class Meta: model = Subscriber fields = ('id', '_links') diff --git a/nesi/softbox/api/views/__init__.py b/nesi/softbox/api/views/__init__.py index edde876..2bc77b7 100644 --- a/nesi/softbox/api/views/__init__.py +++ b/nesi/softbox/api/views/__init__.py @@ -2,4 +2,4 @@ "ontport_views", "cpe_views", "cpeport_views", "vlan_views", "portprofile_views", "emu_views", "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views", - "mgmt_card_views", "mgmt_port_views", "subscriber_views"] + "mgmt_card_views", "mgmt_port_views", "subscriber_views", "portgroupport_views"] diff --git a/nesi/softbox/api/views/portgroupport_views.py b/nesi/softbox/api/views/portgroupport_views.py new file mode 100644 index 0000000..3f452a3 --- /dev/null +++ b/nesi/softbox/api/views/portgroupport_views.py @@ -0,0 +1,53 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from ..schemas.portgroupport_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//portgroupports', methods=['GET']) +def show_portgroupports(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(PortGroupPortsSchema(), PortGroupPort, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//portgroupports/', methods=['GET']) +def show_portgroupport(box_id, id): + response = show_component(PortGroupPort, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//portgroupports/', methods=['PUT']) +def update_portgroupport(box_id, id): + req = flask.request.json + update_component(PortGroupPort, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//portgroupports', methods=['POST']) +def new_portgroupport(box_id): + req = flask.request.json + response = new_component(PortGroupPortSchema(), PortGroupPort, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//portgroupports/', methods=['DELETE']) +def del_portgroupport(box_id, id): + del_component(PortGroupPort, box_id, id) + return flask.Response(status=204) From 414b48a92643ade681b9e8e8409fec5c4628acc1 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 13 Oct 2020 13:48:17 +0200 Subject: [PATCH 104/318] Added portgroups and portgroupports to reachable CommandProcessors --- nesi/softbox/api/schemas/box_schemas.py | 6 +++++- .../port/portgroupportCommandProcessor.py | 4 ++-- .../unit/portgroup/portgroupCommandProcessor.py | 6 +++--- .../root/unit/unitCommandProcessor.py | 6 ++++++ vendors/KeyMile/baseCommandProcessor.py | 16 ++++++++++++++-- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index b28a8e1..87a9215 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -34,7 +34,7 @@ class Meta: 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', - 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', + 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') credentials = ma.Hyperlinks( @@ -81,6 +81,10 @@ class Meta: {'_links': { 'self': ma.URLFor('show_subscribers', box_id='')}}) + portgroupports = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_portgroupports', box_id='')}}) + onts = ma.Hyperlinks({'_links': { 'self': ma.URLFor('show_onts', box_id='')}}) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index d0a5072..706cf6c 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -14,7 +14,7 @@ from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor -class PortgroupPortCommandProcessor(PortCommandProcessor): +class PortgroupportCommandProcessor(PortCommandProcessor): __name__ = 'portgroupport' management_functions = ('main', 'cfgm', 'status') access_points = () @@ -49,7 +49,7 @@ def do_get(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors')) def _init_access_points(self, context=None): - port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + pass def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index a129baa..988535a 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -25,9 +25,9 @@ class PortgroupCommandProcessor(BaseCommandProcessor): def _init_access_points(self, context=None): # work in progress card = self._model.get_card('name', self._parent.component_id) - for port in self._model.get_ports('card_id', card.id): - if port.name.count('/') == 2 and port.name.strip('/')[1] == 'portgroup-' + self.component_id: - identifier = 'port-' + port.name.split('/')[-1] + for gport in self._model.get_portgroupports('card_id', card.id): + if gport.name.split('/')[1] == 'G' + self.component_id: + identifier = 'port-' + gport.name.split('/')[-1] if identifier in self.access_points: continue self.access_points += (identifier,) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index ef7afcd..4e8d4dd 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -35,6 +35,12 @@ def _init_access_points(self, context=None): if identifier in self.access_points: continue self.access_points += (identifier,) + + for gport in self._model.get_portgroupports('card_id', card.id): + identifier = 'portgroup-' + gport.name.split('/')[1][1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) except exceptions.InvalidInputError: pass diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 9238279..b3677f7 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -205,7 +205,7 @@ def change_directory(self, path, context=None): components = [x for x in path.split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', components[0]): raise exceptions.SoftboxenError() @@ -264,6 +264,10 @@ def change_directory(self, path, context=None): if '-' in components[0]: component_type = components[0].split('-')[0] component_id = components[0].split('-')[1] + if component_type == 'port': + if self.__name__ == 'portgroup': + component_type = 'portgroupport' + command_processor = component_type.capitalize() + 'CommandProcessor' else: command_processor = components[0].capitalize() + 'CommandProcessor' @@ -326,7 +330,7 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import \ PortgroupCommandProcessor from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import \ - PortgroupPortCommandProcessor + PortgroupportCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if component_id is not None and self.component_id is not None: @@ -482,6 +486,10 @@ def get_command_processor(self, current_processor, component_type=None): from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import \ + PortgroupCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import \ + PortgroupportCommandProcessor if current_processor.__class__ == RootCommandProcessor: return_to = RootCommandProcessor if component_type not in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services', 'unit') \ @@ -518,6 +526,10 @@ def get_command_processor(self, current_processor, component_type=None): return_to = RootCommandProcessor elif current_processor.__class__ == ServicesCommandProcessor: return_to = RootCommandProcessor + elif current_processor.__class__ == PortgroupportCommandProcessor: + return_to = PortgroupCommandProcessor + elif current_processor.__class__ == PortgroupCommandProcessor: + return_to = UnitCommandProcessor return return_to From 7eadb0fe187ddc4b545e7e11c2a09b3d30bdc7d3 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 13 Oct 2020 15:04:57 +0200 Subject: [PATCH 105/318] Fixed do_get from portgroupport CP --- .../accessPoints/root/unit/port/portCommandProcessor.py | 3 +-- .../unit/portgroup/port/portgroupportCommandProcessor.py | 7 +++++-- vendors/KeyMile/baseCommandProcessor.py | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 0363cef..30f0d40 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -26,8 +26,7 @@ class PortCommandProcessor(BaseCommandProcessor): from .portManagementFunctions import status def get_property(self, command, *args, context=None): - port_name = self._parent.component_id + '/' + self.component_id - port = self._model.get_port('name', port_name) + port = self.get_port_component() scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 706cf6c..81d95ee 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -23,10 +23,13 @@ class PortgroupportCommandProcessor(PortCommandProcessor): from .portgroupportManagementFunctions import cfgm from .portgroupportManagementFunctions import status - def do_get(self, command, *args, context=None): + def get_port_component(self): + return self._model.get_portgroupport('name', self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id) + + def get_property(self, command, *args, context=None): scopes = ('login', 'base', 'get') try: - super().do_get(command, *args, context=None) + super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: if self._validate((args[0],), 'SubscriberList') and context['component_path'].split('/')[-1] == 'status' and \ self._model.get_card('name', self._parent._parent.component_id).product == 'isdn': diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index b3677f7..3ed7fe9 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -416,7 +416,7 @@ def do_get(self, command, *args, context=None): prop = args[0].split('/')[-1] try: tmp_cmdproc = self.change_directory(path, context=context) - tmp_cmdproc.get_property(command, prop, context=context) + tmp_cmdproc.get_property(command, *prop, context=context) except exceptions.CommandExecutionError: raise exceptions.CommandExecutionError(template='syntax_error', template_scopes=('login', 'base', 'syntax_errors'), From 004b5483995601a9bfa249dadb704d29301b76b3 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 14 Oct 2020 08:48:27 +0200 Subject: [PATCH 106/318] added isdnport and pstnport get and set functionality --- .../conf/bootstraps/create-keymile-MG2500.sh | 16 ++++- .../keymile_portgroupport.py | 37 +++++++++++ .../api/models/portgroupport_models.py | 17 +++++ .../api/schemas/portgroupport_schemas.py | 5 +- .../KeyMile/login/base/get/isdnport_bottom.j2 | 9 +++ .../KeyMile/login/base/get/isdnport_middle.j2 | 9 +++ .../KeyMile/login/base/get/isdnport_top.j2 | 4 ++ .../KeyMile/login/base/get/pstnport_bottom.j2 | 9 +++ .../KeyMile/login/base/get/pstnport_middle.j2 | 9 +++ .../KeyMile/login/base/get/pstnport_top.j2 | 4 ++ .../port/portgroupportCommandProcessor.py | 66 +++++++++++++++++-- 11 files changed, 177 insertions(+), 8 deletions(-) create mode 100644 templates/KeyMile/login/base/get/isdnport_bottom.j2 create mode 100644 templates/KeyMile/login/base/get/isdnport_middle.j2 create mode 100644 templates/KeyMile/login/base/get/isdnport_top.j2 create mode 100644 templates/KeyMile/login/base/get/pstnport_bottom.j2 create mode 100644 templates/KeyMile/login/base/get/pstnport_middle.j2 create mode 100644 templates/KeyMile/login/base/get/pstnport_top.j2 diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 8f992ab..ecb035e 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -441,7 +441,21 @@ req='{ "card_id": '$unit_19', "admin_state": "1", "operational_state": "1", - "name": "19/G1/1" + "name": "19/G1/1", + "type": "PSTN" +}' + +port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) + +### PortGroupPort-2 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_19', + "admin_state": "1", + "operational_state": "1", + "name": "19/G2/1", + "type": "ISDN" }' port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) \ No newline at end of file diff --git a/nesi/keymile/keymile_resources/keymile_portgroupport.py b/nesi/keymile/keymile_resources/keymile_portgroupport.py index fa976d3..97619ec 100644 --- a/nesi/keymile/keymile_resources/keymile_portgroupport.py +++ b/nesi/keymile/keymile_resources/keymile_portgroupport.py @@ -27,6 +27,19 @@ class KeymilePortGroupPort(base.Resource): description = base.Field('description') label1 = base.Field('label1') label2 = base.Field('label2') + type = base.Field('type') + enable = base.Field('enable') + subsriber_identification = base.Field('subsriber_identification') + register_as_global = base.Field('register_as_global') + register_default_number_only = base.Field('register_default_number_only') + layer_1_permanently_activated = base.Field('layer_1_permanently_activated') + sip_profile = base.Field('sip_profile') + proxy_registrar_profile = base.Field('proxy_registrar_profile') + codec_sdp_profile = base.Field('codec_sdp_profile') + isdnba_profile = base.Field('isdnba_profile') + pay_phone = base.Field('pay_phone') + pstn_profile = base.Field('pstn_profile') + enterprise_profile = base.Field('enterprise_profile') def set_label(self, l1, l2, desc): self.update(label1=l1) @@ -49,6 +62,30 @@ def up(self): """Set the port state to down""" self.update(operational_state='1') + def set_pstnport(self, enable, subscriberident, registerglobal, phone, sip, proxy, codec, pstn, enterprise): + """Set the pstnport""" + self.update(enable=enable) + self.update(subsriber_identification=subscriberident) + self.update(register_as_global=registerglobal) + self.update(pay_phone=phone) + self.update(sip_profile=sip) + self.update(proxy_registrar_profile=proxy) + self.update(codec_sdp_profile=codec) + self.update(pstn_profile=pstn) + self.update(enterprise_profile=enterprise) + + def set_isdnport(self, enable, subscriberident, registerglobal, regdefault, layer1, sip, proxy, codec, isdn): + """Set the pstnport""" + self.update(enable=enable) + self.update(subsriber_identification=subscriberident) + self.update(register_as_global=registerglobal) + self.update(register_default_number_only=regdefault) + self.update(sip_profile=sip) + self.update(proxy_registrar_profile=proxy) + self.update(codec_sdp_profile=codec) + self.update(layer_1_permanently_activated=layer1) + self.update(isdnba_profile=isdn) + class KeymilePortGroupPortCollection(base.ResourceCollection): """Represent a collection of logical subscribers.""" diff --git a/nesi/softbox/api/models/portgroupport_models.py b/nesi/softbox/api/models/portgroupport_models.py index 24811ba..788bf0e 100644 --- a/nesi/softbox/api/models/portgroupport_models.py +++ b/nesi/softbox/api/models/portgroupport_models.py @@ -11,3 +11,20 @@ class PortGroupPort(db.Model): label1 = db.Column(db.String(), default='""') label2 = db.Column(db.String(), default='""') card_id = db.Column(db.Integer, db.ForeignKey('card.id')) + type = db.Column(db.Enum('ISDN', 'PSTN'), default='ISDN') + + #isdn + enable = db.Column(db.Boolean(), default=False) + subsriber_identification = db.Column(db.String(), default=None) + register_as_global = db.Column(db.Boolean, default=None) + register_default_number_only = db.Column(db.Boolean, default=None) + layer_1_permanently_activated = db.Column(db.Boolean, default=None) + sip_profile = db.Column(db.String(), default=None) + proxy_registrar_profile = db.Column(db.String(), default=None) + codec_sdp_profile = db.Column(db.String(), default=None) + isdnba_profile = db.Column(db.String(), default=None) + + #pstn + pay_phone = db.Column(db.Boolean(), default= None) + pstn_profile = db.Column(db.String(), default=None) + enterprise_profile = db.Column(db.String(), default=None) diff --git a/nesi/softbox/api/schemas/portgroupport_schemas.py b/nesi/softbox/api/schemas/portgroupport_schemas.py index 932f44b..82712dc 100644 --- a/nesi/softbox/api/schemas/portgroupport_schemas.py +++ b/nesi/softbox/api/schemas/portgroupport_schemas.py @@ -18,7 +18,10 @@ class PortGroupPortSchema(ma.ModelSchema): class Meta: model = PortGroupPort fields = ('id', 'name', 'box_id', 'card_id', 'operational_state', 'admin_state', 'description', 'label1', - 'label2', '_links') + 'label2', 'type', 'enable', 'subsriber_identification', 'register_as_global', + 'register_default_number_only', 'layer_1_permanently_activated', 'sip_profile', 'isdnba_profile', + 'proxy_registrar_profile', 'codec_sdp_profile', 'pay_phone', 'pstn_profile', 'enterprise_profile', + '_links') box = ma.Hyperlinks( {'_links': { diff --git a/templates/KeyMile/login/base/get/isdnport_bottom.j2 b/templates/KeyMile/login/base/get/isdnport_bottom.j2 new file mode 100644 index 0000000..97c6e19 --- /dev/null +++ b/templates/KeyMile/login/base/get/isdnport_bottom.j2 @@ -0,0 +1,9 @@ +} \ +{{ context.port.register_as_global }}{{ context.spacer2 }}\ # RegisterAsGlobal +{{ context.port.register_default_number_only }}{{ context.spacer3 }}\ # RegisterDefaultNumberOnly +{{ context.port.layer_1_permanently_activated }}{{ context.spacer8 }}\ # Layer1PermanentlyActivated +{{ context.port.sip_profile }}{{ context.spacer4 }}\ # SipProfile +{{ context.port.proxy_registrar_profile }}{{ context.spacer5 }}\ # ProxyRegistrarProfile +{{ context.port.codec_sdp_profile }}{{ context.spacer6 }}\ # CodecSdpProfile +{{ context.port.isdnba_profile }}{{ context.spacer7 }}\ # IsdnBaProfile + diff --git a/templates/KeyMile/login/base/get/isdnport_middle.j2 b/templates/KeyMile/login/base/get/isdnport_middle.j2 new file mode 100644 index 0000000..19f929b --- /dev/null +++ b/templates/KeyMile/login/base/get/isdnport_middle.j2 @@ -0,0 +1,9 @@ + \ # [0] # + \ # SubscriberId + "9108007" \ # SubscriberNumber + "4962329108007" \ # AuthorisationUserName + "5yhnxz7x" \ # AuthorisationPassword + "" \ # DisplayName + None \ # privacy +; \ + diff --git a/templates/KeyMile/login/base/get/isdnport_top.j2 b/templates/KeyMile/login/base/get/isdnport_top.j2 new file mode 100644 index 0000000..6f7ea38 --- /dev/null +++ b/templates/KeyMile/login/base/get/isdnport_top.j2 @@ -0,0 +1,4 @@ + \ # IsdnPort +{{ context.port.enable }}{{ context.spacer1 }}\ # Enable +{ \ # SubscriberIdentifications + diff --git a/templates/KeyMile/login/base/get/pstnport_bottom.j2 b/templates/KeyMile/login/base/get/pstnport_bottom.j2 new file mode 100644 index 0000000..88b7918 --- /dev/null +++ b/templates/KeyMile/login/base/get/pstnport_bottom.j2 @@ -0,0 +1,9 @@ +} \ +{{ context.port.register_as_global }}{{ context.spacer2 }}\ # RegisterAsGlobal +{{ context.port.pay_phone }}{{ context.spacer3 }}\ # PayPhone +{{ context.port.sip_profile }}{{ context.spacer4 }}\ # SipProfile +{{ context.port.proxy_registrar_profile }}{{ context.spacer5 }}\ # ProxyRegistrarProfile +{{ context.port.codec_sdp_profile }}{{ context.spacer6 }}\ # CodecSdpProfile +{{ context.port.pstn_profile }}{{ context.spacer7 }}\ # PstnProfile +{{ context.port.enterprise_profile }}{{ context.spacer8 }}\ # EnterpriseProfile + diff --git a/templates/KeyMile/login/base/get/pstnport_middle.j2 b/templates/KeyMile/login/base/get/pstnport_middle.j2 new file mode 100644 index 0000000..19f929b --- /dev/null +++ b/templates/KeyMile/login/base/get/pstnport_middle.j2 @@ -0,0 +1,9 @@ + \ # [0] # + \ # SubscriberId + "9108007" \ # SubscriberNumber + "4962329108007" \ # AuthorisationUserName + "5yhnxz7x" \ # AuthorisationPassword + "" \ # DisplayName + None \ # privacy +; \ + diff --git a/templates/KeyMile/login/base/get/pstnport_top.j2 b/templates/KeyMile/login/base/get/pstnport_top.j2 new file mode 100644 index 0000000..9aab7aa --- /dev/null +++ b/templates/KeyMile/login/base/get/pstnport_top.j2 @@ -0,0 +1,4 @@ + \ # PstnPort +{{ context.port.enable }}{{ context.spacer1 }}\ # Enable +{ \ # SubscriberIdentifications + diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 81d95ee..b88c025 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -27,6 +27,7 @@ def get_port_component(self): return self._model.get_portgroupport('name', self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id) def get_property(self, command, *args, context=None): + port = self.get_port_component() scopes = ('login', 'base', 'get') try: super().get_property(command, *args, context=context) @@ -46,6 +47,34 @@ def get_property(self, command, *args, context=None): context=dict(context, subscriber=subscriber)) text += self._render('subscriberList_bottom', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'Isdnport') and context['component_path'].split('/')[-1] == 'cfgm' and \ + port.type == 'ISDN': + context['spacer1'] = self.create_spacers((67,), (port.enable,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (port.register_as_global,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (port.register_default_number_only,))[0] * ' ' + context['spacer4'] = self.create_spacers((67,), (port.sip_profile,))[0] * ' ' + context['spacer5'] = self.create_spacers((67,), (port.proxy_registrar_profile,))[0] * ' ' + context['spacer6'] = self.create_spacers((67,), (port.codec_sdp_profile,))[0] * ' ' + context['spacer7'] = self.create_spacers((67,), (port.isdnba_profile,))[0] * ' ' + context['spacer8'] = self.create_spacers((67,), (port.layer_1_permanently_activated,))[0] * ' ' + text = self._render('isdnport_top', *scopes, context=dict(context, port=port)) + text += self._render('isdnport_middle', *scopes, context=dict(context, subscriber=port)) #TODO: subscriber dynamic + text += self._render('isdnport_bottom', *scopes, context=dict(context, port=port)) + self._write(text) + elif self._validate((args[0],), 'pstnport') and context['component_path'].split('/')[-1] == 'cfgm' and \ + port.type == 'PSTN': + context['spacer1'] = self.create_spacers((67,), (port.enable,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (port.register_as_global,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (port.pay_phone,))[0] * ' ' + context['spacer4'] = self.create_spacers((67,), (port.sip_profile,))[0] * ' ' + context['spacer5'] = self.create_spacers((67,), (port.proxy_registrar_profile,))[0] * ' ' + context['spacer6'] = self.create_spacers((67,), (port.codec_sdp_profile,))[0] * ' ' + context['spacer7'] = self.create_spacers((67,), (port.pstn_profile,))[0] * ' ' + context['spacer8'] = self.create_spacers((67,), (port.enterprise_profile,))[0] * ' ' + text = self._render('pstnport_top', *scopes, context=dict(context, port=port)) + text += self._render('pstnport_middle', *scopes, context=dict(context, subscriber=port)) #TODO: subscriber dynamic + text += self._render('pstnport_bottom', *scopes, context=dict(context, port=port)) self._write(text) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', @@ -60,17 +89,42 @@ def on_unknown_command(self, command, *args, context=None): def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') try: - super().set(command, *args, context=None) - except exceptions.CommandExecutionError: + super().set(command, *args, context=context) + except exceptions.CommandSyntaxError: if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - # TODO test case - return + elif self._validate(args, 'pstnport', str, str, str, str, str, str, str, str, str) and \ + context['component_path'].split('/')[-1] == 'cfgm': + enable, subident, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', + str, str, str, str, str, str, str, str, str) + try: + port = self.get_port_component() + #TODO: integrate subscriber instead of string + enable = True if enable.lower() == 'true' else False + register = True if register.lower() == 'true' else False + phone = True if phone.lower() == 'true' else False + port.set_pstnport(enable, subident, register, phone, sip, proxy, codec, pstn, enterprise) + except exceptions.SoftboxenError: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'isdnport', str, str, str, str, str, str, str, str, str) and \ + context['component_path'].split('/')[-1] == 'cfgm': + enable, subident, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', + str, str, str, str, str, str, str, str, str) + try: + port = self.get_port_component() + #TODO: integrate subscriber instead of string + enable = True if enable.lower() == 'true' else False + register = True if register.lower() == 'true' else False + regdefault = True if regdefault.lower() == 'true' else False + layer1 = True if layer1.lower() == 'true' else False + port.set_isdnport(enable, subident, register, regdefault, layer1, sip, proxy, codec, isdnba) + except exceptions.SoftboxenError: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) \ No newline at end of file From e3173f8b5ddb035caff0253d95ac58eeb6700afe Mon Sep 17 00:00:00 2001 From: png2000 Date: Wed, 14 Oct 2020 09:15:32 +0200 Subject: [PATCH 107/318] =?UTF-8?q?create-keymile-MG2500:=20Name=20hinzuge?= =?UTF-8?q?f=C3=BCgt=20currTemperature=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootup/conf/bootstraps/create-keymile-MG2500.sh | 4 +++- nesi/keymile/api/schemas/keymile_box_schemas.py | 5 +++-- nesi/keymile/keymile_resources/keymile_box.py | 3 +++ nesi/softbox/api/models/box_models.py | 5 +++++ nesi/softbox/api/schemas/box_schemas.py | 13 +++++++++++-- templates/KeyMile/login/base/get/currTemperature.j2 | 3 +++ .../accessPoints/root/rootCommandProcessor.py | 8 ++++++++ 7 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 templates/KeyMile/login/base/get/currTemperature.j2 diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 06f1a66..dc0398c 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -8,6 +8,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst # @@ -31,7 +32,8 @@ req='{ "network_protocol": "telnet", "network_address": "127.0.0.1", "network_port": 9023, - "uuid": "2200" + "uuid": "2200", + "currTemperature": 15 }' box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 diff --git a/nesi/keymile/api/schemas/keymile_box_schemas.py b/nesi/keymile/api/schemas/keymile_box_schemas.py index b4e571e..37352a2 100644 --- a/nesi/keymile/api/schemas/keymile_box_schemas.py +++ b/nesi/keymile/api/schemas/keymile_box_schemas.py @@ -7,16 +7,17 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst from nesi.softbox.api.schemas.box_schemas import * -class HuaweiBoxSchema(BoxSchema): +class KeymileBoxSchema(BoxSchema): class Meta: model = Box - fields = BoxSchema.Meta.fields + ('channels', 'interfaces') + fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature') interfaces = ma.Hyperlinks( {'_links': { diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 178a817..98f6081 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst @@ -27,6 +28,8 @@ class KeyMileBox(Box): """ # Define Keymile Properties + currTemperature = base.Field("currTemperature") + @property def channels(self): """Return `CpePortCollection` object.""" diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 3540487..3aa931b 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst import uuid @@ -54,10 +55,13 @@ class Box(db.Model): credentials = db.relationship('Credential', backref='Box', lazy='dynamic') credential_details = db.relationship('Credential', backref='credentials', lazy='dynamic') users = db.relationship('User', backref='Box', lazy='dynamic') + subracks = db.relationship('Subrack', backref='Box', lazy='dynamic') subrack_details = db.relationship('Subrack', backref='subracks', lazy='dynamic') cards = db.relationship('Card', backref='Box', lazy='dynamic') + mgmt_cards = db.relationship('MgmtCard', backref='Box', lazy='dynamic') ports = db.relationship('Port', backref='Box', lazy='dynamic') + mgmt_ports = db.relationship('MgmtPort', backref='Box', lazy='dynamic') channels = db.relationship('Channel', backref='Box', lazy='dynamic') interfaces = db.relationship('Interface', backref='Box', lazy='dynamic') cpes = db.relationship('Cpe', backref='Box', lazy='dynamic') @@ -114,3 +118,4 @@ class Box(db.Model): pitp_mode = db.Column(db.String(), default='') dsl_mode = db.Column(db.Enum('tr165', 'tr129'), default='tr165') + currTemperature = db.Column(db.Integer(), default=15) \ No newline at end of file diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index b28a8e1..af7f50e 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst @@ -34,8 +35,8 @@ class Meta: 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', - 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', - 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') + 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'mgmt_cards', 'mgmt_ports', + 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links', 'currTemperature') credentials = ma.Hyperlinks( {'_links': { @@ -57,10 +58,18 @@ class Meta: {'_links': { 'self': ma.URLFor('show_cards', box_id='')}}) + mgmt_cards = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_mgmt_cards', box_id='')}}) + ports = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_ports', box_id='')}}) + mgmt_ports = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_mgmt_ports', box_id='')}}) + channels = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_channels', box_id='')}}) diff --git a/templates/KeyMile/login/base/get/currTemperature.j2 b/templates/KeyMile/login/base/get/currTemperature.j2 new file mode 100644 index 0000000..95d1608 --- /dev/null +++ b/templates/KeyMile/login/base/get/currTemperature.j2 @@ -0,0 +1,3 @@ + \ # Current +{{ context.currTemperature }}{{ context.spacer }}\ # Temperature + diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 0e465c6..0029077 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst @@ -24,6 +25,13 @@ class RootCommandProcessor(BaseCommandProcessor): from .rootManagementFunctions import fm from .rootManagementFunctions import status + def do_get(self, command, *args, context=None): + if self._validate(args, "CurrTemperature"): + context['currTemperature'] = self._model.currTemperature + context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' + self._write(self._render('currTemperature', 'login', 'base', 'get', context=context)) + + def _init_access_points(self, context=None): for card in self._model.cards: if 'unit-' + card.name in self.access_points: From 025ee9d80d5e212776486a5e832d6f1c2fb6f62e Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Wed, 14 Oct 2020 09:45:02 +0200 Subject: [PATCH 108/318] Added the concept of logports (still WIP) --- .../conf/bootstraps/create-keymile-MG2500.sh | 13 +- nesi/keymile/api/schemas/__init__.py | 2 +- .../api/schemas/keymile_box_schemas.py | 6 +- .../api/schemas/keymile_channel_schemas.py | 2 +- .../api/schemas/keymile_logport_schemas.py | 19 + nesi/keymile/keymile_resources/__init__.py | 2 +- nesi/keymile/keymile_resources/keymile_box.py | 23 +- .../keymile_resources/keymile_interface.py | 2 + .../keymile_resources/keymile_logport.py | 33 ++ .../keymile/keymile_resources/keymile_port.py | 2 +- nesi/softbox/api/models/box_models.py | 3 + nesi/softbox/api/models/interface_models.py | 1 + nesi/softbox/api/models/logport_models.py | 23 + nesi/softbox/api/schemas/box_schemas.py | 6 +- nesi/softbox/api/schemas/interface_schemas.py | 2 +- nesi/softbox/api/schemas/logport_schemas.py | 50 ++ nesi/softbox/api/views/__init__.py | 2 +- nesi/softbox/api/views/box_views.py | 1 + nesi/softbox/api/views/logport_views.py | 53 ++ nesi/softbox/base_resources/box.py | 4 - .../unit/logport/logportsCommandProcessor.py | 11 +- .../logport/logportsManagementFunctions.py | 10 +- .../logport/port/logportCommandProcessor.py | 28 +- .../port/logportManagementFunctions.py | 489 ++++++++++-------- .../root/unit/unitCommandProcessor.py | 8 + vendors/KeyMile/baseCommandProcessor.py | 24 +- 26 files changed, 562 insertions(+), 257 deletions(-) create mode 100644 nesi/keymile/api/schemas/keymile_logport_schemas.py create mode 100644 nesi/keymile/keymile_resources/keymile_logport.py create mode 100644 nesi/softbox/api/models/logport_models.py create mode 100644 nesi/softbox/api/schemas/logport_schemas.py create mode 100644 nesi/softbox/api/views/logport_views.py diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index dc0398c..6c18767 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -32,7 +32,7 @@ req='{ "network_protocol": "telnet", "network_address": "127.0.0.1", "network_port": 9023, - "uuid": "2200", + "uuid": "2500", "currTemperature": 15 }' @@ -252,6 +252,17 @@ req='{ port_2_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +### LogPort 1 ### + +# Create a logical logport object at the network device (admin operation) +req='{ + "card_id": '$unit_2', + "name": "2/L/2", + "ports": "ports:2" +}' + +logport_2_l_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/logports) + ### Unit-3 ### # Create a physical card at the network device (admin operation) diff --git a/nesi/keymile/api/schemas/__init__.py b/nesi/keymile/api/schemas/__init__.py index 04e408d..4bcd514 100644 --- a/nesi/keymile/api/schemas/__init__.py +++ b/nesi/keymile/api/schemas/__init__.py @@ -14,4 +14,4 @@ if isclass(attribute): # Add the class to this package's variables - globals()[attribute_name] = attribute \ No newline at end of file + globals()[attribute_name] = attribute diff --git a/nesi/keymile/api/schemas/keymile_box_schemas.py b/nesi/keymile/api/schemas/keymile_box_schemas.py index 37352a2..5458c05 100644 --- a/nesi/keymile/api/schemas/keymile_box_schemas.py +++ b/nesi/keymile/api/schemas/keymile_box_schemas.py @@ -17,7 +17,7 @@ class KeymileBoxSchema(BoxSchema): class Meta: model = Box - fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature') + fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature', 'logports') interfaces = ma.Hyperlinks( {'_links': { @@ -26,3 +26,7 @@ class Meta: channels = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_channels', box_id='')}}) + + logports = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_logports', box_id='')}}) diff --git a/nesi/keymile/api/schemas/keymile_channel_schemas.py b/nesi/keymile/api/schemas/keymile_channel_schemas.py index 5d1e101..9808e4b 100644 --- a/nesi/keymile/api/schemas/keymile_channel_schemas.py +++ b/nesi/keymile/api/schemas/keymile_channel_schemas.py @@ -16,4 +16,4 @@ class KeyMileChannelSchema(ChannelSchema): class Meta: model = Channel - fields = ChannelSchema.Meta.fields + ('vccs', 'interfaces') \ No newline at end of file + fields = ChannelSchema.Meta.fields + ('vccs', 'interfaces') diff --git a/nesi/keymile/api/schemas/keymile_logport_schemas.py b/nesi/keymile/api/schemas/keymile_logport_schemas.py new file mode 100644 index 0000000..8a8ae3c --- /dev/null +++ b/nesi/keymile/api/schemas/keymile_logport_schemas.py @@ -0,0 +1,19 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.logport_schemas import * + + +class KeyMileLogPortSchema(LogPortSchema): + class Meta: + model = LogPort + fields = LogPortSchema.Meta.fields + ('interfaces',) diff --git a/nesi/keymile/keymile_resources/__init__.py b/nesi/keymile/keymile_resources/__init__.py index 17f26e0..1fdb98f 100644 --- a/nesi/keymile/keymile_resources/__init__.py +++ b/nesi/keymile/keymile_resources/__init__.py @@ -1,2 +1,2 @@ __all__ = ["keymile_card", "keymile_port", "keymile_subrack", "keymile_channel", "keymile_interface", - "keymile_subscriber"] + "keymile_subscriber", "keymile_logport"] diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 98f6081..a768eb4 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -26,19 +26,18 @@ class KeyMileBox(Box): :param connection: A RestClient instance :param identity: The identity of the System resource """ - # Define Keymile Properties currTemperature = base.Field("currTemperature") @property def channels(self): - """Return `CpePortCollection` object.""" + """Return `ChannelCollection` object.""" return keymile_channel.KeyMileChannelCollection( self._conn, base.get_sub_resource_path_by(self, 'channels')) @property def interfaces(self): - """Return `CpePortCollection` object.""" + """Return `InterfaceCollection` object.""" return keymile_interface.KeyMileInterfaceCollection( self._conn, base.get_sub_resource_path_by(self, 'interfaces')) @@ -62,6 +61,12 @@ def subscribers(self): return keymile_subscriber.KeymileSubscriberCollection( self._conn, base.get_sub_resource_path_by(self, 'subscribers')) + @property + def logports(self): + """Return `LogPortCollection` object.""" + return keymile_logport.KeyMileLogPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'logports')) + def get_card(self, field, value): """Get specific card object.""" return keymile_card.KeyMileCardCollection( @@ -86,6 +91,18 @@ def get_ports(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'ports'), params={field: value}) + def get_logport(self, field, value): + """Get specific logport object.""" + return keymile_logport.KeyMileLogPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'logports'), + params={field: value}).find_by_field_value(field, value) + + def get_logports(self, field, value): + """Get al logport objects with a specific trait.""" + return keymile_logport.KeyMileLogPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'logports'), + params={field: value}) + def get_chan(self, field, value): """Get specific channel object.""" return keymile_channel.KeyMileChannelCollection( diff --git a/nesi/keymile/keymile_resources/keymile_interface.py b/nesi/keymile/keymile_resources/keymile_interface.py index 24c8b82..11bcd1e 100644 --- a/nesi/keymile/keymile_resources/keymile_interface.py +++ b/nesi/keymile/keymile_resources/keymile_interface.py @@ -24,6 +24,8 @@ class KeyMileInterface(base.Resource): port_id = base.Field('port_id') name = base.Field('name') description = base.Field('description') + chan_id = base.Field('chan_id') + logport_id = base.Field('logport_id') class KeyMileInterfaceCollection(base.ResourceCollection): diff --git a/nesi/keymile/keymile_resources/keymile_logport.py b/nesi/keymile/keymile_resources/keymile_logport.py new file mode 100644 index 0000000..0655631 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_logport.py @@ -0,0 +1,33 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.service_port import logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class KeyMileLogPort(base.Resource): + """Represent logical log_port resource.""" + + id = base.Field('id') + name = base.Field('name') + card_id = base.Field('card_id') + ports = base.Field('ports') + + +class KeyMileLogPortCollection(base.ResourceCollection): + """Represent a collection of logical log_ports.""" + + @property + def _resource_type(self): + return KeyMileLogPort diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py index ea36140..c90e06f 100644 --- a/nesi/keymile/keymile_resources/keymile_port.py +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -31,4 +31,4 @@ class KeyMilePortCollection(PortCollection): @property def _resource_type(self): - return KeyMilePort \ No newline at end of file + return KeyMilePort diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 3aa931b..124d230 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -30,6 +30,8 @@ from .user_models import User from .channel_models import Channel from .subscriber_models import Subscriber +from .logport_models import LogPort +from .interface_models import Interface class Box(db.Model): @@ -76,6 +78,7 @@ class Box(db.Model): routes = db.relationship('Route', backref='Box', lazy='dynamic') emus = db.relationship('Emu', backref='Box', lazy='dynamic') subscribers = db.relationship('Subscriber', backref='Box', lazy='dynamic') + logports = db.relationship('LogPort', backref='Box', lazy='dynamic') board_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_instl_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_init_reporting_logging = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/models/interface_models.py b/nesi/softbox/api/models/interface_models.py index 38dc722..d37fede 100644 --- a/nesi/softbox/api/models/interface_models.py +++ b/nesi/softbox/api/models/interface_models.py @@ -20,3 +20,4 @@ class Interface(db.Model): box_id = db.Column(db.Integer, db.ForeignKey('box.id')) chan_id = db.Column(db.Integer, db.ForeignKey('channel.id')) port_id = db.Column(db.Integer, db.ForeignKey('port.id')) + logport_id = db.Column(db.Integer, db.ForeignKey('log_port.id')) diff --git a/nesi/softbox/api/models/logport_models.py b/nesi/softbox/api/models/logport_models.py new file mode 100644 index 0000000..df96174 --- /dev/null +++ b/nesi/softbox/api/models/logport_models.py @@ -0,0 +1,23 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from ..models.interface_models import Interface +from nesi.softbox.api import db + + +class LogPort(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + ports = db.Column(db.String(), default='') + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + card_id = db.Column(db.Integer, db.ForeignKey('card.id')) + interfaces = db.relationship('Interface', backref='LogPort', lazy='dynamic') diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index af7f50e..97e2882 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -31,7 +31,7 @@ class BoxSchema(ma.ModelSchema): class Meta: model = Box fields = ('id', 'vendor', 'model', 'version', 'software_version', 'network_protocol', 'network_address', - 'network_port', 'uuid', 'description', 'interfaces', + 'network_port', 'uuid', 'description', 'interfaces', 'logports', 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', @@ -90,6 +90,10 @@ class Meta: {'_links': { 'self': ma.URLFor('show_subscribers', box_id='')}}) + logports = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_logports', box_id='')}}) + onts = ma.Hyperlinks({'_links': { 'self': ma.URLFor('show_onts', box_id='')}}) diff --git a/nesi/softbox/api/schemas/interface_schemas.py b/nesi/softbox/api/schemas/interface_schemas.py index a98b4a5..1095031 100644 --- a/nesi/softbox/api/schemas/interface_schemas.py +++ b/nesi/softbox/api/schemas/interface_schemas.py @@ -17,7 +17,7 @@ class InterfaceSchema(ma.ModelSchema): class Meta: model = Interface - fields = ('id', 'box_id', 'box', 'chan_id', 'port_id', + fields = ('id', 'box_id', 'box', 'chan_id', 'port_id', 'logport_id', 'name', 'description', '_links') box = ma.Hyperlinks( diff --git a/nesi/softbox/api/schemas/logport_schemas.py b/nesi/softbox/api/schemas/logport_schemas.py new file mode 100644 index 0000000..059ea12 --- /dev/null +++ b/nesi/softbox/api/schemas/logport_schemas.py @@ -0,0 +1,50 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from .interface_schemas import InterfacesSchema +from ..models.logport_models import LogPort + + +class LogPortSchema(ma.ModelSchema): + class Meta: + model = LogPort + fields = ('id', 'box_id', 'box', 'card_id', 'name', 'ports', 'interfaces', '_links') + + interfaces = ma.Nested(InterfacesSchema.InterfaceSchema, many=True) + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_logport', box_id='', id=''), + 'collection': ma.URLFor('show_logports', box_id='')}) + + +class LogPortsSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class LogPortSchema(ma.ModelSchema): + class Meta: + model = LogPort + fields = ('id', 'name', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_logport', box_id='', id='')}) + + members = ma.Nested(LogPortSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_logports', box_id='')}) diff --git a/nesi/softbox/api/views/__init__.py b/nesi/softbox/api/views/__init__.py index edde876..1753661 100644 --- a/nesi/softbox/api/views/__init__.py +++ b/nesi/softbox/api/views/__init__.py @@ -2,4 +2,4 @@ "ontport_views", "cpe_views", "cpeport_views", "vlan_views", "portprofile_views", "emu_views", "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views", - "mgmt_card_views", "mgmt_port_views", "subscriber_views"] + "mgmt_card_views", "mgmt_port_views", "subscriber_views", "logport_views"] diff --git a/nesi/softbox/api/views/box_views.py b/nesi/softbox/api/views/box_views.py index a08b6b9..ba6c867 100644 --- a/nesi/softbox/api/views/box_views.py +++ b/nesi/softbox/api/views/box_views.py @@ -10,6 +10,7 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst +# TODO: When no more new components are being created, update new_box, clone_box, and del_box from .base_views import * from ..models.box_models import Box diff --git a/nesi/softbox/api/views/logport_views.py b/nesi/softbox/api/views/logport_views.py new file mode 100644 index 0000000..81b49c8 --- /dev/null +++ b/nesi/softbox/api/views/logport_views.py @@ -0,0 +1,53 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from ..schemas.logport_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//logports', methods=['GET']) +def show_logports(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(LogPortsSchema(), LogPort, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//logports/', methods=['GET']) +def show_logport(box_id, id): + response = show_component(LogPort, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//logports', methods=['POST']) +def new_logport(box_id): + req = flask.request.json + response = new_component(LogPortSchema(), LogPort, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//logports/', methods=['PUT']) +def update_logport(box_id, id): + req = flask.request.json + update_component(LogPort, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//logports/', methods=['DELETE']) +def del_logport(box_id, id): + del_component(LogPort, box_id, id) + return flask.Response(status=204) diff --git a/nesi/softbox/base_resources/box.py b/nesi/softbox/base_resources/box.py index df93d87..b050b5c 100644 --- a/nesi/softbox/base_resources/box.py +++ b/nesi/softbox/base_resources/box.py @@ -113,10 +113,6 @@ def vlans(self): def service_vlans(self): raise PropertyNotFoundError("abstract service_vlans properties") - @property - def vlans_connections(self): - raise PropertyNotFoundError("abstract vlans properties") - @property def port_profiles(self): raise PropertyNotFoundError("abstract port_profiles properties") diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 9e76d86..d8faa3b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -14,7 +14,7 @@ from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor -class LogPortsCommandProcessor(BaseCommandProcessor): +class LogportsCommandProcessor(BaseCommandProcessor): __name__ = 'logports' management_functions = ('main', 'cfgm') access_points = () @@ -23,12 +23,11 @@ class LogPortsCommandProcessor(BaseCommandProcessor): from .logportsManagementFunctions import cfgm def _init_access_points(self, context=None): # work in progress - card = self._model.get_card('name', context['unit']) - logports = context['logports'] + card = self._model.get_card('name', self._parent.component_id) - for port in self._model.get_ports('card_id', card.id): - if port.name.count('/') == 2 and port.name.strip('/')[1] == 'logports-' + logports: - identifier = 'port-' + port.name.split('/')[-1] + for logport in self._model.get_logports('card_id', card.id): + if logport.name.count('/') == 2: + identifier = 'logport-' + logport.name.split('/')[-1] if identifier in self.access_points: continue self.access_points += (identifier,) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py index d281df9..b9fc7b2 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py @@ -8,10 +8,10 @@ } cfgm = { - 'General': { - 'Cmd': { - 'CreatePort', - 'DeletePort' - } + 'Logicalport': { + 'Cmd': ( + 'Create', + 'Delete' + ) } } \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 193cfe5..7f277c8 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -14,21 +14,24 @@ from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor -class LogPortCommandProcessor(PortCommandProcessor): +class LogportCommandProcessor(PortCommandProcessor): __name__ = 'logport' - management_functions = ('main', 'cfgm', 'status') + management_functions = ('main', 'cfgm', 'fm', 'pm', 'status', 'ifMIB') access_points = () from .logportManagementFunctions import main from .logportManagementFunctions import cfgm + from .logportManagementFunctions import fm + from .logportManagementFunctions import pm from .logportManagementFunctions import status + from .logportManagementFunctions import ifMIB - def do_get(self, command, *args, context=None): + def get_property(self, command, *args, context=None): scopes = ('login', 'base', 'get') try: - super().do_get(command, *args, context=None) + super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: - if self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': + if self._validate((args[0],), 'AttainableRate') and context['component_path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) else: @@ -36,7 +39,18 @@ def do_get(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors')) def _init_access_points(self, context=None): - port = self._model.get_port('name', context['unit'] + '/' + context['portgroup'] + '/' + context['port']) + logport_name = self._parent._parent.component_id + '/L/' + self.component_id + logport = self._model.get_logport('name', logport_name) + try: + _ = self._model.get_interface('logport_id', logport.id) + except exceptions.SoftboxenError: + pass + else: + for interface in self._model.get_interfaces('logport_id', logport.id): + identifier = 'interface-' + interface.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) @@ -44,7 +58,7 @@ def on_unknown_command(self, command, *args, context=None): def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') try: - super().set(command, *args, context=None) + super().set(command, *args, context=context) except exceptions.CommandExecutionError: if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py index 5add929..f2fa827 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py @@ -1,264 +1,313 @@ main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'AdminAndOperStatus': { - 'Prop': { - 'AdministrativeStatus': 'rw', - 'OperationalStatus': 'r-' + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + }, + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } } } -} cfgm = { - 'Multicast': { - 'Prop': { - 'MaxNumberOfMulticastStreams': 'rw', - 'EnableIgmpClassifier': 'rw', - 'AllowStaticStreams': 'rw', - 'EnableFastLeave': 'rw', - 'GroupManagement': 'rw', - 'Bandwidth': 'rw' + 'Multicast': { + 'Prop': { + 'MaxNumberOfMulticastStreams': 'rw', + 'EnableIgmpClassifier': 'rw', + 'AllowStaticStreams': 'rw', + 'EnableFastLeave': 'rw', + 'GroupManagement': 'rw', + 'Bandwidth': 'rw' + }, + 'Cmd': ( + 'GetGroupList', + ) }, - 'Cmd': ( - 'GetGroupList', - ) - }, - 'Traceability': { - 'Prop': { - 'AgentRemoteId': 'rw' - } - }, - 'Security': { - 'Prop': { - 'ServiceOptions': 'rw', - 'MaxNumberOfMac': 'rw' - } - }, - 'AccessControl': { - 'Prop': { - 'ClassificationKey': 'rw', - 'MAT': 'rw' - } - }, - 'RateLimiter': { - 'Prop': { - 'RateLimiting': 'rw', - 'RateLimitingCoS': 'rw' - } - }, - 'Qos': { - 'Prop': { - 'WfqProfile': 'rw' - } - }, - 'Wire': { - 'Prop': { - 'MeltConfiguration': 'rw' - } - }, - 'Profiles': { - 'Prop': { - 'PortProfiles': 'rw' - } - }, - 'Misc': { - 'Prop': { - 'SpecificDPBO': 'rw', - 'SpecificUPBO': 'rw' + 'Traceability': { + 'Prop': { + 'AgentRemoteId': 'rw' + } + }, + 'Security': { + 'Prop': { + 'ServiceOptions': 'rw', + 'MaxNumberOfMac': 'rw' + } + }, + 'AccessControl': { + 'Prop': { + 'ClassificationKey': 'rw', + 'MAT': 'rw' + } + }, + 'RateLimiter': { + 'Prop': { + 'RateLimiting': 'rw', + 'RateLimitingCoS': 'rw' + } + }, + 'Qos': { + 'Prop': { + 'WfqProfile': 'rw' + } + }, + 'subinterface': { + 'Cmd': ( + 'CreateInterface', + 'DeleteInterface' + ) + }, + 'Clock': { + 'Prop': { + 'Referenceclk': 'rw' + } } } -} -status = { - 'General': { - 'Prop': { - 'Standard': 'r-', - 'PowerMgmStatus': 'r-', - 'Vdsl2Parameters': 'r-', - 'EstUPBOElectricalLength': 'r-', - 'LineRate': 'r-', - 'LineSnrMargin': 'r-', - 'AttainableNetDataRate': 'r-', - 'AttainableRate': 'r-', - 'OutputPower': 'r-', - 'BandStatus': 'r-' +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } } - }, - 'statistics': { - 'Prop': { - 'counters': 'r-', - 'PolicingCounters': 'r-' + } + +pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } }, - 'Cmd': ( - 'ResetPortCounters', - ) - }, - 'Nto1MacAccessDynamicList': { - 'Prop': { - 'UnicastList': 'r-' + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) } - }, - 'HostPortStatistics': { - 'GeneralCounters': { + } + +status = { + 'statistics': { 'Prop': { - 'GeneralList': 'r-' + 'counters': 'r-', + 'PolicingCounters': 'r-' }, 'Cmd': ( - 'ResetGeneralCounters', + 'ResetPortCounters', ) }, - 'ProtocolCounters': { - 'IgmpCounters': { - 'Prop': { - 'IgmpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetIgmpCounters', - ) - }, - 'DhcpCounters': { - 'Prop': { - 'DhcpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetDhcpCounters', - ) - }, - 'ArpCounters': { - 'Prop': { - 'ArpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetArpCounters', - ) - }, - 'PPPoECounters': { - 'Prop': { - 'PPPoEProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetPPPoECounters', - ) - }, - 'UnknownSourceMACCounters': { + 'Nto1MacAccessDynamicList': { + 'Prop': { + 'UnicastList': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { 'Prop': { - 'UnknownSrcMACProtocolList': 'r-' + 'GeneralList': 'r-' }, 'Cmd': ( - 'ResetUnknownSrcMACCounters', + 'ResetGeneralCounters', ) }, - }, - }, - 'TLSMacForwardingList': { - 'Prop': { - 'MacForwardingList': 'r-' - }, - 'Cmd': ( - 'FlushMacForwardingList', - ) - }, - '1to1MacForwardingList': { - 'Prop': { - 'One2OneMacForwardingList': 'r-' - } - }, - 'Qos': { - 'Prop': { - 'wfqueues': 'r-' - } - }, - 'Multicast': { - 'stream': { - 'Dynamic': { - 'Prop': { - 'ActiveStreams': 'r-' + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) }, - 'Cmd': ( - 'ClearActiveStreams', + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'Dhcpv6Counters': { + 'Prop': { + 'Dhcpv6ProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpv6Counters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + 'Ndp': { + 'Prop': { + 'NdpList': 'r-' + }, + 'Cmd': ( + 'ResetNdpCounters', ) }, - 'Static': { - 'Prop': { - 'StaticStreams': 'r-' - } }, }, - - 'Vlan': { + 'TLSMacForwardingList': { 'Prop': { - 'AttachedVlans': 'r-' - } - }, - 'Preview': { + 'MacForwardingList': 'r-' + }, 'Cmd': ( - 'ResetPreviewSettings', + 'FlushMacForwardingList', ) }, - 'Bandwidth': { + '1to1MacForwardingList': { 'Prop': { - 'bandwidthStatus': 'r-' + 'One2OneMacForwardingList': 'r-' } }, - }, - 'LineTest': { - 'MELT': { + 'Qos': { 'Prop': { - 'MeltResults': 'r-' - }, + 'wfqueues': 'r-' + } + }, + 'Support': { 'Cmd': ( - 'StartMeltMeasurement', - ) + 'StartReport', + ), + 'File': { + 'ReportFile': 'r-' + } }, - 'Delt': { - 'Prop': { - 'DeltMeasurementStatus': 'r-', - 'RecordedDeltMeasurements': 'r-' + 'Multicast': { + 'stream': { + 'Dynamic': { + 'Prop': { + 'ActiveStreams': 'r-' + }, + 'Cmd': ( + 'ClearActiveStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticStreams': 'r-' + } + }, + }, + + 'Vlan': { + 'Prop': { + 'AttachedVlans': 'r-' + } + }, + 'Preview': { + 'Cmd': ( + 'ResetPreviewSettings', + ) + }, + 'Bandwidth': { + 'Prop': { + 'bandwidthStatus': 'r-' + } }, - 'Cmd': ( - 'StartDeltMeasurement', - ) }, - 'Selt': { + 'General': { 'Prop': { - 'SeltMeasurementStatus': 'r-', - 'RecordedSeltMeasurements': 'r-', - 'CableType': 'rw', - 'BandplanProfile': 'rw', - 'TargetSnrm': 'rw' - }, - 'Cmd': ( - 'StartSeltMeasurement', - ) + 'OperationalWireState': 'r-', + 'ActualStatus': 'r-', + 'DSLMode': 'r-', + 'ReferenceCLK': 'r-' + } }, - }, - 'Defects': { - 'Prop': { - 'Defects': 'r-' - } - }, - 'LineInventory': { - 'Prop': { - 'VendorId': 'r-' - } - }, - 'Maintenance': { - 'Prop': { - 'DslOperationStatus': 'r-' + 'Inventory': { + 'Prop': { + 'Inventory': 'r-' + } } - }, - 'Subcarrier': { - 'Cmd': ( - 'ShowBitAllocation', - ) - }, - 'RfiBands': { - 'Prop': { - 'NotchStatus': 'r-' + } + +ifMIB = { + 'Interfaces': { + 'Prop': { + 'IfTable': 'rw' + } + }, + 'IfMIB': { + 'Objects': { + 'Prop': { + 'XTable': 'rw', + 'StackTable': 'rw' + } + + } } } -} diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index ef7afcd..41b98bc 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -30,11 +30,19 @@ def _init_access_points(self, context=None): self.management_functions = ('main', 'cfgm', 'fm', 'status') + try: + _ = self._model.get_logport('card_id', card.id) + except exceptions.SoftboxenError: + pass + else: + self.access_points += ('logports',) + for port in self._model.get_ports('card_id', card.id): identifier = 'port-' + port.name.split('/')[-1] if identifier in self.access_points: continue self.access_points += (identifier,) + except exceptions.InvalidInputError: pass diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 9238279..4022523 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -205,7 +205,7 @@ def change_directory(self, path, context=None): components = [x for x in path.split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|logports|logport-[0-9]|\.|\.\.)$', components[0]): raise exceptions.SoftboxenError() @@ -297,6 +297,11 @@ def change_directory(self, path, context=None): if self.__name__ != 'port' and self.__name__ != 'chan': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'logport': + if self.__name__ != 'logports': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): if self.__name__ != 'root': raise exceptions.CommandExecutionError(command=None, template=None, @@ -327,6 +332,9 @@ def change_directory(self, path, context=None): PortgroupCommandProcessor from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import \ PortgroupPortCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.logport.logportsCommandProcessor import LogportsCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ + LogportCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if component_id is not None and self.component_id is not None: @@ -375,7 +383,9 @@ def get_parent_and_child_relation(self, search, parent=None, node=None, parent_k } }, "portgroups": {"portgroupports": {}}, - "logports": {"logport": {}}, + "logports": { + "logport": { + "interface": {}}}, "vectoringports": {"vectorport": {}}, "internalports": {"internalport": {}} }, @@ -482,6 +492,9 @@ def get_command_processor(self, current_processor, component_type=None): from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.logport.logportsCommandProcessor import LogportsCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ + LogportCommandProcessor if current_processor.__class__ == RootCommandProcessor: return_to = RootCommandProcessor if component_type not in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services', 'unit') \ @@ -490,7 +503,7 @@ def get_command_processor(self, current_processor, component_type=None): template_scopes=()) # TODO: fix exception to not require all fields as empty elif current_processor.__class__ == UnitCommandProcessor: return_to = RootCommandProcessor - if component_type != 'port' and component_type is not None: + if (component_type != 'port' or component_type != 'logports') and component_type is not None: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif current_processor.__class__ == PortCommandProcessor: @@ -504,6 +517,7 @@ def get_command_processor(self, current_processor, component_type=None): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif current_processor.__class__ == InterfaceCommandProcessor: + return_to = LogportCommandProcessor return_to = ChanCommandProcessor return_to = PortCommandProcessor elif current_processor.__class__ == FanCommandProcessor: @@ -518,6 +532,10 @@ def get_command_processor(self, current_processor, component_type=None): return_to = RootCommandProcessor elif current_processor.__class__ == ServicesCommandProcessor: return_to = RootCommandProcessor + elif current_processor.__class__ == LogportsCommandProcessor: + return_to = UnitCommandProcessor + elif current_processor.__class__ == LogportCommandProcessor: + return_to = LogportsCommandProcessor return return_to From 0b74f35e755448810d6a5d9203e846f61bd772f7 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 14 Oct 2020 11:23:50 +0200 Subject: [PATCH 109/318] finished isdnport and pstnport get and set functionality --- nesi/keymile/keymile_resources/keymile_box.py | 8 ++ .../keymile_portgroupport.py | 7 +- .../keymile_resources/keymile_subscriber.py | 8 ++ .../api/models/portgroupport_models.py | 1 - nesi/softbox/api/models/subscriber_models.py | 4 + .../api/schemas/portgroupport_schemas.py | 2 +- .../softbox/api/schemas/subscriber_schemas.py | 4 +- .../KeyMile/login/base/get/isdnport_middle.j2 | 12 +-- .../KeyMile/login/base/get/pstnport_middle.j2 | 12 +-- .../port/portgroupportCommandProcessor.py | 88 +++++++++++++++++-- 10 files changed, 119 insertions(+), 27 deletions(-) diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index d800261..e5882bf 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -9,6 +9,7 @@ # - Alexander Dincher # # License: https://github.com/inexio/NESi/LICENSE.rst +import os from nesi.keymile.keymile_resources import * @@ -124,6 +125,13 @@ def get_subscribers(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'subscribers'), params={field: value}) + def add_subscriber(self, **fields): + """Add new ont.""" + return keymile_subscriber.KeymileSubscriber.create( + self._conn, + os.path.join(self.path, 'subscribers'), + **fields) + def get_portgroupport(self, field, value): """Get specific portgroupport object.""" return keymile_portgroupport.KeymilePortGroupPortCollection( diff --git a/nesi/keymile/keymile_resources/keymile_portgroupport.py b/nesi/keymile/keymile_resources/keymile_portgroupport.py index 97619ec..b224869 100644 --- a/nesi/keymile/keymile_resources/keymile_portgroupport.py +++ b/nesi/keymile/keymile_resources/keymile_portgroupport.py @@ -29,7 +29,6 @@ class KeymilePortGroupPort(base.Resource): label2 = base.Field('label2') type = base.Field('type') enable = base.Field('enable') - subsriber_identification = base.Field('subsriber_identification') register_as_global = base.Field('register_as_global') register_default_number_only = base.Field('register_default_number_only') layer_1_permanently_activated = base.Field('layer_1_permanently_activated') @@ -62,10 +61,9 @@ def up(self): """Set the port state to down""" self.update(operational_state='1') - def set_pstnport(self, enable, subscriberident, registerglobal, phone, sip, proxy, codec, pstn, enterprise): + def set_pstnport(self, enable, registerglobal, phone, sip, proxy, codec, pstn, enterprise): """Set the pstnport""" self.update(enable=enable) - self.update(subsriber_identification=subscriberident) self.update(register_as_global=registerglobal) self.update(pay_phone=phone) self.update(sip_profile=sip) @@ -74,10 +72,9 @@ def set_pstnport(self, enable, subscriberident, registerglobal, phone, sip, prox self.update(pstn_profile=pstn) self.update(enterprise_profile=enterprise) - def set_isdnport(self, enable, subscriberident, registerglobal, regdefault, layer1, sip, proxy, codec, isdn): + def set_isdnport(self, enable, registerglobal, regdefault, layer1, sip, proxy, codec, isdn): """Set the pstnport""" self.update(enable=enable) - self.update(subsriber_identification=subscriberident) self.update(register_as_global=registerglobal) self.update(register_default_number_only=regdefault) self.update(sip_profile=sip) diff --git a/nesi/keymile/keymile_resources/keymile_subscriber.py b/nesi/keymile/keymile_resources/keymile_subscriber.py index 5dc324d..086cf2e 100644 --- a/nesi/keymile/keymile_resources/keymile_subscriber.py +++ b/nesi/keymile/keymile_resources/keymile_subscriber.py @@ -26,6 +26,14 @@ class KeymileSubscriber(base.Resource): type = base.Field('type') address = base.Field('address') registration_state = base.Field('registration_state') + autorisation_user_name = base.Field('autorisation_user_name') + autorisation_password = base.Field('autorisation_password') + display_name = base.Field('display_name') + privacy = base.Field('privacy') + + def set(self, field, value): + mapping = {field: value} + self.update(**mapping) class KeymileSubscriberCollection(base.ResourceCollection): diff --git a/nesi/softbox/api/models/portgroupport_models.py b/nesi/softbox/api/models/portgroupport_models.py index 788bf0e..4a1a0f9 100644 --- a/nesi/softbox/api/models/portgroupport_models.py +++ b/nesi/softbox/api/models/portgroupport_models.py @@ -15,7 +15,6 @@ class PortGroupPort(db.Model): #isdn enable = db.Column(db.Boolean(), default=False) - subsriber_identification = db.Column(db.String(), default=None) register_as_global = db.Column(db.Boolean, default=None) register_default_number_only = db.Column(db.Boolean, default=None) layer_1_permanently_activated = db.Column(db.Boolean, default=None) diff --git a/nesi/softbox/api/models/subscriber_models.py b/nesi/softbox/api/models/subscriber_models.py index 1dc9cd1..a94baff 100644 --- a/nesi/softbox/api/models/subscriber_models.py +++ b/nesi/softbox/api/models/subscriber_models.py @@ -10,4 +10,8 @@ class Subscriber(db.Model): type = db.Column(db.Enum('unit', 'port'), default='port') address = db.Column(db.String(), default='') registration_state = db.Column(db.Enum('registered'), default='registered') + autorisation_user_name = db.Column(db.String(), default='') + autorisation_password = db.Column(db.String(), default='""') + display_name = db.Column(db.String(), default='') + privacy = db.Column(db.String(), default=None) diff --git a/nesi/softbox/api/schemas/portgroupport_schemas.py b/nesi/softbox/api/schemas/portgroupport_schemas.py index 82712dc..5ef8f85 100644 --- a/nesi/softbox/api/schemas/portgroupport_schemas.py +++ b/nesi/softbox/api/schemas/portgroupport_schemas.py @@ -18,7 +18,7 @@ class PortGroupPortSchema(ma.ModelSchema): class Meta: model = PortGroupPort fields = ('id', 'name', 'box_id', 'card_id', 'operational_state', 'admin_state', 'description', 'label1', - 'label2', 'type', 'enable', 'subsriber_identification', 'register_as_global', + 'label2', 'type', 'enable', 'register_as_global', 'register_default_number_only', 'layer_1_permanently_activated', 'sip_profile', 'isdnba_profile', 'proxy_registrar_profile', 'codec_sdp_profile', 'pay_phone', 'pstn_profile', 'enterprise_profile', '_links') diff --git a/nesi/softbox/api/schemas/subscriber_schemas.py b/nesi/softbox/api/schemas/subscriber_schemas.py index 3efa31c..98c07b8 100644 --- a/nesi/softbox/api/schemas/subscriber_schemas.py +++ b/nesi/softbox/api/schemas/subscriber_schemas.py @@ -17,7 +17,9 @@ class SubscriberSchema(ma.ModelSchema): class Meta: model = Subscriber - fields = ('id', 'name', 'box', 'box_id', 'number', 'type', 'address', 'registration_state', '_links') + fields = ('id', 'name', 'box', 'box_id', 'number', 'type', 'address', 'registration_state', 'display_name', + 'autorisation_user_name', 'autorisation_password', 'privacy', + '_links') box = ma.Hyperlinks( {'_links': { diff --git a/templates/KeyMile/login/base/get/isdnport_middle.j2 b/templates/KeyMile/login/base/get/isdnport_middle.j2 index 19f929b..051b842 100644 --- a/templates/KeyMile/login/base/get/isdnport_middle.j2 +++ b/templates/KeyMile/login/base/get/isdnport_middle.j2 @@ -1,9 +1,9 @@ - \ # [0] # + \ # [{{ context.i }}] # \ # SubscriberId - "9108007" \ # SubscriberNumber - "4962329108007" \ # AuthorisationUserName - "5yhnxz7x" \ # AuthorisationPassword - "" \ # DisplayName - None \ # privacy + "{{ context.subscriber.number }}"{{ context.spacer10 }}\ # SubscriberNumber + "{{ context.subscriber.autorisation_user_name }}"{{ context.spacer11 }}\ # AuthorisationUserName + "{{ context.subscriber.autorisation_password }}"{{ context.spacer12 }}\ # AuthorisationPassword + "{{ context.subscriber.display_name }}"{{ context.spacer13 }}\ # DisplayName + {{ context.subscriber.privacy }}{{ context.spacer14 }}\ # privacy ; \ diff --git a/templates/KeyMile/login/base/get/pstnport_middle.j2 b/templates/KeyMile/login/base/get/pstnport_middle.j2 index 19f929b..051b842 100644 --- a/templates/KeyMile/login/base/get/pstnport_middle.j2 +++ b/templates/KeyMile/login/base/get/pstnport_middle.j2 @@ -1,9 +1,9 @@ - \ # [0] # + \ # [{{ context.i }}] # \ # SubscriberId - "9108007" \ # SubscriberNumber - "4962329108007" \ # AuthorisationUserName - "5yhnxz7x" \ # AuthorisationPassword - "" \ # DisplayName - None \ # privacy + "{{ context.subscriber.number }}"{{ context.spacer10 }}\ # SubscriberNumber + "{{ context.subscriber.autorisation_user_name }}"{{ context.spacer11 }}\ # AuthorisationUserName + "{{ context.subscriber.autorisation_password }}"{{ context.spacer12 }}\ # AuthorisationPassword + "{{ context.subscriber.display_name }}"{{ context.spacer13 }}\ # DisplayName + {{ context.subscriber.privacy }}{{ context.spacer14 }}\ # privacy ; \ diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index b88c025..159651e 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -37,7 +37,7 @@ def get_property(self, command, *args, context=None): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'port': # TODO: show only subscriber of this port + if subscriber.type == 'port' and subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id: context['i'] = i context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' @@ -59,7 +59,19 @@ def get_property(self, command, *args, context=None): context['spacer7'] = self.create_spacers((67,), (port.isdnba_profile,))[0] * ' ' context['spacer8'] = self.create_spacers((67,), (port.layer_1_permanently_activated,))[0] * ' ' text = self._render('isdnport_top', *scopes, context=dict(context, port=port)) - text += self._render('isdnport_middle', *scopes, context=dict(context, subscriber=port)) #TODO: subscriber dynamic + + i = 0 + for subscriber in self._model.subscribers: + if subscriber.type == 'port' and subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id: + context['i'] = i + context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' + context['spacer11'] = self.create_spacers((63,), (subscriber.autorisation_user_name,))[0] * ' ' + context['spacer12'] = self.create_spacers((63,), (subscriber.autorisation_password,))[0] * ' ' + context['spacer13'] = self.create_spacers((63,), (subscriber.display_name,))[0] * ' ' + context['spacer14'] = self.create_spacers((63,), (subscriber.privacy,))[0] * ' ' + i += 1 + text += self._render('isdnport_middle', *scopes, context=dict(context, subscriber=subscriber)) + text += self._render('isdnport_bottom', *scopes, context=dict(context, port=port)) self._write(text) elif self._validate((args[0],), 'pstnport') and context['component_path'].split('/')[-1] == 'cfgm' and \ @@ -73,7 +85,19 @@ def get_property(self, command, *args, context=None): context['spacer7'] = self.create_spacers((67,), (port.pstn_profile,))[0] * ' ' context['spacer8'] = self.create_spacers((67,), (port.enterprise_profile,))[0] * ' ' text = self._render('pstnport_top', *scopes, context=dict(context, port=port)) - text += self._render('pstnport_middle', *scopes, context=dict(context, subscriber=port)) #TODO: subscriber dynamic + + i = 0 + for subscriber in self._model.subscribers: + if subscriber.type == 'port' and subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id: + context['i'] = i + context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' + context['spacer11'] = self.create_spacers((63,), (subscriber.autorisation_user_name,))[0] * ' ' + context['spacer12'] = self.create_spacers((63,), (subscriber.autorisation_password,))[0] * ' ' + context['spacer13'] = self.create_spacers((63,), (subscriber.display_name,))[0] * ' ' + context['spacer14'] = self.create_spacers((65,), (subscriber.privacy,))[0] * ' ' + i += 1 + text += self._render('pstnport_middle', *scopes, context=dict(context, subscriber=subscriber)) + text += self._render('pstnport_bottom', *scopes, context=dict(context, port=port)) self._write(text) else: @@ -102,26 +126,76 @@ def set(self, command, *args, context=None): str, str, str, str, str, str, str, str, str) try: port = self.get_port_component() - #TODO: integrate subscriber instead of string enable = True if enable.lower() == 'true' else False register = True if register.lower() == 'true' else False phone = True if phone.lower() == 'true' else False - port.set_pstnport(enable, subident, register, phone, sip, proxy, codec, pstn, enterprise) + port.set_pstnport(enable, register, phone, sip, proxy, codec, pstn, enterprise) except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'pstnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, + str) and context['component_path'].split('/')[-1] == 'cfgm': + enable, number, username, password, displayname, privacy, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) + try: + port = self.get_port_component() + try: + subscriber = self._model.get_subscriber('number', int(number)) + subscriber.set('autorisation_user_name', username) + subscriber.set('autorisation_password', password) + subscriber.set('display_name', displayname) + subscriber.set('privacy', privacy) + except exceptions.SoftboxenError: + address = self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id + subscriber = self._model.add_subscriber(number=int(number), autorisation_user_name=username, + address=address, privacy=privacy, type='port', + display_name=displayname, autorisation_password=password) + pass + enable = True if enable.lower() == 'true' else False + register = True if register.lower() == 'true' else False + phone = True if phone.lower() == 'true' else False + port.set_pstnport(enable, register, phone, sip, proxy, codec, pstn, enterprise) + except exceptions.SoftboxenError as exe: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'isdnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, + str) and context['component_path'].split('/')[-1] == 'cfgm': + enable, number, username, password, displayname, privacy, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) + try: + port = self.get_port_component() + try: + subscriber = self._model.get_subscriber('number', int(number)) + assert subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id + subscriber.set('autorisation_user_name', username) + subscriber.set('autorisation_password', password) + subscriber.set('display_name', displayname) + subscriber.set('privacy', privacy) + except exceptions.SoftboxenError: + address = self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id + subscriber = self._model.add_subscriber(number=int(number), autorisation_user_name=username, + address=address, privacy=privacy, type='port', + display_name=displayname, autorisation_password=password) + pass + except AssertionError: + raise exceptions.SoftboxenError() + enable = True if enable.lower() == 'true' else False + register = True if register.lower() == 'true' else False + regdefault = True if regdefault.lower() == 'true' else False + layer1 = True if layer1.lower() == 'true' else False + port.set_isdnport(enable, register, regdefault, layer1, sip, proxy, codec, isdnba) + except exceptions.SoftboxenError as exe: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'isdnport', str, str, str, str, str, str, str, str, str) and \ context['component_path'].split('/')[-1] == 'cfgm': enable, subident, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', str, str, str, str, str, str, str, str, str) try: port = self.get_port_component() - #TODO: integrate subscriber instead of string enable = True if enable.lower() == 'true' else False register = True if register.lower() == 'true' else False regdefault = True if regdefault.lower() == 'true' else False layer1 = True if layer1.lower() == 'true' else False - port.set_isdnport(enable, subident, register, regdefault, layer1, sip, proxy, codec, isdnba) + port.set_isdnport(enable, register, regdefault, layer1, sip, proxy, codec, isdnba) except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) From 878d5a7c15f87074c30291abd562aaa3d29d876b Mon Sep 17 00:00:00 2001 From: png2000 Date: Wed, 14 Oct 2020 12:29:11 +0200 Subject: [PATCH 110/318] Resolved merge conflicts --- nesi/keymile/keymile_resources/keymile_box.py | 2 ++ nesi/softbox/api/schemas/box_schemas.py | 2 ++ vendors/KeyMile/accessPoints/root/rootCommandProcessor.py | 7 +++++++ 3 files changed, 11 insertions(+) diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 956dfb2..0bdb62e 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -30,6 +30,8 @@ class KeyMileBox(Box): currTemperature = base.Field("currTemperature") + currTemperature = base.Field("currTemperature") + @property def channels(self): """Return `ChannelCollection` object.""" diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index 7d13b82..3c742cd 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -37,6 +37,8 @@ class Meta: 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'mgmt_cards', 'mgmt_ports', 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') + 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'mgmt_cards', 'mgmt_ports', + 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links', 'currTemperature') credentials = ma.Hyperlinks( {'_links': { diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 0029077..811a236 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -32,6 +32,13 @@ def do_get(self, command, *args, context=None): self._write(self._render('currTemperature', 'login', 'base', 'get', context=context)) + def do_get(self, command, *args, context=None): + if self._validate(args, "CurrTemperature"): + context['currTemperature'] = self._model.currTemperature + context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' + self._write(self._render('currTemperature', 'login', 'base', 'get', context=context)) + + def _init_access_points(self, context=None): for card in self._model.cards: if 'unit-' + card.name in self.access_points: From 1238843ecbea853a7c4e522caf97632c784f7303 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 14 Oct 2020 13:41:11 +0200 Subject: [PATCH 111/318] Added Delete logport command --- nesi/keymile/keymile_resources/keymile_box.py | 2 -- .../keymile_resources/keymile_logport.py | 26 +++++++++++++++++++ nesi/softbox/api/models/logport_models.py | 5 ++++ nesi/softbox/api/schemas/box_schemas.py | 2 -- nesi/softbox/api/schemas/logport_schemas.py | 4 ++- .../accessPoints/root/rootCommandProcessor.py | 14 +++++----- .../unit/logport/logportsCommandProcessor.py | 19 ++++++++++++-- .../logport/port/logportCommandProcessor.py | 4 +++ .../root/unit/unitCommandProcessor.py | 1 - 9 files changed, 62 insertions(+), 15 deletions(-) diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 0bdb62e..956dfb2 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -30,8 +30,6 @@ class KeyMileBox(Box): currTemperature = base.Field("currTemperature") - currTemperature = base.Field("currTemperature") - @property def channels(self): """Return `ChannelCollection` object.""" diff --git a/nesi/keymile/keymile_resources/keymile_logport.py b/nesi/keymile/keymile_resources/keymile_logport.py index 0655631..e619636 100644 --- a/nesi/keymile/keymile_resources/keymile_logport.py +++ b/nesi/keymile/keymile_resources/keymile_logport.py @@ -23,6 +23,32 @@ class KeyMileLogPort(base.Resource): name = base.Field('name') card_id = base.Field('card_id') ports = base.Field('ports') + label1 = base.Field('label1') + label2 = base.Field('label2') + description = base.Field('description') + admin_state = base.Field('admin_state') + operational_state = base.Field('operational_state') + + def admin_up(self): + """Set the admin port state to up""" + self.update(admin_state='1') + + def admin_down(self): + """Set the admin port state to down""" + self.update(admin_state='0') + + def down(self): + """Set the port state to down""" + self.update(operational_state='0') + + def up(self): + """Set the port state to down""" + self.update(operational_state='1') + + def set_label(self, l1, l2, desc): + self.update(label1=l1) + self.update(label2=l2) + self.update(description=desc) class KeyMileLogPortCollection(base.ResourceCollection): diff --git a/nesi/softbox/api/models/logport_models.py b/nesi/softbox/api/models/logport_models.py index df96174..c5d471d 100644 --- a/nesi/softbox/api/models/logport_models.py +++ b/nesi/softbox/api/models/logport_models.py @@ -21,3 +21,8 @@ class LogPort(db.Model): box_id = db.Column(db.Integer, db.ForeignKey('box.id')) card_id = db.Column(db.Integer, db.ForeignKey('card.id')) interfaces = db.relationship('Interface', backref='LogPort', lazy='dynamic') + label1 = db.Column(db.String(), default='""') + label2 = db.Column(db.String(), default='""') + description = db.Column(db.String(), default='""') + operational_state = db.Column(db.Enum('0', '1'), default='0') + admin_state = db.Column(db.Enum('0', '1'), default='0') diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index 3c742cd..7d13b82 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -37,8 +37,6 @@ class Meta: 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'mgmt_cards', 'mgmt_ports', 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') - 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'mgmt_cards', 'mgmt_ports', - 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links', 'currTemperature') credentials = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/logport_schemas.py b/nesi/softbox/api/schemas/logport_schemas.py index 059ea12..28b634e 100644 --- a/nesi/softbox/api/schemas/logport_schemas.py +++ b/nesi/softbox/api/schemas/logport_schemas.py @@ -18,7 +18,9 @@ class LogPortSchema(ma.ModelSchema): class Meta: model = LogPort - fields = ('id', 'box_id', 'box', 'card_id', 'name', 'ports', 'interfaces', '_links') + fields = ('id', 'box_id', 'box', 'card_id', 'name', 'ports', 'interfaces', 'description', 'admin_state', + 'operational_state', 'label1', 'label2', + '_links') interfaces = ma.Nested(InterfacesSchema.InterfaceSchema, many=True) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 811a236..9bff9eb 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -32,12 +32,6 @@ def do_get(self, command, *args, context=None): self._write(self._render('currTemperature', 'login', 'base', 'get', context=context)) - def do_get(self, command, *args, context=None): - if self._validate(args, "CurrTemperature"): - context['currTemperature'] = self._model.currTemperature - context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' - self._write(self._render('currTemperature', 'login', 'base', 'get', context=context)) - def _init_access_points(self, context=None): for card in self._model.cards: @@ -84,5 +78,11 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def get_property(self, command, *args, context=None): - raise exceptions.CommandExecutionError(command=command, template='invalid_property', + scopes = ('login', 'base', 'set') + if self._validate(args, "CurrTemperature"): + context['currTemperature'] = self._model.currTemperature + context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' + self._write(self._render('currTemperature', *scopes, context=context)) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index d8faa3b..b4817e3 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -35,6 +35,21 @@ def _init_access_points(self, context=None): # work in progress def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + def do_delete(self, command, *args, context=None): + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm': + name, = self._dissect(args, str) + if name.startswith('logport-'): + id = name.split('-')[1] + try: + port = self._model.get_logport('name', self._parent.component_id + '/L/' + id) + port.delete() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -42,8 +57,8 @@ def set(self, command, *args, context=None): exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case + name, = self._dissect(args, 'test', str) + #todo testcase return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 7f277c8..3ca08bb 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -27,6 +27,7 @@ class LogportCommandProcessor(PortCommandProcessor): from .logportManagementFunctions import ifMIB def get_property(self, command, *args, context=None): + port = self.get_port_component() scopes = ('login', 'base', 'get') try: super().get_property(command, *args, context=context) @@ -38,6 +39,9 @@ def get_property(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + def get_port_component(self): + return self._model.get_logport('name', self._parent._parent.component_id + '/L/' + self.component_id) + def _init_access_points(self, context=None): logport_name = self._parent._parent.component_id + '/L/' + self.component_id logport = self._model.get_logport('name', logport_name) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 87b94de..8bfcb36 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -51,7 +51,6 @@ def _init_access_points(self, context=None): except exceptions.InvalidInputError: pass - # todo: add portgroup to access_points def get_property(self, command, *args, context=None): card = self._model.get_card('name', self.component_id) From 8ee02d29d7cf17acf3ee876fdb255ab32bab6120 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 14 Oct 2020 15:32:12 +0200 Subject: [PATCH 112/318] Added create logport command --- nesi/keymile/keymile_resources/keymile_box.py | 9 +++++- .../unit/logport/logportsCommandProcessor.py | 28 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 956dfb2..6074c1f 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -110,6 +110,13 @@ def get_logports(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'logports'), params={field: value}) + def add_logport(self, **fields): + """Add new logport.""" + return keymile_logport.KeyMileLogPort.create( + self._conn, + os.path.join(self.path, 'logports'), + **fields) + def get_chan(self, field, value): """Get specific channel object.""" return keymile_channel.KeyMileChannelCollection( @@ -146,7 +153,7 @@ def get_subscribers(self, field, value): params={field: value}) def add_subscriber(self, **fields): - """Add new ont.""" + """Add new subscriber.""" return keymile_subscriber.KeymileSubscriber.create( self._conn, os.path.join(self.path, 'subscribers'), diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index b4817e3..0946d86 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -31,6 +31,9 @@ def _init_access_points(self, context=None): # work in progress if identifier in self.access_points: continue self.access_points += (identifier,) + accpoint = list(self.access_points) + accpoint.sort(key=lambda x: int(x.split('-')[1])) + self.access_points = tuple(accpoint) def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) @@ -50,6 +53,31 @@ def do_delete(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_create(self, command, *args, context=None): + if self._validate(args, str, str, str, str) and context['component_path'].split('/')[-1] == 'cfgm': + p1, p2, p3, p4, = self._dissect(args, str, str, str, str) + ids = [] + ids.append(int(p1.split('-')[1])) if p1.startswith('port-') else ids + ids.append(int(p2.split('-')[1])) if p2.startswith('port-') else ids + ids.append(int(p3.split('-')[1])) if p3.startswith('port-') else ids + ids.append(int(p4.split('-')[1])) if p4.startswith('port-') else ids + if len(ids) >= 0: + ids.sort() + try: + for x in ids: + _ = self._model.get_logport('name', self._parent.component_id + '/L/' + str(x)) + break + except exceptions.SoftboxenError: + name = self._parent.component_id + '/L/' + str(ids[0]) + ports = 'ports: ' + for x in ids: + ports += str(x) + ', ' + logport = self._model.add_logport(card_id=self._parent.component_id, name=name, ports=ports[:-2]) + else: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) From 98de819f503c10c8dd66ded87ba988def24c7fe1 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 15 Oct 2020 11:27:43 +0200 Subject: [PATCH 113/318] Added Set and Get for proxy, registrar and sip --- .../api/schemas/keymile_card_schemas.py | 9 ++- .../keymile/keymile_resources/keymile_card.py | 66 +++++++++++++++++ nesi/softbox/api/models/card_models.py | 38 ++++++++++ nesi/softbox/cli/base.py | 4 +- templates/KeyMile/login/base/get/proxy.j2 | 13 ++++ templates/KeyMile/login/base/get/registrar.j2 | 6 ++ templates/KeyMile/login/base/get/sip.j2 | 28 ++++---- .../accessPoints/root/rootCommandProcessor.py | 6 ++ .../root/unit/unitCommandProcessor.py | 70 ++++++++++++++++++- 9 files changed, 221 insertions(+), 19 deletions(-) create mode 100644 templates/KeyMile/login/base/get/proxy.j2 create mode 100644 templates/KeyMile/login/base/get/registrar.j2 diff --git a/nesi/keymile/api/schemas/keymile_card_schemas.py b/nesi/keymile/api/schemas/keymile_card_schemas.py index 7b658b8..eeaf6aa 100644 --- a/nesi/keymile/api/schemas/keymile_card_schemas.py +++ b/nesi/keymile/api/schemas/keymile_card_schemas.py @@ -20,4 +20,11 @@ class Meta: 'software_name', 'software_revision', 'state', 'serial_number', 'manufacturer_name', 'model_name', 'short_text', 'manufacturer_id', 'manufacturer_part_number', 'manufacturer_build_state', 'customer_id', - 'customer_product_id', 'boot_loader', 'processor', 'label1', 'label2') + 'customer_product_id', 'boot_loader', 'processor', 'label1', 'label2', + 'gateway_name', 'home_domain', 'sip_port_number', 'country_code', 'area_code', + 'retransmission_timer', 'max_retransmission_interval', 'sip_extension', + 'asserted_id_mode', 'overlap_signalling', 'overlap_timer', + 'uac_request_timer', 'uas_request_timer', 'session_expiration', 'proxy_mode', + 'proxy_address', 'proxy_port', 'proxy_address_sec', 'proxy_port_sec', + 'proxy_enable', 'proxy_method', 'proxy_interval', 'registrar_adress', + 'registrar_port', 'registration_mode', 'registration_expiration_time') diff --git a/nesi/keymile/keymile_resources/keymile_card.py b/nesi/keymile/keymile_resources/keymile_card.py index 7680fbc..71fae65 100644 --- a/nesi/keymile/keymile_resources/keymile_card.py +++ b/nesi/keymile/keymile_resources/keymile_card.py @@ -41,11 +41,77 @@ class KeyMileCard(Card): label1 = base.Field('label1') label2 = base.Field('label2') + # Keymile ipsx2/3 card SIP specifications + gateway_name = base.Field('gateway_name') + home_domain = base.Field('home_domain') + sip_port_number = base.Field('sip_port_number') + country_code = base.Field('country_code') + area_code = base.Field('area_code') + retransmission_timer = base.Field('retransmission_timer') + max_retransmission_interval = base.Field('max_retransmission_interval') + sip_extension = base.Field('sip_extension') + asserted_id_mode = base.Field('asserted_id_mode') + overlap_signalling = base.Field('overlap_signalling') + overlap_timer = base.Field('overlap_timer') + uac_request_timer = base.Field('uac_request_timer') + uas_request_timer = base.Field('uas_request_timer') + session_expiration = base.Field('session_expiration') + # Keymile ipsx2/3 card Proxy specification + proxy_mode = base.Field('proxy_mode') + proxy_address = base.Field('proxy_address') + proxy_port = base.Field('proxy_port') + proxy_address_sec = base.Field('proxy_address_sec') + proxy_port_sec = base.Field('proxy_port_sec') + proxy_enable = base.Field('proxy_enable') + proxy_method = base.Field('proxy_method') + proxy_interval = base.Field('proxy_interval') + # Keymile ipsx2/3 card Registrar specification + registrar_adress = base.Field('registrar_adress') + registrar_port = base.Field('registrar_port') + registration_mode = base.Field('registration_mode') + registration_expiration_time = base.Field('registration_expiration_time') + + def set_sip(self, gateway_name, home_domain, sip_port_number, country_code, area_code, retransmission_timer, + max_retransmission_interval, sip_extension, asserted_id_mode, overlap_signalling, overlap_timer, + uac_request_timer, uas_request_timer, session_expiration): + self.update(gateway_name=gateway_name) + self.update(home_domain=home_domain) + self.update(sip_port_number=sip_port_number) + self.update(country_code=country_code) + self.update(area_code=area_code) + self.update(retransmission_timer=retransmission_timer) + self.update(max_retransmission_interval=max_retransmission_interval) + self.update(sip_extension=sip_extension) + self.update(asserted_id_mode=asserted_id_mode) + self.update(overlap_signalling=overlap_signalling) + self.update(overlap_timer=overlap_timer) + self.update(uac_request_timer=uac_request_timer) + self.update(uas_request_timer=uas_request_timer) + self.update(session_expiration=session_expiration) + + def set_label(self, l1, l2, desc): self.update(label1=l1) self.update(label2=l2) self.update(description=desc) + def set_proxy(self, proxy_mode, proxy_address, proxy_port, proxy_address_sec, proxy_port_sec, proxy_enable, + proxy_method, proxy_interval): + self.update(proxy_mode=proxy_mode) + self.update(proxy_address=proxy_address) + self.update(proxy_port=proxy_port) + self.update(proxy_address_sec=proxy_address_sec) + self.update(proxy_port_sec=proxy_port_sec) + self.update(proxy_enable=proxy_enable) + self.update(proxy_method=proxy_method) + self.update(proxy_interval=proxy_interval) + + def set_registrar(self, registrar_adress, registrar_port, registration_mode, registration_expiration_time): + self.update(registrar_adress=registrar_adress) + self.update(registrar_port=registrar_port) + self.update(registration_mode=registration_mode) + self.update(registration_expiration_time=registration_expiration_time) + class KeyMileCardCollection(CardCollection): """Represent a collection of cards.""" diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index aa1855f..f3fc2f9 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -103,3 +103,41 @@ class Card(db.Model): processor = db.Column(db.String(), default='') label1 = db.Column(db.String(), default='""') label2 = db.Column(db.String(), default='""') + + # Keymile ipsx2/3 card SIP specifications + gateway_name = db.Column(db.String(), default='""') + home_domain = db.Column(db.String(), default='""') + sip_port_number = db.Column(db.Integer(), default=0) + country_code = db.Column(db.String(), default='') + area_code = db.Column(db.String(), default='') + retransmission_timer = db.Column(db.Integer(), default=0) + max_retransmission_interval = db.Column(db.Integer(), default=0) + sip_extension = db.Column(db.Boolean, default=False) + asserted_id_mode = db.Column(db.Enum('Asserted', 'Preferred'), default=None) + overlap_signalling = db.Column(db.Boolean, default=False) + overlap_timer = db.Column(db.Integer(), default=0) + uac_request_timer = db.Column(db.Boolean, default=False) + uas_request_timer = db.Column(db.Boolean, default=False) + session_expiration = db.Column(db.Integer(), default=0) + # Keymile ipsx2/3 card Proxy specification + proxy_mode = db.Column(db.Enum('PrimaryOnly', 'Revertive', 'NonRevertive', 'DnsRfc3263'), default='PrimaryOnly') + proxy_address = db.Column(db.String(), default='""') + proxy_port = db.Column(db.Integer(), default=5060) + proxy_address_sec = db.Column(db.String(), default='""') + proxy_port_sec = db.Column(db.Integer(), default=0) + proxy_enable = db.Column(db.Boolean, default=True) + proxy_method = db.Column(db.Enum('Options', 'Register'), default='Options') + proxy_interval = db.Column(db.Integer(), default=10) + # Keymile ipsx2/3 card Registrar specification + registrar_adress = db.Column(db.String(), default='') + registrar_port = db.Column(db.Integer(), default=5060) + registration_mode = db.Column(db.Enum('NoRegistration', 'OneByOneRegistration'), default='OneByOneRegistration') + registration_expiration_time = db.Column(db.Integer(), default=100) + + + # Keymile ipsx2/3 card digimap specification + #digimap_uri_schema = db.Column(db.Enum('sip', 'tel'), default='sip') + #digit_map = db.Column(db.String(), default='') + #digimap_domain_phone_context = db.Column(db.String(), default='') + #digimap_prestrip = db.Column(db.Integer(), default=0) + #digimap_prepend = db.Column(db.String(), default='') diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 04cbce4..500f646 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -449,8 +449,8 @@ def _dissect(self, args, *tokens): raise exceptions.CommandSyntaxError(command=' '.join(args)) if self.case_sensitive is False: - arg = arg.lower() if not isinstance(token, type): + arg = arg.lower() token = token.lower() if type(token) == type: @@ -472,8 +472,8 @@ def _validate(self, args, *tokens): return False if self.case_sensitive is False: - arg = arg.lower() if not isinstance(token, type): + arg = arg.lower() token = token.lower() if arg != token and type(token) != type: diff --git a/templates/KeyMile/login/base/get/proxy.j2 b/templates/KeyMile/login/base/get/proxy.j2 new file mode 100644 index 0000000..c20a356 --- /dev/null +++ b/templates/KeyMile/login/base/get/proxy.j2 @@ -0,0 +1,13 @@ + \ # Proxy +{{ context.card.proxy_mode }}{{ context.spacer1 }}\ # ProxyMode + \ # PrimaryProxy +{{ context.card.proxy_address | safe }}{{ context.spacer2 }}\ # ProxyAddress +{{ context.card.proxy_port }}{{ context.spacer3 }}\ # ProxyPort + \ # SecondaryProxy +{{ context.card.proxy_address_sec | safe }}{{ context.spacer4 }}\ # ProxyAddress +{{ context.card.proxy_port_sec }}{{ context.spacer5 }}\ # ProxyPort + \ # ProxyAvailabilityCheck +{{ context.card.proxy_enable }}{{ context.spacer6 }}\ # Enabled +{{ context.card.proxy_method }}{{ context.spacer7 }}\ # Method +{{ context.card.proxy_interval }}{{ context.spacer8 }}\ # Interval + diff --git a/templates/KeyMile/login/base/get/registrar.j2 b/templates/KeyMile/login/base/get/registrar.j2 new file mode 100644 index 0000000..e4da7e2 --- /dev/null +++ b/templates/KeyMile/login/base/get/registrar.j2 @@ -0,0 +1,6 @@ + \ # Registrar +{{ context.card.registrar_adress | safe }}{{ context.spacer1 }}\ # RegistrarAddress +{{ context.card.registrar_port }}{{ context.spacer2 }}\ # RegistrarPort +{{ context.card.registration_mode }}{{ context.spacer3 }}\ # RegistrationMode +{{ context.card.registration_expiration_time }}{{ context.spacer4 }}\ # RegistrationExpirationTime + diff --git a/templates/KeyMile/login/base/get/sip.j2 b/templates/KeyMile/login/base/get/sip.j2 index fa1eed3..6bfb4e9 100644 --- a/templates/KeyMile/login/base/get/sip.j2 +++ b/templates/KeyMile/login/base/get/sip.j2 @@ -1,17 +1,17 @@ \ # sip -"Name" \ # GatewayName -"hab.dich.loieb.net" \ # HomeDomain -500 \ # SipPortNumber -"+49" \ # CountryCode -"6567" \ # AreaCode -500 \ # RetransmissionTimerT1 -4 \ # MaxRetransmissionIntervalT2 -false \ # SipExtension100relRequired -None \ # assertedIdentityMode -true \ # OverlapSignalling -30 \ # OverlapT10timer +{{ context.card.gateway_name | safe }}{{ context.spacer1 }}\ # GatewayName +{{ context.card.home_domain | safe }}{{ context.spacer2 }}\ # HomeDomain +{{ context.card.sip_port_number }}{{ context.spacer3 }}\ # SipPortNumber +"{{ context.card.country_code | safe }}"{{ context.spacer4 }}\ # CountryCode +"{{ context.card.area_code | safe }}"{{ context.spacer5 }}\ # AreaCode +{{ context.card.retransmission_timer }}{{ context.spacer6 }}\ # RetransmissionTimerT1 +{{ context.card.max_retransmission_interval }}{{ context.spacer7 }}\ # MaxRetransmissionIntervalT2 +{{ context.card.sip_extension }}{{ context.spacer8 }}\ # SipExtension100relRequired +{{ context.card.asserted_id_mode }}{{ context.spacer9 }}\ # assertedIdentityMode +{{ context.card.overlap_signalling }}{{ context.spacer10 }}\ # OverlapSignalling +{{ context.card.overlap_timer }}{{ context.spacer11 }}\ # OverlapT10timer \ # SessionTimer -false \ # UacRequestSessionTimer -false \ # UasRequestSessionTimer -1800 \ # SessionExpiration +{{ context.card.uac_request_timer }}{{ context.spacer12 }}\ # UacRequestSessionTimer +{{ context.card.uas_request_timer }}{{ context.spacer13 }}\ # UasRequestSessionTimer +{{ context.card.session_expiration }}{{ context.spacer14 }}\ # SessionExpiration diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 9bff9eb..75579bb 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -74,6 +74,12 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + def do_save(self, command, *args, context=None): + if len(args) == 0 and context['component_path'].split('/')[-1] == 'cfgm': + pass + else: + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 8bfcb36..1c4ee08 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -78,8 +78,33 @@ def get_property(self, command, *args, context=None): self._write(text) elif self._validate(args, 'SIP') and context['component_path'].split('/')[-1] == 'cfgm' and \ (card.product == 'isdn' or card.product == 'analog'): - # TODO: dynamic fields - text = self._render('sip', *scopes, context=context) + context['spacer1'] = self.create_spacers((67,), (card.gateway_name,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (card.home_domain,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (card.sip_port_number,))[0] * ' ' + context['spacer4'] = self.create_spacers((65,), (card.country_code,))[0] * ' ' + context['spacer5'] = self.create_spacers((65,), (card.area_code,))[0] * ' ' + context['spacer6'] = self.create_spacers((67,), (card.retransmission_timer,))[0] * ' ' + context['spacer7'] = self.create_spacers((67,), (card.max_retransmission_interval,))[0] * ' ' + context['spacer8'] = self.create_spacers((67,), (card.sip_extension,))[0] * ' ' + context['spacer9'] = self.create_spacers((67,), (card.asserted_id_mode,))[0] * ' ' + context['spacer10'] = self.create_spacers((67,), (card.overlap_signalling,))[0] * ' ' + context['spacer11'] = self.create_spacers((67,), (card.overlap_timer,))[0] * ' ' + context['spacer12'] = self.create_spacers((67,), (card.uac_request_timer,))[0] * ' ' + context['spacer13'] = self.create_spacers((67,), (card.uas_request_timer,))[0] * ' ' + context['spacer14'] = self.create_spacers((67,), (card.session_expiration,))[0] * ' ' + text = self._render('sip', *scopes, context=dict(context, card=card)) + self._write(text) + elif self._validate(args, 'Proxy') and context['component_path'].split('/')[-1] == 'cfgm' and \ + (card.product == 'isdn' or card.product == 'analog'): + context['spacer1'] = self.create_spacers((67,), (card.proxy_mode,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (card.proxy_address,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (card.proxy_port,))[0] * ' ' + context['spacer4'] = self.create_spacers((67,), (card.proxy_address_sec,))[0] * ' ' + context['spacer5'] = self.create_spacers((67,), (card.proxy_port_sec,))[0] * ' ' + context['spacer6'] = self.create_spacers((67,), (card.proxy_enable,))[0] * ' ' + context['spacer7'] = self.create_spacers((67,), (card.proxy_method,))[0] * ' ' + context['spacer8'] = self.create_spacers((67,), (card.proxy_interval,))[0] * ' ' + text = self._render('proxy', *scopes, context=dict(context, card=card)) self._write(text) elif self._validate(args, 'IP') and context['component_path'].split('/')[-1] == 'cfgm' and \ (card.product == 'isdn' or card.product == 'analog'): @@ -94,6 +119,14 @@ def get_property(self, command, *args, context=None): text = self._render('labels', *scopes, context=dict(context, port=card)) self._write(text) + elif self._validate(args, 'Registrar') and context['component_path'].split('/')[-1] == 'cfgm': + context['spacer1'] = self.create_spacers((67,), (card.registrar_adress,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (card.registrar_port,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (card.registration_mode,))[0] * ' ' + context['spacer4'] = self.create_spacers((67,), (card.registration_expiration_time,))[0] * ' ' + text = self._render('registrar', *scopes, context=dict(context, card=card)) + self._write(text) + elif self._validate(args, 'HardwareAndSoftware') and context['component_path'].split('/')[-1] == 'main': unit_hardware = '"' + card.board_name + '"' context['unit_hardware'] = unit_hardware @@ -198,6 +231,10 @@ def get_component(self): return self._model.get_card('name', self.component_id) def set(self, command, *args, context=None): + try: + card = self._model.get_card('name', self.component_id) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' @@ -211,5 +248,34 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'SIP', str, str, str, str, str, str, str, str, str, str, str, str, str, str) and \ + context['component_path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): + gw, hd, spn, cc, ac, rt, mri, se, aim, os, ot, uac, uas, sessione = self._dissect( + args, 'Sip', str, str, str, str, str, str, str, str, str, str, str, str, str, str) + try: + se = True if se.lower() == 'true' else False + os = True if os.lower() == 'true' else False + uac = True if uac.lower() == 'true' else False + uas = True if uas.lower() == 'true' else False + aim = None if aim.lower() == 'none' else aim + + card.set_sip(gw, hd, int(spn), cc, ac, int(rt), int(mri), se, aim, os, int(ot), uac, uas, int(sessione)) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args, 'Registrar', str, str, str, str) and \ + context['component_path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): + ra, rp, rm, rt = self._dissect(args, 'Registrar', str, str, str, str) + try: + card.set_registrar(ra, int(rp), rm, int(rt)) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args, 'Proxy', str, str, str, str, str, str, str, str) and \ + context['component_path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): + pm, pa1, pp1, pa2, pp2, pe, pmethod, pi = self._dissect(args, 'Proxy', str, str, str, str, str, str, str, str) + try: + pe = True if pe.lower() == 'true' else False + card.set_proxy(pm, pa1, int(pp1), pa2, int(pp2), pe, pmethod, int(pi)) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) else: raise exceptions.CommandSyntaxError(command=command) From 08afb38cd5e99db01a15a68e72cf4a28ae124ccf Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 15 Oct 2020 14:44:49 +0200 Subject: [PATCH 114/318] Added create and delete of vcc after a chanel --- nesi/keymile/keymile_resources/keymile_box.py | 7 ++ .../keymile_resources/keymile_interface.py | 4 + nesi/softbox/api/models/interface_models.py | 4 + nesi/softbox/api/schemas/interface_schemas.py | 2 +- .../KeyMile/login/base/set/vcc_success.j2 | 3 + .../accessPoints/root/rootCommandProcessor.py | 1 + .../unit/logport/logportsCommandProcessor.py | 1 + .../logport/port/logportCommandProcessor.py | 1 + .../unit/port/chan/chanCommandProcessor.py | 83 +++++++++++++++++-- .../unit/port/chan/vcc/vccCommandProcessor.py | 12 +++ .../root/unit/port/portCommandProcessor.py | 1 + .../portgroup/portgroupCommandProcessor.py | 1 + .../root/unit/unitCommandProcessor.py | 2 +- vendors/KeyMile/baseCommandProcessor.py | 9 +- 14 files changed, 121 insertions(+), 10 deletions(-) create mode 100644 templates/KeyMile/login/base/set/vcc_success.j2 diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 6074c1f..d4d5b73 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -140,6 +140,13 @@ def get_interfaces(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'interfaces'), params={field: value}) + def add_interface(self, **fields): + """Add new interface/vcc.""" + return keymile_interface.KeyMileInterface.create( + self._conn, + os.path.join(self.path, 'interfaces'), + **fields) + def get_subscriber(self, field, value): """Get specific subscriber object.""" return keymile_subscriber.KeymileSubscriberCollection( diff --git a/nesi/keymile/keymile_resources/keymile_interface.py b/nesi/keymile/keymile_resources/keymile_interface.py index 11bcd1e..b827fbe 100644 --- a/nesi/keymile/keymile_resources/keymile_interface.py +++ b/nesi/keymile/keymile_resources/keymile_interface.py @@ -27,6 +27,10 @@ class KeyMileInterface(base.Resource): chan_id = base.Field('chan_id') logport_id = base.Field('logport_id') + #vcc + vcc_profile = base.Field('vcc_profile') + vlan_profile = base.Field('vlan_profile') + class KeyMileInterfaceCollection(base.ResourceCollection): """Represent a collection of interfaces.""" diff --git a/nesi/softbox/api/models/interface_models.py b/nesi/softbox/api/models/interface_models.py index d37fede..b8e3322 100644 --- a/nesi/softbox/api/models/interface_models.py +++ b/nesi/softbox/api/models/interface_models.py @@ -21,3 +21,7 @@ class Interface(db.Model): chan_id = db.Column(db.Integer, db.ForeignKey('channel.id')) port_id = db.Column(db.Integer, db.ForeignKey('port.id')) logport_id = db.Column(db.Integer, db.ForeignKey('log_port.id')) + + #vcc + vcc_profile = db.Column(db.String(), default=None) # default or profile_name, default:= vpi=0 and vci=33 + vlan_profile = db.Column(db.String(), default=None) # default or profile_name, must be untagged diff --git a/nesi/softbox/api/schemas/interface_schemas.py b/nesi/softbox/api/schemas/interface_schemas.py index 1095031..159b4e3 100644 --- a/nesi/softbox/api/schemas/interface_schemas.py +++ b/nesi/softbox/api/schemas/interface_schemas.py @@ -18,7 +18,7 @@ class InterfaceSchema(ma.ModelSchema): class Meta: model = Interface fields = ('id', 'box_id', 'box', 'chan_id', 'port_id', 'logport_id', - 'name', 'description', '_links') + 'name', 'description', 'vcc_profile', 'vlan_profile', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/templates/KeyMile/login/base/set/vcc_success.j2 b/templates/KeyMile/login/base/set/vcc_success.j2 new file mode 100644 index 0000000..b5a9cf3 --- /dev/null +++ b/templates/KeyMile/login/base/set/vcc_success.j2 @@ -0,0 +1,3 @@ + \ # CreateVcc +vcc-{{ context.id }}{{ context.spacer1 }}\ # VCC ID + diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 75579bb..699d6ca 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -34,6 +34,7 @@ def do_get(self, command, *args, context=None): def _init_access_points(self, context=None): + self.access_points = () for card in self._model.cards: if 'unit-' + card.name in self.access_points: continue diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 0946d86..0e540e3 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -23,6 +23,7 @@ class LogportsCommandProcessor(BaseCommandProcessor): from .logportsManagementFunctions import cfgm def _init_access_points(self, context=None): # work in progress + self.access_points = () card = self._model.get_card('name', self._parent.component_id) for logport in self._model.get_logports('card_id', card.id): diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 3ca08bb..f0a62d1 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -43,6 +43,7 @@ def get_port_component(self): return self._model.get_logport('name', self._parent._parent.component_id + '/L/' + self.component_id) def _init_access_points(self, context=None): + self.access_points = () logport_name = self._parent._parent.component_id + '/L/' + self.component_id logport = self._model.get_logport('name', logport_name) try: diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 288e2db..3562f7c 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -26,18 +26,75 @@ class ChanCommandProcessor(BaseCommandProcessor): from .chanManagementFunctions import status def _init_access_points(self, context=None): + self.access_points = () chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) card = self._model.get_card('name', self._parent._parent.component_id) for interface in self._model.get_interfaces('chan_id', chan.id): - if card.product != 'adsl': - ap_name = 'interface-' + if interface.chan_id is not None: + if card.product != 'adsl': + ap_name = 'interface-' + else: + ap_name = 'vcc-' + identifier = ap_name + interface.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + + def do_deletevcc(self, command, *args, context=None): + card = self._model.get_card('name', self._parent._parent.component_id) + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': + # all or vcc_id + name, = self._dissect(args, str) + if name == 'all': + chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + for vcc in self._model.get_interfaces('chan_id', chan.id): + vcc.delete() + elif name.startswith('vcc-'): + id = name.split('-')[1] + try: + vcc = self._model.get_interface('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + id) + vcc.delete() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) else: - ap_name = 'vcc-' - identifier = ap_name + interface.name.split('/')[-1] - if identifier in self.access_points: - continue - self.access_points += (identifier,) + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_createvcc(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + card = self._model.get_card('name', self._parent._parent.component_id) + if self._validate(args, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': + # vcc profile and vlan profile + vcc_prof, vlan_prof = self._dissect(args, str, str) + # TODO: Check if profiles := default or profile names + try: + chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + id = 1 + for vcc in self._model.get_interfaces('chan_id', chan.id): + if vcc.chan_id is not None: + new_id = int(vcc.name[-1]) + 1 + id = new_id if new_id > id else id + try: + name = self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + str(id) + _ = self._model.get_interface('name', name) + assert False + except exceptions.SoftboxenError as exe: + vcc = self._model.add_interface(name=name, chan_id=chan.id, vcc_profile=vcc_prof, + vlan_profile=vlan_prof) + context['spacer1'] = self.create_spacers((63,), (str(id),))[0] * ' ' + context['id'] = str(id) + # TODO: Template is unknown + text = self._render('vcc_success', *scopes, context=context) + self._write(text) + except AssertionError: + raise exceptions.CommandSyntaxError(command=command) + + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) @@ -54,3 +111,15 @@ def set(self, command, *args, context=None): return else: raise exceptions.CommandSyntaxError(command=command) + + def get_property(self, command, *args, context=None): + #card = self._model.get_card('name', self.component_id) + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py index c0e0842..fca7430 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py @@ -35,3 +35,15 @@ def set(self, command, *args, context=None): raise exc else: raise exceptions.CommandSyntaxError(command=command) + + def get_property(self, command, *args, context=None): + #card = self._model.get_card('name', self.component_id) + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 30f0d40..505f08e 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -59,6 +59,7 @@ def get_property(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors')) def _init_access_points(self, context=None): + self.access_points = () port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) for chan in self._model.get_chans('port_id', port.id): diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index 988535a..9c51c4c 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -23,6 +23,7 @@ class PortgroupCommandProcessor(BaseCommandProcessor): from .portgroupManagementFunctions import cfgm def _init_access_points(self, context=None): # work in progress + self.access_points = () card = self._model.get_card('name', self._parent.component_id) for gport in self._model.get_portgroupports('card_id', card.id): diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 1c4ee08..5826e8e 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -25,6 +25,7 @@ class UnitCommandProcessor(BaseCommandProcessor): from .unitManagementFunctions import status def _init_access_points(self, context=None): + self.access_points = () try: card = self._model.get_card('name', self.component_id) @@ -51,7 +52,6 @@ def _init_access_points(self, context=None): except exceptions.InvalidInputError: pass - def get_property(self, command, *args, context=None): card = self._model.get_card('name', self.component_id) scopes = ('login', 'base', 'get') diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 8fc80b6..db62303 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -305,7 +305,10 @@ def change_directory(self, path, context=None): if self.__name__ != 'logports': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - + elif component_type == 'vcc': + if self.__name__ != 'chan': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): if self.__name__ != 'root': raise exceptions.CommandExecutionError(command=None, template=None, @@ -339,6 +342,7 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.unit.logport.logportsCommandProcessor import LogportsCommandProcessor from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ LogportCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.chan.vcc.vccCommandProcessor import VccCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if component_id is not None and self.component_id is not None: @@ -503,6 +507,7 @@ def get_command_processor(self, current_processor, component_type=None): from vendors.KeyMile.accessPoints.root.unit.logport.logportsCommandProcessor import LogportsCommandProcessor from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ LogportCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.chan.vcc.vccCommandProcessor import VccCommandProcessor if current_processor.__class__ == RootCommandProcessor: return_to = RootCommandProcessor if component_type not in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services', 'unit') \ @@ -548,6 +553,8 @@ def get_command_processor(self, current_processor, component_type=None): return_to = UnitCommandProcessor elif current_processor.__class__ == LogportCommandProcessor: return_to = LogportsCommandProcessor + elif current_processor.__class__ == VccCommandProcessor: + return_to = ChanCommandProcessor return return_to From 8d2c5bb0ac2aa81a749a37ef5a7ee899c32f60f1 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 15 Oct 2020 15:55:24 +0200 Subject: [PATCH 115/318] Added delete of interface after a chanel, port and logports --- .../logport/port/logportCommandProcessor.py | 22 +++++++++++++++++++ .../unit/port/chan/chanCommandProcessor.py | 21 ++++++++++++++++++ .../root/unit/port/portCommandProcessor.py | 22 +++++++++++++++++++ .../port/portgroupportCommandProcessor.py | 3 +++ 4 files changed, 68 insertions(+) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index f0a62d1..fce9dc3 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -57,6 +57,28 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) + def do_deleteinterface(self, command, *args, context=None): + card = self._model.get_card('name', self._parent._parent.component_id) + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': + # all or interface_id + name, = self._dissect(args, str) + if name == 'all': + logport_name = self._parent._parent.component_id + '/L/' + self.component_id + logport = self._model.get_logport('name', logport_name) + for interface in self._model.get_interfaces('logport_id', logport.id): + interface.delete() + elif name.startswith('interface-'): + id = name.split('-')[1] + try: + interface = self._model.get_interface('name', self._parent._parent.component_id + '/L/' + self.component_id + '/' + id) + interface.delete() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 3562f7c..7f51a20 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -62,6 +62,27 @@ def do_deletevcc(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_deleteinterface(self, command, *args, context=None): + card = self._model.get_card('name', self._parent._parent.component_id) + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product != 'adsl' and card.product != 'sdsl': + # all or interface_id + name, = self._dissect(args, str) + if name == 'all': + chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + for interface in self._model.get_interfaces('chan_id', chan.id): + interface.delete() + elif name.startswith('interface-'): + id = name.split('-')[1] + try: + interface = self._model.get_interface('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + id) + interface.delete() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def do_createvcc(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent._parent.component_id) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 505f08e..ebe6514 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -62,6 +62,7 @@ def _init_access_points(self, context=None): self.access_points = () port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + #TODO: add interfaces for ftth and special cards for chan in self._model.get_chans('port_id', port.id): identifier = 'chan-' + chan.name.split('/')[-1] if identifier in self.access_points: @@ -71,6 +72,27 @@ def _init_access_points(self, context=None): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + def do_deleteinterface(self, command, *args, context=None): + card = self._model.get_card('name', self._parent.component_id) + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'ftth': + # all or interface_id + name, = self._dissect(args, str) + if name == 'all': + port = self.get_port_component() + for interface in self._model.get_interfaces('port_id', port.id): + interface.delete() + elif name.startswith('interface-'): + id = name.split('-')[1] + try: + interface = self._model.get_interface('name', self._parent.component_id + '/' + self.component_id + '/' + id) + interface.delete() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def get_port_component(self): return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 159651e..a6986a8 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -107,6 +107,9 @@ def get_property(self, command, *args, context=None): def _init_access_points(self, context=None): pass + def do_deleteinterface(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) From 80d5fe4f1dbd5092f0e6cb6367f44716e29ca9b0 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 15 Oct 2020 16:49:24 +0200 Subject: [PATCH 116/318] Added create interface after a chanel, port and logports --- .../login/base/set/interface_success.j2 | 3 + .../logport/port/logportCommandProcessor.py | 34 +++++++++++ .../unit/port/chan/chanCommandProcessor.py | 61 +++++++++++++++++++ .../root/unit/port/portCommandProcessor.py | 33 ++++++++++ .../port/portgroupportCommandProcessor.py | 3 + 5 files changed, 134 insertions(+) create mode 100644 templates/KeyMile/login/base/set/interface_success.j2 diff --git a/templates/KeyMile/login/base/set/interface_success.j2 b/templates/KeyMile/login/base/set/interface_success.j2 new file mode 100644 index 0000000..96bd08d --- /dev/null +++ b/templates/KeyMile/login/base/set/interface_success.j2 @@ -0,0 +1,3 @@ + \ # CreateInterface +interface-{{ context.id }}{{ context.spacer1 }}\ # Interface ID + diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index fce9dc3..16e3827 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -79,6 +79,40 @@ def do_deleteinterface(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_createinterface(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + card = self._model.get_card('name', self._parent._parent.component_id) + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': + # vcc profile and vlan profile + vlan_prof, = self._dissect(args, str) + # TODO: Check if profiles := default or profile names + try: + logport_name = self._parent._parent.component_id + '/L/' + self.component_id + logport = self._model.get_logport('name', logport_name) + id = 1 + for interface in self._model.get_interfaces('logport_id', logport.id): + if interface.logport_id is not None: + new_id = int(interface.name[-1]) + 1 + id = new_id if new_id > id else id + try: + name = self._parent._parent.component_id + '/L/' + self.component_id + '/' + str(id) + _ = self._model.get_interface('name', name) + assert False + except exceptions.SoftboxenError as exe: + vcc = self._model.add_interface(name=name, logport_id=logport.id, vlan_profile=vlan_prof) + context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' + context['id'] = str(id) + # TODO: Template is unknown + text = self._render('interface_success', *scopes, context=context) + self._write(text) + except AssertionError: + raise exceptions.CommandSyntaxError(command=command) + + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 7f51a20..1c4646b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -83,6 +83,67 @@ def do_deleteinterface(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_createinterface(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + card = self._model.get_card('name', self._parent._parent.component_id) + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.board_name.contains('SUV'): + # vcc profile and vlan profile + vlan_prof, = self._dissect(args, str) + # TODO: Check if profiles := default or profile names + try: + chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + id = 1 + for interface in self._model.get_interfaces('chan_id', chan.id): + if interface.chan_id is not None: + new_id = int(interface.name[-1]) + 1 + id = new_id if new_id > id else id + try: + name = self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + str(id) + _ = self._model.get_interface('name', name) + assert False + except exceptions.SoftboxenError as exe: + interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof) + context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' + context['id'] = str(id) + # TODO: Template is unknown + text = self._render('interface_success', *scopes, context=context) + self._write(text) + except AssertionError: + raise exceptions.CommandSyntaxError(command=command) + + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.board_name.contains('SUV'): + # vcc profile and vlan profile + vlan_prof, vcc_prof = self._dissect(args, str, str) + # TODO: Check if profiles := default or profile names + try: + chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + id = 1 + for interface in self._model.get_interfaces('chan_id', chan.id): + if interface.chan_id is not None: + new_id = int(interface.name[-1]) + 1 + id = new_id if new_id > id else id + try: + name = self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + str(id) + _ = self._model.get_interface('name', name) + assert False + except exceptions.SoftboxenError as exe: + interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof, + vcc_profile=vcc_prof) + context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' + context['id'] = str(id) + # TODO: Template is unknown + text = self._render('interface_success', *scopes, context=context) + self._write(text) + except AssertionError: + raise exceptions.CommandSyntaxError(command=command) + + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def do_createvcc(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent._parent.component_id) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index ebe6514..a4a6468 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -93,6 +93,39 @@ def do_deleteinterface(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_createinterface(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + card = self._model.get_card('name', self._parent.component_id) + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.board_name.contains('SUE'): + # vcc profile and vlan profile + vlan_prof, = self._dissect(args, str) + # TODO: Check if profiles := default or profile names + try: + port = self.get_port_component() + id = 1 + for interface in self._model.get_interfaces('port_id', port.id): + if interface.port_id is not None: + new_id = int(interface.name[-1]) + 1 + id = new_id if new_id > id else id + try: + name = self._parent.component_id + '/' + self.component_id + '/' + str(id) + _ = self._model.get_interface('name', name) + assert False + except exceptions.SoftboxenError as exe: + interf = self._model.add_interface(name=name, port_id=port.id, vlan_profile=vlan_prof) + context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' + context['id'] = str(id) + # TODO: Template is unknown + text = self._render('interface_success', *scopes, context=context) + self._write(text) + except AssertionError: + raise exceptions.CommandSyntaxError(command=command) + + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def get_port_component(self): return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index a6986a8..cb73492 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -110,6 +110,9 @@ def _init_access_points(self, context=None): def do_deleteinterface(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + def do_createinterface(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) From 84bb9ab7bad57a6ed8e27e0af7e3fd2a834ce18a Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 16 Oct 2020 13:12:58 +0200 Subject: [PATCH 117/318] Added new (6-in1) 'subpacket'-commandProcessor --- nesi/softbox/api/schemas/box_schemas.py | 8 ++-- .../accessPoints/root/rootCommandProcessor.py | 2 +- ...or.py => macaccessctrlCommandProcessor.py} | 10 ++--- ...py => macaccessctrlManagementFunctions.py} | 0 .../services/subpacketCommandProcessor.py | 27 ++++++++++++ .../services/subpacketManagementFunctions.py | 15 +++++++ vendors/KeyMile/baseCommandProcessor.py | 42 ++++++++++++++++--- 7 files changed, 89 insertions(+), 15 deletions(-) rename vendors/KeyMile/accessPoints/root/services/{macAccessCtrlCommandProcessor.py => macaccessctrlCommandProcessor.py} (85%) rename vendors/KeyMile/accessPoints/root/services/{macAccessCtrlManagementFunctions.py => macaccessctrlManagementFunctions.py} (100%) create mode 100644 vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/services/subpacketManagementFunctions.py diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index 7d13b82..e9e061f 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -31,11 +31,11 @@ class BoxSchema(ma.ModelSchema): class Meta: model = Box fields = ('id', 'vendor', 'model', 'version', 'software_version', 'network_protocol', 'network_address', - 'network_port', 'uuid', 'description', 'interfaces', 'logports', - 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', + 'network_port', 'uuid', 'description', 'interfaces', 'logports', 'ont_ports', 'cpes', + 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', 'mgmt_ports', 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'currTemperature', - 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', - 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'mgmt_cards', 'mgmt_ports', + 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', + 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'mgmt_cards', 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') credentials = ma.Hyperlinks( diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 699d6ca..cacd03f 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -34,7 +34,7 @@ def do_get(self, command, *args, context=None): def _init_access_points(self, context=None): - self.access_points = () + self.access_points = ('eoam', 'fan', 'multicast', 'services', 'tdmConnections') for card in self._model.cards: if 'unit-' + card.name in self.access_points: continue diff --git a/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py similarity index 85% rename from vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py rename to vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py index 42dbfba..a2e56c6 100644 --- a/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py @@ -14,15 +14,15 @@ from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor -class MacAccessCtrlCommandProcessor(BaseCommandProcessor): +class MacaccessctrlCommandProcessor(BaseCommandProcessor): __name__ = 'macAccessCtrl' management_functions = ('main', 'cfgm', 'fm', 'status') access_points = () - from .macAccessCtrlManagementFunctions import main - from .macAccessCtrlManagementFunctions import cfgm - from .macAccessCtrlManagementFunctions import fm - from .macAccessCtrlManagementFunctions import status + from .macaccessctrlManagementFunctions import main + from .macaccessctrlManagementFunctions import cfgm + from .macaccessctrlManagementFunctions import fm + from .macaccessctrlManagementFunctions import status def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/services/macAccessCtrlManagementFunctions.py b/vendors/KeyMile/accessPoints/root/services/macaccessctrlManagementFunctions.py similarity index 100% rename from vendors/KeyMile/accessPoints/root/services/macAccessCtrlManagementFunctions.py rename to vendors/KeyMile/accessPoints/root/services/macaccessctrlManagementFunctions.py diff --git a/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py new file mode 100644 index 0000000..706cc3b --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py @@ -0,0 +1,27 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class SubpacketCommandProcessor(BaseCommandProcessor): + __name__ = 'subpacket' + management_functions = ('main', 'cfgm') + access_points = () + + from .subpacketManagementFunctions import main + from .subpacketManagementFunctions import cfgm + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/services/subpacketManagementFunctions.py b/vendors/KeyMile/accessPoints/root/services/subpacketManagementFunctions.py new file mode 100644 index 0000000..aa446e7 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/subpacketManagementFunctions.py @@ -0,0 +1,15 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } + +cfgm = { + 'Cmd': ( + 'CreateService', + 'DeleteService' + ) + } diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index db62303..1e9088d 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -194,6 +194,9 @@ def do_ls(self, command, *args, context=None): command=command) def change_directory(self, path, context=None): + if re.match("1to1DoubleTag|1to1SingleTag|mcast|nto1|pls|tls", path): + context['ServiceType'] = path + path = 'subpacket' path = path.lower() if path == '/': if self.__name__ != 'root': @@ -205,7 +208,7 @@ def change_directory(self, path, context=None): components = [x for x in path.split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|logports|logport-[0-9]|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|macaccessctrl|tdmconnection|logports|logport-[0-9]|\.|\.\.)$', components[0]): raise exceptions.SoftboxenError() @@ -309,6 +312,10 @@ def change_directory(self, path, context=None): if self.__name__ != 'chan': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'packet' or component_type == 'macAccessCtrl': + if self.__name__ != 'services': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): if self.__name__ != 'root': raise exceptions.CommandExecutionError(command=None, template=None, @@ -343,6 +350,10 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ LogportCommandProcessor from vendors.KeyMile.accessPoints.root.unit.port.chan.vcc.vccCommandProcessor import VccCommandProcessor + from vendors.KeyMile.accessPoints.root.services.packetCommandProcessor import PacketCommandProcessor + from vendors.KeyMile.accessPoints.root.services.macaccessctrlCommandProcessor import \ + MacaccessctrlCommandProcessor + from vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor import SubpacketCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if component_id is not None and self.component_id is not None: @@ -354,7 +365,10 @@ def change_directory(self, path, context=None): if context['component_path'] == '/': new_path = components[0] else: - new_path = '/' + components[0] + if path == 'subpacket': + new_path = '/' + context['ServiceType'] + else: + new_path = '/' + components[0] context['component_path'] += new_path if len(remaining_args) > 0: @@ -398,8 +412,13 @@ def get_parent_and_child_relation(self, search, parent=None, node=None, parent_k "internalports": {"internalport": {}} }, "eoam": {}, - "tdmConnections": {}, - "services": {}, + "tdmconnections": {}, + "services": { + "packet": { + "subpacket": {} + }, + "macaccessctrl": {} + }, "multicast": {} }} for x, y in node.items(): @@ -471,6 +490,9 @@ def do_cd(self, command, *args, context=None): raise exceptions.CommandSyntaxError() elif self._validate(args, str): path = args[0] + if re.match("1to1DoubleTag|1to1SingleTag|mcast|nto1|pls|tls", path): + context['ServiceType'] = path + path = 'subpacket' try: subprocessor = self.change_directory(path, context=context) @@ -508,9 +530,13 @@ def get_command_processor(self, current_processor, component_type=None): from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ LogportCommandProcessor from vendors.KeyMile.accessPoints.root.unit.port.chan.vcc.vccCommandProcessor import VccCommandProcessor + from vendors.KeyMile.accessPoints.root.services.packetCommandProcessor import PacketCommandProcessor + from vendors.KeyMile.accessPoints.root.services.macaccessctrlCommandProcessor import\ + MacaccessctrlCommandProcessor + from vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor import SubpacketCommandProcessor if current_processor.__class__ == RootCommandProcessor: return_to = RootCommandProcessor - if component_type not in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services', 'unit') \ + if component_type not in ('fan', 'eoam', 'tdmconnections', 'multicast', 'services', 'unit') \ and component_type is not None: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty @@ -555,6 +581,12 @@ def get_command_processor(self, current_processor, component_type=None): return_to = LogportsCommandProcessor elif current_processor.__class__ == VccCommandProcessor: return_to = ChanCommandProcessor + elif current_processor.__class__ == PacketCommandProcessor: + return_to = ServicesCommandProcessor + elif current_processor.__class__ == MacaccessctrlCommandProcessor: + return_to = ServicesCommandProcessor + elif current_processor.__class__ == SubpacketCommandProcessor: + return_to = PacketCommandProcessor return return_to From 028593e89b41e8f789a0ec699cbb9ff43fb1f582 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Mon, 19 Oct 2020 08:31:06 +0200 Subject: [PATCH 118/318] small fixes according to create Interfaces --- .../conf/bootstraps/create-keymile-MG2500.sh | 51 +++++++++++++++++-- .../unit/port/chan/chanCommandProcessor.py | 4 +- .../root/unit/port/portCommandProcessor.py | 9 +++- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index af898a8..73f9f84 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -328,6 +328,17 @@ req='{ unit_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_4', + "admin_state": "1", + "operational_state": "1" +}' + +port_4_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + ### Unit-5 ### # Create a physical card at the network device (admin operation) @@ -355,6 +366,27 @@ req='{ unit_5=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_5', + "admin_state": "1", + "operational_state": "1" +}' + +port_5_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Chan-1 ### + +# Create a logical channel at the network device (admin operation) +req='{ + "port_id": '$port_5_1', + "description": "Channel #1" +}' + +chan_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/channels) + ### Unit-6 ### # Create a physical card at the network device (admin operation) @@ -387,19 +419,19 @@ unit_6=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "vdsl", - "board_name": "SUVM6", + "product": "ftth", + "board_name": "SUEN3", "supplier_build_state": "R1K", "board_id": "377", "hardware_key": 14, "software": "suvm6_r3e10_01.esw", - "software_name": "SUVM6", + "software_name": "SUEN3", "software_revision": "R3E10_01", "state": "Ok", "serial_number": "6135149854", "manufacturer_name": "KEYMILE", "model_name": "37900528", - "short_text": "MG SUVM6 VDSL2/17MHz ISDN 48pt", + "short_text": "MG SUEN3 VDSL2/17MHz ISDN 48pt", "manufacturer_id": "100989", "manufacturer_part_number": "09869778", "manufacturer_build_state": "20", @@ -409,6 +441,17 @@ req='{ unit_7=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_7', + "admin_state": "1", + "operational_state": "1" +}' + +port_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + ### Unit-8 ### # Create a physical card at the network device (admin operation) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 1c4646b..67bb191 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -86,7 +86,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.board_name.contains('SUV'): + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name: # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names @@ -113,7 +113,7 @@ def do_createinterface(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.board_name.contains('SUV'): + elif self._validate(args, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name : # vcc profile and vlan profile vlan_prof, vcc_prof = self._dissect(args, str, str) # TODO: Check if profiles := default or profile names diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index a4a6468..59dca98 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -62,13 +62,18 @@ def _init_access_points(self, context=None): self.access_points = () port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) - #TODO: add interfaces for ftth and special cards for chan in self._model.get_chans('port_id', port.id): identifier = 'chan-' + chan.name.split('/')[-1] if identifier in self.access_points: continue self.access_points += (identifier,) + for interface in self._model.get_interfaces('port_id', port.id): + identifier = 'interface-' + interface.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) @@ -96,7 +101,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.board_name.contains('SUE'): + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUE' in card.board_name: # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names From d11d11e56fcca8ce98098ba9746a3daf12fdc8e2 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Mon, 19 Oct 2020 10:35:36 +0200 Subject: [PATCH 119/318] Added Backup functionality --- .../api/schemas/keymile_box_schemas.py | 5 +++-- nesi/keymile/keymile_resources/keymile_box.py | 12 +++++++++++ nesi/softbox/api/models/box_models.py | 6 +++++- .../accessPoints/root/rootCommandProcessor.py | 20 +++++++++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/nesi/keymile/api/schemas/keymile_box_schemas.py b/nesi/keymile/api/schemas/keymile_box_schemas.py index 5458c05..de66bed 100644 --- a/nesi/keymile/api/schemas/keymile_box_schemas.py +++ b/nesi/keymile/api/schemas/keymile_box_schemas.py @@ -14,10 +14,11 @@ from nesi.softbox.api.schemas.box_schemas import * -class KeymileBoxSchema(BoxSchema): +class KeyMileBoxSchema(BoxSchema): class Meta: model = Box - fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature', 'logports') + fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature', 'logports', 'backup_ip', 'login', + 'password', 'backup_path') interfaces = ma.Hyperlinks( {'_links': { diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index d4d5b73..3875921 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -29,6 +29,18 @@ class KeyMileBox(Box): """ currTemperature = base.Field("currTemperature") + backup_ip = base.Field("backup_ip") + login = base.Field("login") + password = base.Field("password") + backup_path = base.Field("backup_path") + + def set_backup(self, backup_ip, login, password): + self.update(backup_ip=backup_ip) + self.update(login=login) + self.update(password=password) + + def set_path(self, path): + self.update(backup_path=path) @property def channels(self): diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 72fbeba..aa91ddd 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -123,4 +123,8 @@ class Box(db.Model): pitp_mode = db.Column(db.String(), default='') dsl_mode = db.Column(db.Enum('tr165', 'tr129'), default='tr165') - currTemperature = db.Column(db.Integer(), default=15) \ No newline at end of file + currTemperature = db.Column(db.Integer(), default=15) + backup_ip = db.Column(db.String(), default='') + login = db.Column(db.String(), default='') + password = db.Column(db.String(), default='') + backup_path = db.Column(db.String(), default='') diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index cacd03f..24ce5a0 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -81,6 +81,26 @@ def do_save(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_ftpserver(self, command, *args, context=None): + if self._validate(args, str, str, str) and context['component_path'].split('/')[-1] != 'cfgm': + ip, login, pw = self._dissect(args, str, str, str) + try: + self._model.set_backup(ip, login, pw) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_upload(self, command, *args, context=None): + if self._validate(args, '/cfgm/configuration', str) and context['component_path'].split('/')[-1] != 'cfgm': + path, = self._dissect(args, '/cfgm/configuration', str) + try: + self._model.set_path(path) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) From 5f7e985be1da081d1aa192ef853f988704491903 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Mon, 19 Oct 2020 12:02:32 +0200 Subject: [PATCH 120/318] Added Loopback tests --- .../conf/bootstraps/create-keymile-MG2500.sh | 11 +++++ .../api/schemas/keymile_port_schemas.py | 2 +- .../keymile/keymile_resources/keymile_port.py | 12 ++++++ nesi/softbox/api/models/port_models.py | 3 +- .../login/base/get/quickloopbacktest.j2 | 3 ++ .../root/unit/port/portCommandProcessor.py | 42 +++++++++++++++++++ .../root/unit/unitCommandProcessor.py | 1 - vendors/KeyMile/baseCommandProcessor.py | 6 +++ 8 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 templates/KeyMile/login/base/get/quickloopbacktest.j2 diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 73f9f84..7819f8b 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -490,6 +490,17 @@ req='{ unit_19=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_19', + "admin_state": "1", + "operational_state": "1" +}' + +port_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + ### PortGroupPort-1 ### # Create a physical port at the network device (admin operation) diff --git a/nesi/keymile/api/schemas/keymile_port_schemas.py b/nesi/keymile/api/schemas/keymile_port_schemas.py index c8a1f07..99356da 100644 --- a/nesi/keymile/api/schemas/keymile_port_schemas.py +++ b/nesi/keymile/api/schemas/keymile_port_schemas.py @@ -16,6 +16,6 @@ class KeyMilePortSchema(PortSchema): class Meta: model = Port - fields = PortSchema.Meta.fields + ('channels', 'label1', 'label2') + fields = PortSchema.Meta.fields + ('channels', 'label1', 'label2', 'loopbacktest_state') channels = ma.Nested(CpesSchema.CpeSchema, many=True) diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py index c90e06f..3c45b71 100644 --- a/nesi/keymile/keymile_resources/keymile_port.py +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -19,12 +19,24 @@ class KeyMilePort(Port): """Represent physical port resource.""" label1 = base.Field('label1') label2 = base.Field('label2') + loopbacktest_state = base.Field('loopbacktest_state') def set_label(self, l1, l2, desc): self.update(label1=l1) self.update(label2=l2) self.update(description=desc) + def set_test_state(self, state): + self.update(loopbacktest_state=state) + + def lock_admin(self): + """Set the admin port state to up""" + self.update(admin_state='2') + + def unlock_admin(self): + """Set the admin port state to down""" + self.update(admin_state='3') + class KeyMilePortCollection(PortCollection): """Represent a collection of ports.""" diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 1705e0c..61bf14f 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -32,7 +32,7 @@ class Port(db.Model): shutdown = db.Column(db.Boolean(), default=False) speed = db.Column(db.Enum('10M', '1G', '10G'), default='1G') operational_state = db.Column(db.Enum('0', '1', '2'), default='0') # Alcatel: 0 => down, 1 => up, 2 => not-appl; Huawei: 0 => deactivated, 1 => activated, 2 => activating - admin_state = db.Column(db.Enum('0', '1', '2'), default='0') # Alcatel: 0 => down, 1 => up, 2 => not-appl; Huawei: 0 => deactivated, 1 => activated, 2 => activating + admin_state = db.Column(db.Enum('0', '1', '2', '3'), default='0') # Alcatel: 0 => down, 1 => up, 2 => not-appl; Huawei: 0 => deactivated, 1 => activated, 2 => activating; KeyMile: 0 => down, 1 => up, 2 => locked, 3 => unlocked upstream = db.Column(db.Integer(), default=0) downstream = db.Column(db.Integer(), default=0) upstream_max = db.Column(db.String(), default="100000") @@ -313,3 +313,4 @@ class Port(db.Model): interfaces = db.relationship('Interface', backref='Port', lazy='dynamic') label1 = db.Column(db.String(), default='""') label2 = db.Column(db.String(), default='""') + loopbacktest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NoTestResult', 'Stopped', 'Interrupted'), default='NoTestResult') diff --git a/templates/KeyMile/login/base/get/quickloopbacktest.j2 b/templates/KeyMile/login/base/get/quickloopbacktest.j2 new file mode 100644 index 0000000..38b4f82 --- /dev/null +++ b/templates/KeyMile/login/base/get/quickloopbacktest.j2 @@ -0,0 +1,3 @@ + \ # QuickLoopbackTest +{{ context.loopbacktest_state }}{{ context.spacer1 }}\ # State + diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 59dca98..726e628 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -12,6 +12,7 @@ from nesi import exceptions from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor +import time class PortCommandProcessor(BaseCommandProcessor): @@ -27,6 +28,7 @@ class PortCommandProcessor(BaseCommandProcessor): def get_property(self, command, *args, context=None): port = self.get_port_component() + card = self._model.get_card('name', self._parent.component_id) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -36,6 +38,12 @@ def get_property(self, command, *args, context=None): elif self._validate((args[0],), 'AttainableRate') and context['component_path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) + elif self._validate((args[0],), 'QuickLoopbackTest') and context['component_path'].split('/')[-1] == 'status'\ + and (card.product == 'isdn' or 'SUI' in card.board_name): + context['spacer1'] = self.create_spacers((67,), (port.loopbacktest_state,))[0] * ' ' + context['loopbacktest_state'] = port.loopbacktest_state + text = self._render('quickloopbacktest', *scopes, context=context) + self._write(text) elif self._validate((args[0],), 'AdministrativeStatus') and context['component_path'].split('/')[-1] == 'main': self.map_states(port, 'port') context['spacer'] = self.create_spacers((67,), (port.admin_state,))[0] * ' ' @@ -74,6 +82,40 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) + def do_lock(self, command, *args, context=None): + card = self._model.get_card('name', self._parent.component_id) + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn': + try: + port = self.get_port_component() + port.lock_admin() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_startquickloopbacktest(self, command, *args, context=None): + card = self._model.get_card('name', self._parent.component_id) + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn': + try: + port = self.get_port_component() + time.sleep(5) + port.set_test_state('Passed') + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_unlock(self, command, *args, context=None): + card = self._model.get_card('name', self._parent.component_id) + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn': + try: + port = self.get_port_component() + port.unlock_admin() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 5826e8e..a12beba 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -60,7 +60,6 @@ def get_property(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'SubscriberList') and context['component_path'].split('/')[-1] == 'status' and \ (card.product == 'isdn' or card.product == 'analog'): text = self._render('subscriberList_top', *scopes, context=context) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 1e9088d..e465c52 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -43,6 +43,12 @@ def map_states(self, object, type): elif object.admin_state == '1': if type == 'port': object.admin_state = 'Up' + elif object.admin_state == '2': + if type == 'port': + object.admin_state = 'Locked' + elif object.admin_state == '3': + if type == 'port': + object.admin_state = 'Unlocked' if object.operational_state == '0': if type == 'port': From 2bb5ccdc6f562ca6b6323b44d04460a9073f2649 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Mon, 19 Oct 2020 13:58:20 +0200 Subject: [PATCH 121/318] Added Service (srvc) buisness object --- .../conf/bootstraps/create-keymile-MG2500.sh | 14 +++- nesi/keymile/keymile_resources/__init__.py | 2 +- nesi/keymile/keymile_resources/keymile_box.py | 33 +++++++--- .../keymile_portgroupport.py | 6 +- .../keymile/keymile_resources/keymile_srvc.py | 35 ++++++++++ .../keymile_resources/keymile_subscriber.py | 6 +- nesi/softbox/api/models/box_models.py | 2 + nesi/softbox/api/models/srvc_models.py | 23 +++++++ nesi/softbox/api/models/subscriber_models.py | 13 ++++ nesi/softbox/api/schemas/box_schemas.py | 6 +- nesi/softbox/api/schemas/srvc_schemas.py | 48 ++++++++++++++ nesi/softbox/api/views/__init__.py | 2 +- nesi/softbox/api/views/srvc_views.py | 53 +++++++++++++++ .../KeyMile/login/base/get/service_mcast.j2 | 6 ++ .../KeyMile/login/base/get/service_nto1.j2 | 16 +++++ .../base/get/service_onetoonedoubletag.j2 | 6 ++ .../base/get/service_onetoonesingletag.j2 | 8 +++ .../KeyMile/login/base/get/service_pls.j2 | 6 ++ .../KeyMile/login/base/get/service_tls.j2 | 6 ++ .../root/services/srvcCommandProcessor.py | 64 +++++++++++++++++++ .../root/services/srvcManagementFunctions.py | 31 +++++++++ .../services/subpacketCommandProcessor.py | 15 +++++ vendors/KeyMile/baseCommandProcessor.py | 22 +++++-- 23 files changed, 401 insertions(+), 22 deletions(-) create mode 100644 nesi/keymile/keymile_resources/keymile_srvc.py create mode 100644 nesi/softbox/api/models/srvc_models.py create mode 100644 nesi/softbox/api/schemas/srvc_schemas.py create mode 100644 nesi/softbox/api/views/srvc_views.py create mode 100644 templates/KeyMile/login/base/get/service_mcast.j2 create mode 100644 templates/KeyMile/login/base/get/service_nto1.j2 create mode 100644 templates/KeyMile/login/base/get/service_onetoonedoubletag.j2 create mode 100644 templates/KeyMile/login/base/get/service_onetoonesingletag.j2 create mode 100644 templates/KeyMile/login/base/get/service_pls.j2 create mode 100644 templates/KeyMile/login/base/get/service_tls.j2 create mode 100644 vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/services/srvcManagementFunctions.py diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 7819f8b..f224350 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -525,4 +525,16 @@ req='{ "type": "ISDN" }' -port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) \ No newline at end of file +port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) + +### Nto1-Service-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "name": "srvc-1", + "service_type": "nto1", + "svid": 123, + "address": "/unit-1/port-1/chan-1/interface-1" +}' + +srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) \ No newline at end of file diff --git a/nesi/keymile/keymile_resources/__init__.py b/nesi/keymile/keymile_resources/__init__.py index e797e60..9e17078 100644 --- a/nesi/keymile/keymile_resources/__init__.py +++ b/nesi/keymile/keymile_resources/__init__.py @@ -1,2 +1,2 @@ __all__ = ["keymile_card", "keymile_port", "keymile_subrack", "keymile_channel", "keymile_interface", - "keymile_subscriber", "keymile_logport", "keymile_portgroupport"] + "keymile_subscriber", "keymile_logport", "keymile_portgroupport", "keymile_srvc"] diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 3875921..2d27406 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -14,7 +14,6 @@ from nesi.keymile.keymile_resources import * - from nesi.softbox.base_resources import credentials, base from nesi.softbox.base_resources.box import BoxCollection, Box, logging @@ -71,13 +70,13 @@ def cards(self): @property def subscribers(self): """Return `SubscriberCollection` object.""" - return keymile_subscriber.KeymileSubscriberCollection( + return keymile_subscriber.KeyMileSubscriberCollection( self._conn, base.get_sub_resource_path_by(self, 'subscribers')) @property def portgroupsports(self): """Return `PortgrouportCollection` object.""" - return keymile_portgroupport.KeymilePortGroupPortCollection( + return keymile_portgroupport.KeyMilePortGroupPortCollection( self._conn, base.get_sub_resource_path_by(self, 'portgrouports')) @property @@ -86,6 +85,12 @@ def logports(self): return keymile_logport.KeyMileLogPortCollection( self._conn, base.get_sub_resource_path_by(self, 'logports')) + @property + def srvcs(self): + """Return `SrvcCollection` object.""" + return keymile_srvc.KeyMileSrvcCollection( + self._conn, base.get_sub_resource_path_by(self, 'srvcs')) + def get_card(self, field, value): """Get specific card object.""" return keymile_card.KeyMileCardCollection( @@ -161,34 +166,46 @@ def add_interface(self, **fields): def get_subscriber(self, field, value): """Get specific subscriber object.""" - return keymile_subscriber.KeymileSubscriberCollection( + return keymile_subscriber.KeyMileSubscriberCollection( self._conn, base.get_sub_resource_path_by(self, 'subscribers'), params={field: value}).find_by_field_value(field, value) def get_subscribers(self, field, value): """Get specific subscribers object.""" - return keymile_subscriber.KeymileSubscriberCollection( + return keymile_subscriber.KeyMileSubscriberCollection( self._conn, base.get_sub_resource_path_by(self, 'subscribers'), params={field: value}) def add_subscriber(self, **fields): """Add new subscriber.""" - return keymile_subscriber.KeymileSubscriber.create( + return keymile_subscriber.KeyMileSubscriber.create( self._conn, os.path.join(self.path, 'subscribers'), **fields) def get_portgroupport(self, field, value): """Get specific portgroupport object.""" - return keymile_portgroupport.KeymilePortGroupPortCollection( + return keymile_portgroupport.KeyMilePortGroupPortCollection( self._conn, base.get_sub_resource_path_by(self, 'portgroupports'), params={field: value}).find_by_field_value(field, value) def get_portgroupports(self, field, value): """Get specific portgroupports object.""" - return keymile_portgroupport.KeymilePortGroupPortCollection( + return keymile_portgroupport.KeyMilePortGroupPortCollection( self._conn, base.get_sub_resource_path_by(self, 'portgroupports'), params={field: value}) + + def get_srvc(self, field, value): + """Get specific srvc object.""" + return keymile_srvc.KeyMileSrvcCollection( + self._conn, base.get_sub_resource_path_by(self, 'srvcs'), + params={field: value}).find_by_field_value(field, value) + + def get_srvcs(self, field, value): + """Get specific srvcs object.""" + return keymile_srvc.KeyMileSrvcCollection( + self._conn, base.get_sub_resource_path_by(self, 'srvcs'), + params={field: value}) class KeyMileBoxCollection(BoxCollection): diff --git a/nesi/keymile/keymile_resources/keymile_portgroupport.py b/nesi/keymile/keymile_resources/keymile_portgroupport.py index b224869..ce52bb6 100644 --- a/nesi/keymile/keymile_resources/keymile_portgroupport.py +++ b/nesi/keymile/keymile_resources/keymile_portgroupport.py @@ -16,7 +16,7 @@ LOG = logging.getLogger(__name__) -class KeymilePortGroupPort(base.Resource): +class KeyMilePortGroupPort(base.Resource): """Represent logical subscriber resource.""" # fields @@ -84,9 +84,9 @@ def set_isdnport(self, enable, registerglobal, regdefault, layer1, sip, proxy, c self.update(isdnba_profile=isdn) -class KeymilePortGroupPortCollection(base.ResourceCollection): +class KeyMilePortGroupPortCollection(base.ResourceCollection): """Represent a collection of logical subscribers.""" @property def _resource_type(self): - return KeymilePortGroupPort + return KeyMilePortGroupPort diff --git a/nesi/keymile/keymile_resources/keymile_srvc.py b/nesi/keymile/keymile_resources/keymile_srvc.py new file mode 100644 index 0000000..fad2756 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_srvc.py @@ -0,0 +1,35 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.service_port import logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class KeyMileSrvc(base.Resource): + """Represent logical srvc resource.""" + + id = base.Field('id') + name = base.Field('name') + service_type = base.Field('service_type') + address = base.Field('address') + svid = base.Field('svid') + + +class KeyMileSrvcCollection(base.ResourceCollection): + """Represent a collection of logical srvcs.""" + + @property + def _resource_type(self): + return KeyMileSrvc diff --git a/nesi/keymile/keymile_resources/keymile_subscriber.py b/nesi/keymile/keymile_resources/keymile_subscriber.py index 086cf2e..6eaefbf 100644 --- a/nesi/keymile/keymile_resources/keymile_subscriber.py +++ b/nesi/keymile/keymile_resources/keymile_subscriber.py @@ -16,7 +16,7 @@ LOG = logging.getLogger(__name__) -class KeymileSubscriber(base.Resource): +class KeyMileSubscriber(base.Resource): """Represent logical subscriber resource.""" # fields @@ -36,9 +36,9 @@ def set(self, field, value): self.update(**mapping) -class KeymileSubscriberCollection(base.ResourceCollection): +class KeyMileSubscriberCollection(base.ResourceCollection): """Represent a collection of logical subscribers.""" @property def _resource_type(self): - return KeymileSubscriber + return KeyMileSubscriber diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index aa91ddd..b411a6b 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -33,6 +33,7 @@ from .portgroupport_models import PortGroupPort from .logport_models import LogPort from .interface_models import Interface +from .srvc_models import Srvc class Box(db.Model): @@ -81,6 +82,7 @@ class Box(db.Model): subscribers = db.relationship('Subscriber', backref='Box', lazy='dynamic') portgroupports = db.relationship('PortGroupPort', backref='Box', lazy='dynamic') logports = db.relationship('LogPort', backref='Box', lazy='dynamic') + srvcs = db.relationship('Srvc', backref='Box', lazy='dynamic') board_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_instl_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_init_reporting_logging = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/models/srvc_models.py b/nesi/softbox/api/models/srvc_models.py new file mode 100644 index 0000000..6452ac2 --- /dev/null +++ b/nesi/softbox/api/models/srvc_models.py @@ -0,0 +1,23 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst +import uuid +from nesi.softbox.api import db + + +class Srvc(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + service_type = db.Column(db.Enum('1to1DoubleTag', '1to1SingleTag', 'mcast', 'nto1', 'pls', 'tls', ''), default='') + address = db.Column(db.String(), default='') + svid = db.Column(db.Integer(), default=None) diff --git a/nesi/softbox/api/models/subscriber_models.py b/nesi/softbox/api/models/subscriber_models.py index a94baff..ec22ecf 100644 --- a/nesi/softbox/api/models/subscriber_models.py +++ b/nesi/softbox/api/models/subscriber_models.py @@ -1,3 +1,16 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + from nesi.softbox.api import db diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index e9e061f..7aa238e 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -31,7 +31,7 @@ class BoxSchema(ma.ModelSchema): class Meta: model = Box fields = ('id', 'vendor', 'model', 'version', 'software_version', 'network_protocol', 'network_address', - 'network_port', 'uuid', 'description', 'interfaces', 'logports', 'ont_ports', 'cpes', + 'network_port', 'uuid', 'description', 'interfaces', 'logports', 'ont_ports', 'cpes', 'srvcs', 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', 'mgmt_ports', 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'currTemperature', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', @@ -98,6 +98,10 @@ class Meta: {'_links': { 'self': ma.URLFor('show_logports', box_id='')}}) + srvcs = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_srvcs', box_id='')}}) + onts = ma.Hyperlinks({'_links': { 'self': ma.URLFor('show_onts', box_id='')}}) diff --git a/nesi/softbox/api/schemas/srvc_schemas.py b/nesi/softbox/api/schemas/srvc_schemas.py new file mode 100644 index 0000000..f1bba10 --- /dev/null +++ b/nesi/softbox/api/schemas/srvc_schemas.py @@ -0,0 +1,48 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.srvc_models import Srvc + + +class SrvcSchema(ma.ModelSchema): + class Meta: + model = Srvc + fields = ('id', 'box', 'box_id', 'name', 'service_type', 'address', 'svid', '_links') + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_srvc', box_id='', id=''), + 'collection': ma.URLFor('show_srvcs', box_id='')}) + + +class SrvcsSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class SrvcSchema(ma.ModelSchema): + class Meta: + model = Srvc + fields = ('id', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_srvc', box_id='', id='')}) + + members = ma.Nested(SrvcSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_srvcs', box_id='')}) diff --git a/nesi/softbox/api/views/__init__.py b/nesi/softbox/api/views/__init__.py index 340544e..e87d03d 100644 --- a/nesi/softbox/api/views/__init__.py +++ b/nesi/softbox/api/views/__init__.py @@ -1,5 +1,5 @@ __all__ = ["box_views", "credential_views", "route_views", "subrack_views", "card_views", "port_views", "ont_views", "ontport_views", "cpe_views", "cpeport_views", "vlan_views", "portprofile_views", "emu_views", - "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", + "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", "srvc_views", "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views", "mgmt_card_views", "mgmt_port_views", "subscriber_views", "portgroupport_views", "logport_views"] diff --git a/nesi/softbox/api/views/srvc_views.py b/nesi/softbox/api/views/srvc_views.py new file mode 100644 index 0000000..263a2b9 --- /dev/null +++ b/nesi/softbox/api/views/srvc_views.py @@ -0,0 +1,53 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from ..schemas.srvc_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//srvcs', methods=['GET']) +def show_srvcs(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(SrvcsSchema(), Srvc, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//srvcs/', methods=['GET']) +def show_srvc(box_id, id): + response = show_component(Srvc, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//srvcs/', methods=['PUT']) +def update_srvc(box_id, id): + req = flask.request.json + update_component(Srvc, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//srvcs', methods=['POST']) +def new_srvc(box_id): + req = flask.request.json + response = new_component(SrvcSchema(), Srvc, req, box_id) + return response, 201 + +@app.route(PREFIX + '/boxen//srvcs/', methods=['DELETE']) +def del_srvc(box_id, id): + del_component(Srvc, box_id, id) + return flask.Response(status=204) diff --git a/templates/KeyMile/login/base/get/service_mcast.j2 b/templates/KeyMile/login/base/get/service_mcast.j2 new file mode 100644 index 0000000..bcbaf3b --- /dev/null +++ b/templates/KeyMile/login/base/get/service_mcast.j2 @@ -0,0 +1,6 @@ + \ # MCastAccessService + \ # Interface +{{ context.service.address }}{{ context.spacer1 }}\ # Address + \ # Specific +{{ context.service.svid }}{{ context.spacer2 }}\ # Svid + diff --git a/templates/KeyMile/login/base/get/service_nto1.j2 b/templates/KeyMile/login/base/get/service_nto1.j2 new file mode 100644 index 0000000..edb2127 --- /dev/null +++ b/templates/KeyMile/login/base/get/service_nto1.j2 @@ -0,0 +1,16 @@ + \ # Nto1AccessService + \ # Interface +{{ context.service.address }}{{ context.spacer1 }}\ # Address + \ # Specific +{{ context.service.svid }}{{ context.spacer2 }}\ # Svid +CoS0 \ # STagPriority +PPPoE \ # LogonMethod +Add \ # VLANHandling +false \ # SourceFilter +false \ # DestinationFilter +false \ # SourceIPFilter +false \ # DynamicARPInspection +false \ # MacForcedForwarding +Assigned \ # PriorityHandling +default \ # CoSProfile + diff --git a/templates/KeyMile/login/base/get/service_onetoonedoubletag.j2 b/templates/KeyMile/login/base/get/service_onetoonedoubletag.j2 new file mode 100644 index 0000000..60476ca --- /dev/null +++ b/templates/KeyMile/login/base/get/service_onetoonedoubletag.j2 @@ -0,0 +1,6 @@ + \ # OnetoOneDoubleTagAccessService + \ # Interface +{{ context.service.address }}{{ context.spacer1 }}\ # Address + \ # Specific +{{ context.service.svid }}{{ context.spacer2 }}\ # Svid + diff --git a/templates/KeyMile/login/base/get/service_onetoonesingletag.j2 b/templates/KeyMile/login/base/get/service_onetoonesingletag.j2 new file mode 100644 index 0000000..be29c7c --- /dev/null +++ b/templates/KeyMile/login/base/get/service_onetoonesingletag.j2 @@ -0,0 +1,8 @@ + \ # OnetoOneSingleTagAccessService + \ # Interface +{{ context.service.address }}{{ context.spacer1 }}\ # Address + \ # Specific +{{ context.service.svid }}{{ context.spacer2 }}\ # Svid +CoS0 \ # STagPriority +Add \ # VLANHandling + diff --git a/templates/KeyMile/login/base/get/service_pls.j2 b/templates/KeyMile/login/base/get/service_pls.j2 new file mode 100644 index 0000000..d0f3789 --- /dev/null +++ b/templates/KeyMile/login/base/get/service_pls.j2 @@ -0,0 +1,6 @@ + \ # PLSAccessService + \ # Interface +{{ context.service.address }}{{ context.spacer1 }}\ # Address + \ # Specific +{{ context.service.svid }}{{ context.spacer2 }}\ # Svid + diff --git a/templates/KeyMile/login/base/get/service_tls.j2 b/templates/KeyMile/login/base/get/service_tls.j2 new file mode 100644 index 0000000..9c22053 --- /dev/null +++ b/templates/KeyMile/login/base/get/service_tls.j2 @@ -0,0 +1,6 @@ + \ # TLSAccessService + \ # Interface +{{ context.service.address }}{{ context.spacer1 }}\ # Address + \ # Specific +{{ context.service.svid }}{{ context.spacer2 }}\ # Svid + diff --git a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py new file mode 100644 index 0000000..edd2132 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py @@ -0,0 +1,64 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class SrvcCommandProcessor(BaseCommandProcessor): + __name__ = 'srvc' + management_functions = ('main', 'cfgm', 'status') + access_points = () + + from .srvcManagementFunctions import main + from .srvcManagementFunctions import cfgm + from .srvcManagementFunctions import status + + def get_property(self, command, *args, context=None): + service_name = 'srvc-' + self.component_id + services = self._model.get_srvcs('name', service_name) + for s in services: + if s.service_type == context['ServiceType']: + service = s + context['service'] = service + break + scopes = ('login', 'base', 'get') + try: + super().get_property(command, *args, context=context) + except exceptions.CommandExecutionError: + if self._validate((args[0],), 'Service') and context['component_path'].split('/')[-1] == 'cfgm': + if service.service_type == '1to1DoubleTag': + template_name = 'service_onetoonedoubletag' + elif service.service_type == '1to1SingleTag': + template_name = 'service_onetoonesingletag' + elif service.service_type == 'mcast': + template_name = 'service_mcast' + elif service.service_type == 'nto1': + template_name = 'service_nto1' + elif service.service_type == 'pls': + template_name = 'service_pls' + elif service.service_type == 'tls': + template_name = 'service_tls' + else: + raise exceptions.CommandExecutionError(command=command) + context['spacer1'] = self.create_spacers((67,), (service.address,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (service.svid,))[0] * ' ' + text = self._render(template_name, *scopes, context=context) + self._write(text) + + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/services/srvcManagementFunctions.py b/vendors/KeyMile/accessPoints/root/services/srvcManagementFunctions.py new file mode 100644 index 0000000..be32883 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/srvcManagementFunctions.py @@ -0,0 +1,31 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminOperStatus': { + 'Prop': { + 'AdminState': 'rw', + 'OperState': 'r-' + } + } + } + +cfgm = { + 'Nto1AccessService': { + 'Prop': { + 'Service': 'rw' + } + } + } + +status = { + 'mgmt': { + 'Prop': { + 'maList': 'r-', + 'mepList': 'r-' + } + } + } diff --git a/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py index 706cc3b..27d0c7c 100644 --- a/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py @@ -23,5 +23,20 @@ class SubpacketCommandProcessor(BaseCommandProcessor): from .subpacketManagementFunctions import main from .subpacketManagementFunctions import cfgm + def _init_access_points(self, context=None): + self.access_points = () + try: + self.management_functions = ('main', 'cfgm') + s_type = context['ServiceType'] + + srvcs = self._model.get_srvcs('service_type', s_type) + for srvc in srvcs: + identifier = srvc.name + if identifier in self.access_points: + continue + self.access_points += (identifier,) + except exceptions.InvalidInputError: + pass + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index e465c52..5a46f19 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -214,7 +214,7 @@ def change_directory(self, path, context=None): components = [x for x in path.split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|macaccessctrl|tdmconnection|logports|logport-[0-9]|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|srvc-[0-9]|macaccessctrl|tdmconnection|logports|logport-[0-9]|\.|\.\.)$', components[0]): raise exceptions.SoftboxenError() @@ -307,7 +307,7 @@ def change_directory(self, path, context=None): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'interface': - if self.__name__ != 'port' and self.__name__ != 'chan': + if self.__name__ != 'port' and self.__name__ != 'chan' and self.__name__ != 'logport': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'logport': @@ -322,6 +322,14 @@ def change_directory(self, path, context=None): if self.__name__ != 'services': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'subpacket': + if self.__name__ != 'packet': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'srvc': + if self.__name__ != 'subpacket': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): if self.__name__ != 'root': raise exceptions.CommandExecutionError(command=None, template=None, @@ -360,6 +368,7 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.services.macaccessctrlCommandProcessor import \ MacaccessctrlCommandProcessor from vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor import SubpacketCommandProcessor + from vendors.KeyMile.accessPoints.root.services.srvcCommandProcessor import SrvcCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if component_id is not None and self.component_id is not None: @@ -401,7 +410,7 @@ def get_parent_and_child_relation(self, search, parent=None, node=None, parent_k "control": {}, "media": {}, "port": { - "chanel": { + "channel": { "interfaces": { "hell": {} } @@ -421,7 +430,9 @@ def get_parent_and_child_relation(self, search, parent=None, node=None, parent_k "tdmconnections": {}, "services": { "packet": { - "subpacket": {} + "subpacket": { + "srvc": {} + } }, "macaccessctrl": {} }, @@ -540,6 +551,7 @@ def get_command_processor(self, current_processor, component_type=None): from vendors.KeyMile.accessPoints.root.services.macaccessctrlCommandProcessor import\ MacaccessctrlCommandProcessor from vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor import SubpacketCommandProcessor + from vendors.KeyMile.accessPoints.root.services.srvcCommandProcessor import SrvcCommandProcessor if current_processor.__class__ == RootCommandProcessor: return_to = RootCommandProcessor if component_type not in ('fan', 'eoam', 'tdmconnections', 'multicast', 'services', 'unit') \ @@ -593,6 +605,8 @@ def get_command_processor(self, current_processor, component_type=None): return_to = ServicesCommandProcessor elif current_processor.__class__ == SubpacketCommandProcessor: return_to = PacketCommandProcessor + elif current_processor.__class__ == SrvcCommandProcessor: + return_to = SubpacketCommandProcessor return return_to From 8eec3813d8d09c0292c24e1ebc9541a4ea5ac51f Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Mon, 19 Oct 2020 14:07:01 +0200 Subject: [PATCH 122/318] Added Melt and Line tests --- .../api/schemas/keymile_port_schemas.py | 3 +- .../keymile/keymile_resources/keymile_port.py | 8 +++ nesi/softbox/api/models/port_models.py | 2 + .../KeyMile/login/base/get/line__results.j2 | 13 +++++ .../KeyMile/login/base/get/melt_results.j2 | 13 +++++ .../root/unit/port/portCommandProcessor.py | 52 +++++++++++++++++-- 6 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 templates/KeyMile/login/base/get/line__results.j2 create mode 100644 templates/KeyMile/login/base/get/melt_results.j2 diff --git a/nesi/keymile/api/schemas/keymile_port_schemas.py b/nesi/keymile/api/schemas/keymile_port_schemas.py index 99356da..fba20f5 100644 --- a/nesi/keymile/api/schemas/keymile_port_schemas.py +++ b/nesi/keymile/api/schemas/keymile_port_schemas.py @@ -16,6 +16,7 @@ class KeyMilePortSchema(PortSchema): class Meta: model = Port - fields = PortSchema.Meta.fields + ('channels', 'label1', 'label2', 'loopbacktest_state') + fields = PortSchema.Meta.fields + ('channels', 'label1', 'label2', 'loopbacktest_state', 'melttest_state', + 'linetest_state') channels = ma.Nested(CpesSchema.CpeSchema, many=True) diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py index 3c45b71..80865e8 100644 --- a/nesi/keymile/keymile_resources/keymile_port.py +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -20,6 +20,8 @@ class KeyMilePort(Port): label1 = base.Field('label1') label2 = base.Field('label2') loopbacktest_state = base.Field('loopbacktest_state') + melttest_state = base.Field('melttest_state') + linetest_state = base.Field('linetest_state') def set_label(self, l1, l2, desc): self.update(label1=l1) @@ -37,6 +39,12 @@ def unlock_admin(self): """Set the admin port state to down""" self.update(admin_state='3') + def set_melttest_state(self, state): + self.update(melttest_state=state) + + def set_linetest_state(self, state): + self.update(linetest_state=state) + class KeyMilePortCollection(PortCollection): """Represent a collection of ports.""" diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 61bf14f..7f99aab 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -314,3 +314,5 @@ class Port(db.Model): label1 = db.Column(db.String(), default='""') label2 = db.Column(db.String(), default='""') loopbacktest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NoTestResult', 'Stopped', 'Interrupted'), default='NoTestResult') + melttest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NotTested'), default='NotTested') + linetest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NotTested'), default='NotTested') diff --git a/templates/KeyMile/login/base/get/line__results.j2 b/templates/KeyMile/login/base/get/line__results.j2 new file mode 100644 index 0000000..a8b7151 --- /dev/null +++ b/templates/KeyMile/login/base/get/line__results.j2 @@ -0,0 +1,13 @@ +TimeStamp 2010-09-21T10:36:11 +State {{ context.test_state }} +Results + | TestDescription | Status | MeasuredValue +---+--------------------------+-----------+--------------- + 0 | Foreign DC Voltage a-b | Ok | -30 mV + 1 | Foreign DC Voltage a-GND | Ok | -162 mV + 2 | Foreign DC Voltage b-GND | Ok | -133 mV + 3 | Foreign AC Voltage a-b | Ok | 11 mV + 4 | Foreign AC Voltage a-GND | Ok | 12 mV + 5 | Foreign AC Voltage b-GND | Ok | 11 mV + 6 | Resistance a-b | Ok | 10000.000 kOhm + diff --git a/templates/KeyMile/login/base/get/melt_results.j2 b/templates/KeyMile/login/base/get/melt_results.j2 new file mode 100644 index 0000000..a8b7151 --- /dev/null +++ b/templates/KeyMile/login/base/get/melt_results.j2 @@ -0,0 +1,13 @@ +TimeStamp 2010-09-21T10:36:11 +State {{ context.test_state }} +Results + | TestDescription | Status | MeasuredValue +---+--------------------------+-----------+--------------- + 0 | Foreign DC Voltage a-b | Ok | -30 mV + 1 | Foreign DC Voltage a-GND | Ok | -162 mV + 2 | Foreign DC Voltage b-GND | Ok | -133 mV + 3 | Foreign AC Voltage a-b | Ok | 11 mV + 4 | Foreign AC Voltage a-GND | Ok | 12 mV + 5 | Foreign AC Voltage b-GND | Ok | 11 mV + 6 | Resistance a-b | Ok | 10000.000 kOhm + diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 726e628..cf02d77 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -39,11 +39,23 @@ def get_property(self, command, *args, context=None): text = self._render('attainable_rate', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'QuickLoopbackTest') and context['component_path'].split('/')[-1] == 'status'\ - and (card.product == 'isdn' or 'SUI' in card.board_name): + and (card.product == 'isdn' or 'SUI' in card.board_name) and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.loopbacktest_state,))[0] * ' ' context['loopbacktest_state'] = port.loopbacktest_state text = self._render('quickloopbacktest', *scopes, context=context) self._write(text) + elif self._validate((args[0],), 'LineTestResults') and context['component_path'].split('/')[-1] == 'status'\ + and 'SUP' in card.board_name and self.__name__ == 'port': + context['spacer1'] = self.create_spacers((67,), (port.linetest_state,))[0] * ' ' + context['test_state'] = port.linetest_state + text = self._render('line_results', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'MeltResults') and context['component_path'].split('/')[-1] == 'status'\ + and card.product != 'isdn' and self.__name__ == 'port': + context['spacer1'] = self.create_spacers((67,), (port.melttest_state,))[0] * ' ' + context['test_state'] = port.melttest_state + text = self._render('melt_results', *scopes, context=context) + self._write(text) elif self._validate((args[0],), 'AdministrativeStatus') and context['component_path'].split('/')[-1] == 'main': self.map_states(port, 'port') context['spacer'] = self.create_spacers((67,), (port.admin_state,))[0] * ' ' @@ -84,7 +96,8 @@ def _init_access_points(self, context=None): def do_lock(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn': + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn' \ + and self.__name__ == 'port': try: port = self.get_port_component() port.lock_admin() @@ -95,9 +108,11 @@ def do_lock(self, command, *args, context=None): def do_startquickloopbacktest(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn': + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn' \ + and self.__name__ == 'port': try: port = self.get_port_component() + port.set_test_state('Running') time.sleep(5) port.set_test_state('Passed') except exceptions.SoftboxenError: @@ -105,9 +120,38 @@ def do_startquickloopbacktest(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_startlinetest(self, command, *args, context=None): + card = self._model.get_card('name', self._parent.component_id) + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and 'SUP' in card.board_name \ + and self.__name__ == 'port': + try: + port = self.get_port_component() + port.set_test_state('Running') + time.sleep(5) + port.set_linetest_state('Passed') + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_startmeltmeasurement(self, command, *args, context=None): + card = self._model.get_card('name', self._parent.component_id) + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product != 'isdn' \ + and self.__name__ == 'port': + try: + port = self.get_port_component() + port.set_melttest_state('Running') + time.sleep(5) + port.set_melttest_state('Passed') + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def do_unlock(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn': + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn' \ + and self.__name__ == 'port': try: port = self.get_port_component() port.unlock_admin() From 29806c9f4516f8fa87eaf21428591e3e36d13778 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 19 Oct 2020 14:57:35 +0200 Subject: [PATCH 123/318] Fixed a bug where cd'ing up from an management function resulted in the path being broken --- vendors/KeyMile/baseCommandProcessor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 5a46f19..7ce2615 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -247,7 +247,8 @@ def change_directory(self, path, context=None): if exit_component in ('main', 'cfgm', 'fm', 'pm', 'status'): self.set_prompt_end_pos(context=context) if path != '..': - return self._parent.change_directory(path[3:], context=context) + context['path'] = context['component_path'] + return self.change_directory(path[3:], context=context) return self if path == '..': From ba54af75d6f2733aacd8fcc447aac4a1692225a6 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 19 Oct 2020 15:19:55 +0200 Subject: [PATCH 124/318] Fixed broken navigation to tdmConnections --- ...mandProcessor.py => tdmconnectionsCommandProcessor.py} | 6 +++--- ...tFunctions.py => tdmconnectionsManagementFunctions.py} | 0 vendors/KeyMile/baseCommandProcessor.py | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) rename vendors/KeyMile/accessPoints/root/{tdmConnectionsCommandProcessor.py => tdmconnectionsCommandProcessor.py} (87%) rename vendors/KeyMile/accessPoints/root/{tdmConnectionsManagementFunctions.py => tdmconnectionsManagementFunctions.py} (100%) diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py similarity index 87% rename from vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py rename to vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py index 15fe3fd..a50788a 100644 --- a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py @@ -14,13 +14,13 @@ from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor -class TdmConnectionsCommandProcessor(BaseCommandProcessor): +class TdmconnectionsCommandProcessor(BaseCommandProcessor): __name__ = 'tdmConnections' management_functions = ('main', 'cfgm') access_points = () - from .tdmConnectionsManagementFunctions import main - from .tdmConnectionsManagementFunctions import cfgm + from .tdmconnectionsManagementFunctions import main + from .tdmconnectionsManagementFunctions import cfgm def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsManagementFunctions.py b/vendors/KeyMile/accessPoints/root/tdmconnectionsManagementFunctions.py similarity index 100% rename from vendors/KeyMile/accessPoints/root/tdmConnectionsManagementFunctions.py rename to vendors/KeyMile/accessPoints/root/tdmconnectionsManagementFunctions.py diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 7ce2615..93ab5cd 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -214,7 +214,7 @@ def change_directory(self, path, context=None): components = [x for x in path.split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|srvc-[0-9]|macaccessctrl|tdmconnection|logports|logport-[0-9]|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|srvc-[0-9]|macaccessctrl|tdmconnections|logports|logport-[0-9]|\.|\.\.)$', components[0]): raise exceptions.SoftboxenError() @@ -355,7 +355,7 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor import AlarmCommandProcessor from vendors.KeyMile.accessPoints.root.eoamCommandProcessor import EoamCommandProcessor from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor - from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor + from vendors.KeyMile.accessPoints.root.tdmconnectionsCommandProcessor import TdmconnectionsCommandProcessor from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import \ PortgroupCommandProcessor @@ -538,7 +538,7 @@ def get_command_processor(self, current_processor, component_type=None): from vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor import AlarmCommandProcessor from vendors.KeyMile.accessPoints.root.eoamCommandProcessor import EoamCommandProcessor from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor - from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor + from vendors.KeyMile.accessPoints.root.tdmconnectionsCommandProcessor import TdmconnectionsCommandProcessor from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import \ PortgroupCommandProcessor @@ -586,7 +586,7 @@ def get_command_processor(self, current_processor, component_type=None): return_to = RootCommandProcessor elif current_processor.__class__ == MulticastCommandProcessor: return_to = RootCommandProcessor - elif current_processor.__class__ == TdmConnectionsCommandProcessor: + elif current_processor.__class__ == TdmconnectionsCommandProcessor: return_to = RootCommandProcessor elif current_processor.__class__ == ServicesCommandProcessor: return_to = RootCommandProcessor From 4f0ed17361bc3bddd74f04391d404b6cf4abb4c9 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Mon, 19 Oct 2020 15:47:42 +0200 Subject: [PATCH 125/318] Added set and get channel profile --- .../api/schemas/keymile_channel_schemas.py | 2 +- .../keymile_resources/keymile_channel.py | 4 ++ nesi/softbox/api/models/channel_models.py | 1 + .../KeyMile/login/base/get/chan_profile.j2 | 2 +- .../unit/port/chan/chanCommandProcessor.py | 37 ++++++++++++++++--- 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/nesi/keymile/api/schemas/keymile_channel_schemas.py b/nesi/keymile/api/schemas/keymile_channel_schemas.py index 9808e4b..8d4555b 100644 --- a/nesi/keymile/api/schemas/keymile_channel_schemas.py +++ b/nesi/keymile/api/schemas/keymile_channel_schemas.py @@ -16,4 +16,4 @@ class KeyMileChannelSchema(ChannelSchema): class Meta: model = Channel - fields = ChannelSchema.Meta.fields + ('vccs', 'interfaces') + fields = ChannelSchema.Meta.fields + ('vccs', 'interfaces', 'chan_profile_name') diff --git a/nesi/keymile/keymile_resources/keymile_channel.py b/nesi/keymile/keymile_resources/keymile_channel.py index 18e4a80..1fc9462 100644 --- a/nesi/keymile/keymile_resources/keymile_channel.py +++ b/nesi/keymile/keymile_resources/keymile_channel.py @@ -24,6 +24,10 @@ class KeyMileChannel(base.Resource): port_id = base.Field('port_id') name = base.Field('name') description = base.Field('description') + chan_profile_name = base.Field('chan_profile_name') + + def set_profile_name(self, name): + self.update(chan_profile_name=name) class KeyMileChannelCollection(base.ResourceCollection): diff --git a/nesi/softbox/api/models/channel_models.py b/nesi/softbox/api/models/channel_models.py index 4837c8f..4c3cc18 100644 --- a/nesi/softbox/api/models/channel_models.py +++ b/nesi/softbox/api/models/channel_models.py @@ -18,6 +18,7 @@ class Channel(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) description = db.Column(db.String()) + chan_profile_name = db.Column(db.String(), default='') box_id = db.Column(db.Integer, db.ForeignKey('box.id')) port_id = db.Column(db.Integer, db.ForeignKey('port.id')) interfaces = db.relationship('Interface', backref='Channel', lazy='dynamic') diff --git a/templates/KeyMile/login/base/get/chan_profile.j2 b/templates/KeyMile/login/base/get/chan_profile.j2 index 7691f6d..c60d36c 100644 --- a/templates/KeyMile/login/base/get/chan_profile.j2 +++ b/templates/KeyMile/login/base/get/chan_profile.j2 @@ -1,3 +1,3 @@ \ # ChannelProfile -{{ context.port_profile.name }}{{ context.spacer }}\ # Name +{{ context.profile_name }}{{ context.spacer1 }}\ # Name diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 67bb191..220b516 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -167,7 +167,7 @@ def do_createvcc(self, command, *args, context=None): vlan_profile=vlan_prof) context['spacer1'] = self.create_spacers((63,), (str(id),))[0] * ' ' context['id'] = str(id) - # TODO: Template is unknown + # TODO: unknown Template text = self._render('vcc_success', *scopes, context=context) self._write(text) except AssertionError: @@ -182,26 +182,51 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def set(self, command, *args, context=None): + card = self._model.get_card('name', self._parent._parent.component_id) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return + elif self._validate(args, 'chanprofile', str) and 'SUV' in card.board_name: + name, = self._dissect(args, 'chanprofile', str) + try: + #TODO: Check if profile with this name exists or default + channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + channel.set_profile_name(name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args, 'ProfileName', str) and 'SUV' not in card.board_name: + name, = self._dissect(args, 'ProfileName', str) + try: + # TODO: Check if profile with this name exists or default + channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + channel.set_profile_name(name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) else: raise exceptions.CommandSyntaxError(command=command) def get_property(self, command, *args, context=None): - #card = self._model.get_card('name', self.component_id) + card = self._model.get_card('name', self._parent._parent.component_id) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'Chanprofile') and 'SUV' in card.board_name: + channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + context['spacer1'] = self.create_spacers((67,), (channel.chan_profile_name,))[0] * ' ' + context['profile_name'] = channel.chan_profile_name + text = self._render('chan_profile', *scopes, context=context) + self._write(text) + elif self._validate(args, 'ProfileName') and 'SUV' not in card.board_name: + channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + context['spacer1'] = self.create_spacers((67,), (channel.chan_profile_name,))[0] * ' ' + context['profile_name'] = channel.chan_profile_name + text = self._render('chan_profile', *scopes, context=context) + self._write(text) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) From 4c0068da5f45fa9bc0cc78b815c7d7a68a74d344 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 20 Oct 2020 08:44:16 +0200 Subject: [PATCH 126/318] Fixed navigation for packet accessPoints --- .../root/services/servicesCommandProcessor.py | 2 +- vendors/KeyMile/baseCommandProcessor.py | 65 ++++++++++++------- 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py index 47ca719..0604db8 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -17,7 +17,7 @@ class ServicesCommandProcessor(BaseCommandProcessor): __name__ = 'services' management_functions = ('main', 'fm', 'status') - access_points = ('packet', 'macAccessCtrl') + access_points = ('macAccessCtrl', 'packet') from .servicesManagementFunctions import main from .servicesManagementFunctions import fm diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 93ab5cd..6fe36b9 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -200,9 +200,6 @@ def do_ls(self, command, *args, context=None): command=command) def change_directory(self, path, context=None): - if re.match("1to1DoubleTag|1to1SingleTag|mcast|nto1|pls|tls", path): - context['ServiceType'] = path - path = 'subpacket' path = path.lower() if path == '/': if self.__name__ != 'root': @@ -214,9 +211,11 @@ def change_directory(self, path, context=None): components = [x for x in path.split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|srvc-[0-9]|macaccessctrl|tdmconnections|logports|logport-[0-9]|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|srvc-[0-9]|macaccessctrl|tdmconnections|logports|logport-[0-9]|1to1doubletag|1to1singletag|mcast|nto1|pls|tls|\.|\.\.)$', components[0]): - raise exceptions.SoftboxenError() + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) if path == '.': return self @@ -280,7 +279,17 @@ def change_directory(self, path, context=None): command_processor = component_type.capitalize() + 'CommandProcessor' else: - command_processor = components[0].capitalize() + 'CommandProcessor' + if components[0] in ('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'): + if context['path'].split('/')[-1] in ( + '1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'): + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + + context['ServiceType'] = components[0] + + command_processor = 'SubpacketCommandProcessor' + else: + command_processor = components[0].capitalize() + 'CommandProcessor' if component_type == 'unit': if (self._model.version == '2200' and not 9 <= int(component_id) <= 12) or (self._model.version == '2300' and not 7 <= int(component_id) <= 14) or (self._model.version == '2500' and not 1 <= int(component_id) <= 21): @@ -319,26 +328,40 @@ def change_directory(self, path, context=None): if self.__name__ != 'chan': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'packet' or component_type == 'macAccessCtrl': + + elif components[0] in ('packet', 'macAccessCtrl'): if self.__name__ != 'services': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'subpacket': - if self.__name__ != 'packet': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'srvc': - if self.__name__ != 'subpacket': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): if self.__name__ != 'root': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + if components[0] in ('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'): + if self.__name__ != 'packet': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty if components[0] in ('main', 'cfgm', 'fm', 'pm', 'status'): - if re.search('(main|cfgm|fm|pm|status)', context['path']): - return self + if context['path'].split('/')[-1] in ('main', 'cfgm', 'fm', 'pm', 'status'): + raise exceptions.CommandExecutionError(command=None, template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors')) + + mf_layers = {} + if components[0] == 'status': + mf_layers = self.status + elif components[0] == 'cfgm': + mf_layers = self.cfgm + elif components[0] == 'fm': + mf_layers = self.fm + elif components[0] == 'pm': + mf_layers = self.pm + elif components[0] == 'main': + mf_layers = self.main + + if len(mf_layers) == 0: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if context['component_path'] == '/': new_path = components[0] else: @@ -508,18 +531,12 @@ def do_cd(self, command, *args, context=None): raise exceptions.CommandSyntaxError() elif self._validate(args, str): path = args[0] - if re.match("1to1DoubleTag|1to1SingleTag|mcast|nto1|pls|tls", path): - context['ServiceType'] = path - path = 'subpacket' - try: subprocessor = self.change_directory(path, context=context) return_to = self.get_command_processor(subprocessor) except: context['component_path'] = context['path'] - raise exceptions.CommandExecutionError(template='invalid_management_function_error', - template_scopes=('login', 'base', 'execution_errors'), - command=None) + raise context['path'] = context['component_path'] subprocessor.loop(context=context, return_to=return_to) else: From 00525d922a18504b572430f71a7462f37dbeb8ff Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 20 Oct 2020 09:18:11 +0200 Subject: [PATCH 127/318] Added set and get port profile --- .../api/schemas/keymile_port_schemas.py | 5 +- .../keymile/keymile_resources/keymile_port.py | 30 +++++++++ nesi/softbox/api/models/port_models.py | 13 ++++ .../KeyMile/login/base/get/port_profile.j2 | 3 + .../KeyMile/login/base/get/port_profiles.j2 | 19 ++++++ .../root/unit/port/portCommandProcessor.py | 67 ++++++++++++++++++- 6 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 templates/KeyMile/login/base/get/port_profile.j2 create mode 100644 templates/KeyMile/login/base/get/port_profiles.j2 diff --git a/nesi/keymile/api/schemas/keymile_port_schemas.py b/nesi/keymile/api/schemas/keymile_port_schemas.py index fba20f5..687a495 100644 --- a/nesi/keymile/api/schemas/keymile_port_schemas.py +++ b/nesi/keymile/api/schemas/keymile_port_schemas.py @@ -17,6 +17,9 @@ class KeyMilePortSchema(PortSchema): class Meta: model = Port fields = PortSchema.Meta.fields + ('channels', 'label1', 'label2', 'loopbacktest_state', 'melttest_state', - 'linetest_state') + 'linetest_state', 'profile1_enable', 'profile1_name', 'profile1_elength', + 'profile2_enable', 'profile2_name', 'profile2_elength', 'profile3_enable', + 'profile3_name', 'profile3_elength', 'profile4_enable', 'profile4_name', + 'profile_mode') channels = ma.Nested(CpesSchema.CpeSchema, many=True) diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py index 80865e8..1555ef7 100644 --- a/nesi/keymile/keymile_resources/keymile_port.py +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -22,6 +22,36 @@ class KeyMilePort(Port): loopbacktest_state = base.Field('loopbacktest_state') melttest_state = base.Field('melttest_state') linetest_state = base.Field('linetest_state') + profile1_enable = base.Field('profile1_enable') + profile1_name = base.Field('profile1_name') + profile1_elength = base.Field('profile1_elength') + profile2_enable = base.Field('profile2_enable') + profile2_name = base.Field('profile2_name') + profile2_elength = base.Field('profile2_elength') + profile3_enable = base.Field('profile3_enable') + profile3_name = base.Field('profile3_name') + profile3_elength = base.Field('profile3_elength') + profile4_enable = base.Field('profile4_enable') + profile4_name = base.Field('profile4_name') + profile_mode = base.Field('profile_mode') + + def set_profile(self, name): + self.update(profile1_name=name) + + + def set_profiles(self, e1, n1, el1, e2, n2, el2, e3, n3, el3, e4, n4, mode): + self.update(profile1_enable=e1) + self.update(profile1_name=n1) + self.update(profile1_elength=el1) + self.update(profile2_enable=e2) + self.update(profile2_name=n2) + self.update(profile2_elength=el2) + self.update(profile3_enable=e3) + self.update(profile3_name=n3) + self.update(profile3_elength=el3) + self.update(profile4_enable=e4) + self.update(profile4_name=n4) + self.update(profile_mode=mode) def set_label(self, l1, l2, desc): self.update(label1=l1) diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 7f99aab..32e0380 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -316,3 +316,16 @@ class Port(db.Model): loopbacktest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NoTestResult', 'Stopped', 'Interrupted'), default='NoTestResult') melttest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NotTested'), default='NotTested') linetest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NotTested'), default='NotTested') + #profiles + profile1_enable = db.Column(db.Boolean(), default=False) + profile1_name = db.Column(db.String(), default='') + profile1_elength = db.Column(db.Integer, default=0) + profile2_enable = db.Column(db.Boolean(), default=False) + profile2_name = db.Column(db.String(), default='') + profile2_elength = db.Column(db.Integer, default=0) + profile3_enable = db.Column(db.Boolean(), default=False) + profile3_name = db.Column(db.String(), default='') + profile3_elength = db.Column(db.Integer, default=0) + profile4_enable = db.Column(db.Boolean(), default=False) + profile4_name = db.Column(db.String(), default='') + profile_mode = db.Column(db.Enum('Priority', 'ElectricalLoopLength'), default=None) diff --git a/templates/KeyMile/login/base/get/port_profile.j2 b/templates/KeyMile/login/base/get/port_profile.j2 new file mode 100644 index 0000000..cd044d5 --- /dev/null +++ b/templates/KeyMile/login/base/get/port_profile.j2 @@ -0,0 +1,3 @@ + \ # PortProfile +{{ context.profile_name }}{{ context.spacer1 }}\ # Name + diff --git a/templates/KeyMile/login/base/get/port_profiles.j2 b/templates/KeyMile/login/base/get/port_profiles.j2 new file mode 100644 index 0000000..89af093 --- /dev/null +++ b/templates/KeyMile/login/base/get/port_profiles.j2 @@ -0,0 +1,19 @@ + \ # Profiles + \ # VDSLxPrio1 +{{ context.port.profile1_enable }}{{ context.spacer1 }}\ # Enabled +{{ context.port.profile1_name }}{{ context.spacer2 }}\ # Name +{{ context.port.profile1_elength }}{{ context.spacer3 }}\ # MaxElectricalLoopLength + \ # VDSLxPrio2 +{{ context.port.profile2_enable }}{{ context.spacer4 }}\ # Enabled +{{ context.port.profile2_name }}{{ context.spacer5 }}\ # Name +{{ context.port.profile2_elength }}{{ context.spacer6 }}\ # MaxElectricalLoopLength + \ # VDSLxPrio3 +{{ context.port.profile3_enable }}{{ context.spacer7 }}\ # Enabled +{{ context.port.profile3_name }}{{ context.spacer8 }}\ # Name +{{ context.port.profile3_elength }}{{ context.spacer9 }}\ # MaxElectricalLoopLength + \ # ADSLxPrio4 +{{ context.port.profile4_enable }}{{ context.spacer10 }}\ # Enabled +{{ context.port.profile4_name }}{{ context.spacer11 }}\ # Name + \ # AutomaticProfileSwitching +{{ context.port.profile_mode }}{{ context.spacer12 }}\ # Mode + diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index cf02d77..23e03c1 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -35,6 +35,35 @@ def get_property(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + + elif self._validate(args, 'Portprofile') and context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM'\ + not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': + context['spacer1'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' + context['profile_name'] = port.profile1_name + text = self._render('port_profile', *scopes, context=context) + self._write(text) + elif self._validate(args, 'Portprofiles') and context['component_path'].split('/')[-1] == 'cfgm' and \ + 'SUVD2' in card.board_name and self.__name__ == 'port': + context['spacer1'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' + context['profile_name'] = port.profile1_name + text = self._render('port_profile', *scopes, context=context) + self._write(text) + elif self._validate(args, 'Portprofiles') and self.__name__ == 'port' and \ + context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM' in card.board_name: + context['spacer1'] = self.create_spacers((67,), (port.profile1_enable,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (port.profile1_elength,))[0] * ' ' + context['spacer4'] = self.create_spacers((67,), (port.profile2_enable,))[0] * ' ' + context['spacer5'] = self.create_spacers((67,), (port.profile2_name,))[0] * ' ' + context['spacer6'] = self.create_spacers((67,), (port.profile2_elength,))[0] * ' ' + context['spacer7'] = self.create_spacers((67,), (port.profile3_enable,))[0] * ' ' + context['spacer8'] = self.create_spacers((67,), (port.profile3_name,))[0] * ' ' + context['spacer9'] = self.create_spacers((67,), (port.profile3_elength,))[0] * ' ' + context['spacer10'] = self.create_spacers((67,), (port.profile4_enable,))[0] * ' ' + context['spacer11'] = self.create_spacers((67,), (port.profile4_name,))[0] * ' ' + context['spacer12'] = self.create_spacers((67,), (port.profile_mode,))[0] * ' ' + text = self._render('port_profiles', *scopes, context=dict(context, port=port)) + self._write(text) elif self._validate((args[0],), 'AttainableRate') and context['component_path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) @@ -206,7 +235,7 @@ def do_createinterface(self, command, *args, context=None): interf = self._model.add_interface(name=name, port_id=port.id, vlan_profile=vlan_prof) context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' context['id'] = str(id) - # TODO: Template is unknown + # TODO: unknown Template text = self._render('interface_success', *scopes, context=context) self._write(text) except AssertionError: @@ -222,11 +251,47 @@ def get_port_component(self): def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') + card = self._model.get_card('name', self._parent.component_id) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'Portprofile', str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM'\ + not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': + profile, = self._dissect(args, 'Portprofile', str) + try: + port = self.get_port_component() + port.set_profile(profile) + + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'Portprofiles', str) and context['component_path'].split('/')[-1] == 'cfgm' and \ + 'SUVD2' in card.board_name and self.__name__ == 'port': + profile, = self._dissect(args, 'Portprofiles', str) + try: + port = self.get_port_component() + port.set_profile(profile) + + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'Portprofiles', str, str, str, str, str, str, str, str, str, str, str, str) and \ + context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM' in card.board_name and self.__name__ == 'port': + en1, name1, elen1, en2, name2, elen2, en3, name3, elen3, en4, name4, mode = self._dissect(args, + 'Portprofiles', str, str, str, str, str, str, str, str, str, str, str, str) + try: + port = self.get_port_component() + en1 = True if en1.lower() == 'true' else False + en2 = True if en2.lower() == 'true' else False + en3 = True if en3.lower() == 'true' else False + en4 = True if en4.lower() == 'true' else False + port.set_profiles(en1, name1, int(elen1), en2, name2, int(elen2), en3, name3, int(elen3), en4, name4, mode) + + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'AdministrativeStatus', str) and context['component_path'].split('/')[-1] == 'main': state, = self._dissect(args, 'AdministrativeStatus', str) try: From d81c8ca1c3b31231c9dc23e83fd128450f31ea9b Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 20 Oct 2020 10:30:29 +0200 Subject: [PATCH 128/318] Removed 'component_path' --- templates/KeyMile/login/base/ls/ls_header.j2 | 2 +- .../accessPoints/root/rootCommandProcessor.py | 6 +-- .../root/services/srvcCommandProcessor.py | 2 +- .../unit/logport/logportsCommandProcessor.py | 4 +- .../logport/port/logportCommandProcessor.py | 6 +-- .../unit/port/chan/chanCommandProcessor.py | 10 ++--- .../root/unit/port/portCommandProcessor.py | 32 ++++++++-------- .../port/portgroupportCommandProcessor.py | 14 +++---- .../root/unit/unitCommandProcessor.py | 26 ++++++------- vendors/KeyMile/baseCommandProcessor.py | 37 +++++++++---------- vendors/KeyMile/main.py | 1 - 11 files changed, 69 insertions(+), 71 deletions(-) diff --git a/templates/KeyMile/login/base/ls/ls_header.j2 b/templates/KeyMile/login/base/ls/ls_header.j2 index 2f31160..e0a8150 100644 --- a/templates/KeyMile/login/base/ls/ls_header.j2 +++ b/templates/KeyMile/login/base/ls/ls_header.j2 @@ -1,4 +1,4 @@ -Infos of AP: {{ context.ls_path }} +Infos of AP: {{ context.path }} Name : MileGate 2200 Main Mode : Equipment State : Ok diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 24ce5a0..674f148 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -76,13 +76,13 @@ def set(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors')) def do_save(self, command, *args, context=None): - if len(args) == 0 and context['component_path'].split('/')[-1] == 'cfgm': + if len(args) == 0 and context['path'].split('/')[-1] == 'cfgm': pass else: raise exceptions.CommandSyntaxError(command=command) def do_ftpserver(self, command, *args, context=None): - if self._validate(args, str, str, str) and context['component_path'].split('/')[-1] != 'cfgm': + if self._validate(args, str, str, str) and context['path'].split('/')[-1] != 'cfgm': ip, login, pw = self._dissect(args, str, str, str) try: self._model.set_backup(ip, login, pw) @@ -92,7 +92,7 @@ def do_ftpserver(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_upload(self, command, *args, context=None): - if self._validate(args, '/cfgm/configuration', str) and context['component_path'].split('/')[-1] != 'cfgm': + if self._validate(args, '/cfgm/configuration', str) and context['path'].split('/')[-1] != 'cfgm': path, = self._dissect(args, '/cfgm/configuration', str) try: self._model.set_path(path) diff --git a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py index edd2132..02c5dcc 100644 --- a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py @@ -36,7 +36,7 @@ def get_property(self, command, *args, context=None): try: super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: - if self._validate((args[0],), 'Service') and context['component_path'].split('/')[-1] == 'cfgm': + if self._validate((args[0],), 'Service') and context['path'].split('/')[-1] == 'cfgm': if service.service_type == '1to1DoubleTag': template_name = 'service_onetoonedoubletag' elif service.service_type == '1to1SingleTag': diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 0e540e3..9e76d14 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -40,7 +40,7 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_delete(self, command, *args, context=None): - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm': + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm': name, = self._dissect(args, str) if name.startswith('logport-'): id = name.split('-')[1] @@ -55,7 +55,7 @@ def do_delete(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_create(self, command, *args, context=None): - if self._validate(args, str, str, str, str) and context['component_path'].split('/')[-1] == 'cfgm': + if self._validate(args, str, str, str, str) and context['path'].split('/')[-1] == 'cfgm': p1, p2, p3, p4, = self._dissect(args, str, str, str, str) ids = [] ids.append(int(p1.split('-')[1])) if p1.startswith('port-') else ids diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 16e3827..8d7b5b7 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -32,7 +32,7 @@ def get_property(self, command, *args, context=None): try: super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: - if self._validate((args[0],), 'AttainableRate') and context['component_path'].split('/')[-1] == 'status': + if self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) else: @@ -59,7 +59,7 @@ def _init_access_points(self, context=None): def do_deleteinterface(self, command, *args, context=None): card = self._model.get_card('name', self._parent._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': # all or interface_id name, = self._dissect(args, str) if name == 'all': @@ -82,7 +82,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 220b516..147e4d8 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -43,7 +43,7 @@ def _init_access_points(self, context=None): def do_deletevcc(self, command, *args, context=None): card = self._model.get_card('name', self._parent._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': # all or vcc_id name, = self._dissect(args, str) if name == 'all': @@ -64,7 +64,7 @@ def do_deletevcc(self, command, *args, context=None): def do_deleteinterface(self, command, *args, context=None): card = self._model.get_card('name', self._parent._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product != 'adsl' and card.product != 'sdsl': + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product != 'adsl' and card.product != 'sdsl': # all or interface_id name, = self._dissect(args, str) if name == 'all': @@ -86,7 +86,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name: + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name: # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names @@ -113,7 +113,7 @@ def do_createinterface(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name : + elif self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name : # vcc profile and vlan profile vlan_prof, vcc_prof = self._dissect(args, str, str) # TODO: Check if profiles := default or profile names @@ -147,7 +147,7 @@ def do_createinterface(self, command, *args, context=None): def do_createvcc(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent._parent.component_id) - if self._validate(args, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': + if self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': # vcc profile and vlan profile vcc_prof, vlan_prof = self._dissect(args, str, str) # TODO: Check if profiles := default or profile names diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 23e03c1..b355f31 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -64,39 +64,39 @@ def get_property(self, command, *args, context=None): context['spacer12'] = self.create_spacers((67,), (port.profile_mode,))[0] * ' ' text = self._render('port_profiles', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate((args[0],), 'AttainableRate') and context['component_path'].split('/')[-1] == 'status': + elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'QuickLoopbackTest') and context['component_path'].split('/')[-1] == 'status'\ + elif self._validate((args[0],), 'QuickLoopbackTest') and context['path'].split('/')[-1] == 'status'\ and (card.product == 'isdn' or 'SUI' in card.board_name) and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.loopbacktest_state,))[0] * ' ' context['loopbacktest_state'] = port.loopbacktest_state text = self._render('quickloopbacktest', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'LineTestResults') and context['component_path'].split('/')[-1] == 'status'\ + elif self._validate((args[0],), 'LineTestResults') and context['path'].split('/')[-1] == 'status'\ and 'SUP' in card.board_name and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.linetest_state,))[0] * ' ' context['test_state'] = port.linetest_state text = self._render('line_results', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'MeltResults') and context['component_path'].split('/')[-1] == 'status'\ + elif self._validate((args[0],), 'MeltResults') and context['path'].split('/')[-1] == 'status'\ and card.product != 'isdn' and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.melttest_state,))[0] * ' ' context['test_state'] = port.melttest_state text = self._render('melt_results', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'AdministrativeStatus') and context['component_path'].split('/')[-1] == 'main': + elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': self.map_states(port, 'port') context['spacer'] = self.create_spacers((67,), (port.admin_state,))[0] * ' ' text = self._render('administrative_status', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate(args, 'Labels') and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'Labels') and context['path'].split('/')[-1] == 'main': context['spacer1'] = self.create_spacers((67,), (port.label1,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (port.label2,))[0] * ' ' context['spacer3'] = self.create_spacers((67,), (port.description,))[0] * ' ' text = self._render('labels', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate((args[0],), 'OperationalStatus') and context['component_path'].split('/')[-1] == 'main': + elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': self.map_states(port, 'port') port_operational_state = port.operational_state context['port_operational_state'] = port_operational_state @@ -125,7 +125,7 @@ def _init_access_points(self, context=None): def do_lock(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn' \ + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: port = self.get_port_component() @@ -137,7 +137,7 @@ def do_lock(self, command, *args, context=None): def do_startquickloopbacktest(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn' \ + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: port = self.get_port_component() @@ -151,7 +151,7 @@ def do_startquickloopbacktest(self, command, *args, context=None): def do_startlinetest(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and 'SUP' in card.board_name \ + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and 'SUP' in card.board_name \ and self.__name__ == 'port': try: port = self.get_port_component() @@ -165,7 +165,7 @@ def do_startlinetest(self, command, *args, context=None): def do_startmeltmeasurement(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product != 'isdn' \ + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product != 'isdn' \ and self.__name__ == 'port': try: port = self.get_port_component() @@ -179,7 +179,7 @@ def do_startmeltmeasurement(self, command, *args, context=None): def do_unlock(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn' \ + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: port = self.get_port_component() @@ -194,7 +194,7 @@ def on_unknown_command(self, command, *args, context=None): def do_deleteinterface(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'ftth': + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'ftth': # all or interface_id name, = self._dissect(args, str) if name == 'all': @@ -216,7 +216,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUE' in card.board_name: + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUE' in card.board_name: # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names @@ -292,7 +292,7 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'AdministrativeStatus', str) and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'AdministrativeStatus', str) and context['path'].split('/')[-1] == 'main': state, = self._dissect(args, 'AdministrativeStatus', str) try: port = self.get_port_component() @@ -305,7 +305,7 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'Labels', str, str, str) and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': label1, label2, description = self._dissect(args, 'Labels', str, str, str) try: port = self.get_port_component() diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index cb73492..e22f293 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -32,7 +32,7 @@ def get_property(self, command, *args, context=None): try: super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: - if self._validate((args[0],), 'SubscriberList') and context['component_path'].split('/')[-1] == 'status' and \ + if self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ self._model.get_card('name', self._parent._parent.component_id).product == 'isdn': text = self._render('subscriberList_top', *scopes, context=context) i = 0 @@ -48,7 +48,7 @@ def get_property(self, command, *args, context=None): text += self._render('subscriberList_bottom', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'Isdnport') and context['component_path'].split('/')[-1] == 'cfgm' and \ + elif self._validate((args[0],), 'Isdnport') and context['path'].split('/')[-1] == 'cfgm' and \ port.type == 'ISDN': context['spacer1'] = self.create_spacers((67,), (port.enable,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (port.register_as_global,))[0] * ' ' @@ -74,7 +74,7 @@ def get_property(self, command, *args, context=None): text += self._render('isdnport_bottom', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate((args[0],), 'pstnport') and context['component_path'].split('/')[-1] == 'cfgm' and \ + elif self._validate((args[0],), 'pstnport') and context['path'].split('/')[-1] == 'cfgm' and \ port.type == 'PSTN': context['spacer1'] = self.create_spacers((67,), (port.enable,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (port.register_as_global,))[0] * ' ' @@ -127,7 +127,7 @@ def set(self, command, *args, context=None): exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc elif self._validate(args, 'pstnport', str, str, str, str, str, str, str, str, str) and \ - context['component_path'].split('/')[-1] == 'cfgm': + context['path'].split('/')[-1] == 'cfgm': enable, subident, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', str, str, str, str, str, str, str, str, str) try: @@ -140,7 +140,7 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'pstnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, - str) and context['component_path'].split('/')[-1] == 'cfgm': + str) and context['path'].split('/')[-1] == 'cfgm': enable, number, username, password, displayname, privacy, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) try: port = self.get_port_component() @@ -164,7 +164,7 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'isdnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, - str) and context['component_path'].split('/')[-1] == 'cfgm': + str) and context['path'].split('/')[-1] == 'cfgm': enable, number, username, password, displayname, privacy, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) try: port = self.get_port_component() @@ -192,7 +192,7 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'isdnport', str, str, str, str, str, str, str, str, str) and \ - context['component_path'].split('/')[-1] == 'cfgm': + context['path'].split('/')[-1] == 'cfgm': enable, subident, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', str, str, str, str, str, str, str, str, str) try: diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index a12beba..5b675a2 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -60,7 +60,7 @@ def get_property(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'SubscriberList') and context['component_path'].split('/')[-1] == 'status' and \ + elif self._validate(args, 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ (card.product == 'isdn' or card.product == 'analog'): text = self._render('subscriberList_top', *scopes, context=context) i = 0 @@ -75,7 +75,7 @@ def get_property(self, command, *args, context=None): text += self._render('subscriberList_item', *scopes, context=dict(context, subscriber=subscriber)) text += self._render('subscriberList_bottom', *scopes, context=context) self._write(text) - elif self._validate(args, 'SIP') and context['component_path'].split('/')[-1] == 'cfgm' and \ + elif self._validate(args, 'SIP') and context['path'].split('/')[-1] == 'cfgm' and \ (card.product == 'isdn' or card.product == 'analog'): context['spacer1'] = self.create_spacers((67,), (card.gateway_name,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (card.home_domain,))[0] * ' ' @@ -93,7 +93,7 @@ def get_property(self, command, *args, context=None): context['spacer14'] = self.create_spacers((67,), (card.session_expiration,))[0] * ' ' text = self._render('sip', *scopes, context=dict(context, card=card)) self._write(text) - elif self._validate(args, 'Proxy') and context['component_path'].split('/')[-1] == 'cfgm' and \ + elif self._validate(args, 'Proxy') and context['path'].split('/')[-1] == 'cfgm' and \ (card.product == 'isdn' or card.product == 'analog'): context['spacer1'] = self.create_spacers((67,), (card.proxy_mode,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (card.proxy_address,))[0] * ' ' @@ -105,20 +105,20 @@ def get_property(self, command, *args, context=None): context['spacer8'] = self.create_spacers((67,), (card.proxy_interval,))[0] * ' ' text = self._render('proxy', *scopes, context=dict(context, card=card)) self._write(text) - elif self._validate(args, 'IP') and context['component_path'].split('/')[-1] == 'cfgm' and \ + elif self._validate(args, 'IP') and context['path'].split('/')[-1] == 'cfgm' and \ (card.product == 'isdn' or card.product == 'analog'): # TODO: dynamic fields text = self._render('ip', *scopes, context=context) self._write(text) - elif self._validate(args, 'Labels') and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'Labels') and context['path'].split('/')[-1] == 'main': context['spacer1'] = self.create_spacers((67,), (card.label1,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (card.label2,))[0] * ' ' context['spacer3'] = self.create_spacers((67,), (card.description,))[0] * ' ' text = self._render('labels', *scopes, context=dict(context, port=card)) self._write(text) - elif self._validate(args, 'Registrar') and context['component_path'].split('/')[-1] == 'cfgm': + elif self._validate(args, 'Registrar') and context['path'].split('/')[-1] == 'cfgm': context['spacer1'] = self.create_spacers((67,), (card.registrar_adress,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (card.registrar_port,))[0] * ' ' context['spacer3'] = self.create_spacers((67,), (card.registration_mode,))[0] * ' ' @@ -126,7 +126,7 @@ def get_property(self, command, *args, context=None): text = self._render('registrar', *scopes, context=dict(context, card=card)) self._write(text) - elif self._validate(args, 'HardwareAndSoftware') and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'HardwareAndSoftware') and context['path'].split('/')[-1] == 'main': unit_hardware = '"' + card.board_name + '"' context['unit_hardware'] = unit_hardware context['spacer_1'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' @@ -151,7 +151,7 @@ def get_property(self, command, *args, context=None): text = self._render('hardware_and_software', *scopes, context=context) self._write(text) - elif self._validate(args, 'CurrentStatus') and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'CurrentStatus') and context['path'].split('/')[-1] == 'main': unit_state = card.state context['unit_state'] = unit_state context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' @@ -173,7 +173,7 @@ def get_property(self, command, *args, context=None): text = self._render('current_status', *scopes, context=context) self._write(text) - elif self._validate(args, 'EquipmentInventory') and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'EquipmentInventory') and context['path'].split('/')[-1] == 'main': unit_symbol = '"' + card.board_name + '"' context['unit_symbol'] = unit_symbol context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' @@ -239,7 +239,7 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'Labels', str, str, str) and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': label1, label2, description = self._dissect(args, 'Labels', str, str, str) try: component = self.get_component() @@ -248,7 +248,7 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'SIP', str, str, str, str, str, str, str, str, str, str, str, str, str, str) and \ - context['component_path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): + context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): gw, hd, spn, cc, ac, rt, mri, se, aim, os, ot, uac, uas, sessione = self._dissect( args, 'Sip', str, str, str, str, str, str, str, str, str, str, str, str, str, str) try: @@ -262,14 +262,14 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) elif self._validate(args, 'Registrar', str, str, str, str) and \ - context['component_path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): + context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): ra, rp, rm, rt = self._dissect(args, 'Registrar', str, str, str, str) try: card.set_registrar(ra, int(rp), rm, int(rt)) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) elif self._validate(args, 'Proxy', str, str, str, str, str, str, str, str) and \ - context['component_path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): + context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): pm, pa1, pp1, pa2, pp2, pe, pmethod, pi = self._dissect(args, 'Proxy', str, str, str, str, str, str, str, str) try: pe = True if pe.lower() == 'true' else False diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 6fe36b9..ca9206a 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -111,13 +111,12 @@ def do_pwd(self, command, *args, context=None): context['spacer'] = self.create_spacers((67,), (context['path'],))[0] * ' ' self._write(self._render('pwd', 'login', 'base', context=context)) - def ls(self, context=None, path_type='path'): + def ls(self, context=None): scopes = ('login', 'base', 'ls') - context['ls_path'] = context[path_type] - if re.search('(pm|fm|status|main|cfgm)', context['ls_path']): - mf_type = context['ls_path'].split('/')[-1] + if re.search('(pm|fm|status|main|cfgm)', context['path']): + mf_type = context['path'].split('/')[-1] - mf_layers = None + mf_layers = {} if mf_type == 'status': mf_layers = self.status elif mf_type == 'cfgm': @@ -183,17 +182,18 @@ def do_ls(self, command, *args, context=None): pass elif self._validate(args, str): path = args[0] + current_path = context['path'] try: tmp_cmdproc = self.change_directory(path, context=context) - tmp_cmdproc.ls(context=context, path_type='component_path') + tmp_cmdproc.ls(context=context) except exceptions.CommandExecutionError: - context['component_path'] = context['path'] + context['path'] = current_path raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) - context['component_path'] = context['path'] + context['path'] = current_path else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), @@ -205,7 +205,7 @@ def change_directory(self, path, context=None): if self.__name__ != 'root': return self._parent.change_directory(path, context=context) else: - context['component_path'] = '/' + context['path'] = '/' return self components = [x for x in path.split('/') if x] @@ -237,16 +237,15 @@ def change_directory(self, path, context=None): command=None) if path.startswith('..'): - splitted_path = [x for x in context['component_path'].split('/') if x] + splitted_path = [x for x in context['path'].split('/') if x] exit_component = None if len(splitted_path) != 0: exit_component = splitted_path.pop() - context['component_path'] = '/' + '/'.join(splitted_path) + context['path'] = '/' + '/'.join(splitted_path) if exit_component in ('main', 'cfgm', 'fm', 'pm', 'status'): self.set_prompt_end_pos(context=context) if path != '..': - context['path'] = context['component_path'] return self.change_directory(path[3:], context=context) return self @@ -263,7 +262,7 @@ def change_directory(self, path, context=None): if self.__name__ != 'root': subprocessor = self._parent.change_directory(path, context=context) else: - context['component_path'] = '/' + context['path'] = '/' subprocessor = self.change_directory(path.lstrip('/'), context=context) else: remaining_args = '/'.join(components[1:]) @@ -362,11 +361,11 @@ def change_directory(self, path, context=None): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - if context['component_path'] == '/': + if context['path'] == '/': new_path = components[0] else: new_path = '/' + components[0] - context['component_path'] += new_path + context['path'] += new_path return self from vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor import UnitCommandProcessor @@ -401,14 +400,14 @@ def change_directory(self, path, context=None): if component_id is not None: subprocessor.set_component_id(component_id) - if context['component_path'] == '/': + if context['path'] == '/': new_path = components[0] else: if path == 'subpacket': new_path = '/' + context['ServiceType'] else: new_path = '/' + components[0] - context['component_path'] += new_path + context['path'] += new_path if len(remaining_args) > 0: subprocessor = subprocessor.change_directory(remaining_args, context=context) @@ -531,13 +530,13 @@ def do_cd(self, command, *args, context=None): raise exceptions.CommandSyntaxError() elif self._validate(args, str): path = args[0] + current_path = context['path'] try: subprocessor = self.change_directory(path, context=context) return_to = self.get_command_processor(subprocessor) except: - context['component_path'] = context['path'] + context['path'] = current_path raise - context['path'] = context['component_path'] subprocessor.loop(context=context, return_to=return_to) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', diff --git a/vendors/KeyMile/main.py b/vendors/KeyMile/main.py index 95e03f6..ff9abd4 100644 --- a/vendors/KeyMile/main.py +++ b/vendors/KeyMile/main.py @@ -56,7 +56,6 @@ def on_unknown_command(self, command, *args, context=None): RootCommandProcessor, 'login', 'base') context['path'] = '/' - context['component_path'] = '/' self._write(self._render('login_message', 'login', 'base', context=context)) From ab3d183845af115e0d75b88be7540c066e3b5a3a Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 20 Oct 2020 10:37:50 +0200 Subject: [PATCH 129/318] Now completely removed 'component_path' --- .../root/unit/port/portCommandProcessor.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index b355f31..69f8a04 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -36,20 +36,20 @@ def get_property(self, command, *args, context=None): exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'Portprofile') and context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM'\ + elif self._validate(args, 'Portprofile') and context['path'].split('/')[-1] == 'cfgm' and 'SUVM'\ not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' context['profile_name'] = port.profile1_name text = self._render('port_profile', *scopes, context=context) self._write(text) - elif self._validate(args, 'Portprofiles') and context['component_path'].split('/')[-1] == 'cfgm' and \ + elif self._validate(args, 'Portprofiles') and context['path'].split('/')[-1] == 'cfgm' and \ 'SUVD2' in card.board_name and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' context['profile_name'] = port.profile1_name text = self._render('port_profile', *scopes, context=context) self._write(text) elif self._validate(args, 'Portprofiles') and self.__name__ == 'port' and \ - context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM' in card.board_name: + context['path'].split('/')[-1] == 'cfgm' and 'SUVM' in card.board_name: context['spacer1'] = self.create_spacers((67,), (port.profile1_enable,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' context['spacer3'] = self.create_spacers((67,), (port.profile1_elength,))[0] * ' ' @@ -257,7 +257,7 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'Portprofile', str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM'\ + elif self._validate(args, 'Portprofile', str) and context['path'].split('/')[-1] == 'cfgm' and 'SUVM'\ not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': profile, = self._dissect(args, 'Portprofile', str) try: @@ -267,7 +267,7 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'Portprofiles', str) and context['component_path'].split('/')[-1] == 'cfgm' and \ + elif self._validate(args, 'Portprofiles', str) and context['path'].split('/')[-1] == 'cfgm' and \ 'SUVD2' in card.board_name and self.__name__ == 'port': profile, = self._dissect(args, 'Portprofiles', str) try: @@ -278,7 +278,7 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'Portprofiles', str, str, str, str, str, str, str, str, str, str, str, str) and \ - context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM' in card.board_name and self.__name__ == 'port': + context['path'].split('/')[-1] == 'cfgm' and 'SUVM' in card.board_name and self.__name__ == 'port': en1, name1, elen1, en2, name2, elen2, en3, name3, elen3, en4, name4, mode = self._dissect(args, 'Portprofiles', str, str, str, str, str, str, str, str, str, str, str, str) try: From 01ca141bd5d82475713a5a87fe9ad82273ed6004 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Tue, 20 Oct 2020 10:39:45 +0200 Subject: [PATCH 130/318] Added more features to srvc objects --- .../conf/bootstraps/create-keymile-MG2500.sh | 1 - nesi/keymile/keymile_resources/keymile_box.py | 7 ++++ nesi/softbox/api/models/srvc_models.py | 2 +- nesi/softbox/api/schemas/srvc_schemas.py | 2 +- nesi/softbox/api/views/srvc_views.py | 14 +++++++ .../unknown_service_fragment.j2 | 2 + .../root/services/srvcCommandProcessor.py | 7 ++-- .../services/subpacketCommandProcessor.py | 38 +++++++++++++++++++ 8 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 templates/KeyMile/login/base/execution_errors/unknown_service_fragment.j2 diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index f224350..ac248e6 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -531,7 +531,6 @@ port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) # Create a physical port at the network device (admin operation) req='{ - "name": "srvc-1", "service_type": "nto1", "svid": 123, "address": "/unit-1/port-1/chan-1/interface-1" diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 2d27406..b53b9d7 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -207,6 +207,13 @@ def get_srvcs(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'srvcs'), params={field: value}) + def add_srvc(self, **fields): + """Add new srvc.""" + return keymile_srvc.KeyMileSrvc.create( + self._conn, + os.path.join(self.path, 'srvcs'), + **fields) + class KeyMileBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/softbox/api/models/srvc_models.py b/nesi/softbox/api/models/srvc_models.py index 6452ac2..8e0ec84 100644 --- a/nesi/softbox/api/models/srvc_models.py +++ b/nesi/softbox/api/models/srvc_models.py @@ -18,6 +18,6 @@ class Srvc(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) - service_type = db.Column(db.Enum('1to1DoubleTag', '1to1SingleTag', 'mcast', 'nto1', 'pls', 'tls', ''), default='') + service_type = db.Column(db.Enum('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls')) address = db.Column(db.String(), default='') svid = db.Column(db.Integer(), default=None) diff --git a/nesi/softbox/api/schemas/srvc_schemas.py b/nesi/softbox/api/schemas/srvc_schemas.py index f1bba10..482b246 100644 --- a/nesi/softbox/api/schemas/srvc_schemas.py +++ b/nesi/softbox/api/schemas/srvc_schemas.py @@ -36,7 +36,7 @@ class Meta: class SrvcSchema(ma.ModelSchema): class Meta: model = Srvc - fields = ('id', '_links') + fields = ('id', 'name', '_links') _links = ma.Hyperlinks( {'self': ma.URLFor( diff --git a/nesi/softbox/api/views/srvc_views.py b/nesi/softbox/api/views/srvc_views.py index 263a2b9..3315341 100644 --- a/nesi/softbox/api/views/srvc_views.py +++ b/nesi/softbox/api/views/srvc_views.py @@ -44,9 +44,23 @@ def update_srvc(box_id, id): @app.route(PREFIX + '/boxen//srvcs', methods=['POST']) def new_srvc(box_id): req = flask.request.json + + if 'name' not in req or req['name'] == "": + srvcs = json.loads(show_components(SrvcsSchema(), Srvc, req={'service_type': req['service_type']}, box_id=box_id).data.decode('utf-8')) + last_srvc = None + for s in srvcs['members']: + last_srvc = s + + if last_srvc is not None: + _, num = last_srvc['name'].split('-') + req['name'] = 'srvc-' + str(int(num)+1) + else: + req['name'] = 'srvc-1' + response = new_component(SrvcSchema(), Srvc, req, box_id) return response, 201 + @app.route(PREFIX + '/boxen//srvcs/', methods=['DELETE']) def del_srvc(box_id, id): del_component(Srvc, box_id, id) diff --git a/templates/KeyMile/login/base/execution_errors/unknown_service_fragment.j2 b/templates/KeyMile/login/base/execution_errors/unknown_service_fragment.j2 new file mode 100644 index 0000000..46fd889 --- /dev/null +++ b/templates/KeyMile/login/base/execution_errors/unknown_service_fragment.j2 @@ -0,0 +1,2 @@ +error: Unknown service fragment + diff --git a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py index 02c5dcc..7a9e401 100644 --- a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py @@ -28,7 +28,7 @@ def get_property(self, command, *args, context=None): service_name = 'srvc-' + self.component_id services = self._model.get_srvcs('name', service_name) for s in services: - if s.service_type == context['ServiceType']: + if s.service_type.lower() == context['ServiceType']: service = s context['service'] = service break @@ -37,9 +37,10 @@ def get_property(self, command, *args, context=None): super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: if self._validate((args[0],), 'Service') and context['path'].split('/')[-1] == 'cfgm': - if service.service_type == '1to1DoubleTag': + # TODO: Find missing templates, and replace placeholder templates + if service.service_type == '1to1doubletag': template_name = 'service_onetoonedoubletag' - elif service.service_type == '1to1SingleTag': + elif service.service_type == '1to1singletag': template_name = 'service_onetoonesingletag' elif service.service_type == 'mcast': template_name = 'service_mcast' diff --git a/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py index 27d0c7c..10db20e 100644 --- a/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py @@ -38,5 +38,43 @@ def _init_access_points(self, context=None): except exceptions.InvalidInputError: pass + def do_deleteservice(self, command, *args, context=None): + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm': + srvc_id, = self._dissect(args, str) + service_name = 'srvc-' + srvc_id + service = None + services = self._model.get_srvcs('name', service_name) + for s in services: + if s.service_type == context['ServiceType']: + service = s + break + if service is None: + raise exceptions.CommandExecutionError(command=command, template='unknown_service_fragment', + template_scopes=('login', 'base', 'execution_errors')) + service.delete() + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_createservice(self, command, *args, context=None): + if context['ServiceType'] == 'nto1' and context['path'].split('/')[-1] == 'cfgm': + if len(args) == 12: + address, svid = self._dissect(args[:2], str, str) + # TODO: validate address + srvc = self._model.add_srvc(service_type='nto1', address=address, svid=svid) + + else: + raise exceptions.CommandSyntaxError(command=command) + + elif context['ServiceType'] == '1to1singletag' and context['path'].split('/')[-1] == 'cfgm': + if len(args) == 4: + address, svid = self._dissect(args[:2], str, str) + # TODO: validate address + srvc = self._model.add_srvc(service_type='1to1singletag', address=address, svid=svid) + + else: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) From 4f8e13e32639a3e6bd404e404aa04f2506f5848c Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 20 Oct 2020 11:00:19 +0200 Subject: [PATCH 131/318] Added ip commands and reset mode --- .../api/schemas/keymile_card_schemas.py | 3 ++- .../keymile/keymile_resources/keymile_card.py | 8 ++++++ nesi/softbox/api/models/card_models.py | 3 +++ templates/KeyMile/login/base/get/ip.j2 | 6 ++--- .../root/unit/unitCommandProcessor.py | 25 +++++++++++++++++-- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/nesi/keymile/api/schemas/keymile_card_schemas.py b/nesi/keymile/api/schemas/keymile_card_schemas.py index eeaf6aa..7f62849 100644 --- a/nesi/keymile/api/schemas/keymile_card_schemas.py +++ b/nesi/keymile/api/schemas/keymile_card_schemas.py @@ -27,4 +27,5 @@ class Meta: 'uac_request_timer', 'uas_request_timer', 'session_expiration', 'proxy_mode', 'proxy_address', 'proxy_port', 'proxy_address_sec', 'proxy_port_sec', 'proxy_enable', 'proxy_method', 'proxy_interval', 'registrar_adress', - 'registrar_port', 'registration_mode', 'registration_expiration_time') + 'registrar_port', 'registration_mode', 'registration_expiration_time', + 'gateway_ipaddress', 'subnet_mask', 'default_gateway') diff --git a/nesi/keymile/keymile_resources/keymile_card.py b/nesi/keymile/keymile_resources/keymile_card.py index 71fae65..4e65f98 100644 --- a/nesi/keymile/keymile_resources/keymile_card.py +++ b/nesi/keymile/keymile_resources/keymile_card.py @@ -41,6 +41,10 @@ class KeyMileCard(Card): label1 = base.Field('label1') label2 = base.Field('label2') + gateway_ipaddress = base.Field('gateway_ipaddress') + subnet_mask = base.Field('subnet_mask') + default_gateway = base.Field('default_gateway') + # Keymile ipsx2/3 card SIP specifications gateway_name = base.Field('gateway_name') home_domain = base.Field('home_domain') @@ -89,6 +93,10 @@ def set_sip(self, gateway_name, home_domain, sip_port_number, country_code, area self.update(uas_request_timer=uas_request_timer) self.update(session_expiration=session_expiration) + def set_ip(self, gateway_ipaddress, subnet_mask, default_gateway): + self.update(gateway_ipaddress=gateway_ipaddress) + self.update(subnet_mask=subnet_mask) + self.update(default_gateway=default_gateway) def set_label(self, l1, l2, desc): self.update(label1=l1) diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index f3fc2f9..efbadfd 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -103,6 +103,9 @@ class Card(db.Model): processor = db.Column(db.String(), default='') label1 = db.Column(db.String(), default='""') label2 = db.Column(db.String(), default='""') + gateway_ipaddress = db.Column(db.String(), default='""') + subnet_mask = db.Column(db.String(), default='""') + default_gateway = db.Column(db.String(), default='""') # Keymile ipsx2/3 card SIP specifications gateway_name = db.Column(db.String(), default='""') diff --git a/templates/KeyMile/login/base/get/ip.j2 b/templates/KeyMile/login/base/get/ip.j2 index c5d5e83..e9fe969 100644 --- a/templates/KeyMile/login/base/get/ip.j2 +++ b/templates/KeyMile/login/base/get/ip.j2 @@ -1,5 +1,5 @@ \ # Ip -10.16.12.14 \ # GatewayIpAddress -255.255.255.0 \ # SubnetMask -10.16.12.1 \ # DefaultGateway +{{ context.card.gateway_ipaddress }}{{ context.spacer1 }}\ # GatewayIpAddress +{{ context.card.subnet_mask }}{{ context.spacer2 }}\ # SubnetMask +{{ context.card.default_gateway }}{{ context.spacer3 }}\ # DefaultGateway diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 5b675a2..cc7a690 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -9,6 +9,7 @@ # - Alexander Dincher # # License: https://github.com/inexio/NESi/LICENSE.rst +import time from nesi import exceptions from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor @@ -107,8 +108,10 @@ def get_property(self, command, *args, context=None): self._write(text) elif self._validate(args, 'IP') and context['path'].split('/')[-1] == 'cfgm' and \ (card.product == 'isdn' or card.product == 'analog'): - # TODO: dynamic fields - text = self._render('ip', *scopes, context=context) + context['spacer1'] = self.create_spacers((67,), (card.gateway_ipaddress,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (card.subnet_mask,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (card.default_gateway,))[0] * ' ' + text = self._render('ip', *scopes, context=dict(context, card=card)) self._write(text) elif self._validate(args, 'Labels') and context['path'].split('/')[-1] == 'main': @@ -247,6 +250,14 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'Ip', str, str, str) and context['component_path'].split('/')[-1] == 'cfgm': + ip1, ip2, ip3 = self._dissect(args, 'Ip', str, str, str) + try: + component = self.get_component() + component.set_ip(ip1, ip2, ip3) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'SIP', str, str, str, str, str, str, str, str, str, str, str, str, str, str) and \ context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): gw, hd, spn, cc, ac, rt, mri, se, aim, os, ot, uac, uas, sessione = self._dissect( @@ -278,3 +289,13 @@ def set(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) else: raise exceptions.CommandSyntaxError(command=command) + + def do_restart(self, command, *args, context=None): + card = self._model.get_card('name', self.component_id) + if len(args) == 0 and context['path'].split('/')[-1] == 'main' and (card.product == 'isdn' or card.product == 'analog'): + time.sleep(10) + exc = exceptions.TerminalExitError() + exc.return_to = 'sysreboot' + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) From 7c2b25039e5afbbe47ab0368136c566634b2a546 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 20 Oct 2020 12:42:11 +0200 Subject: [PATCH 132/318] Removed obsolete functions and fixed some navigation bugs --- vendors/KeyMile/baseCommandProcessor.py | 177 ++---------------------- 1 file changed, 15 insertions(+), 162 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index ca9206a..f300be3 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -201,6 +201,15 @@ def do_ls(self, command, *args, context=None): def change_directory(self, path, context=None): path = path.lower() + if re.search('^(?:[^.]+/)+\.\.$', path): + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + if re.search('^(?:[^.]+/)+\.\.(?:/.+)+$', path): + raise exceptions.CommandExecutionError(template='invalid_address_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + if path == '/': if self.__name__ != 'root': return self._parent.change_directory(path, context=context) @@ -226,16 +235,6 @@ def change_directory(self, path, context=None): return self.change_directory(path[2:], context=context) - if re.search('\.\./(?:[^.]+/)+\.\.', path): - if path.endswith('..'): - raise exceptions.CommandExecutionError(template='invalid_management_function_error', - template_scopes=('login', 'base', 'execution_errors'), - command=None) - else: - raise exceptions.CommandExecutionError(template='invalid_address_error', - template_scopes=('login', 'base', 'execution_errors'), - command=None) - if path.startswith('..'): splitted_path = [x for x in context['path'].split('/') if x] exit_component = None @@ -250,8 +249,13 @@ def change_directory(self, path, context=None): return self if path == '..': + if self.__name__ == 'root': + return self return self._parent + if self.__name__ == 'root': + return self.change_directory(path[3:], context=context) + return self._parent.change_directory(path[3:], context=context) if path.startswith('/'): if 'unit-' not in components[0] and components[0] not in ( @@ -414,72 +418,6 @@ def change_directory(self, path, context=None): return subprocessor - ''' - search := string keyword like "unit" or "port" - parent := string keyword to describe the parent of search like "root" - node := contains the dict tree or - None for default tree structure - parent_keys := should be None / important for recursive call - return := Tuple of (ParentList, ChildList) or ([],[]) - ''' - - def get_parent_and_child_relation(self, search, parent=None, node=None, parent_keys=None): - if parent == "": - return ([], []) - if node is None: - node = { - "root": { - "unit": { - "control": {}, - "media": {}, - "port": { - "channel": { - "interfaces": { - "hell": {} - } - }, - "interfaces": { - "hell2": {} - } - }, - "portgroups": {"portgroupports": {}}, - "logports": { - "logport": { - "interface": {}}}, - "vectoringports": {"vectorport": {}}, - "internalports": {"internalport": {}} - }, - "eoam": {}, - "tdmconnections": {}, - "services": { - "packet": { - "subpacket": { - "srvc": {} - } - }, - "macaccessctrl": {} - }, - "multicast": {} - }} - for x, y in node.items(): - if x == search and (parent is None or parent_keys.__contains__(parent)): - if parent is not None: - pp = [parent] - elif parent_keys is None: - pp = [] - else: - pp = [parent_keys] - pc = list(y.keys()) - return (pp, pc) - else: - (pp, pc) = self.get_parent_and_child_relation(search=search, parent=parent, node=y, parent_keys=x) - if pp == [] and pc == []: - pass - else: - return (pp, pc) - else: - return ([], []) - def do_get(self, command, *args, context=None): if len(args) >= 1: if '/' in args[0]: @@ -533,100 +471,15 @@ def do_cd(self, command, *args, context=None): current_path = context['path'] try: subprocessor = self.change_directory(path, context=context) - return_to = self.get_command_processor(subprocessor) except: context['path'] = current_path raise - subprocessor.loop(context=context, return_to=return_to) + subprocessor.loop(context=context, return_to=subprocessor._parent) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=command) - def get_command_processor(self, current_processor, component_type=None): - from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor import UnitCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.chan.chanCommandProcessor import ChanCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor import \ - InterfaceCommandProcessor - from vendors.KeyMile.accessPoints.root.fan.fanCommandProcessor import FanCommandProcessor - from vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor import AlarmCommandProcessor - from vendors.KeyMile.accessPoints.root.eoamCommandProcessor import EoamCommandProcessor - from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor - from vendors.KeyMile.accessPoints.root.tdmconnectionsCommandProcessor import TdmconnectionsCommandProcessor - from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import \ - PortgroupCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import \ - PortgroupportCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.logport.logportsCommandProcessor import LogportsCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ - LogportCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.chan.vcc.vccCommandProcessor import VccCommandProcessor - from vendors.KeyMile.accessPoints.root.services.packetCommandProcessor import PacketCommandProcessor - from vendors.KeyMile.accessPoints.root.services.macaccessctrlCommandProcessor import\ - MacaccessctrlCommandProcessor - from vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor import SubpacketCommandProcessor - from vendors.KeyMile.accessPoints.root.services.srvcCommandProcessor import SrvcCommandProcessor - if current_processor.__class__ == RootCommandProcessor: - return_to = RootCommandProcessor - if component_type not in ('fan', 'eoam', 'tdmconnections', 'multicast', 'services', 'unit') \ - and component_type is not None: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif current_processor.__class__ == UnitCommandProcessor: - return_to = RootCommandProcessor - if (component_type != 'port' or component_type != 'logports') and component_type is not None: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif current_processor.__class__ == PortCommandProcessor: - return_to = UnitCommandProcessor - if component_type != 'chan' and component_type is not None: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif current_processor.__class__ == ChanCommandProcessor: - return_to = PortCommandProcessor - if component_type != 'interface' and component_type is not None: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif current_processor.__class__ == InterfaceCommandProcessor: - return_to = LogportCommandProcessor - return_to = ChanCommandProcessor - return_to = PortCommandProcessor - elif current_processor.__class__ == FanCommandProcessor: - return_to = RootCommandProcessor - elif current_processor.__class__ == AlarmCommandProcessor: - return_to = FanCommandProcessor - elif current_processor.__class__ == EoamCommandProcessor: - return_to = RootCommandProcessor - elif current_processor.__class__ == MulticastCommandProcessor: - return_to = RootCommandProcessor - elif current_processor.__class__ == TdmconnectionsCommandProcessor: - return_to = RootCommandProcessor - elif current_processor.__class__ == ServicesCommandProcessor: - return_to = RootCommandProcessor - elif current_processor.__class__ == PortgroupportCommandProcessor: - return_to = PortgroupCommandProcessor - elif current_processor.__class__ == PortgroupCommandProcessor: - return_to = UnitCommandProcessor - elif current_processor.__class__ == LogportsCommandProcessor: - return_to = UnitCommandProcessor - elif current_processor.__class__ == LogportCommandProcessor: - return_to = LogportsCommandProcessor - elif current_processor.__class__ == VccCommandProcessor: - return_to = ChanCommandProcessor - elif current_processor.__class__ == PacketCommandProcessor: - return_to = ServicesCommandProcessor - elif current_processor.__class__ == MacaccessctrlCommandProcessor: - return_to = ServicesCommandProcessor - elif current_processor.__class__ == SubpacketCommandProcessor: - return_to = PacketCommandProcessor - elif current_processor.__class__ == SrvcCommandProcessor: - return_to = SubpacketCommandProcessor - - return return_to - def do_exit(self, command, *args, context=None): exc = exceptions.TerminalExitError() exc.return_to = 'sysexit' From 559b78f0d2ede5d64a2473187206f1adc91b3b07 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 20 Oct 2020 13:08:10 +0200 Subject: [PATCH 133/318] Added Mgmt Card system in KeyMile --- .../conf/bootstraps/create-keymile-MG2500.sh | 40 +++++++++++++ .../api/schemas/keymile_mgmt_card_schemas.py | 24 ++++++++ .../api/schemas/keymile_mgmt_port_schemas.py | 20 +++++++ nesi/keymile/keymile_resources/__init__.py | 3 +- nesi/keymile/keymile_resources/keymile_box.py | 28 +++++++++- .../keymile_resources/keymile_mgmt_card.py | 56 +++++++++++++++++++ .../keymile_resources/keymile_mgmt_port.py | 34 +++++++++++ nesi/softbox/api/models/box_models.py | 2 + nesi/softbox/api/models/mgmt_card_models.py | 26 ++++++++- nesi/softbox/api/models/mgmt_port_models.py | 2 +- nesi/softbox/base_resources/mgmt_card.py | 20 ++++++- .../root/unit/port/portCommandProcessor.py | 40 +++++++------ .../root/unit/unitCommandProcessor.py | 27 ++++++--- vendors/KeyMile/baseCommandProcessor.py | 5 +- 14 files changed, 295 insertions(+), 32 deletions(-) create mode 100644 nesi/keymile/api/schemas/keymile_mgmt_card_schemas.py create mode 100644 nesi/keymile/api/schemas/keymile_mgmt_port_schemas.py create mode 100644 nesi/keymile/keymile_resources/keymile_mgmt_card.py create mode 100644 nesi/keymile/keymile_resources/keymile_mgmt_port.py diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index ac248e6..dd35d3c 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -479,6 +479,46 @@ req='{ unit_8=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Mgmt-Unit-11 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "board_name": "COGE1", + "supplier_build_state": "R3D", + "board_id": "305", + "hardware_key": 104, + "software": "COGE1_r5c01.esw", + "software_name": "COGE1", + "software_revision": "R5C01", + "state": "Ok", + "serial_number": "4810312946", + "manufacturer_name": "KEYMILE", + "model_name": "37900030", + "short_text": "MG COGE1 COGE1+ AnnexB 32-port", + "manufacturer_id": "100989", + "manufacturer_part_number": "09860762", + "manufacturer_build_state": "05", + "boot_loader": "BLSU1_R1F01/CT18388", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" +}' + +unit_11=$(create_resource "$req" $ENDPOINT/boxen/$box_id/mgmt_cards) + +### Mgmt-Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "mgmt_card_id": '$unit_11', + "admin_state": "1", + "operational_state": "1" +}' + +port_4_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/mgmt_ports) + + + ### Unit-19 ### # Create a physical card at the network device (admin operation) diff --git a/nesi/keymile/api/schemas/keymile_mgmt_card_schemas.py b/nesi/keymile/api/schemas/keymile_mgmt_card_schemas.py new file mode 100644 index 0000000..d4be416 --- /dev/null +++ b/nesi/keymile/api/schemas/keymile_mgmt_card_schemas.py @@ -0,0 +1,24 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.mgmt_card_schemas import * + + +class KeyMileMgmtCardSchema(MgmtCardSchema): + class Meta: + model = MgmtCard + fields = MgmtCardSchema.Meta.fields + ('board_name', 'supplier_build_state', 'board_id', 'hardware_key', + 'software','software_name', 'software_revision', 'state', 'serial_number', + 'manufacturer_name', 'model_name', 'short_text', 'manufacturer_id', + 'manufacturer_part_number', 'manufacturer_build_state', 'customer_id', + 'customer_product_id', 'boot_loader', 'processor', 'label1', 'label2', + 'product') diff --git a/nesi/keymile/api/schemas/keymile_mgmt_port_schemas.py b/nesi/keymile/api/schemas/keymile_mgmt_port_schemas.py new file mode 100644 index 0000000..9b0a12f --- /dev/null +++ b/nesi/keymile/api/schemas/keymile_mgmt_port_schemas.py @@ -0,0 +1,20 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.mgmt_port_schemas import * + + +class KeyMilePortSchema(MgmtPortSchema): + class Meta: + model = MgmtPort + fields = MgmtPortSchema.Meta.fields + ('label1', 'label2') + diff --git a/nesi/keymile/keymile_resources/__init__.py b/nesi/keymile/keymile_resources/__init__.py index 9e17078..4d2603c 100644 --- a/nesi/keymile/keymile_resources/__init__.py +++ b/nesi/keymile/keymile_resources/__init__.py @@ -1,2 +1,3 @@ __all__ = ["keymile_card", "keymile_port", "keymile_subrack", "keymile_channel", "keymile_interface", - "keymile_subscriber", "keymile_logport", "keymile_portgroupport", "keymile_srvc"] + "keymile_subscriber", "keymile_logport", "keymile_portgroupport", "keymile_srvc", "keymile_mgmt_card", + "keymile_mgmt_port"] diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index b53b9d7..c5467c0 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -62,11 +62,25 @@ def credentials(self): @property def cards(self): - """Return `CredentialsCollection` object.""" + """Return `cardCollection` object.""" return keymile_card.KeyMileCardCollection( self._conn, base.get_sub_resource_path_by( self, 'cards')) + @property + def mgmt_cards(self): + """Return `mgmtcardCollection` object.""" + return keymile_mgmt_card.KeyMileMgntCardCollection( + self._conn, base.get_sub_resource_path_by( + self, 'mgmt_cards')) + + @property + def mgmt_ports(self): + """Return `mgmtportCollection` object.""" + return keymile_mgmt_port.KeyMileMgmtPortCollection( + self._conn, base.get_sub_resource_path_by( + self, 'mgmt_ports')) + @property def subscribers(self): """Return `SubscriberCollection` object.""" @@ -103,6 +117,18 @@ def get_cards(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'cards'), params={field: value}) + def get_mgmt_card(self, field, value): + """Get specific mgnt card object.""" + return keymile_mgmt_card.KeyMileMgntCardCollection( + self._conn, base.get_sub_resource_path_by(self, 'mgmt_cards'), + params={field: value}).find_by_field_value(field, value) + + def get_mgmt_port(self, field, value): + """Get specific mgmtport object.""" + return keymile_mgmt_port.KeyMileMgmtPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'mgmt_ports'), + params={field: value}).find_by_field_value(field, value) + def get_port(self, field, value): """Get specific port object.""" return keymile_port.KeyMilePortCollection( diff --git a/nesi/keymile/keymile_resources/keymile_mgmt_card.py b/nesi/keymile/keymile_resources/keymile_mgmt_card.py new file mode 100644 index 0000000..acfa59f --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_mgmt_card.py @@ -0,0 +1,56 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.mgmt_card import MgmtCard, MgmtCardCollection, logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class KeyMileMgmtCard(MgmtCard): + """Represent physical shelf resource.""" + + board_name = base.Field('board_name') + supplier_build_state = base.Field('supplier_build_state') + board_id = base.Field('board_id') + hardware_key = base.Field('hardware_key') + software = base.Field('software') + software_name = base.Field('software_name') + software_revision = base.Field('software_revision') + state = base.Field('state') + serial_number = base.Field('serial_number') + manufacturer_name = base.Field('manufacturer_name') + model_name = base.Field('model_name') + short_text = base.Field('short_text') + manufacturer_id = base.Field('manufacturer_id') + manufacturer_part_number = base.Field('manufacturer_part_number') + manufacturer_build_state = base.Field('manufacturer_build_state') + customer_id = base.Field('customer_id') + customer_product_id = base.Field('customer_product_id') + boot_loader = base.Field('boot_loader') + processor = base.Field('processor') + label1 = base.Field('label1') + label2 = base.Field('label2') + product = base.Field('product') + + def set_label(self, l1, l2, desc): + self.update(label1=l1) + self.update(label2=l2) + self.update(description=desc) + + +class KeyMileMgntCardCollection(MgmtCardCollection): + """Represent a collection of cards.""" + + @property + def _resource_type(self): + return KeyMileMgmtCard diff --git a/nesi/keymile/keymile_resources/keymile_mgmt_port.py b/nesi/keymile/keymile_resources/keymile_mgmt_port.py new file mode 100644 index 0000000..fa92b38 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_mgmt_port.py @@ -0,0 +1,34 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.mgmt_port import MgmtPortCollection, MgmtPort, logging, base + +LOG = logging.getLogger(__name__) + + +class KeyMileMgmtPort(MgmtPort): + """Represent physical port resource.""" + label1 = base.Field('label1') + label2 = base.Field('label2') + + def set_label(self, l1, l2, desc): + self.update(label1=l1) + self.update(label2=l2) + self.update(description=desc) + + +class KeyMileMgmtPortCollection(MgmtPortCollection): + """Represent a collection of ports.""" + + @property + def _resource_type(self): + return KeyMileMgmtPort diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index b411a6b..9ed22a9 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -34,6 +34,8 @@ from .logport_models import LogPort from .interface_models import Interface from .srvc_models import Srvc +from .mgmt_card_models import MgmtCard +from .mgmt_port_models import MgmtPort class Box(db.Model): diff --git a/nesi/softbox/api/models/mgmt_card_models.py b/nesi/softbox/api/models/mgmt_card_models.py index 80cd845..2c24945 100644 --- a/nesi/softbox/api/models/mgmt_card_models.py +++ b/nesi/softbox/api/models/mgmt_card_models.py @@ -20,8 +20,30 @@ class MgmtCard(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) - description = db.Column(db.String(), default='None') subrack_id = db.Column(db.Integer, db.ForeignKey('subrack.id')) + mgmt_ports = db.relationship('MgmtPort', backref='MgmtCard', lazy='dynamic') + + description = db.Column(db.String(), default='') admin_state = db.Column(db.Enum('0', '1'), default='0') operational_state = db.Column(db.Enum('0', '1'), default='0') - mgmt_ports = db.relationship('MgmtPort', backref='MgmtCard', lazy='dynamic') + board_name = db.Column(db.String(), default='') + supplier_build_state = db.Column(db.Enum('R1G', 'R1D', 'R2B', 'R2A', 'R1K', 'R1H', 'R2B', 'R1E', 'R3D', 'R1C', + 'R1A', ''), default='') + board_id = db.Column(db.Enum('345', '332', '303', '308', '377', '356', '305', '307', '330', '0'), default='0') + hardware_key = db.Column(db.Integer(), default=0) + software = db.Column(db.String(), default='') + software_name = db.Column(db.String(), default='') + software_revision = db.Column(db.String(), default='') + state = db.Column(db.Enum('Ok', 'Empty'), default='Empty') + serial_number = db.Column(db.String(), default='') + manufacturer_name = db.Column(db.String(), default='') + model_name = db.Column(db.String(), default='') + short_text = db.Column(db.String(), default='') + manufacturer_id = db.Column(db.String(), default='') + manufacturer_part_number = db.Column(db.String(), default='') + manufacturer_build_state = db.Column(db.String(), default='') + customer_id = db.Column(db.String(), default='') + customer_product_id = db.Column(db.String(), default='') + boot_loader = db.Column(db.String(), default='') + processor = db.Column(db.String(), default='') + product = db.Column(db.Enum('mgmt'), nullable=False, default='mgmt') diff --git a/nesi/softbox/api/models/mgmt_port_models.py b/nesi/softbox/api/models/mgmt_port_models.py index 5fa2437..eb1b56e 100644 --- a/nesi/softbox/api/models/mgmt_port_models.py +++ b/nesi/softbox/api/models/mgmt_port_models.py @@ -17,7 +17,7 @@ class MgmtPort(db.Model): name = db.Column(db.String(64)) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) mgmt_card_id = db.Column(db.Integer, db.ForeignKey('mgmt_card.id')) + admin_state = db.Column(db.Enum('0', '1'), default='0') operational_state = db.Column(db.Enum('0', '1'), default='0') - description = db.Column(db.String(64)) diff --git a/nesi/softbox/base_resources/mgmt_card.py b/nesi/softbox/base_resources/mgmt_card.py index feef2d0..09c9273 100644 --- a/nesi/softbox/base_resources/mgmt_card.py +++ b/nesi/softbox/base_resources/mgmt_card.py @@ -22,9 +22,25 @@ class MgmtCard(base.Resource): """Represent physical shelf resource.""" id = base.Field('id') name = base.Field('name') - box_id = base.Field('box_id') description = base.Field('description') - subrack_id = base.Field('subrack_id') + admin_state = base.Field('admin_state') + operational_state = base.Field('operational_state') + + def admin_up(self): + """Set the admin port state to up""" + self.update(admin_state='1') + + def admin_down(self): + """Set the admin port state to down""" + self.update(admin_state='0') + + def down(self): + """Set the port state to down""" + self.update(operational_state='0') + + def up(self): + """Set the port state to down""" + self.update(operational_state='1') class MgmtCardCollection(base.ResourceCollection): diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 69f8a04..d5b5f38 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -28,7 +28,7 @@ class PortCommandProcessor(BaseCommandProcessor): def get_property(self, command, *args, context=None): port = self.get_port_component() - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -37,7 +37,7 @@ def get_property(self, command, *args, context=None): raise exc elif self._validate(args, 'Portprofile') and context['path'].split('/')[-1] == 'cfgm' and 'SUVM'\ - not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': + not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port' and card.product != 'mgmt': context['spacer1'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' context['profile_name'] = port.profile1_name text = self._render('port_profile', *scopes, context=context) @@ -64,7 +64,7 @@ def get_property(self, command, *args, context=None): context['spacer12'] = self.create_spacers((67,), (port.profile_mode,))[0] * ' ' text = self._render('port_profiles', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': + elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status' and card.product != 'mgmt': text = self._render('attainable_rate', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'QuickLoopbackTest') and context['path'].split('/')[-1] == 'status'\ @@ -80,7 +80,7 @@ def get_property(self, command, *args, context=None): text = self._render('line_results', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'MeltResults') and context['path'].split('/')[-1] == 'status'\ - and card.product != 'isdn' and self.__name__ == 'port': + and card.product != 'isdn' and self.__name__ == 'port' and card.product != 'mgmt': context['spacer1'] = self.create_spacers((67,), (port.melttest_state,))[0] * ' ' context['test_state'] = port.melttest_state text = self._render('melt_results', *scopes, context=context) @@ -109,7 +109,10 @@ def get_property(self, command, *args, context=None): def _init_access_points(self, context=None): self.access_points = () - port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + port = self.get_port_component() + + if port.name.startswith('11') or port.name.startswith('13'): + return for chan in self._model.get_chans('port_id', port.id): identifier = 'chan-' + chan.name.split('/')[-1] @@ -124,7 +127,7 @@ def _init_access_points(self, context=None): self.access_points += (identifier,) def do_lock(self, command, *args, context=None): - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: @@ -136,7 +139,7 @@ def do_lock(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_startquickloopbacktest(self, command, *args, context=None): - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: @@ -150,7 +153,7 @@ def do_startquickloopbacktest(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_startlinetest(self, command, *args, context=None): - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if len(args) == 0 and context['path'].split('/')[-1] == 'status' and 'SUP' in card.board_name \ and self.__name__ == 'port': try: @@ -164,9 +167,9 @@ def do_startlinetest(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_startmeltmeasurement(self, command, *args, context=None): - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product != 'isdn' \ - and self.__name__ == 'port': + and self.__name__ == 'port' and card.product != 'mgmt': try: port = self.get_port_component() port.set_melttest_state('Running') @@ -178,7 +181,7 @@ def do_startmeltmeasurement(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_unlock(self, command, *args, context=None): - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: @@ -193,7 +196,7 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_deleteinterface(self, command, *args, context=None): - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'ftth': # all or interface_id name, = self._dissect(args, str) @@ -215,7 +218,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUE' in card.board_name: # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) @@ -247,18 +250,21 @@ def do_createinterface(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def get_port_component(self): - return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + if self._parent.component_id == '11' or self._parent.component_id == '13': + return self._model.get_mgmt_port('name', self._parent.component_id + '/' + self.component_id) + else: + return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc elif self._validate(args, 'Portprofile', str) and context['path'].split('/')[-1] == 'cfgm' and 'SUVM'\ - not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': + not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port' and card.product != 'mgmt': profile, = self._dissect(args, 'Portprofile', str) try: port = self.get_port_component() @@ -268,7 +274,7 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'Portprofiles', str) and context['path'].split('/')[-1] == 'cfgm' and \ - 'SUVD2' in card.board_name and self.__name__ == 'port': + 'SUVD2' in card.board_name and self.__name__ == 'port' and card.product != 'mgmt': profile, = self._dissect(args, 'Portprofiles', str) try: port = self.get_port_component() diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index cc7a690..8c1d5d9 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -28,7 +28,7 @@ class UnitCommandProcessor(BaseCommandProcessor): def _init_access_points(self, context=None): self.access_points = () try: - card = self._model.get_card('name', self.component_id) + card = self.get_component() self.management_functions = ('main', 'cfgm', 'fm', 'status') @@ -45,6 +45,12 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) + for port in self._model.get_mgmt_port('mgmt_card_id', card.id): + identifier = 'port-' + port.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + for gport in self._model.get_portgroupports('card_id', card.id): identifier = 'portgroup-' + gport.name.split('/')[1][1] if identifier in self.access_points: @@ -54,7 +60,7 @@ def _init_access_points(self, context=None): pass def get_property(self, command, *args, context=None): - card = self._model.get_card('name', self.component_id) + card = self.get_component() scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -121,7 +127,7 @@ def get_property(self, command, *args, context=None): text = self._render('labels', *scopes, context=dict(context, port=card)) self._write(text) - elif self._validate(args, 'Registrar') and context['path'].split('/')[-1] == 'cfgm': + elif self._validate(args, 'Registrar') and context['path'].split('/')[-1] == 'cfgm' and card.product != 'mgmt': context['spacer1'] = self.create_spacers((67,), (card.registrar_adress,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (card.registrar_port,))[0] * ' ' context['spacer3'] = self.create_spacers((67,), (card.registration_mode,))[0] * ' ' @@ -230,11 +236,17 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def get_component(self): - return self._model.get_card('name', self.component_id) + try: + if self.component_id == '11' or self.component_id == '13': + return self._model.get_mgmt_card('name', self.component_id) + else: + return self._model.get_card('name', self.component_id) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError() def set(self, command, *args, context=None): try: - card = self._model.get_card('name', self.component_id) + card = self.get_component() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) if self._validate(args, *()): @@ -250,7 +262,8 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'Ip', str, str, str) and context['component_path'].split('/')[-1] == 'cfgm': + elif self._validate(args, 'Ip', str, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and \ + card.product != 'mgmt': ip1, ip2, ip3 = self._dissect(args, 'Ip', str, str, str) try: component = self.get_component() @@ -291,7 +304,7 @@ def set(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_restart(self, command, *args, context=None): - card = self._model.get_card('name', self.component_id) + card = self.get_component() if len(args) == 0 and context['path'].split('/')[-1] == 'main' and (card.product == 'isdn' or card.product == 'analog'): time.sleep(10) exc = exceptions.TerminalExitError() diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index f300be3..9dc2cab 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -307,7 +307,10 @@ def change_directory(self, path, context=None): template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'port': try: - self._model.get_port('name', self.component_id + '/' + component_id) + if self.component_id == '11' or self.component_id == '13': + self._model.get_mgmt_port('name', self.component_id + '/' + component_id) + else: + self._model.get_port('name', self.component_id + '/' + component_id) except exceptions.InvalidInputError: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty From ea2497a034e722f7ea9039f90506ee475c2d47d5 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 20 Oct 2020 14:36:16 +0200 Subject: [PATCH 134/318] Added Mgmt Card and Mgmt Port Command Processors --- nesi/keymile/keymile_resources/keymile_box.py | 6 + .../mgmt_port/mgmtportCommandProcessor.py | 104 ++++++ .../mgmt_port/mgmtportManagementFunctions.py | 334 ++++++++++++++++++ .../mgmt_unit/mgmtunitCommandProcessor.py | 139 ++++++++ .../mgmt_unit/mgmtunitManagementFunctions.py | 194 ++++++++++ .../unit/logport/logportsCommandProcessor.py | 2 +- .../logport/port/logportCommandProcessor.py | 4 +- .../root/unit/port/portCommandProcessor.py | 50 ++- .../port/portgroupportCommandProcessor.py | 12 +- .../root/unit/unitCommandProcessor.py | 13 +- vendors/KeyMile/baseCommandProcessor.py | 15 + 11 files changed, 826 insertions(+), 47 deletions(-) create mode 100644 vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index c5467c0..09f1e61 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -129,6 +129,12 @@ def get_mgmt_port(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'mgmt_ports'), params={field: value}).find_by_field_value(field, value) + def get_mgmt_ports(self, field, value): + """Get specific mgmtport object.""" + return keymile_mgmt_port.KeyMileMgmtPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'mgmt_ports'), + params={field: value}) + def get_port(self, field, value): """Get specific port object.""" return keymile_port.KeyMilePortCollection( diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py new file mode 100644 index 0000000..dae5325 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py @@ -0,0 +1,104 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor +import time + + +class MgmtportCommandProcessor(BaseCommandProcessor): + __name__ = 'mgmtport' + management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') + access_points = () + + from .mgmtportManagementFunctions import main + from .mgmtportManagementFunctions import cfgm + from .mgmtportManagementFunctions import fm + from .mgmtportManagementFunctions import pm + from .mgmtportManagementFunctions import status + + def get_property(self, command, *args, context=None): + port = self.get_port_component() + card = self._parent.get_component() + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + + elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': + self.map_states(port, 'port') + context['spacer'] = self.create_spacers((67,), (port.admin_state,))[0] * ' ' + text = self._render('administrative_status', *scopes, context=dict(context, port=port)) + self._write(text) + elif self._validate(args, 'Labels') and context['path'].split('/')[-1] == 'main': + context['spacer1'] = self.create_spacers((67,), (port.label1,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (port.label2,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (port.description,))[0] * ' ' + text = self._render('labels', *scopes, context=dict(context, port=port)) + self._write(text) + elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': + self.map_states(port, 'port') + port_operational_state = port.operational_state + context['port_operational_state'] = port_operational_state + context['spacer'] = self.create_spacers((67,), (port_operational_state,))[0] * ' ' + text = self._render('operational_status', *scopes, context=context) + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + + def _init_access_points(self, context=None): + self.access_points = () + return + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) + + def get_port_component(self): + if self._parent.component_id == '11' or self._parent.component_id == '13': + raise exceptions.CommandSyntaxError() + else: + return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + + def set(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + card = self._parent.get_component() + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'AdministrativeStatus', str) and context['path'].split('/')[-1] == 'main': + state, = self._dissect(args, 'AdministrativeStatus', str) + try: + port = self.get_port_component() + if state == 'up': + port.admin_up() + elif state == 'down': + port.admin_down() + else: + raise exceptions.SoftboxenError() + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': + label1, label2, description = self._dissect(args, 'Labels', str, str, str) + try: + port = self.get_port_component() + port.set_label(label1, label2, description) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py new file mode 100644 index 0000000..9529dba --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py @@ -0,0 +1,334 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + } +} + +cfgm = { + 'Multicast': { + 'Prop': { + 'MaxNumberOfMulticastStreams': 'rw', + 'EnableIgmpClassifier': 'rw', + 'AllowStaticStreams': 'rw', + 'EnableFastLeave': 'rw', + 'GroupManagement': 'rw', + 'Bandwidth': 'rw' + }, + 'Cmd': ( + 'GetGroupList', + ) + }, + 'Traceability': { + 'Prop': { + 'AgentRemoteId': 'rw' + } + }, + 'Security': { + 'Prop': { + 'ServiceOptions': 'rw', + 'MaxNumberOfMac': 'rw' + } + }, + 'AccessControl': { + 'Prop': { + 'ClassificationKey': 'rw', + 'MAT': 'rw' + } + }, + 'RateLimiter': { + 'Prop': { + 'RateLimiting': 'rw', + 'RateLimitingCoS': 'rw' + } + }, + 'Qos': { + 'Prop': { + 'WfqProfile': 'rw' + } + }, + 'Wire': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'PortProfiles': 'rw' + } + }, + 'Misc': { + 'Prop': { + 'SpecificDPBO': 'rw', + 'SpecificUPBO': 'rw' + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } +} + +status = { + 'General': { + 'Prop': { + 'Standard': 'r-', + 'PowerMgmStatus': 'r-', + 'Vdsl2Parameters': 'r-', + 'EstUPBOElectricalLength': 'r-', + 'LineRate': 'r-', + 'LineSnrMargin': 'r-', + 'AttainableNetDataRate': 'r-', + 'AttainableRate': 'r-', + 'OutputPower': 'r-', + 'BandStatus': 'r-' + } + }, + 'statistics': { + 'Prop': { + 'counters': 'r-', + 'PolicingCounters': 'r-' + }, + 'Cmd': ( + 'ResetPortCounters', + ) + }, + 'Nto1MacAccessDynamicList': { + 'Prop': { + 'UnicastList': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters', + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + }, + }, + 'TLSMacForwardingList': { + 'Prop': { + 'MacForwardingList': 'r-' + }, + 'Cmd': ( + 'FlushMacForwardingList', + ) + }, + '1to1MacForwardingList': { + 'Prop': { + 'One2OneMacForwardingList': 'r-' + } + }, + 'Qos': { + 'Prop': { + 'wfqueues': 'r-' + } + }, + 'Multicast': { + 'stream': { + 'Dynamic': { + 'Prop': { + 'ActiveStreams': 'r-' + }, + 'Cmd': ( + 'ClearActiveStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticStreams': 'r-' + } + }, + }, + + 'Vlan': { + 'Prop': { + 'AttachedVlans': 'r-' + } + }, + 'Preview': { + 'Cmd': ( + 'ResetPreviewSettings', + ) + }, + 'Bandwidth': { + 'Prop': { + 'bandwidthStatus': 'r-' + } + }, + }, + 'LineTest': { + 'MELT': { + 'Prop': { + 'MeltResults': 'r-' + }, + 'Cmd': ( + 'StartMeltMeasurement', + ) + }, + 'Delt': { + 'Prop': { + 'DeltMeasurementStatus': 'r-', + 'RecordedDeltMeasurements': 'r-' + }, + 'Cmd': ( + 'StartDeltMeasurement', + ) + }, + 'Selt': { + 'Prop': { + 'SeltMeasurementStatus': 'r-', + 'RecordedSeltMeasurements': 'r-', + 'CableType': 'rw', + 'BandplanProfile': 'rw', + 'TargetSnrm': 'rw' + }, + 'Cmd': ( + 'StartSeltMeasurement', + ) + }, + }, + 'Defects': { + 'Prop': { + 'Defects': 'r-' + } + }, + 'LineInventory': { + 'Prop': { + 'VendorId': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'DslOperationStatus': 'r-' + } + }, + 'Subcarrier': { + 'Cmd': ( + 'ShowBitAllocation', + ) + }, + 'RfiBands': { + 'Prop': { + 'NotchStatus': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py new file mode 100644 index 0000000..78de871 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py @@ -0,0 +1,139 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst +import time + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class MgmtunitCommandProcessor(BaseCommandProcessor): + __name__ = 'mgmtunit' + management_functions = ('main', 'fm') + access_points = () # 'internalPorts', only on certain cards + + from .mgmtunitManagementFunctions import main + from .mgmtunitManagementFunctions import cfgm + from .mgmtunitManagementFunctions import fm + from .mgmtunitManagementFunctions import status + + def _init_access_points(self, context=None): + self.access_points = () + try: + card = self.get_component() + + self.management_functions = ('main', 'cfgm', 'fm', 'status') + + for port in self._model.get_mgmt_ports('mgmt_card_id', card.id): + identifier = 'port-' + port.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + + except exceptions.InvalidInputError: + pass + + def get_property(self, command, *args, context=None): + card = self.get_component() + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'Labels') and context['path'].split('/')[-1] == 'main': + context['spacer1'] = self.create_spacers((67,), (card.label1,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (card.label2,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (card.description,))[0] * ' ' + text = self._render('labels', *scopes, context=dict(context, port=card)) + self._write(text) + elif self._validate(args, 'EquipmentInventory') and context['path'].split('/')[-1] == 'main': + unit_symbol = '"' + card.board_name + '"' + context['unit_symbol'] = unit_symbol + context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' + unit_short_text = '"' + card.short_text + '"' + context['unit_short_text'] = unit_short_text + context['spacer_2'] = self.create_spacers((67,), (unit_short_text,))[0] * ' ' + unit_board_id = card.board_id + context['unit_board_id'] = unit_board_id + context['spacer_3'] = self.create_spacers((67,), (unit_board_id,))[0] * ' ' + unit_hardware_key = card.hardware_key + context['unit_hardware_key'] = unit_hardware_key + context['spacer_4'] = self.create_spacers((67,), (unit_hardware_key,))[0] * ' ' + unit_manufacturer_id = '"' + card.manufacturer_id + '"' + context['unit_manufacturer_id'] = unit_manufacturer_id + context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_id,))[0] * ' ' + unit_serial_number = '"' + card.serial_number + '"' + context['unit_serial_number'] = unit_serial_number + context['spacer_6'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' + unit_manufacturer_part_number = '"' + card.manufacturer_part_number + '"' + context['unit_manufacturer_part_number'] = unit_manufacturer_part_number + context['spacer_7'] = self.create_spacers((67,), (unit_manufacturer_part_number,))[0] * ' ' + unit_manufacturer_build_state = '"' + card.manufacturer_build_state + '"' + context['unit_manufacturer_build_state'] = unit_manufacturer_build_state + context['spacer_8'] = self.create_spacers((67,), (unit_manufacturer_build_state,))[0] * ' ' + unit_supplier_part_number = '"' + card.model_name + '"' + context['unit_supplier_part_number'] = unit_supplier_part_number + context['spacer_9'] = self.create_spacers((67,), (unit_supplier_part_number,))[0] * ' ' + unit_supplier_build_state = '"' + card.supplier_build_state + '"' + context['unit_supplier_build_state'] = unit_supplier_build_state + context['spacer_10'] = self.create_spacers((67,), (unit_supplier_build_state,))[0] * ' ' + unit_customer_id = '"' + card.customer_id + '"' + context['unit_customer_id'] = unit_customer_id + context['spacer_11'] = self.create_spacers((67,), (unit_customer_id,))[0] * ' ' + unit_customer_product_id = '"' + card.customer_product_id + '"' + context['unit_customer_product_id'] = unit_customer_product_id + context['spacer_12'] = self.create_spacers((67,), (unit_customer_product_id,))[0] * ' ' + unit_boot_loader = '"' + card.boot_loader + '"' + context['unit_boot_loader'] = unit_boot_loader + context['spacer_13'] = self.create_spacers((67,), (unit_boot_loader,))[0] * ' ' + unit_processor = '"' + card.processor + '"' + context['unit_processor'] = unit_processor + context['spacer_14'] = self.create_spacers((67,), (unit_processor,))[0] * ' ' + text = self._render('equipment_inventory', *scopes, context=context) + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) + + def get_component(self): + try: + if self.component_id == '11' or self.component_id == '13': + return self._model.get_mgmt_card('name', self.component_id) + else: + raise exceptions.CommandSyntaxError() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError() + + def set(self, command, *args, context=None): + try: + card = self.get_component() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': + label1, label2, description = self._dissect(args, 'Labels', str, str, str) + try: + component = self.get_component() + component.set_label(label1, label2, description) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + else: + raise exceptions.CommandSyntaxError(command=command) + diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py new file mode 100644 index 0000000..0a5adbd --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py @@ -0,0 +1,194 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'Equipment': { + 'Prop': { + 'AssignmentStatus': 'r-', + 'CurrentStatus': 'r-' + }, + 'Cmd': ( + 'Assign', + 'Unassign', + 'Restart', + 'StopInBoot' + ) + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + }, + 'Logbooks': { + 'Cmd': ( + 'GetAlarmLogbook', + 'GetEventLogbook', + 'GetEquipmentLogbook' + ) + }, + 'Software': { + 'Prop': { + 'DiskSpace': 'r-', + 'SoftwareOnUnit': 'r-', + 'HardwareAndSoftware': 'r-', + 'Status': 'r-', + 'Configuration': 'rw' + }, + 'Cmd': ( + 'DeleteSoftware', + 'StartSoftware' + ), + 'File': { + 'Software': 'rw' + } + } +} + +cfgm = { + 'Vlan': { + 'Prop': { + 'VlanCosTable': 'r-' + } + }, + 'Security': { + 'Prop': { + 'filtering': 'rw', + 'EoamMode': 'rw' + } + }, + 'Logon': { + 'Prop': { + 'LogonOptions': 'rw', + 'OneToOneOptions': 'rw' + } + }, + 'Mac': { + 'Prop': { + 'MacServiceBased': 'rw' + } + }, + 'HostPort': { + 'Prop': { + 'PolicerProfile': 'rw', + 'TrunkPolicerProfile': 'rw', + 'ProtRateLimiter': 'rw' + } + }, + 'QoS': { + 'Prop': { + 'ColorMarking': 'rw' + } + }, + 'Wire': { + 'General': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Thresholds': { + 'Prop': { + 'MeltAlarmThresholds': 'rw' + } + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +status = { + 'MacAllocationTable': { + 'Prop': { + 'MacAllocationTableEntries': 'r-' + } + }, + 'SwitchPort': { + 'Prop': { + 'Mac': 'r-', + 'MacStatus': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters', + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + }, + }, + 'BufferManagement': { + 'Prop': { + 'BufferMgmtStatus': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'MeltLineTestStatus': 'r-', + 'SearchTone': 'rw' + }, + 'Cmd': ( + 'StartMeltAll', + 'StopMeltAll' + ) + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 9e76d14..5a36410 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -69,7 +69,7 @@ def do_create(self, command, *args, context=None): _ = self._model.get_logport('name', self._parent.component_id + '/L/' + str(x)) break except exceptions.SoftboxenError: - name = self._parent.component_id + '/L/' + str(ids[0]) + name = self._parent.component_id + '/L/' + str(ids[0]) ports = 'ports: ' for x in ids: ports += str(x) + ', ' diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 8d7b5b7..3bc74fb 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -27,7 +27,7 @@ class LogportCommandProcessor(PortCommandProcessor): from .logportManagementFunctions import ifMIB def get_property(self, command, *args, context=None): - port = self.get_port_component() + port = self.get_component() scopes = ('login', 'base', 'get') try: super().get_property(command, *args, context=context) @@ -39,7 +39,7 @@ def get_property(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - def get_port_component(self): + def get_component(self): return self._model.get_logport('name', self._parent._parent.component_id + '/L/' + self.component_id) def _init_access_points(self, context=None): diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index d5b5f38..a7a4f50 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -27,7 +27,7 @@ class PortCommandProcessor(BaseCommandProcessor): from .portManagementFunctions import status def get_property(self, command, *args, context=None): - port = self.get_port_component() + port = self.get_component() card = self._parent.get_component() scopes = ('login', 'base', 'get') if self._validate(args, *()): @@ -37,7 +37,7 @@ def get_property(self, command, *args, context=None): raise exc elif self._validate(args, 'Portprofile') and context['path'].split('/')[-1] == 'cfgm' and 'SUVM'\ - not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port' and card.product != 'mgmt': + not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' context['profile_name'] = port.profile1_name text = self._render('port_profile', *scopes, context=context) @@ -64,7 +64,7 @@ def get_property(self, command, *args, context=None): context['spacer12'] = self.create_spacers((67,), (port.profile_mode,))[0] * ' ' text = self._render('port_profiles', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status' and card.product != 'mgmt': + elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'QuickLoopbackTest') and context['path'].split('/')[-1] == 'status'\ @@ -80,7 +80,7 @@ def get_property(self, command, *args, context=None): text = self._render('line_results', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'MeltResults') and context['path'].split('/')[-1] == 'status'\ - and card.product != 'isdn' and self.__name__ == 'port' and card.product != 'mgmt': + and card.product != 'isdn' and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.melttest_state,))[0] * ' ' context['test_state'] = port.melttest_state text = self._render('melt_results', *scopes, context=context) @@ -109,10 +109,7 @@ def get_property(self, command, *args, context=None): def _init_access_points(self, context=None): self.access_points = () - port = self.get_port_component() - - if port.name.startswith('11') or port.name.startswith('13'): - return + port = self.get_component() for chan in self._model.get_chans('port_id', port.id): identifier = 'chan-' + chan.name.split('/')[-1] @@ -131,7 +128,7 @@ def do_lock(self, command, *args, context=None): if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: - port = self.get_port_component() + port = self.get_component() port.lock_admin() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -143,7 +140,7 @@ def do_startquickloopbacktest(self, command, *args, context=None): if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: - port = self.get_port_component() + port = self.get_component() port.set_test_state('Running') time.sleep(5) port.set_test_state('Passed') @@ -157,7 +154,7 @@ def do_startlinetest(self, command, *args, context=None): if len(args) == 0 and context['path'].split('/')[-1] == 'status' and 'SUP' in card.board_name \ and self.__name__ == 'port': try: - port = self.get_port_component() + port = self.get_component() port.set_test_state('Running') time.sleep(5) port.set_linetest_state('Passed') @@ -169,9 +166,9 @@ def do_startlinetest(self, command, *args, context=None): def do_startmeltmeasurement(self, command, *args, context=None): card = self._parent.get_component() if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product != 'isdn' \ - and self.__name__ == 'port' and card.product != 'mgmt': + and self.__name__ == 'port': try: - port = self.get_port_component() + port = self.get_component() port.set_melttest_state('Running') time.sleep(5) port.set_melttest_state('Passed') @@ -185,7 +182,7 @@ def do_unlock(self, command, *args, context=None): if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: - port = self.get_port_component() + port = self.get_component() port.unlock_admin() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -201,7 +198,7 @@ def do_deleteinterface(self, command, *args, context=None): # all or interface_id name, = self._dissect(args, str) if name == 'all': - port = self.get_port_component() + port = self.get_component() for interface in self._model.get_interfaces('port_id', port.id): interface.delete() elif name.startswith('interface-'): @@ -224,7 +221,7 @@ def do_createinterface(self, command, *args, context=None): vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names try: - port = self.get_port_component() + port = self.get_component() id = 1 for interface in self._model.get_interfaces('port_id', port.id): if interface.port_id is not None: @@ -249,11 +246,8 @@ def do_createinterface(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def get_port_component(self): - if self._parent.component_id == '11' or self._parent.component_id == '13': - return self._model.get_mgmt_port('name', self._parent.component_id + '/' + self.component_id) - else: - return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + def get_component(self): + return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') @@ -264,20 +258,20 @@ def set(self, command, *args, context=None): exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc elif self._validate(args, 'Portprofile', str) and context['path'].split('/')[-1] == 'cfgm' and 'SUVM'\ - not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port' and card.product != 'mgmt': + not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': profile, = self._dissect(args, 'Portprofile', str) try: - port = self.get_port_component() + port = self.get_component() port.set_profile(profile) except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'Portprofiles', str) and context['path'].split('/')[-1] == 'cfgm' and \ - 'SUVD2' in card.board_name and self.__name__ == 'port' and card.product != 'mgmt': + 'SUVD2' in card.board_name and self.__name__ == 'port': profile, = self._dissect(args, 'Portprofiles', str) try: - port = self.get_port_component() + port = self.get_component() port.set_profile(profile) except exceptions.SoftboxenError(): @@ -288,7 +282,7 @@ def set(self, command, *args, context=None): en1, name1, elen1, en2, name2, elen2, en3, name3, elen3, en4, name4, mode = self._dissect(args, 'Portprofiles', str, str, str, str, str, str, str, str, str, str, str, str) try: - port = self.get_port_component() + port = self.get_component() en1 = True if en1.lower() == 'true' else False en2 = True if en2.lower() == 'true' else False en3 = True if en3.lower() == 'true' else False @@ -301,7 +295,7 @@ def set(self, command, *args, context=None): elif self._validate(args, 'AdministrativeStatus', str) and context['path'].split('/')[-1] == 'main': state, = self._dissect(args, 'AdministrativeStatus', str) try: - port = self.get_port_component() + port = self.get_component() if state == 'up': port.admin_up() elif state == 'down': @@ -314,7 +308,7 @@ def set(self, command, *args, context=None): elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': label1, label2, description = self._dissect(args, 'Labels', str, str, str) try: - port = self.get_port_component() + port = self.get_component() port.set_label(label1, label2, description) except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index e22f293..67bcda4 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -23,11 +23,11 @@ class PortgroupportCommandProcessor(PortCommandProcessor): from .portgroupportManagementFunctions import cfgm from .portgroupportManagementFunctions import status - def get_port_component(self): + def get_component(self): return self._model.get_portgroupport('name', self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id) def get_property(self, command, *args, context=None): - port = self.get_port_component() + port = self.get_component() scopes = ('login', 'base', 'get') try: super().get_property(command, *args, context=context) @@ -131,7 +131,7 @@ def set(self, command, *args, context=None): enable, subident, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', str, str, str, str, str, str, str, str, str) try: - port = self.get_port_component() + port = self.get_component() enable = True if enable.lower() == 'true' else False register = True if register.lower() == 'true' else False phone = True if phone.lower() == 'true' else False @@ -143,7 +143,7 @@ def set(self, command, *args, context=None): str) and context['path'].split('/')[-1] == 'cfgm': enable, number, username, password, displayname, privacy, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) try: - port = self.get_port_component() + port = self.get_component() try: subscriber = self._model.get_subscriber('number', int(number)) subscriber.set('autorisation_user_name', username) @@ -167,7 +167,7 @@ def set(self, command, *args, context=None): str) and context['path'].split('/')[-1] == 'cfgm': enable, number, username, password, displayname, privacy, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) try: - port = self.get_port_component() + port = self.get_component() try: subscriber = self._model.get_subscriber('number', int(number)) assert subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id @@ -196,7 +196,7 @@ def set(self, command, *args, context=None): enable, subident, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', str, str, str, str, str, str, str, str, str) try: - port = self.get_port_component() + port = self.get_component() enable = True if enable.lower() == 'true' else False register = True if register.lower() == 'true' else False regdefault = True if regdefault.lower() == 'true' else False diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 8c1d5d9..f20ce24 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -45,12 +45,6 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) - for port in self._model.get_mgmt_port('mgmt_card_id', card.id): - identifier = 'port-' + port.name.split('/')[-1] - if identifier in self.access_points: - continue - self.access_points += (identifier,) - for gport in self._model.get_portgroupports('card_id', card.id): identifier = 'portgroup-' + gport.name.split('/')[1][1] if identifier in self.access_points: @@ -127,7 +121,7 @@ def get_property(self, command, *args, context=None): text = self._render('labels', *scopes, context=dict(context, port=card)) self._write(text) - elif self._validate(args, 'Registrar') and context['path'].split('/')[-1] == 'cfgm' and card.product != 'mgmt': + elif self._validate(args, 'Registrar') and context['path'].split('/')[-1] == 'cfgm': context['spacer1'] = self.create_spacers((67,), (card.registrar_adress,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (card.registrar_port,))[0] * ' ' context['spacer3'] = self.create_spacers((67,), (card.registration_mode,))[0] * ' ' @@ -238,7 +232,7 @@ def on_unknown_command(self, command, *args, context=None): def get_component(self): try: if self.component_id == '11' or self.component_id == '13': - return self._model.get_mgmt_card('name', self.component_id) + raise exceptions.CommandSyntaxError() else: return self._model.get_card('name', self.component_id) except exceptions.SoftboxenError: @@ -262,8 +256,7 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'Ip', str, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and \ - card.product != 'mgmt': + elif self._validate(args, 'Ip', str, str, str) and context['component_path'].split('/')[-1] == 'cfgm': ip1, ip2, ip3 = self._dissect(args, 'Ip', str, str, str) try: component = self.get_component() diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 9dc2cab..70e3f22 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -279,6 +279,11 @@ def change_directory(self, path, context=None): if component_type == 'port': if self.__name__ == 'portgroup': component_type = 'portgroupport' + elif self.__name__ == 'mgmtunit': + component_type = 'mgmtport' + if component_type == 'unit': + if component_id == '11' or component_id == '13': + component_type = 'mgmtunit' command_processor = component_type.capitalize() + 'CommandProcessor' else: @@ -322,6 +327,14 @@ def change_directory(self, path, context=None): if self.__name__ != 'port': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'mgmtunit': + if self.__name__ != 'root': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'mgmtport': + if self.__name__ != 'mgmtunit': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'interface': if self.__name__ != 'port' and self.__name__ != 'chan' and self.__name__ != 'logport': raise exceptions.CommandExecutionError(command=None, template=None, @@ -399,6 +412,8 @@ def change_directory(self, path, context=None): MacaccessctrlCommandProcessor from vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor import SubpacketCommandProcessor from vendors.KeyMile.accessPoints.root.services.srvcCommandProcessor import SrvcCommandProcessor + from vendors.KeyMile.accessPoints.root.mgmt_unit.mgmtunitCommandProcessor import MgmtunitCommandProcessor + from vendors.KeyMile.accessPoints.root.mgmt_unit.mgmt_port.mgmtportCommandProcessor import MgmtportCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if component_id is not None and self.component_id is not None: From 24fd0a84d7eff93526b52dc3b3b92d12d87be627 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 20 Oct 2020 15:06:51 +0200 Subject: [PATCH 135/318] Restructured change_directory function and fixed some navigation bugs --- vendors/KeyMile/baseCommandProcessor.py | 146 +++++++++++++++--------- 1 file changed, 91 insertions(+), 55 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 70e3f22..672c667 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -201,63 +201,32 @@ def do_ls(self, command, *args, context=None): def change_directory(self, path, context=None): path = path.lower() - if re.search('^(?:[^.]+/)+\.\.$', path): + + if re.search('^(?:[^.]+/)+\.{1,2}$', path): raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) - if re.search('^(?:[^.]+/)+\.\.(?:/.+)+$', path): + if re.search('^(?:[^.]+/)+\.{1,2}(?:/.+)+$', path): raise exceptions.CommandExecutionError(template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors'), command=None) - if path == '/': - if self.__name__ != 'root': - return self._parent.change_directory(path, context=context) - else: - context['path'] = '/' - return self + allowed_path_components = ( + 'unit-[0-9]+', 'port-[0-9]+', 'portgroup-[0-9]+', 'chan-[0-9]+', 'interface-[0-9]+', 'vcc-[0-9]+', + 'alarm-[0-9]+', 'main', 'cfgm', 'fm', 'pm', 'status', 'eoam', 'fan', 'multicast', 'services', 'packet', + 'srvc-[0-9]', 'macaccessctrl', 'tdmconnections', 'logports', 'logport-[0-9]', '1to1doubletag', + '1to1singletag', 'mcast', 'nto1', 'pls', 'tls', '\.', '\.\.' + ) components = [x for x in path.split('/') if x] - - if not re.search( - '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|srvc-[0-9]|macaccessctrl|tdmconnections|logports|logport-[0-9]|1to1doubletag|1to1singletag|mcast|nto1|pls|tls|\.|\.\.)$', - components[0]): - raise exceptions.CommandExecutionError(template='invalid_management_function_error', - template_scopes=('login', 'base', 'execution_errors'), - command=None) - - if path == '.': - return self - - if path.startswith('./'): - if path == './': - return self - - return self.change_directory(path[2:], context=context) - - if path.startswith('..'): - splitted_path = [x for x in context['path'].split('/') if x] - exit_component = None - if len(splitted_path) != 0: - exit_component = splitted_path.pop() - context['path'] = '/' + '/'.join(splitted_path) - - if exit_component in ('main', 'cfgm', 'fm', 'pm', 'status'): - self.set_prompt_end_pos(context=context) - if path != '..': - return self.change_directory(path[3:], context=context) - return self - - if path == '..': - if self.__name__ == 'root': + if path.startswith('/'): + if path == '/': + if self.__name__ != 'root': + return self._parent.change_directory(path, context=context) + else: + context['path'] = '/' return self - return self._parent - if self.__name__ == 'root': - return self.change_directory(path[3:], context=context) - - return self._parent.change_directory(path[3:], context=context) - if path.startswith('/'): if 'unit-' not in components[0] and components[0] not in ( 'eoam', 'fan', 'multicast', 'services', 'tdmConnection', 'main', 'cfgm', 'fm', 'pm', 'status'): raise exceptions.CommandExecutionError(command=None, template=None, @@ -268,7 +237,44 @@ def change_directory(self, path, context=None): else: context['path'] = '/' subprocessor = self.change_directory(path.lstrip('/'), context=context) + elif path.startswith('.'): + if path == '.': + return self + + if path.startswith('./'): + if path == './': + return self + + return self.change_directory(path[2:], context=context) + + if path.startswith('..'): + splitted_path = [x for x in context['path'].split('/') if x] + exit_component = None + if len(splitted_path) != 0: + exit_component = splitted_path.pop() + context['path'] = '/' + '/'.join(splitted_path) + + if exit_component in ('main', 'cfgm', 'fm', 'pm', 'status'): + self.set_prompt_end_pos(context=context) + if path != '..': + return self.change_directory(path[3:], context=context) + return self + + if path == '..' or path == '../': + if self.__name__ == 'root': + return self + return self._parent + + if self.__name__ == 'root': + return self.change_directory(path[3:], context=context) + + return self._parent.change_directory(path[3:], context=context) else: + if not re.search('^(' + '|'.join(allowed_path_components) + ')$', components[0]): + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + remaining_args = '/'.join(components[1:]) component_type = None @@ -324,6 +330,12 @@ def change_directory(self, path, context=None): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'chan': + try: + self._model.get_chan('name', self._parent.component_id + '/' + self.component_id + '/' + component_id) + except exceptions.InvalidInputError: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if self.__name__ != 'port': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty @@ -336,19 +348,47 @@ def change_directory(self, path, context=None): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'interface': + try: + self._model.get_interface('name', self._parent.component_id + '/' + self.component_id + '/' + component_id) + except exceptions.InvalidInputError: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if self.__name__ != 'port' and self.__name__ != 'chan' and self.__name__ != 'logport': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'logport': + try: + self._model.get_logport('name', self._parent.component_id + '/L/' + component_id) + except exceptions.InvalidInputError: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if self.__name__ != 'logports': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'vcc': + try: + self._model.get_interface('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + component_id) + except exceptions.InvalidInputError: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if self.__name__ != 'chan': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'srvc': + try: + self._model.get_srvc('name', 'srvc-' + component_id) + except exceptions.InvalidInputError: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + + if self.__name__ != 'subpacket': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty - elif components[0] in ('packet', 'macAccessCtrl'): + if components[0] in ('packet', 'macAccessCtrl'): if self.__name__ != 'services': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty @@ -386,6 +426,7 @@ def change_directory(self, path, context=None): else: new_path = '/' + components[0] context['path'] += new_path + self.set_prompt_end_pos(context=context) return self from vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor import UnitCommandProcessor @@ -416,19 +457,13 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.mgmt_unit.mgmt_port.mgmtportCommandProcessor import MgmtportCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') - if component_id is not None and self.component_id is not None: - subprocessor.set_component_id(self.component_id + '/' + component_id) - if component_id is not None: subprocessor.set_component_id(component_id) if context['path'] == '/': new_path = components[0] else: - if path == 'subpacket': - new_path = '/' + context['ServiceType'] - else: - new_path = '/' + components[0] + new_path = '/' + components[0] context['path'] += new_path if len(remaining_args) > 0: @@ -492,7 +527,8 @@ def do_cd(self, command, *args, context=None): except: context['path'] = current_path raise - subprocessor.loop(context=context, return_to=subprocessor._parent) + if not isinstance(subprocessor, self.__class__): + subprocessor.loop(context=context, return_to=subprocessor._parent) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), From 0977239437e7df5e2e54ef06a58235d3e88f73da Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 20 Oct 2020 15:27:27 +0200 Subject: [PATCH 136/318] Refactored integration test files --- .../conf/bootstraps/create-keymile-MG2500.sh | 19 +++- .../keymile/getInventory2.txt | 10 +-- .../keymile/getMonitoring3.txt | 8 -- .../integration_tests/keymile/getState1.txt | 87 +++++-------------- .../integration_tests/keymile/getVoice5.txt | 6 +- .../keymile/setChannelProfile14.txt | 7 +- .../keymile/setInterface16.txt | 19 ++-- .../integration_tests/keymile/setIpAddr6.txt | 16 ++-- .../keymile/setPortProfile13.txt | 7 +- .../keymile/setSIPDomain12.txt | 10 +-- .../integration_tests/keymile/setTraffic1.txt | 13 ++- .../integration_tests/keymile/setVCC15.txt | 4 +- .../integration_tests/keymile/setconfDsl2.txt | 29 +++---- .../keymile/setconfVoice9.txt | 24 +++-- .../keymile/setdeconfVoicePort11.txt | 3 +- .../keymile/setdeconfVoicePort17.txt | 12 ++- .../keymile/setportaktiv4.txt | 14 +-- .../keymile/setportdeactiv5.txt | 15 +--- .../keymile/setunconfDsl3.txt | 20 ++--- .../{test Loopback3.txt => testLoopback3.txt} | 3 +- .../keymile/testVoicePort2.txt | 9 +- .../keymile/testmelting4.txt | 14 ++- 22 files changed, 125 insertions(+), 224 deletions(-) rename test_cases/integration_tests/keymile/{test Loopback3.txt => testLoopback3.txt} (60%) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index dd35d3c..a7209fa 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -385,7 +385,7 @@ req='{ "description": "Channel #1" }' -chan_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/channels) +chan_5_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/channels) ### Unit-6 ### @@ -414,6 +414,17 @@ req='{ unit_6=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_6', + "admin_state": "1", + "operational_state": "1" +}' + +port_6_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + ### Unit-7 ### # Create a physical card at the network device (admin operation) @@ -450,7 +461,7 @@ req='{ "operational_state": "1" }' -port_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_7_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) ### Unit-8 ### @@ -515,7 +526,7 @@ req='{ "operational_state": "1" }' -port_4_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/mgmt_ports) +port_11_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/mgmt_ports) @@ -539,7 +550,7 @@ req='{ "operational_state": "1" }' -port_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_19_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) ### PortGroupPort-1 ### diff --git a/test_cases/integration_tests/keymile/getInventory2.txt b/test_cases/integration_tests/keymile/getInventory2.txt index c45e0e0..16f77b4 100644 --- a/test_cases/integration_tests/keymile/getInventory2.txt +++ b/test_cases/integration_tests/keymile/getInventory2.txt @@ -3,16 +3,16 @@ secret ls cd /services/packet/nto1/ ls -cd /services/packet/nto1/srvc-{$match}/cfgm +cd /services/packet/nto1/srvc-1/cfgm get Service -cd /unit-{$slot} +cd /unit-11 ls -cd /unit-{$slot}/mai +cd /unit-19/main get HardwareAndSoftware get CurrentStatus get EquipmentInventory -cd /unit-{$slot}/port-{$port} +cd /unit-1/port-1} ls -cd /unit-{$slot}/port-{$port}/main +cd /unit-1/port-{1/main get OperationalStatus exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getMonitoring3.txt b/test_cases/integration_tests/keymile/getMonitoring3.txt index 6338665..e4259f3 100644 --- a/test_cases/integration_tests/keymile/getMonitoring3.txt +++ b/test_cases/integration_tests/keymile/getMonitoring3.txt @@ -10,12 +10,4 @@ cd .. cd unit-1 ls cd .. - - - - - - - - exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getState1.txt b/test_cases/integration_tests/keymile/getState1.txt index cdfab20..2c5d8b1 100644 --- a/test_cases/integration_tests/keymile/getState1.txt +++ b/test_cases/integration_tests/keymile/getState1.txt @@ -1,104 +1,57 @@ admin secret -#adsl SUAD2 -cd /unit-{$card}/port-{$port}/status +cd /unit-1/port-1/status get AttainableRate -cd /unit-{$card}/port-{$port}/main +cd /unit-1/port-1/main get AdministrativeStatus get OperationalStatus -cd /unit-{$card}/port-{$port}/chan-1/cfgm +cd /unit-1/port-1/chan-1/cfgm get ProfileName get ChanProfile -cd /unit-{$card}/port-{$port}/chan-1/status +cd /unit-1/port-1/chan-1/status get status -cd /unit-{$card}/port-{$port}/chan-1/vcc-1/cfgm +cd /unit-1/port-1/chan-1/vcc-1/cfgm get configuredProfiles -cd /unit-{$card}/port-{$port}/chan-1/vcc-1/status +cd /unit-1/port-1/chan-1/vcc-1/status get ServiceStatus cd /unit-11 ls -cd /unit-{$slotIpss} +cd /unit-19 ls -#vdsl SUVD2 -cd /unit-{$card}/port-{$port}/status -get AttainableRate -cd /unit-{$card}/port-{$port}/main -get AdministrativeStatus -get OperationalStatus -cd /unit-{$card}/port-{$port}/chan-1/cfgm -get ChanProfile -cd /unit-{$card}/port-{$port}/chan-1/status -get status -cd /unit-{$card}/port-{$port}/chan-1/interface-1/cfgm -get configuredProfiles -get vlanProfile -cd /unit-{$card}/port-{$port}/chan-1/interface-1/status -get ServiceStatus -cd /unit-11 -ls -cd /unit-{$card}/port-{$port} -get status/VendorId -cd /unit-{$slotIpss} -ls -#xdsl -cd /unit-{$card}/port-{$port}/status -get AttainableRate -get UnicastList -cd /unit-{$card}/port-{$port}/main -get AdministrativeStatus -get OperationalStatus -cd /unit-{$card}/port-{$port} -ls -cd /unit-{$card}/port-{$port}/chan-1/cfgm -get ChanProfile -cd /unit-{$card}/port-{$port}/chan-1/status -get status -cd /unit-{$card}/port-{$port}/chan-1/interface-1/cfgm -get configuredProfiles -cd /unit-{$card}/port-{$port}/chan-1/interface-1/status -get ServiceStatus -cd /unit-{$card} -ls -cd /unit-11 -ls -cd /unit-{$card}/port-{$port} -get status/VendorId -#ftth -cd /unit-{$card}/port-{$port}/main +cd /unit-7/port-1/main get AdministrativeStatus get OperationalStatus -cd /unit-{$card}/port-{$port} +cd /unit-7/port-1 ls -cd /unit-{$card}/port-{$port}/status +cd /unit-7/port-1/status get PortMacStatus get PortGeneralStatus -cd /unit-{$card}/port-{$port}/interface-1/cfgm +cd /unit-7/port-1/interface-1/cfgm get configuredProfiles get vlanProfile get IfRateLimiting -cd /unit-{$card}/port-{$port}/interface-1/status +cd /unit-7/port-1/interface-1/status get ServiceStatus -cd /unit-{$card}/port-{$port}/status +cd /unit-7/port-1/status get DDMStatus -#sdsl -cd /unit-{$card}/port-{$port}/main +cd /unit-2/port-1/main ls -cd /unit-{$card}/port-{$port}/status +cd /unit-2/port-1/status ls get LineActualState get LineOperationState -cd /unit-{$card}/logports/logport-{$port}/status +cd /unit-2/logports/logport-2/status get ActualStatus get OperationalWireState -cd /unit-{$card}/logports/logport-{$port}/main +cd /unit-2/logports/logport-2/main get AdministrativeStatus get OperationalStatus -cd /unit-{$card}/logports/logport-{$port}/cfgm +cd /unit-2/logports/logport-2/cfgm get SpanProfiles -cd /unit-{$card}/logports/logport-{$port}/interface-1/cfgm +cd /unit-2/logports/logport-2/interface-1/cfgm get configuredProfiles get vlanProfile -cd /unit-{$card}/logports/logport-{$port}/interface-1/status +cd /unit-2/logports/logport-2/interface-1/status get ServiceStatus ls exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getVoice5.txt b/test_cases/integration_tests/keymile/getVoice5.txt index e3318fa..e61689a 100644 --- a/test_cases/integration_tests/keymile/getVoice5.txt +++ b/test_cases/integration_tests/keymile/getVoice5.txt @@ -1,9 +1,7 @@ admin secret -#analog -cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm +cd /unit-19/portgroup-1/port-1/cfgm get pstnport -#isdn -cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm +cd /unit-19/portgroup-2/port-1/cfgm get isdnport exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setChannelProfile14.txt b/test_cases/integration_tests/keymile/setChannelProfile14.txt index 3ad57dd..00530d5 100644 --- a/test_cases/integration_tests/keymile/setChannelProfile14.txt +++ b/test_cases/integration_tests/keymile/setChannelProfile14.txt @@ -1,11 +1,10 @@ admin secret -cd /unit-$card/port-$port/chan-1/cfgm -#SUVM6/4 -set chanprofile $profile +cd /unit-5/port-1/chan-1/cfgm +set chanprofile rofile set chanprofile default #else -cd /unit-$card/port-$port/chan-1/cfgm +cd /unit-5/port-1/chan-1/cfgm set ProfileName $profile set ProfileName default exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setInterface16.txt b/test_cases/integration_tests/keymile/setInterface16.txt index 16a5569..e719a80 100644 --- a/test_cases/integration_tests/keymile/setInterface16.txt +++ b/test_cases/integration_tests/keymile/setInterface16.txt @@ -1,15 +1,12 @@ admin secret -#SUSE1 -cd /unit-$card/logports/logport-$port/cfgm -#SUEN4 -cd /unit-$card/port-$port/cfgm -#SUE16 -cd /unit-$card/port-$port/cfgm -#ftth -cd /unit-$card/port-$port/cfgm -#else -cd /unit-$card/port-$port/chan-1/cfgm -CreateInterface default VCC_1_32_10100 +cd /unit-2/logports/logport-2/cfgm +CreateInterface default VCC_1_100 +DeleteInterface all +cd /unit-7/port-1/cfgm +CreateInterface default VCC_1_32100 +DeleteInterface all +cd /unit-5/port-1/chan-1/cfgm +CreateInterface default VC 1wdf DeleteInterface all exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setIpAddr6.txt b/test_cases/integration_tests/keymile/setIpAddr6.txt index e4e5a91..ec96fcd 100644 --- a/test_cases/integration_tests/keymile/setIpAddr6.txt +++ b/test_cases/integration_tests/keymile/setIpAddr6.txt @@ -1,17 +1,15 @@ admin secret cd /services/packet/1to1SingleTag/srvc-1/cfgm -set Service /unit-{$managementSlot}/control {$input->vlan_voice_new} CoS0 Add +set Service /unit-19/control {$input->vlan_voice_new} CoS0 Add cd /services/packet/1to1SingleTag/srvc-2/cfgm -set Service /unit-{$managementSlot}/media {$input->vlan_voice_new} CoS0 Add -cd /unit-{$managementSlot}/cfgm -set Ip {$input->ip_voice} 255.255.255.0 {$input->gateway_voice} +set Service /unit-19/media {$input->vlan_voice_new} CoS0 Add +cd /unit-19/cfgm +set Ip 11.1.1.1 155.255.255.0 2.3.3.3 cd /cfgm save -cd /unit-{$managementSlot}/main +cd /unit-19/main restart -set /cfgm/IP_Address {$input->ip_new} 255.255.255.0 {$input->gateway} -/cfgm/Save -/unit-11/main/restart -set /cfgm/VlanId {$input->vlan_new} +admin +secret exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setPortProfile13.txt b/test_cases/integration_tests/keymile/setPortProfile13.txt index ed42302..6ee1f57 100644 --- a/test_cases/integration_tests/keymile/setPortProfile13.txt +++ b/test_cases/integration_tests/keymile/setPortProfile13.txt @@ -1,10 +1,5 @@ admin secret - -cd /unit-$card/port-$port/cfgm -#SUVM6 posibilities -set portprofiles true $vdslProfile 0 false default 0 false default 0 false default Priority -set portprofiles true " . $vdslProfile . " 0 false default 0 false default 0 false default Priority -set portprofiles false default 0 false default 0 false default 0 true " . $adslProfile . " Priority +cd /unit-6/port-1/cfgm set portprofiles true default 0 false default 0 false default 0 true default Priority exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setSIPDomain12.txt b/test_cases/integration_tests/keymile/setSIPDomain12.txt index d465075..fd572f6 100644 --- a/test_cases/integration_tests/keymile/setSIPDomain12.txt +++ b/test_cases/integration_tests/keymile/setSIPDomain12.txt @@ -1,12 +1,10 @@ admin secret -#analog or isdn -cd /unit-{$slotIpss}/cfgm +cd /unit-19/cfgm get Sip -set Proxy PrimaryOnly $domain 5060 "" 0 true Options 10 "" 0 true Options 10 -set Registrar $domain 5060 OneByOneRegistration 1 -set Sip $name $domain 5060 +49 $area 500 4 false None true 30 false false 1800 -set digitmap {sip "xxx" $domain 0 ""; sip "*xx*x.#" $domain 0 ""; sip "*xx*" $domain 0 ""; sip "*xx#" $domain 0 ""; sip "#xx#" $domain 0 ""; } +set Proxy PrimaryOnly domain 5060 "" 0 true Options 10 "" 0 true Options 10 +set Registrar domain 5060 OneByOneRegistration 1 +set Sip $name domain 5060 +49 area 500 4 false None true 30 false false 1800 cd /cfgm save exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setTraffic1.txt b/test_cases/integration_tests/keymile/setTraffic1.txt index a9cc539..bcaee65 100644 --- a/test_cases/integration_tests/keymile/setTraffic1.txt +++ b/test_cases/integration_tests/keymile/setTraffic1.txt @@ -1,16 +1,13 @@ admin secret -#ftth -cd /unit-$card +cd /unit-7 ls -#SUEN4 -cd /unit-$card/port-$port/cfgm +cd /unit-7/port-1/cfgm Set Mode "Speed1000 Autoneg On" Set FlowControl false -CreateInterface VLAN_$trafficVlan -#else -cd /unit-$card/port-$port/cfgm +CreateInterface VLAN_name +cd /unit-7/port-1/cfgm Set Mode "1000MbitsFullDuplex" Set FlowControl false -CreateInterface VLAN_$trafficVlan +CreateInterface VLAN_name exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setVCC15.txt b/test_cases/integration_tests/keymile/setVCC15.txt index cd9305b..dfc9f0b 100644 --- a/test_cases/integration_tests/keymile/setVCC15.txt +++ b/test_cases/integration_tests/keymile/setVCC15.txt @@ -1,6 +1,6 @@ admin secret -cd /unit-$card/port-$port/chan-1/cfgm -CreateVcc $profile default +cd /unit-1/port-1/chan-1/cfgm +CreateVcc default default DeleteVcc all exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfDsl2.txt b/test_cases/integration_tests/keymile/setconfDsl2.txt index c2e2afc..61e065d 100644 --- a/test_cases/integration_tests/keymile/setconfDsl2.txt +++ b/test_cases/integration_tests/keymile/setconfDsl2.txt @@ -1,26 +1,19 @@ admin secret #adsl -cd /unit-$card/port-$port/main -Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" +cd /unit-1/port-1/main +Set Labels "umlctId)" "arrierId" "" set AdministrativeStatus up -#vdsl -cd /unit-$card/port-$port/main -Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" +cd /unit-5/port-1/main +Set Labels "Id" "ierLind" "" set AdministrativeStatus up -#xdsl -cd /unit-$card/port-$port/main -Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" +cd /unit-7/port-1/main +Set Labels "ctId" "d" "" set AdministrativeStatus up -#ftth -cd /unit-$card/port-$port/main -Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" -set AdministrativeStatus up -#sdsl -cd /unit-$card/logports/cfgm -create $bonding_port $profile -cd /unit-$card/logports/logport-$port/cfgm -CreateInterface name $servicetype -cd /unit-$card/logports/logport-$port/main +cd /unit-2/logports/cfgm +create port-1 +cd /unit-$card/logports/logport-1/cfgm +CreateInterface name +cd /unit-$card/logports/logport-1/main set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfVoice9.txt b/test_cases/integration_tests/keymile/setconfVoice9.txt index 60f70f6..6c4c2fe 100644 --- a/test_cases/integration_tests/keymile/setconfVoice9.txt +++ b/test_cases/integration_tests/keymile/setconfVoice9.txt @@ -1,19 +1,17 @@ admin secret #analog -cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm -set pstnport true {$numbers} true false none none none none none -cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/main -Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" -cd /unit-$voiceCard/port-$voicePort/main +cd /unit-19/portgroup-1/port-1/cfgm +set pstnport true 11 true false none none none none none +cd /unit-19/portgroup-1/port-1/main +Set Labels "ssdd" "sssd" "" +cd /unit-19/port-1/main set AdministrativeStatus up -Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" -#isdn -cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm -set isdnport true {$numbers} true false none none none none none -cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/main -Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" -cd /unit-$voiceCard/port-$voicePort/main +Set Labels www "carrierLineId" "" +cd /unit-19/portgroup-2/port-1/cfgm +set isdnport true 112 true false none none none none none +cd /unit-19/portgroup-2/port-1/main +Set Labels dada "test" "" +cd /unit-19/port-1/main set AdministrativeStatus up -Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt index 6704e55..c5dc42a 100644 --- a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt @@ -1,7 +1,6 @@ admin secret -#isdn or analog -cd /unit-$ipsxSlot/portgroup-$card/port-$port/cfgm +cd /unit-19/portgroup-1/port-1/cfgm get pstnport cd / exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt index d82cfe2..9099c38 100644 --- a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt @@ -1,20 +1,18 @@ admin secret -#analog cd /unit-$card/port-$port/main set AdministrativeStatus down Set Labels "" "" "" -cd /unit-$ipsxSlot/portgroup-$card/port-$port/cfgm +cd /unit-19/portgroup-1/port-1/cfgm Set pstnport false {} true false none none none none none -cd /unit-$ipsxSlot/portgroup-$card/port-$port/main +cd /unit-19/portgroup-1/port-1/main Set Labels "" "" "" -#isdn -cd /unit-$card/port-$port/main +cd /unit-19/port-1/main set AdministrativeStatus down Set Labels "" "" "" -cd /unit-$ipsxSlot/portgroup-$card/port-$port/cfgm +cd /unit-19/portgroup-2/port-1/cfgm Set isdnport false {} true false false none none none none -cd /unit-$ipsxSlot/portgroup-$card/port-$port/main +cd /unit-19/portgroup-2/port-1/main Set Labels "" "" "" diff --git a/test_cases/integration_tests/keymile/setportaktiv4.txt b/test_cases/integration_tests/keymile/setportaktiv4.txt index c917fa5..f538660 100644 --- a/test_cases/integration_tests/keymile/setportaktiv4.txt +++ b/test_cases/integration_tests/keymile/setportaktiv4.txt @@ -1,18 +1,12 @@ admin secret -#adsl -cd /unit-$card/port-$port/main +cd /unit-1/port-1/main set AdministrativeStatus up -#vdsl -cd /unit-$card/port-$port/main +cd /unit-5/port-1/main set AdministrativeStatus up -#xdsl -cd /unit-$card/port-$port/main -set AdministrativeStatus up -#ftth -cd /unit-$card/port-$port/main +cd /unit-7/port-1/main set AdministrativeStatus up #sdsl -cd /unit-$card/logports/logport-$port/main +cd /unit-2/logports/logport-2/main set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setportdeactiv5.txt b/test_cases/integration_tests/keymile/setportdeactiv5.txt index 041cd8d..88ca770 100644 --- a/test_cases/integration_tests/keymile/setportdeactiv5.txt +++ b/test_cases/integration_tests/keymile/setportdeactiv5.txt @@ -1,18 +1,11 @@ admin secret -#adsl -cd /unit-$card/port-$port/main +cd /unit-1/port-1/main set AdministrativeStatus down -#vdsl -cd /unit-$card/port-$port/main +cd /unit-5/port-1/main set AdministrativeStatus down -#xdsl -cd /unit-$card/port-$port/main +cd /unit-7/port-1/main set AdministrativeStatus down -#ftth -cd /unit-$card/port-$port/main -set AdministrativeStatus down -#sdsl -cd /unit-$card/logports/logport-$port/main +cd /unit-2/logports/logport-2/main set AdministrativeStatus down exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setunconfDsl3.txt b/test_cases/integration_tests/keymile/setunconfDsl3.txt index 7213e54..5eb92fd 100644 --- a/test_cases/integration_tests/keymile/setunconfDsl3.txt +++ b/test_cases/integration_tests/keymile/setunconfDsl3.txt @@ -1,26 +1,20 @@ admin secret -#adsl -cd /unit-$card/port-$port/main +cd /unit-1/port-1/main set AdministrativeStatus down Set Labels "" "" "" -#vdsl -cd /unit-$card/port-$port/main -set AdministrativeStatus down -Set Labels "" "" "" -#xdsl -cd /unit-$card/port-$port/main +cd /unit-5/port-1/main set AdministrativeStatus down Set Labels "" "" "" #ftth -cd /unit-$card/port-$port/main +cd /unit-7/port-1/main set AdministrativeStatus down Set Labels "" "" "" #sdsl -cd /unit-$card/logports/logport-$port/main +cd /unit-2/logports/logport-2/main set AdministrativeStatus down Set Labels "" "" "" -cd /unit-$card/logports/logport-$port/main -cd /unit-$card/logports/cfgm -Delete logport-$port +cd /unit-2/logports/logport-2/main +cd /unit-2/logports/cfgm +Delete logport-2 exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/test Loopback3.txt b/test_cases/integration_tests/keymile/testLoopback3.txt similarity index 60% rename from test_cases/integration_tests/keymile/test Loopback3.txt rename to test_cases/integration_tests/keymile/testLoopback3.txt index a4c19e2..2ebea1b 100644 --- a/test_cases/integration_tests/keymile/test Loopback3.txt +++ b/test_cases/integration_tests/keymile/testLoopback3.txt @@ -1,7 +1,6 @@ admin secret -#isdn -cd /unit-$voiceCard/port-$voicePort/status +cd /unit-19/port-1/status Lock StartQuickLoopbackTest get QuickLoopbackTest diff --git a/test_cases/integration_tests/keymile/testVoicePort2.txt b/test_cases/integration_tests/keymile/testVoicePort2.txt index 0602971..66f987f 100644 --- a/test_cases/integration_tests/keymile/testVoicePort2.txt +++ b/test_cases/integration_tests/keymile/testVoicePort2.txt @@ -1,10 +1,9 @@ admin secret -cd /unit-{$voice_card}/main +cd /unit-19/main get HardwareAndSoftware -/unit-$voice_card/port-$voice_port/status/StartLineTest -get /unit-$voice_card/port-$voice_port/status/LineTestResults -#SUVM6 -cd /unit-$card/port-$port/main +/unit-19/port-1/status/StartLineTest +get /unit-19/port-1/status/LineTestResults +cd /unit-6/port-1/main set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/testmelting4.txt b/test_cases/integration_tests/keymile/testmelting4.txt index a526c37..4f509dd 100644 --- a/test_cases/integration_tests/keymile/testmelting4.txt +++ b/test_cases/integration_tests/keymile/testmelting4.txt @@ -1,13 +1,9 @@ admin secret -#voiceport -/unit-$voice_card/port-$voice_port/status/StartLineTest -get /unit-$voice_card/port-$voice_port/status/LineTestResults -#else -/unit-$card/port-$port/status/StartMeltMeasurement -get /unit-$card/port-$port/status/MeltResults - -#SUVM6 -cd /unit-$card/port-$port/main +/unit-19/port-1/status/StartLineTest +get /unit-19/port-1/status/LineTestResults +/unit-1/port-1/status/StartMeltMeasurement +get /unit-1/port-1/status/MeltResults +cd /unit-6/port-1/main set AdministrativeStatus up exit \ No newline at end of file From 308ab85b56920e999cf4b75a2da339725d2edbe3 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Tue, 20 Oct 2020 15:38:45 +0200 Subject: [PATCH 137/318] Added more functions to ports --- .../api/schemas/keymile_port_schemas.py | 2 +- .../keymile/keymile_resources/keymile_port.py | 8 +++++ nesi/softbox/api/models/port_models.py | 4 ++- .../unit/port/chan/chanCommandProcessor.py | 2 +- .../root/unit/port/portCommandProcessor.py | 36 +++++++++++++++++++ vendors/KeyMile/baseCommandProcessor.py | 14 ++++++++ 6 files changed, 63 insertions(+), 3 deletions(-) diff --git a/nesi/keymile/api/schemas/keymile_port_schemas.py b/nesi/keymile/api/schemas/keymile_port_schemas.py index 687a495..d10607c 100644 --- a/nesi/keymile/api/schemas/keymile_port_schemas.py +++ b/nesi/keymile/api/schemas/keymile_port_schemas.py @@ -20,6 +20,6 @@ class Meta: 'linetest_state', 'profile1_enable', 'profile1_name', 'profile1_elength', 'profile2_enable', 'profile2_name', 'profile2_elength', 'profile3_enable', 'profile3_name', 'profile3_elength', 'profile4_enable', 'profile4_name', - 'profile_mode') + 'profile_mode', 'mode', 'flow_control') channels = ma.Nested(CpesSchema.CpeSchema, many=True) diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py index 1555ef7..81a248d 100644 --- a/nesi/keymile/keymile_resources/keymile_port.py +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -22,6 +22,8 @@ class KeyMilePort(Port): loopbacktest_state = base.Field('loopbacktest_state') melttest_state = base.Field('melttest_state') linetest_state = base.Field('linetest_state') + mode = base.Field('mode') + flow_control = base.Field('flow_control') profile1_enable = base.Field('profile1_enable') profile1_name = base.Field('profile1_name') profile1_elength = base.Field('profile1_elength') @@ -75,6 +77,12 @@ def set_melttest_state(self, state): def set_linetest_state(self, state): self.update(linetest_state=state) + def set_mode(self, mode): + self.update(mode=mode) + + def set_flow_control(self, ctrl): + self.update(flow_control=ctrl) + class KeyMilePortCollection(PortCollection): """Represent a collection of ports.""" diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 32e0380..6ed09a0 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -316,7 +316,9 @@ class Port(db.Model): loopbacktest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NoTestResult', 'Stopped', 'Interrupted'), default='NoTestResult') melttest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NotTested'), default='NotTested') linetest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NotTested'), default='NotTested') - #profiles + mode = db.Column(db.String(), default='') + flow_control = db.Column(db.String(), default='') + # profiles profile1_enable = db.Column(db.Boolean(), default=False) profile1_name = db.Column(db.String(), default='') profile1_elength = db.Column(db.Integer, default=0) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 147e4d8..fecf4ae 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -113,7 +113,7 @@ def do_createinterface(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name : + elif self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name: # vcc profile and vlan profile vlan_prof, vcc_prof = self._dissect(args, str, str) # TODO: Check if profiles := default or profile names diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index a7a4f50..7ceb588 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -313,5 +313,41 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + + elif self._validate(args, 'Mode', str) and context['path'].split('/')[-1] == 'cfgm' and "SUE" in \ + card.board_name and self.__name__ == 'port' and card.product == 'ftth': + if '"' in args[1]: + mode = self.args_in_quotes_joiner((args[1],)) + else: + mode, = self._dissect(args, 'Mode', str) + try: + port = self.get_port_component() + port.set_mode(mode) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + + elif self._validate(args, 'Mode', str, str, str) and context['path'].split('/')[-1] == 'cfgm' and "SUE" in \ + card.board_name and self.__name__ == 'port' and card.product == 'ftth': + if '"' in args[1]: + mode = self.args_in_quotes_joiner(args[1:]) + else: + mode, = self._dissect(args, 'Mode', str) + try: + port = self.get_port_component() + port.set_mode(mode) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + + elif self._validate(args, 'FlowControl', str) and context['path'].split('/')[-1] == 'cfgm' and "SUE" in \ + card.board_name and self.__name__ == 'port' and card.product == 'ftth': + ctrl, = self._dissect(args, 'FlowControl', str) + try: + port = self.get_port_component() + port.set_flow_control(ctrl) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 672c667..42d3a19 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -541,3 +541,17 @@ def do_exit(self, command, *args, context=None): def _init_access_points(self, context=None): pass # Abstract method not implemented + + def args_in_quotes_joiner(self, args): + saved_args = [] + save = False + for i in range(len(args)): + if args[i].startswith("\""): + save = True + if save: + saved_args.append(args[i]) + if args[i].endswith("\""): + save = False + name = ' '.join(saved_args).replace("\"", "") + + return name From fe345727065e9638a86140c4aa2f6961c83f27d4 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 21 Oct 2020 08:41:07 +0200 Subject: [PATCH 138/318] Added set service on srvc- --- .../conf/bootstraps/create-keymile-MG2500.sh | 22 ++++++ .../keymile/keymile_resources/keymile_srvc.py | 8 +++ nesi/softbox/api/models/srvc_models.py | 2 + nesi/softbox/api/schemas/srvc_schemas.py | 3 +- .../KeyMile/login/base/get/service_nto1.j2 | 4 +- .../base/get/service_onetoonesingletag.j2 | 4 +- .../root/services/srvcCommandProcessor.py | 68 ++++++++++++------- 7 files changed, 81 insertions(+), 30 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index a7209fa..421825a 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -587,4 +587,26 @@ req='{ "address": "/unit-1/port-1/chan-1/interface-1" }' +srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) + +### 1to1singletag-Service-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "service_type": "1to1singletag", + "svid": 1213, + "address": "/unit-19/control" +}' + +srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) + +### 1to1singletag-Service-2 ### + +# Create a physical port at the network device (admin operation) +req='{ + "service_type": "1to1singletag", + "svid": 187, + "address": "/unit-19/media" +}' + srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) \ No newline at end of file diff --git a/nesi/keymile/keymile_resources/keymile_srvc.py b/nesi/keymile/keymile_resources/keymile_srvc.py index fad2756..d1b7a16 100644 --- a/nesi/keymile/keymile_resources/keymile_srvc.py +++ b/nesi/keymile/keymile_resources/keymile_srvc.py @@ -25,6 +25,14 @@ class KeyMileSrvc(base.Resource): service_type = base.Field('service_type') address = base.Field('address') svid = base.Field('svid') + stag_priority = base.Field('stag_priority') + vlan_handling = base.Field('vlan_handling') + + def set_service(self, address, svid, stag_prio, vlan): + self.update(address=address) + self.update(svid=svid) + self.update(stag_priority=stag_prio) + self.update(vlan_handling=vlan) class KeyMileSrvcCollection(base.ResourceCollection): diff --git a/nesi/softbox/api/models/srvc_models.py b/nesi/softbox/api/models/srvc_models.py index 8e0ec84..c0074a9 100644 --- a/nesi/softbox/api/models/srvc_models.py +++ b/nesi/softbox/api/models/srvc_models.py @@ -21,3 +21,5 @@ class Srvc(db.Model): service_type = db.Column(db.Enum('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls')) address = db.Column(db.String(), default='') svid = db.Column(db.Integer(), default=None) + stag_priority = db.Column(db.Enum('CoS0', 'CoS1', 'CoS2', 'CoS3', 'CoS4', 'CoS5', 'CoS6', 'CoS7'), default=None) + vlan_handling = db.Column(db.Enum('Add', 'Transparent', 'Swap'), default=None) diff --git a/nesi/softbox/api/schemas/srvc_schemas.py b/nesi/softbox/api/schemas/srvc_schemas.py index 482b246..034283f 100644 --- a/nesi/softbox/api/schemas/srvc_schemas.py +++ b/nesi/softbox/api/schemas/srvc_schemas.py @@ -18,7 +18,8 @@ class SrvcSchema(ma.ModelSchema): class Meta: model = Srvc - fields = ('id', 'box', 'box_id', 'name', 'service_type', 'address', 'svid', '_links') + fields = ('id', 'box', 'box_id', 'name', 'service_type', 'address', 'svid', 'stag_priority', 'vlan_handling', + '_links') box = ma.Hyperlinks( {'_links': { diff --git a/templates/KeyMile/login/base/get/service_nto1.j2 b/templates/KeyMile/login/base/get/service_nto1.j2 index edb2127..2a30929 100644 --- a/templates/KeyMile/login/base/get/service_nto1.j2 +++ b/templates/KeyMile/login/base/get/service_nto1.j2 @@ -3,9 +3,9 @@ {{ context.service.address }}{{ context.spacer1 }}\ # Address \ # Specific {{ context.service.svid }}{{ context.spacer2 }}\ # Svid -CoS0 \ # STagPriority +{{ context.service.stag_priority }}{{ context.spacer3 }}\ # STagPriority PPPoE \ # LogonMethod -Add \ # VLANHandling +{{ context.service.vlan_handling }}{{ context.spacer4 }}\ # VLANHandling false \ # SourceFilter false \ # DestinationFilter false \ # SourceIPFilter diff --git a/templates/KeyMile/login/base/get/service_onetoonesingletag.j2 b/templates/KeyMile/login/base/get/service_onetoonesingletag.j2 index be29c7c..1a31a6c 100644 --- a/templates/KeyMile/login/base/get/service_onetoonesingletag.j2 +++ b/templates/KeyMile/login/base/get/service_onetoonesingletag.j2 @@ -3,6 +3,6 @@ {{ context.service.address }}{{ context.spacer1 }}\ # Address \ # Specific {{ context.service.svid }}{{ context.spacer2 }}\ # Svid -CoS0 \ # STagPriority -Add \ # VLANHandling +{{ context.service.stag_priority }}{{ context.spacer3 }}\ # STagPriority +{{ context.service.vlan_handling }}{{ context.spacer4 }}\ # VLANHandling diff --git a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py index 7a9e401..4294e2b 100644 --- a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py @@ -28,36 +28,54 @@ def get_property(self, command, *args, context=None): service_name = 'srvc-' + self.component_id services = self._model.get_srvcs('name', service_name) for s in services: - if s.service_type.lower() == context['ServiceType']: + if s.service_type.lower() == context['ServiceType'] and s.name == service_name: service = s context['service'] = service break scopes = ('login', 'base', 'get') - try: - super().get_property(command, *args, context=context) - except exceptions.CommandExecutionError: - if self._validate((args[0],), 'Service') and context['path'].split('/')[-1] == 'cfgm': - # TODO: Find missing templates, and replace placeholder templates - if service.service_type == '1to1doubletag': - template_name = 'service_onetoonedoubletag' - elif service.service_type == '1to1singletag': - template_name = 'service_onetoonesingletag' - elif service.service_type == 'mcast': - template_name = 'service_mcast' - elif service.service_type == 'nto1': - template_name = 'service_nto1' - elif service.service_type == 'pls': - template_name = 'service_pls' - elif service.service_type == 'tls': - template_name = 'service_tls' - else: - raise exceptions.CommandExecutionError(command=command) - context['spacer1'] = self.create_spacers((67,), (service.address,))[0] * ' ' - context['spacer2'] = self.create_spacers((67,), (service.svid,))[0] * ' ' - text = self._render(template_name, *scopes, context=context) - self._write(text) - + if self._validate((args[0],), 'Service') and context['path'].split('/')[-1] == 'cfgm': + # TODO: Find missing templates, and replace placeholder templates + if service.service_type == '1to1doubletag': + template_name = 'service_onetoonedoubletag' + elif service.service_type == '1to1singletag': + template_name = 'service_onetoonesingletag' + elif service.service_type == 'mcast': + template_name = 'service_mcast' + elif service.service_type == 'nto1': + template_name = 'service_nto1' + elif service.service_type == 'pls': + template_name = 'service_pls' + elif service.service_type == 'tls': + template_name = 'service_tls' else: + raise exceptions.CommandExecutionError(command=command) + context['spacer1'] = self.create_spacers((67,), (service.address,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (service.svid,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (service.stag_priority,))[0] * ' ' + context['spacer4'] = self.create_spacers((67,), (service.vlan_handling,))[0] * ' ' + text = self._render(template_name, *scopes, context=context) + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'Service', str, str, str, str) and context['path'].split('/')[-1] == 'cfgm': + address, svid, stag, vlan = self._dissect(args, 'Service', str, str, str, str) + try: + service_name = 'srvc-' + self.component_id + services = self._model.get_srvcs('name', service_name) + for s in services: + if s.service_type.lower() == context['ServiceType'] and s.name == service_name: + service = s + break + service.set_service(address, int(svid), stag, vlan) + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) From d08351504bdeec80fff60166b027e225e5d057d7 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 21 Oct 2020 09:01:39 +0200 Subject: [PATCH 139/318] Restructured change_directory and fixed some navigation bugs --- vendors/KeyMile/baseCommandProcessor.py | 89 ++++++++++--------------- 1 file changed, 37 insertions(+), 52 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 42d3a19..7b8d1fd 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -238,6 +238,15 @@ def change_directory(self, path, context=None): context['path'] = '/' subprocessor = self.change_directory(path.lstrip('/'), context=context) elif path.startswith('.'): + if path.startswith('...'): + if '/' in path: + raise exceptions.CommandExecutionError(template='invalid_address_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + else: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if path == '.': return self @@ -305,17 +314,38 @@ def change_directory(self, path, context=None): else: command_processor = components[0].capitalize() + 'CommandProcessor' + def validate_relation(component_type, name): + relations = { + 'root': ('unit', 'mgmtunit', 'fan', 'eoam', 'tdmConnections', 'multicast', 'services'), + 'unit': ('port', 'portgroup', 'logports', 'huntgroup'), + 'mgmtunit': ('mgmtport',), + 'fan': ('alarm',), + 'services': ('packet', 'macaccessctrl'), + 'port': ('chan', 'interface'), + 'portgroup': ('port',), + 'chan': ('vcc', 'interface',), + 'logport': ('interface',), + 'packet': ('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'), + 'subpacket': ('srvc',), + } + + if component_type not in relations[name]: + return False + + return True + + if component_type: + validation = validate_relation(component_type, self.__name__) + else: + validation = validate_relation(components[0], self.__name__) + if validation is False: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if component_type == 'unit': if (self._model.version == '2200' and not 9 <= int(component_id) <= 12) or (self._model.version == '2300' and not 7 <= int(component_id) <= 14) or (self._model.version == '2500' and not 1 <= int(component_id) <= 21): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty# - if self.__name__ != 'root': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'portgroup' or component_type == 'logports' or component_type == 'huntgroup': - if self.__name__ != 'unit': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'port': try: if self.component_id == '11' or self.component_id == '13': @@ -325,58 +355,30 @@ def change_directory(self, path, context=None): except exceptions.InvalidInputError: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - - if self.__name__ != 'unit' and self.__name__ != 'portgroup': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'chan': try: self._model.get_chan('name', self._parent.component_id + '/' + self.component_id + '/' + component_id) except exceptions.InvalidInputError: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - - if self.__name__ != 'port': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'mgmtunit': - if self.__name__ != 'root': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'mgmtport': - if self.__name__ != 'mgmtunit': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'interface': try: self._model.get_interface('name', self._parent.component_id + '/' + self.component_id + '/' + component_id) except exceptions.InvalidInputError: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - - if self.__name__ != 'port' and self.__name__ != 'chan' and self.__name__ != 'logport': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'logport': try: self._model.get_logport('name', self._parent.component_id + '/L/' + component_id) except exceptions.InvalidInputError: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - - if self.__name__ != 'logports': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'vcc': try: self._model.get_interface('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + component_id) except exceptions.InvalidInputError: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - - if self.__name__ != 'chan': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'srvc': try: self._model.get_srvc('name', 'srvc-' + component_id) @@ -384,23 +386,6 @@ def change_directory(self, path, context=None): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - if self.__name__ != 'subpacket': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - - if components[0] in ('packet', 'macAccessCtrl'): - if self.__name__ != 'services': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): - if self.__name__ != 'root': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - if components[0] in ('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'): - if self.__name__ != 'packet': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - if components[0] in ('main', 'cfgm', 'fm', 'pm', 'status'): if context['path'].split('/')[-1] in ('main', 'cfgm', 'fm', 'pm', 'status'): raise exceptions.CommandExecutionError(command=None, template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors')) From 974fbcc903973935678baed2b02c4bf2d7586765 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 21 Oct 2020 09:19:06 +0200 Subject: [PATCH 140/318] Added history in KeyMile script --- .../conf/bootstraps/create-keymile-MG2500.sh | 113 +++++++++++++----- 1 file changed, 80 insertions(+), 33 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 421825a..7a91f28 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -20,6 +20,51 @@ path="`dirname \"$0\"`" . $path/functions.sh + +#--------------------------------------------------------# +# # +# Subrack 0 # +# |---> Unit-1 (adsl) (SUAD2) # +# | |-> Port-1 # +# | | |-> Chan-1 # +# | | |-> Interface-1 # +# | # +# |---> Unit-2 (sdsl) (SUSE1) # +# | |-> Port-1 # +# | |-> Port-2 # +# | |-> LogPorts # +# | | |-> LogPort-2 # +# | # +# |---> Unit-3 (sdsl) (SUSE1) # +# | |-> Port-1 # +# | | |-> Interface-1 # +# | # +# |---> Unit-4 (adsl) (SUAD2) # +# | |-> Port-1 # +# | # +# |---> Unit-5 (vdsl) (SUVM4) # +# | |-> Port-1 # +# | | |-> Chan-1 # +# | # +# |---> Unit-6 (vdsl) (SUVM6) # +# | |-> Port-1 # +# | # +# |---> Unit-7 (ftth) (SUEN3) # +# | |-> Port-1 # +# | # +# |---> Unit-8 (vdsl) (SUVM6) # +# | # +# |---> Unit-11 (mgmt) (COGE1) # +# | |-> Port-1 (mgmt) # +# | # +# |---> Unit-19 (isdn) (isdn) # +# | |-> Port-1 # +# | |-> PortGroup-1 (PSTN) # +# | | |-> Port-1 # +# | |-> PortGroup-2 (ISDN) # +# | | |-> Port-1 # +#--------------------------------------------------------# + # Create a network device (admin operation) req='{ "vendor": "KeyMile", @@ -127,6 +172,41 @@ req='{ subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) +### Nto1-Service-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "service_type": "nto1", + "svid": 123, + "address": "/unit-1/port-1/chan-1/interface-1" +}' + +srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) + +### 1to1singletag-Service-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "service_type": "1to1singletag", + "svid": 1213, + "address": "/unit-19/control" +}' + +srvc_1to1singletag_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) + +### 1to1singletag-Service-2 ### + +# Create a physical port at the network device (admin operation) +req='{ + "service_type": "1to1singletag", + "svid": 187, + "address": "/unit-19/media" +}' + +srvc_1to1singletag_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) + + + ### Subrack 0 ### # Create a physical subrack at the network device (admin operation) @@ -577,36 +657,3 @@ req='{ }' port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) - -### Nto1-Service-1 ### - -# Create a physical port at the network device (admin operation) -req='{ - "service_type": "nto1", - "svid": 123, - "address": "/unit-1/port-1/chan-1/interface-1" -}' - -srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) - -### 1to1singletag-Service-1 ### - -# Create a physical port at the network device (admin operation) -req='{ - "service_type": "1to1singletag", - "svid": 1213, - "address": "/unit-19/control" -}' - -srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) - -### 1to1singletag-Service-2 ### - -# Create a physical port at the network device (admin operation) -req='{ - "service_type": "1to1singletag", - "svid": 187, - "address": "/unit-19/media" -}' - -srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) \ No newline at end of file From 1f20e676b48e9a1cb82f1c3ae2a36b313100de0a Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Wed, 21 Oct 2020 09:20:05 +0200 Subject: [PATCH 141/318] Corrected Mgmt Card/Mgmt Port management functions --- .../mgmt_port/mgmtportManagementFunctions.py | 466 +++++++----------- .../mgmt_unit/mgmtunitManagementFunctions.py | 257 ++++------ 2 files changed, 263 insertions(+), 460 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py index 9529dba..c0a9d28 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py @@ -1,334 +1,216 @@ main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'AdminAndOperStatus': { - 'Prop': { - 'AdministrativeStatus': 'rw', - 'OperationalStatus': 'r-' - } - } -} - -cfgm = { - 'Multicast': { - 'Prop': { - 'MaxNumberOfMulticastStreams': 'rw', - 'EnableIgmpClassifier': 'rw', - 'AllowStaticStreams': 'rw', - 'EnableFastLeave': 'rw', - 'GroupManagement': 'rw', - 'Bandwidth': 'rw' + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } }, - 'Cmd': ( - 'GetGroupList', - ) - }, - 'Traceability': { - 'Prop': { - 'AgentRemoteId': 'rw' - } - }, - 'Security': { - 'Prop': { - 'ServiceOptions': 'rw', - 'MaxNumberOfMac': 'rw' - } - }, - 'AccessControl': { - 'Prop': { - 'ClassificationKey': 'rw', - 'MAT': 'rw' - } - }, - 'RateLimiter': { - 'Prop': { - 'RateLimiting': 'rw', - 'RateLimitingCoS': 'rw' - } - }, - 'Qos': { - 'Prop': { - 'WfqProfile': 'rw' - } - }, - 'Wire': { - 'Prop': { - 'MeltConfiguration': 'rw' - } - }, - 'Profiles': { - 'Prop': { - 'PortProfiles': 'rw' - } - }, - 'Misc': { - 'Prop': { - 'SpecificDPBO': 'rw', - 'SpecificUPBO': 'rw' - } - } -} - -fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' + 'SFP': { + 'Prop': { + 'EquipmentInventory': 'r-' + } } } -} -pm = { - 'PerformanceMonitoring': { - 'Cmd': ( - 'UserCounter', - 'GetHistory15min', - 'GetHistory24h', - 'GetAlarm15min', - 'GetAlarm24hRecursive', - 'ResetUserCounter', - 'ResetAlarm15min', - 'ResetAlarm24h' - ) - }, - 'UserCounter': { - 'Prop': { - 'UserCounterDisplayMode': 'rw', - 'UserCounterTable': 'r-' - }, - 'Cmd': ( - 'UserCounterReset', - ) - }, - 'History15min': { - 'Prop': { - 'History15minDisplayMode': 'rw', - 'History15minTable': 'r-' - } - }, - 'History24h': { - 'Prop': { - 'History24hDisplayMode': 'rw', - 'History24hTable': 'r-' - } - }, - 'Alarm15min': { - 'Prop': { - 'Alarm15minDisplayMode': 'rw', - 'Alarm15minTable': 'r-' - }, - 'Cmd': ( - 'Alarm15minReset', - ) - }, - 'Alarm24h': { - 'Prop': { - 'Alarm24hDisplayMode': 'rw', - 'Alarm24hTable': 'r-' +cfgm = { + 'PortMode': { + 'Prop': { + 'PortMode': 'rw', + 'Redundancy': 'rw', + 'PortVlan': 'rw', + 'MTUSize': 'rw' + } }, - 'Cmd': ( - 'Alarm24hReset', - ) - } -} - -status = { - 'General': { - 'Prop': { - 'Standard': 'r-', - 'PowerMgmStatus': 'r-', - 'Vdsl2Parameters': 'r-', - 'EstUPBOElectricalLength': 'r-', - 'LineRate': 'r-', - 'LineSnrMargin': 'r-', - 'AttainableNetDataRate': 'r-', - 'AttainableRate': 'r-', - 'OutputPower': 'r-', - 'BandStatus': 'r-' - } - }, - 'statistics': { - 'Prop': { - 'counters': 'r-', - 'PolicingCounters': 'r-' + 'Rstp': { + 'Prop': { + 'Rstp': 'rw', + 'RstpParams': 'rw' + } }, - 'Cmd': ( - 'ResetPortCounters', - ) - }, - 'Nto1MacAccessDynamicList': { - 'Prop': { - 'UnicastList': 'r-' - } - }, - 'HostPortStatistics': { - 'GeneralCounters': { + 'VlanList': { 'Prop': { - 'GeneralList': 'r-' + 'ManagementVlan': 'r-', + 'ListType': 'rw', + 'VlanList': 'rw' }, 'Cmd': ( - 'ResetGeneralCounters', + 'FlushVlanList', ) }, - 'ProtocolCounters': { - 'IgmpCounters': { - 'Prop': { - 'IgmpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetIgmpCounters', - ) - }, - 'DhcpCounters': { - 'Prop': { - 'DhcpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetDhcpCounters', - ) - }, - 'ArpCounters': { - 'Prop': { - 'ArpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetArpCounters', - ) - }, - 'PPPoECounters': { - 'Prop': { - 'PPPoEProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetPPPoECounters', - ) - }, - 'UnknownSourceMACCounters': { - 'Prop': { - 'UnknownSrcMACProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetUnknownSrcMACCounters', - ) - }, + 'QoS': { + 'Prop': { + 'SchedulingProfileName': 'rw' + } }, - }, - 'TLSMacForwardingList': { - 'Prop': { - 'MacForwardingList': 'r-' + 'Multicast': { + 'Prop': { + 'EnableIgmpClassifier': 'rw', + 'AllowStaticStreams': 'rw', + 'MulticastPortMode': 'rw' + } }, - 'Cmd': ( - 'FlushMacForwardingList', - ) - }, - '1to1MacForwardingList': { - 'Prop': { - 'One2OneMacForwardingList': 'r-' - } - }, - 'Qos': { - 'Prop': { - 'wfqueues': 'r-' - } - }, - 'Multicast': { - 'stream': { - 'Dynamic': { - 'Prop': { - 'ActiveStreams': 'r-' - }, - 'Cmd': ( - 'ClearActiveStreams', - ) - }, - 'Static': { - 'Prop': { - 'StaticStreams': 'r-' - } - }, + 'LinkAggregation': { + 'Prop': { + 'LinkAggregation': 'rw' + } }, - - 'Vlan': { + 'PHY': { + 'Prop': { + 'PhyMode': 'rw', + 'PhyFlowControl': 'rw' + } + }, + 'Eoam': { + 'Prop': { + 'NetworkNetworkInterface': 'rw' + } + }, + 'PriorityMapping': { 'Prop': { - 'AttachedVlans': 'r-' + 'DSCPTo802Dot1qTxPriorityMapping': 'rw' } }, - 'Preview': { + 'Mirroring': { + 'Prop': { + 'MirrorPortList': 'rw' + } + } + } + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, 'Cmd': ( - 'ResetPreviewSettings', + 'Acknowledge', ) }, - 'Bandwidth': { + 'Configuration': { 'Prop': { - 'bandwidthStatus': 'r-' + 'AlarmConfiguration': 'rw' } - }, - }, - 'LineTest': { - 'MELT': { + } + } + +pm = { + 'UserCounter': { 'Prop': { - 'MeltResults': 'r-' + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' }, 'Cmd': ( - 'StartMeltMeasurement', + 'UserCounterReset', ) }, - 'Delt': { + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { 'Prop': { - 'DeltMeasurementStatus': 'r-', - 'RecordedDeltMeasurements': 'r-' + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' }, 'Cmd': ( - 'StartDeltMeasurement', + 'Alarm15minReset', ) }, - 'Selt': { + 'Alarm24h': { 'Prop': { - 'SeltMeasurementStatus': 'r-', - 'RecordedSeltMeasurements': 'r-', - 'CableType': 'rw', - 'BandplanProfile': 'rw', - 'TargetSnrm': 'rw' + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' }, 'Cmd': ( - 'StartSeltMeasurement', + 'Alarm24hReset', ) }, - }, - 'Defects': { - 'Prop': { - 'Defects': 'r-' - } - }, - 'LineInventory': { - 'Prop': { - 'VendorId': 'r-' - } - }, - 'Maintenance': { - 'Prop': { - 'DslOperationStatus': 'r-' + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) } - }, - 'Subcarrier': { - 'Cmd': ( - 'ShowBitAllocation', - ) - }, - 'RfiBands': { - 'Prop': { - 'NotchStatus': 'r-' + } + +status = { + 'PortMode': { + 'Prop': { + 'DefaultConfigEnabled': 'r-' + } + }, + 'MAC': { + 'Prop': { + 'PortMacStatus': 'r-' + } + }, + 'Phy': { + 'Prop': { + 'PortLinkStatus': 'r-' + } + }, + 'Rstp': { + 'Prop': { + 'PortRstpStatus': 'r-' + } + }, + 'LinkAggregation': { + 'Prop': { + 'Status': 'r-' + } + }, + 'Ddm': { + 'Prop': { + 'DdmStatus': 'r-' + } + }, + 'QoS': { + 'Prop': { + 'QosStatus': 'r-' + } + }, + 'Multicast': { + 'stream': { + 'Dynamic': { + 'Prop': { + 'ActiveStreams': 'r-' + }, + 'Cmd': ( + 'ClearActiveStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticStreams': 'r-' + } + }, + }, + + 'Vlan': { + 'Prop': { + 'AttachedVlans': 'r-' + } + + } } } -} diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py index 0a5adbd..e7a7937 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py @@ -1,194 +1,115 @@ main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'Equipment': { - 'Prop': { - 'AssignmentStatus': 'r-', - 'CurrentStatus': 'r-' + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } }, - 'Cmd': ( - 'Assign', - 'Unassign', - 'Restart', - 'StopInBoot' - ) - }, - 'Inventory': { - 'Prop': { - 'EquipmentInventory': 'r-' - } - }, - 'Logbooks': { - 'Cmd': ( - 'GetAlarmLogbook', - 'GetEventLogbook', - 'GetEquipmentLogbook' - ) - }, - 'Software': { - 'Prop': { - 'DiskSpace': 'r-', - 'SoftwareOnUnit': 'r-', - 'HardwareAndSoftware': 'r-', - 'Status': 'r-', - 'Configuration': 'rw' + 'Equipment': { + 'Prop': { + 'AssignmentStatus': 'r-', + 'CurrentStatus': 'r-' + }, + 'Cmd': ( + 'Assign', + 'Unassign', + 'Restart', + 'StopInBoot' + ) + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + }, + 'Logbooks': { + 'Cmd': ( + 'GetAlarmLogbook', + 'GetEventLogbook', + 'GetEquipmentLogbook' + ) }, - 'Cmd': ( - 'DeleteSoftware', - 'StartSoftware' - ), - 'File': { - 'Software': 'rw' + 'Software': { + 'Prop': { + 'DiskSpace': 'r-', + 'SoftwareOnUnit': 'r-', + 'HardwareAndSoftware': 'r-', + 'Status': 'r-', + 'Configuration': 'rw' + }, + 'Cmd': ( + 'DeleteSoftware', + 'StartSoftware' + ), + 'File': { + 'Software': 'rw' + } } } -} cfgm = { - 'Vlan': { - 'Prop': { - 'VlanCosTable': 'r-' - } - }, - 'Security': { - 'Prop': { - 'filtering': 'rw', - 'EoamMode': 'rw' - } - }, - 'Logon': { - 'Prop': { - 'LogonOptions': 'rw', - 'OneToOneOptions': 'rw' - } - }, - 'Mac': { - 'Prop': { - 'MacServiceBased': 'rw' - } - }, - 'HostPort': { - 'Prop': { - 'PolicerProfile': 'rw', - 'TrunkPolicerProfile': 'rw', - 'ProtRateLimiter': 'rw' - } - }, - 'QoS': { - 'Prop': { - 'ColorMarking': 'rw' - } - }, - 'Wire': { - 'General': { + 'Filter': { 'Prop': { - 'MeltConfiguration': 'rw' + 'BroadcastFilter': 'rw' } }, - 'Thresholds': { + 'PriorityMapping': { 'Prop': { - 'MeltAlarmThresholds': 'rw' + 'DSCPTo802Dot1qPriorityMapping': 'rw' + } + }, + 'PacketBuffer': { + 'Prop': { + 'PacketBufferProfileName': 'rw' } } } -} fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } } } -} -status = { - 'MacAllocationTable': { - 'Prop': { - 'MacAllocationTableEntries': 'r-' - } - }, - 'SwitchPort': { - 'Prop': { - 'Mac': 'r-', - 'MacStatus': 'r-' - } - }, - 'HostPortStatistics': { - 'GeneralCounters': { - 'Prop': { - 'GeneralList': 'r-' - }, +pm = { + 'PerformanceMonitoring': { 'Cmd': ( - 'ResetGeneralCounters', + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' ) + } + } + +status = { + 'QoS': { + 'Prop': { + 'QosPriorityMappingStatus': 'r-' + } }, - 'ProtocolCounters': { - 'IgmpCounters': { - 'Prop': { - 'IgmpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetIgmpCounters', - ) - }, - 'DhcpCounters': { - 'Prop': { - 'DhcpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetDhcpCounters', - ) - }, - 'ArpCounters': { - 'Prop': { - 'ArpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetArpCounters', - ) - }, - 'PPPoECounters': { - 'Prop': { - 'PPPoEProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetPPPoECounters', - ) - }, - 'UnknownSourceMACCounters': { - 'Prop': { - 'UnknownSrcMACProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetUnknownSrcMACCounters', - ) - }, + 'PacketBuffer': { + 'Prop': { + 'PacketBufferStatus': 'r-' + } }, - }, - 'BufferManagement': { - 'Prop': { - 'BufferMgmtStatus': 'r-' + 'Redundancy': { + 'Prop': { + 'Status': 'r-' + } } - }, - 'Maintenance': { - 'Prop': { - 'MeltLineTestStatus': 'r-', - 'SearchTone': 'rw' - }, - 'Cmd': ( - 'StartMeltAll', - 'StopMeltAll' - ) } -} From 229af07180cb4a75c88f6fc8e1e854086a9cb1c7 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 21 Oct 2020 10:00:30 +0200 Subject: [PATCH 142/318] Fixed a navigation issue --- vendors/KeyMile/baseCommandProcessor.py | 28 +++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 7b8d1fd..5817686 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -23,9 +23,14 @@ class BaseCommandProcessor(base.CommandProcessor): component_id = None + component_name = None + def set_component_id(self, id): self.component_id = id + def set_component_name(self, name): + self.component_name = name + main = {} cfgm = {} @@ -324,23 +329,38 @@ def validate_relation(component_type, name): 'port': ('chan', 'interface'), 'portgroup': ('port',), 'chan': ('vcc', 'interface',), + 'logports': ('logport',), 'logport': ('interface',), 'packet': ('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'), 'subpacket': ('srvc',), } - if component_type not in relations[name]: + try: + if component_type not in relations[name]: + return False + except KeyError: + return False + + return True + + def check_for_component(component_type, component_name): + try: + self._model.get_ + component_type('name', component_name) + except exceptions.InvalidInputError: return False return True if component_type: validation = validate_relation(component_type, self.__name__) + #if validation: + #validation = check_for_component(component_type, self.component_name + '/' + component_id) else: validation = validate_relation(components[0], self.__name__) - if validation is False: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty + if components[0] not in ('main', 'cfgm', 'fm', 'pm', 'status'): + if validation is False: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty if component_type == 'unit': if (self._model.version == '2200' and not 9 <= int(component_id) <= 12) or (self._model.version == '2300' and not 7 <= int(component_id) <= 14) or (self._model.version == '2500' and not 1 <= int(component_id) <= 21): From e0e7742b74176df2807b0d853857ba7db5afd6a9 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 21 Oct 2020 12:39:38 +0200 Subject: [PATCH 143/318] Further restructuring of change_directory --- vendors/KeyMile/baseCommandProcessor.py | 112 +++++++++++------------- 1 file changed, 50 insertions(+), 62 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 5817686..00baae4 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -31,6 +31,26 @@ def set_component_id(self, id): def set_component_name(self, name): self.component_name = name + def get_component(self, component_type, component_name): + if component_type == 'unit': + self._model.get_card('name', component_name) + if component_type == 'mgmtunit': + self._model.get_mgmt_card('name', component_name) + elif component_type == 'port': + self._model.get_port('name', component_name) + elif component_type == 'chan': + self._model.get_chan('name', component_name) + elif component_type == 'mgmtport': + self._model.get_mgmt_port('name', component_name) + elif component_type == 'interface' or component_type == 'vcc': + self._model.get_interface('name', component_name) + elif component_type == 'logport': + self._model.get_logport('name', component_name) + elif component_type == 'srvc': + self._model.get_srvc('name', component_name) + elif component_type == 'portgroupport': + self._model.get_portgroupport('name', component_name) + main = {} cfgm = {} @@ -232,11 +252,6 @@ def change_directory(self, path, context=None): context['path'] = '/' return self - if 'unit-' not in components[0] and components[0] not in ( - 'eoam', 'fan', 'multicast', 'services', 'tdmConnection', 'main', 'cfgm', 'fm', 'pm', 'status'): - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - if self.__name__ != 'root': subprocessor = self._parent.change_directory(path, context=context) else: @@ -321,13 +336,13 @@ def change_directory(self, path, context=None): def validate_relation(component_type, name): relations = { - 'root': ('unit', 'mgmtunit', 'fan', 'eoam', 'tdmConnections', 'multicast', 'services'), + 'root': ('unit', 'mgmtunit', 'fan', 'eoam', 'tdmconnections', 'multicast', 'services'), 'unit': ('port', 'portgroup', 'logports', 'huntgroup'), 'mgmtunit': ('mgmtport',), 'fan': ('alarm',), 'services': ('packet', 'macaccessctrl'), 'port': ('chan', 'interface'), - 'portgroup': ('port',), + 'portgroup': ('portgroupport',), 'chan': ('vcc', 'interface',), 'logports': ('logport',), 'logport': ('interface',), @@ -344,8 +359,11 @@ def validate_relation(component_type, name): return True def check_for_component(component_type, component_name): + if component_type in ('portgroup', 'unit', 'mgmtunit'): + return True + try: - self._model.get_ + component_type('name', component_name) + self.get_component(component_type, component_name) except exceptions.InvalidInputError: return False @@ -353,8 +371,16 @@ def check_for_component(component_type, component_name): if component_type: validation = validate_relation(component_type, self.__name__) - #if validation: - #validation = check_for_component(component_type, self.component_name + '/' + component_id) + if validation: + if self.component_name: + if component_type == 'srvc': + validation = check_for_component(component_type, components[0]) + elif component_type == 'logport': + validation = check_for_component(component_type, self.component_name + '/L/' + component_id) + else: + validation = check_for_component(component_type, self.component_name + '/' + component_id) + else: + validation = check_for_component(component_type, component_id) else: validation = validate_relation(components[0], self.__name__) if components[0] not in ('main', 'cfgm', 'fm', 'pm', 'status'): @@ -366,63 +392,12 @@ def check_for_component(component_type, component_name): if (self._model.version == '2200' and not 9 <= int(component_id) <= 12) or (self._model.version == '2300' and not 7 <= int(component_id) <= 14) or (self._model.version == '2500' and not 1 <= int(component_id) <= 21): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty# - elif component_type == 'port': - try: - if self.component_id == '11' or self.component_id == '13': - self._model.get_mgmt_port('name', self.component_id + '/' + component_id) - else: - self._model.get_port('name', self.component_id + '/' + component_id) - except exceptions.InvalidInputError: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'chan': - try: - self._model.get_chan('name', self._parent.component_id + '/' + self.component_id + '/' + component_id) - except exceptions.InvalidInputError: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'interface': - try: - self._model.get_interface('name', self._parent.component_id + '/' + self.component_id + '/' + component_id) - except exceptions.InvalidInputError: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'logport': - try: - self._model.get_logport('name', self._parent.component_id + '/L/' + component_id) - except exceptions.InvalidInputError: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'vcc': - try: - self._model.get_interface('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + component_id) - except exceptions.InvalidInputError: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'srvc': - try: - self._model.get_srvc('name', 'srvc-' + component_id) - except exceptions.InvalidInputError: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty if components[0] in ('main', 'cfgm', 'fm', 'pm', 'status'): if context['path'].split('/')[-1] in ('main', 'cfgm', 'fm', 'pm', 'status'): raise exceptions.CommandExecutionError(command=None, template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors')) - mf_layers = {} - if components[0] == 'status': - mf_layers = self.status - elif components[0] == 'cfgm': - mf_layers = self.cfgm - elif components[0] == 'fm': - mf_layers = self.fm - elif components[0] == 'pm': - mf_layers = self.pm - elif components[0] == 'main': - mf_layers = self.main - - if len(mf_layers) == 0: + if components[0] not in self.management_functions: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty @@ -465,6 +440,19 @@ def check_for_component(component_type, component_name): if component_id is not None: subprocessor.set_component_id(component_id) + if self.component_name: + if components[0] == 'logports': + component_name = self.component_name + '/L' + elif component_type == 'portgroup': + component_name = self.component_name + '/G' + component_id + elif component_type == 'srvc': + component_name = 'srvc' + component_id + else: + component_name = self.component_name + '/' + component_id + subprocessor.set_component_name(component_name) + else: + subprocessor.set_component_name(component_id) + if context['path'] == '/': new_path = components[0] else: From 357929da5b65e17e4bae94799e8b8c12b4e84a6d Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 21 Oct 2020 12:55:21 +0200 Subject: [PATCH 144/318] Refactored integration tests and fixed small bugs --- .../conf/bootstraps/create-keymile-MG2500.sh | 13 ++++- bootup/restapi.sh | 2 +- nesi/softbox/api/views/interface_views.py | 4 ++ .../integration_tests/keymile/backup.txt | 2 +- .../integration_tests/keymile/getDslam4.txt | 2 +- .../keymile/getInventory2.txt | 2 +- .../integration_tests/keymile/getIpsx7.txt | 2 +- .../keymile/getMonitoring3.txt | 2 +- .../integration_tests/keymile/getState1.txt | 2 +- .../keymile/getSubscriber6.txt | 2 +- .../integration_tests/keymile/getVoice5.txt | 2 +- .../keymile/setChannelProfile14.txt | 2 +- .../keymile/setDslProfile8.txt | 2 +- .../keymile/setInterface16.txt | 2 +- .../integration_tests/keymile/setIpAddr6.txt | 8 +-- .../keymile/setPortProfile13.txt | 2 +- .../keymile/setSIPDomain12.txt | 2 +- .../integration_tests/keymile/setTraffic1.txt | 2 +- .../integration_tests/keymile/setVCC15.txt | 2 +- .../integration_tests/keymile/setconfDsl2.txt | 7 ++- .../keymile/setconfVoice9.txt | 3 +- .../keymile/setdeconfVoicePort11.txt | 2 +- .../keymile/setdeconfVoicePort17.txt | 2 +- .../keymile/setportaktiv4.txt | 3 +- .../keymile/setportdeactiv5.txt | 2 +- .../keymile/setunconfDsl3.txt | 4 +- .../keymile/testLoopback3.txt | 2 +- .../keymile/testVoicePort2.txt | 2 +- .../keymile/testmelting4.txt | 2 +- test_cases/unit_tests/keymile/test_keymile.py | 54 ++++++++++++++++--- .../root/unit/port/portCommandProcessor.py | 23 ++++---- .../root/unit/unitCommandProcessor.py | 5 +- 32 files changed, 109 insertions(+), 59 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 7a91f28..199f2e4 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -205,7 +205,7 @@ req='{ srvc_1to1singletag_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) - +#################################################################################################################### ### Subrack 0 ### @@ -323,7 +323,7 @@ req='{ port_2_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### LogPort 1 ### +### LogPort-2 ### # Create a logical logport object at the network device (admin operation) req='{ @@ -334,6 +334,15 @@ req='{ logport_2_l_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/logports) +### Interface-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "logport_id": '$logport_2_l_2' +}' + +interface_2_l_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) + ### Unit-3 ### # Create a physical card at the network device (admin operation) diff --git a/bootup/restapi.sh b/bootup/restapi.sh index 7071288..6d8dd93 100755 --- a/bootup/restapi.sh +++ b/bootup/restapi.sh @@ -191,7 +191,7 @@ if [ $huawei_api = "yes" ]; then bash bootup/conf/bootstraps/create-huawei-5623.sh fi if [ $keymile_api = "yes" ]; then - bash bootup/conf/bootstraps/create-keymile-MG2200.sh #work_in_progress + bash bootup/conf/bootstraps/create-keymile-MG2500.sh fi if [ $edgecore_api = "yes" ]; then bash bootup/conf/bootstraps/create-alcatel-7360.sh #work_in_progress diff --git a/nesi/softbox/api/views/interface_views.py b/nesi/softbox/api/views/interface_views.py index 9987f5a..74159f2 100644 --- a/nesi/softbox/api/views/interface_views.py +++ b/nesi/softbox/api/views/interface_views.py @@ -13,6 +13,7 @@ from .base_views import * from ..models.port_models import Port from ..models.channel_models import Channel +from ..models.logport_models import LogPort from ..schemas.interface_schemas import * PREFIX = '/nesi/v1' @@ -46,6 +47,9 @@ def new_interface(box_id): elif 'chan_id' in req: channel = json.loads(show_component(Channel, box_id, req['chan_id']).data.decode('utf-8')) req['name'] = channel['name'] + "/" + str(len(channel['interfaces']) + 1) + elif 'logport_id' in req: + logport = json.loads(show_component(LogPort, box_id, req['logport_id']).data.decode('utf-8')) + req['name'] = logport['name'] + "/" + str(len(logport['interfaces']) + 1) else: raise exceptions.Forbidden('can not have port and channel as parent') response = new_component(InterfaceSchema(), Interface, req, box_id) diff --git a/test_cases/integration_tests/keymile/backup.txt b/test_cases/integration_tests/keymile/backup.txt index 6f999b9..5db5c11 100644 --- a/test_cases/integration_tests/keymile/backup.txt +++ b/test_cases/integration_tests/keymile/backup.txt @@ -1,3 +1,3 @@ -admin +manager secret exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getDslam4.txt b/test_cases/integration_tests/keymile/getDslam4.txt index a36c092..45ada2c 100644 --- a/test_cases/integration_tests/keymile/getDslam4.txt +++ b/test_cases/integration_tests/keymile/getDslam4.txt @@ -1,4 +1,4 @@ -admin +manager secret ls exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getInventory2.txt b/test_cases/integration_tests/keymile/getInventory2.txt index 16f77b4..27a0277 100644 --- a/test_cases/integration_tests/keymile/getInventory2.txt +++ b/test_cases/integration_tests/keymile/getInventory2.txt @@ -1,4 +1,4 @@ -admin +manager secret ls cd /services/packet/nto1/ diff --git a/test_cases/integration_tests/keymile/getIpsx7.txt b/test_cases/integration_tests/keymile/getIpsx7.txt index dead751..6537d4b 100644 --- a/test_cases/integration_tests/keymile/getIpsx7.txt +++ b/test_cases/integration_tests/keymile/getIpsx7.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-19/status get SubscriberList diff --git a/test_cases/integration_tests/keymile/getMonitoring3.txt b/test_cases/integration_tests/keymile/getMonitoring3.txt index e4259f3..eaecda9 100644 --- a/test_cases/integration_tests/keymile/getMonitoring3.txt +++ b/test_cases/integration_tests/keymile/getMonitoring3.txt @@ -1,4 +1,4 @@ -admin +manager secret ls cd status diff --git a/test_cases/integration_tests/keymile/getState1.txt b/test_cases/integration_tests/keymile/getState1.txt index 2c5d8b1..542cbd6 100644 --- a/test_cases/integration_tests/keymile/getState1.txt +++ b/test_cases/integration_tests/keymile/getState1.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-1/port-1/status get AttainableRate diff --git a/test_cases/integration_tests/keymile/getSubscriber6.txt b/test_cases/integration_tests/keymile/getSubscriber6.txt index 1a0f1b4..601fc6a 100644 --- a/test_cases/integration_tests/keymile/getSubscriber6.txt +++ b/test_cases/integration_tests/keymile/getSubscriber6.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-19/portgroup-1/port-1/status get SubscriberList diff --git a/test_cases/integration_tests/keymile/getVoice5.txt b/test_cases/integration_tests/keymile/getVoice5.txt index e61689a..0f51655 100644 --- a/test_cases/integration_tests/keymile/getVoice5.txt +++ b/test_cases/integration_tests/keymile/getVoice5.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-19/portgroup-1/port-1/cfgm get pstnport diff --git a/test_cases/integration_tests/keymile/setChannelProfile14.txt b/test_cases/integration_tests/keymile/setChannelProfile14.txt index 00530d5..5135d50 100644 --- a/test_cases/integration_tests/keymile/setChannelProfile14.txt +++ b/test_cases/integration_tests/keymile/setChannelProfile14.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-5/port-1/chan-1/cfgm set chanprofile rofile diff --git a/test_cases/integration_tests/keymile/setDslProfile8.txt b/test_cases/integration_tests/keymile/setDslProfile8.txt index 6f999b9..5db5c11 100644 --- a/test_cases/integration_tests/keymile/setDslProfile8.txt +++ b/test_cases/integration_tests/keymile/setDslProfile8.txt @@ -1,3 +1,3 @@ -admin +manager secret exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setInterface16.txt b/test_cases/integration_tests/keymile/setInterface16.txt index e719a80..dc0e318 100644 --- a/test_cases/integration_tests/keymile/setInterface16.txt +++ b/test_cases/integration_tests/keymile/setInterface16.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-2/logports/logport-2/cfgm CreateInterface default VCC_1_100 diff --git a/test_cases/integration_tests/keymile/setIpAddr6.txt b/test_cases/integration_tests/keymile/setIpAddr6.txt index ec96fcd..1a31d6d 100644 --- a/test_cases/integration_tests/keymile/setIpAddr6.txt +++ b/test_cases/integration_tests/keymile/setIpAddr6.txt @@ -1,15 +1,15 @@ -admin +manager secret cd /services/packet/1to1SingleTag/srvc-1/cfgm -set Service /unit-19/control {$input->vlan_voice_new} CoS0 Add +set Service /unit-19/control 11 CoS0 Add cd /services/packet/1to1SingleTag/srvc-2/cfgm -set Service /unit-19/media {$input->vlan_voice_new} CoS0 Add +set Service /unit-19/media 1 CoS0 Add cd /unit-19/cfgm set Ip 11.1.1.1 155.255.255.0 2.3.3.3 cd /cfgm save cd /unit-19/main restart -admin +manager secret exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setPortProfile13.txt b/test_cases/integration_tests/keymile/setPortProfile13.txt index 6ee1f57..0b30451 100644 --- a/test_cases/integration_tests/keymile/setPortProfile13.txt +++ b/test_cases/integration_tests/keymile/setPortProfile13.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-6/port-1/cfgm set portprofiles true default 0 false default 0 false default 0 true default Priority diff --git a/test_cases/integration_tests/keymile/setSIPDomain12.txt b/test_cases/integration_tests/keymile/setSIPDomain12.txt index fd572f6..a973089 100644 --- a/test_cases/integration_tests/keymile/setSIPDomain12.txt +++ b/test_cases/integration_tests/keymile/setSIPDomain12.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-19/cfgm get Sip diff --git a/test_cases/integration_tests/keymile/setTraffic1.txt b/test_cases/integration_tests/keymile/setTraffic1.txt index bcaee65..0f61dff 100644 --- a/test_cases/integration_tests/keymile/setTraffic1.txt +++ b/test_cases/integration_tests/keymile/setTraffic1.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-7 ls diff --git a/test_cases/integration_tests/keymile/setVCC15.txt b/test_cases/integration_tests/keymile/setVCC15.txt index dfc9f0b..2000864 100644 --- a/test_cases/integration_tests/keymile/setVCC15.txt +++ b/test_cases/integration_tests/keymile/setVCC15.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-1/port-1/chan-1/cfgm CreateVcc default default diff --git a/test_cases/integration_tests/keymile/setconfDsl2.txt b/test_cases/integration_tests/keymile/setconfDsl2.txt index 61e065d..70dd24b 100644 --- a/test_cases/integration_tests/keymile/setconfDsl2.txt +++ b/test_cases/integration_tests/keymile/setconfDsl2.txt @@ -1,6 +1,5 @@ -admin +manager secret -#adsl cd /unit-1/port-1/main Set Labels "umlctId)" "arrierId" "" set AdministrativeStatus up @@ -12,8 +11,8 @@ Set Labels "ctId" "d" "" set AdministrativeStatus up cd /unit-2/logports/cfgm create port-1 -cd /unit-$card/logports/logport-1/cfgm +cd /unit-2/logports/logport-1/cfgm CreateInterface name -cd /unit-$card/logports/logport-1/main +cd /unit-2/logports/logport-1/main set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfVoice9.txt b/test_cases/integration_tests/keymile/setconfVoice9.txt index 6c4c2fe..c25801f 100644 --- a/test_cases/integration_tests/keymile/setconfVoice9.txt +++ b/test_cases/integration_tests/keymile/setconfVoice9.txt @@ -1,6 +1,5 @@ -admin +manager secret -#analog cd /unit-19/portgroup-1/port-1/cfgm set pstnport true 11 true false none none none none none cd /unit-19/portgroup-1/port-1/main diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt index c5dc42a..33b5824 100644 --- a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-19/portgroup-1/port-1/cfgm get pstnport diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt index 9099c38..9b41b86 100644 --- a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-$card/port-$port/main set AdministrativeStatus down diff --git a/test_cases/integration_tests/keymile/setportaktiv4.txt b/test_cases/integration_tests/keymile/setportaktiv4.txt index f538660..4f2f968 100644 --- a/test_cases/integration_tests/keymile/setportaktiv4.txt +++ b/test_cases/integration_tests/keymile/setportaktiv4.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-1/port-1/main set AdministrativeStatus up @@ -6,7 +6,6 @@ cd /unit-5/port-1/main set AdministrativeStatus up cd /unit-7/port-1/main set AdministrativeStatus up -#sdsl cd /unit-2/logports/logport-2/main set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setportdeactiv5.txt b/test_cases/integration_tests/keymile/setportdeactiv5.txt index 88ca770..79b499f 100644 --- a/test_cases/integration_tests/keymile/setportdeactiv5.txt +++ b/test_cases/integration_tests/keymile/setportdeactiv5.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-1/port-1/main set AdministrativeStatus down diff --git a/test_cases/integration_tests/keymile/setunconfDsl3.txt b/test_cases/integration_tests/keymile/setunconfDsl3.txt index 5eb92fd..c8406f4 100644 --- a/test_cases/integration_tests/keymile/setunconfDsl3.txt +++ b/test_cases/integration_tests/keymile/setunconfDsl3.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-1/port-1/main set AdministrativeStatus down @@ -6,11 +6,9 @@ Set Labels "" "" "" cd /unit-5/port-1/main set AdministrativeStatus down Set Labels "" "" "" -#ftth cd /unit-7/port-1/main set AdministrativeStatus down Set Labels "" "" "" -#sdsl cd /unit-2/logports/logport-2/main set AdministrativeStatus down Set Labels "" "" "" diff --git a/test_cases/integration_tests/keymile/testLoopback3.txt b/test_cases/integration_tests/keymile/testLoopback3.txt index 2ebea1b..6e41de5 100644 --- a/test_cases/integration_tests/keymile/testLoopback3.txt +++ b/test_cases/integration_tests/keymile/testLoopback3.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-19/port-1/status Lock diff --git a/test_cases/integration_tests/keymile/testVoicePort2.txt b/test_cases/integration_tests/keymile/testVoicePort2.txt index 66f987f..cacc582 100644 --- a/test_cases/integration_tests/keymile/testVoicePort2.txt +++ b/test_cases/integration_tests/keymile/testVoicePort2.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-19/main get HardwareAndSoftware diff --git a/test_cases/integration_tests/keymile/testmelting4.txt b/test_cases/integration_tests/keymile/testmelting4.txt index 4f509dd..4255a3d 100644 --- a/test_cases/integration_tests/keymile/testmelting4.txt +++ b/test_cases/integration_tests/keymile/testmelting4.txt @@ -1,4 +1,4 @@ -admin +manager secret /unit-19/port-1/status/StartLineTest get /unit-19/port-1/status/LineTestResults diff --git a/test_cases/unit_tests/keymile/test_keymile.py b/test_cases/unit_tests/keymile/test_keymile.py index e5a171a..db68fa4 100644 --- a/test_cases/unit_tests/keymile/test_keymile.py +++ b/test_cases/unit_tests/keymile/test_keymile.py @@ -25,19 +25,57 @@ def test_box(self): assert True def test_card(self): - assert True + card = self.model.get_card("name", '19') + card.set_sip('gateway_name', 'home_domain', 1, 'country_code', 'area_code', 12, 11, True, 'Asserted', False, + 1, False, False, 1222) + assert card.gateway_name == 'gateway_name' + assert card.uas_request_timer is False + card.set_ip('1.1.1.1', '2.22.2.2', '111.111.111.111') + assert card.subnet_mask == '2.22.2.2' + card.set_label('"l1"', '"l2"', 'desc') + assert card.label1 == '"l1"' + card.set_proxy('PrimaryOnly', 'proxy_address', 11, 'proxy_address_sec', 12, True, + 'Register', 33) + assert card.proxy_mode == 'PrimaryOnly' + assert card.proxy_interval == 33 def test_channel(self): - assert True - - def test_interface(self): - assert True + channel = self.model.get_chan('id', 1) + channel.set_profile_name('name') + assert channel.chan_profile_name == 'name' def test_port(self): - assert True + port = self.model.get_port('id', 1) + port.set_profiles(True, 'n1', 1, False, 'n2', 0, True, 'dff', 11, False, 'n4', 'Priority') + assert port.profile1_name == 'n1' + assert port.profile1_enable is True + port.set_test_state('Passed') + assert port.loopbacktest_state == 'Passed' + port.lock_admin() + assert port.admin_state == '2' + port.unlock_admin() + assert port.admin_state == '3' + port.set_melttest_state('Passed') + assert port.melttest_state == 'Passed' + port.set_linetest_state('Passed') + assert port.linetest_state == 'Passed' + port.set_mode('mode') + assert port.mode == 'mode' + port.set_flow_control('test') + assert port.flow_control == 'test' - def test_subrack(self): - assert True + def test_portgroupport(self): + port = self.model.get_portgroupport('name', '19/G1/1') + port.set_pstnport(True, True, True, 'sip', 'proxy', 'codec', 'pstn', 'enterprise') + assert port.enable is True + assert port.enterprise_profile == 'enterprise' + port.set_isdnport(False, True, True, True, 'sip', 'proxy', 'codec', 'isdn') + assert port.enable is False + assert port.isdnba_profile == 'isdn' + + def test_srcv(self): + srvc = self.model.get_srvc('id', 2) + srvc.set_service('address', 11, 'CoS0', 'Add') @pytest.mark.parametrize("path", DATA) def test_integration(self, path): diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 7ceb588..0c36329 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -28,6 +28,7 @@ class PortCommandProcessor(BaseCommandProcessor): def get_property(self, command, *args, context=None): port = self.get_component() + context['port'] = port card = self._parent.get_component() scopes = ('login', 'base', 'get') if self._validate(args, *()): @@ -264,7 +265,7 @@ def set(self, command, *args, context=None): port = self.get_component() port.set_profile(profile) - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'Portprofiles', str) and context['path'].split('/')[-1] == 'cfgm' and \ @@ -274,7 +275,7 @@ def set(self, command, *args, context=None): port = self.get_component() port.set_profile(profile) - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'Portprofiles', str, str, str, str, str, str, str, str, str, str, str, str) and \ @@ -289,7 +290,7 @@ def set(self, command, *args, context=None): en4 = True if en4.lower() == 'true' else False port.set_profiles(en1, name1, int(elen1), en2, name2, int(elen2), en3, name3, int(elen3), en4, name4, mode) - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'AdministrativeStatus', str) and context['path'].split('/')[-1] == 'main': @@ -302,7 +303,7 @@ def set(self, command, *args, context=None): port.admin_down() else: raise exceptions.SoftboxenError() - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': @@ -310,7 +311,7 @@ def set(self, command, *args, context=None): try: port = self.get_component() port.set_label(label1, label2, description) - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) @@ -321,9 +322,9 @@ def set(self, command, *args, context=None): else: mode, = self._dissect(args, 'Mode', str) try: - port = self.get_port_component() + port = self.get_component() port.set_mode(mode) - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) @@ -334,9 +335,9 @@ def set(self, command, *args, context=None): else: mode, = self._dissect(args, 'Mode', str) try: - port = self.get_port_component() + port = self.get_component() port.set_mode(mode) - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) @@ -344,9 +345,9 @@ def set(self, command, *args, context=None): card.board_name and self.__name__ == 'port' and card.product == 'ftth': ctrl, = self._dissect(args, 'FlowControl', str) try: - port = self.get_port_component() + port = self.get_component() port.set_flow_control(ctrl) - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) else: diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index f20ce24..8cef5d2 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -256,7 +256,7 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'Ip', str, str, str) and context['component_path'].split('/')[-1] == 'cfgm': + elif self._validate(args, 'Ip', str, str, str) and context['path'].split('/')[-1] == 'cfgm': ip1, ip2, ip3 = self._dissect(args, 'Ip', str, str, str) try: component = self.get_component() @@ -278,6 +278,9 @@ def set(self, command, *args, context=None): card.set_sip(gw, hd, int(spn), cc, ac, int(rt), int(mri), se, aim, os, int(ot), uac, uas, int(sessione)) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args[0], 'Digitmap') and \ + context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): + pass elif self._validate(args, 'Registrar', str, str, str, str) and \ context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): ra, rp, rm, rt = self._dissect(args, 'Registrar', str, str, str, str) From 02fe34b1cec4fd15694fb894a7c46dab4a83dbd4 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 21 Oct 2020 12:57:20 +0200 Subject: [PATCH 145/318] added interface into script description --- bootup/conf/bootstraps/create-keymile-MG2500.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 199f2e4..8716102 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -34,6 +34,7 @@ path="`dirname \"$0\"`" # | |-> Port-2 # # | |-> LogPorts # # | | |-> LogPort-2 # +# | | | |-> Interface-1 # # | # # |---> Unit-3 (sdsl) (SUSE1) # # | |-> Port-1 # From f8680dd7c9812c06b51b7d51c84b6e0fc2d98c14 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 22 Oct 2020 10:46:07 +0200 Subject: [PATCH 146/318] Further refactoring of change_directory, added component_name class variable and refactored logic for checking existence of a component --- .../mgmt_port/mgmtportCommandProcessor.py | 11 +- .../mgmt_unit/mgmtunitCommandProcessor.py | 8 +- .../root/services/srvcCommandProcessor.py | 3 + .../logport/port/logportCommandProcessor.py | 5 +- .../unit/port/chan/chanCommandProcessor.py | 23 +-- .../unit/port/chan/vcc/vccCommandProcessor.py | 49 ----- .../port/chan/vcc/vccManagementFunctions.py | 104 ----------- .../interface/interfaceCommandProcessor.py | 3 + .../root/unit/port/portCommandProcessor.py | 2 +- .../port/portgroupportCommandProcessor.py | 4 +- .../root/unit/unitCommandProcessor.py | 8 +- vendors/KeyMile/baseCommandProcessor.py | 170 ++++++++---------- 12 files changed, 105 insertions(+), 285 deletions(-) delete mode 100644 vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py delete mode 100644 vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py index dae5325..8edc2f4 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py @@ -65,11 +65,8 @@ def _init_access_points(self, context=None): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) - def get_port_component(self): - if self._parent.component_id == '11' or self._parent.component_id == '13': - raise exceptions.CommandSyntaxError() - else: - return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + def get_component(self): + return self._model.get_mgmt_port('name', self.component_name) def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') @@ -82,7 +79,7 @@ def set(self, command, *args, context=None): elif self._validate(args, 'AdministrativeStatus', str) and context['path'].split('/')[-1] == 'main': state, = self._dissect(args, 'AdministrativeStatus', str) try: - port = self.get_port_component() + port = self.get_component() if state == 'up': port.admin_up() elif state == 'down': @@ -95,7 +92,7 @@ def set(self, command, *args, context=None): elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': label1, label2, description = self._dissect(args, 'Labels', str, str, str) try: - port = self.get_port_component() + port = self.get_component() port.set_label(label1, label2, description) except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py index 78de871..8b0f59f 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py @@ -108,13 +108,7 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def get_component(self): - try: - if self.component_id == '11' or self.component_id == '13': - return self._model.get_mgmt_card('name', self.component_id) - else: - raise exceptions.CommandSyntaxError() - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError() + return self._model.get_mgmt_card('name', self.component_name) def set(self, command, *args, context=None): try: diff --git a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py index 4294e2b..a35ef8f 100644 --- a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py @@ -81,3 +81,6 @@ def set(self, command, *args, context=None): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + + def get_component(self): + return self._model.get_srvcs('name', self.component_name) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 3bc74fb..36de9cd 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -40,12 +40,11 @@ def get_property(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors')) def get_component(self): - return self._model.get_logport('name', self._parent._parent.component_id + '/L/' + self.component_id) + return self._model.get_logport('name', self.component_name) def _init_access_points(self, context=None): self.access_points = () - logport_name = self._parent._parent.component_id + '/L/' + self.component_id - logport = self._model.get_logport('name', logport_name) + logport = self.get_component() try: _ = self._model.get_interface('logport_id', logport.id) except exceptions.SoftboxenError: diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index fecf4ae..bcfc005 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -27,7 +27,7 @@ class ChanCommandProcessor(BaseCommandProcessor): def _init_access_points(self, context=None): self.access_points = () - chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + chan = self.get_component() card = self._model.get_card('name', self._parent._parent.component_id) for interface in self._model.get_interfaces('chan_id', chan.id): @@ -47,7 +47,7 @@ def do_deletevcc(self, command, *args, context=None): # all or vcc_id name, = self._dissect(args, str) if name == 'all': - chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + chan = self.get_component() for vcc in self._model.get_interfaces('chan_id', chan.id): vcc.delete() elif name.startswith('vcc-'): @@ -68,7 +68,7 @@ def do_deleteinterface(self, command, *args, context=None): # all or interface_id name, = self._dissect(args, str) if name == 'all': - chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + chan = self.get_component() for interface in self._model.get_interfaces('chan_id', chan.id): interface.delete() elif name.startswith('interface-'): @@ -91,7 +91,7 @@ def do_createinterface(self, command, *args, context=None): vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names try: - chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + chan = self.get_component() id = 1 for interface in self._model.get_interfaces('chan_id', chan.id): if interface.chan_id is not None: @@ -118,7 +118,7 @@ def do_createinterface(self, command, *args, context=None): vlan_prof, vcc_prof = self._dissect(args, str, str) # TODO: Check if profiles := default or profile names try: - chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + chan = self.get_component() id = 1 for interface in self._model.get_interfaces('chan_id', chan.id): if interface.chan_id is not None: @@ -152,7 +152,7 @@ def do_createvcc(self, command, *args, context=None): vcc_prof, vlan_prof = self._dissect(args, str, str) # TODO: Check if profiles := default or profile names try: - chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + chan = self.get_component() id = 1 for vcc in self._model.get_interfaces('chan_id', chan.id): if vcc.chan_id is not None: @@ -192,7 +192,7 @@ def set(self, command, *args, context=None): name, = self._dissect(args, 'chanprofile', str) try: #TODO: Check if profile with this name exists or default - channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + channel = self.get_component() channel.set_profile_name(name) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -200,13 +200,16 @@ def set(self, command, *args, context=None): name, = self._dissect(args, 'ProfileName', str) try: # TODO: Check if profile with this name exists or default - channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + channel = self.get_component() channel.set_profile_name(name) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) else: raise exceptions.CommandSyntaxError(command=command) + def get_component(self): + return self._model.get_chan('name', self.component_name) + def get_property(self, command, *args, context=None): card = self._model.get_card('name', self._parent._parent.component_id) scopes = ('login', 'base', 'get') @@ -216,13 +219,13 @@ def get_property(self, command, *args, context=None): exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc elif self._validate(args, 'Chanprofile') and 'SUV' in card.board_name: - channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + channel = self.get_component() context['spacer1'] = self.create_spacers((67,), (channel.chan_profile_name,))[0] * ' ' context['profile_name'] = channel.chan_profile_name text = self._render('chan_profile', *scopes, context=context) self._write(text) elif self._validate(args, 'ProfileName') and 'SUV' not in card.board_name: - channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + channel = self.get_component() context['spacer1'] = self.create_spacers((67,), (channel.chan_profile_name,))[0] * ' ' context['profile_name'] = channel.chan_profile_name text = self._render('chan_profile', *scopes, context=context) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py deleted file mode 100644 index fca7430..0000000 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py +++ /dev/null @@ -1,49 +0,0 @@ -# This file is part of the NESi software. -# -# Copyright (c) 2020 -# Original Software Design by Ilya Etingof . -# -# Software adapted by inexio . -# - Janis Groß -# - Philip Konrath -# - Alexander Dincher -# -# License: https://github.com/inexio/NESi/LICENSE.rst - -from nesi import exceptions -from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor - - -class VccCommandProcessor(BaseCommandProcessor): - __name__ = 'vcc' - management_functions = ('main', 'cfgm', 'pm', 'status') - access_points = () - - from .vccManagementFunctions import main - from .vccManagementFunctions import cfgm - from .vccManagementFunctions import pm - from .vccManagementFunctions import status - - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - - def set(self, command, *args, context=None): - if self._validate(args, *()): - exc = exceptions.CommandSyntaxError(command=command) - exc.template = 'syntax_error' - exc.template_scopes = ('login', 'base', 'syntax_errors') - raise exc - else: - raise exceptions.CommandSyntaxError(command=command) - - def get_property(self, command, *args, context=None): - #card = self._model.get_card('name', self.component_id) - scopes = ('login', 'base', 'get') - if self._validate(args, *()): - exc = exceptions.CommandSyntaxError(command=command) - exc.template = 'syntax_error' - exc.template_scopes = ('login', 'base', 'syntax_errors') - raise exc - else: - raise exceptions.CommandExecutionError(command=command, template='invalid_property', - template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py deleted file mode 100644 index 9278f33..0000000 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py +++ /dev/null @@ -1,104 +0,0 @@ -main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } -} - -cfgm = { - 'Traceability': { - 'Prop': { - 'AutomaticAgentCircuitId': 'rw', - 'AgentCircuitId': 'rw' - } - }, - 'Filter': { - 'Prop': { - 'MACSourceFilteringMode': 'rw', - 'MacAccessWhitelist': 'rw', - 'NumberOfMacForFloodingPrev': 'rw', - 'L2CPFilter': 'rw', - 'DestMacBlacklistProfile': 'rw', - 'SrcMacBlacklist': 'rw' - } - }, - 'IfRateLimiter': { - 'Prop': { - 'IfRateLimiting': 'rw' - } - }, - 'Profiles': { - 'Prop': { - 'configuredProfiles': 'rw' - } - } -} - -pm = { - 'PerformanceMonitoring': { - 'Cmd': ( - 'UserCounter', - 'GetHistory15min', - 'GetHistory24h', - 'GetAlarm15min', - 'GetAlarm24hRecursive', - 'ResetUserCounter', - 'ResetAlarm15min', - 'ResetAlarm24h' - ) - }, - 'UserCounter': { - 'Prop': { - 'UserCounterDisplayMode': 'rw', - 'UserCounterTable': 'r-' - }, - 'Cmd': ( - 'UserCounterReset', - ) - }, - 'History15min': { - 'Prop': { - 'History15minDisplayMode': 'rw', - 'History15minTable': 'r-' - } - }, - 'History24h': { - 'Prop': { - 'History24hDisplayMode': 'rw', - 'History24hTable': 'r-' - } - }, - 'Alarm15min': { - 'Prop': { - 'Alarm15minDisplayMode': 'rw', - 'Alarm15minTable': 'r-' - }, - 'Cmd': ( - 'Alarm15minReset', - ) - }, - 'Alarm24h': { - 'Prop': { - 'Alarm24hDisplayMode': 'rw', - 'Alarm24hTable': 'r-' - }, - 'Cmd': ( - 'Alarm24hReset', - ) - } -} - -status = { - 'ServiceInfo': { - 'Prop': { - 'ServiceStatus': 'r-' - } - }, - 'UserConnection': { - 'Prop': { - 'CurrentPppConnectionState': 'r-' - } - } -} diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index 1073477..b73c2a6 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -39,3 +39,6 @@ def set(self, command, *args, context=None): return else: raise exceptions.CommandSyntaxError(command=command) + + def get_component(self): + return self._model.get_interface('name', self.component_name) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 0c36329..be2247b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -248,7 +248,7 @@ def do_createinterface(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def get_component(self): - return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + return self._model.get_port('name', self.component_name) def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 67bcda4..391cc16 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -24,7 +24,7 @@ class PortgroupportCommandProcessor(PortCommandProcessor): from .portgroupportManagementFunctions import status def get_component(self): - return self._model.get_portgroupport('name', self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id) + return self._model.get_portgroupport('name', self.component_name) def get_property(self, command, *args, context=None): port = self.get_component() @@ -37,7 +37,7 @@ def get_property(self, command, *args, context=None): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'port' and subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id: + if subscriber.type == 'port' and subscriber.address == self.component_name: context['i'] = i context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 8cef5d2..cd69007 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -230,13 +230,7 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def get_component(self): - try: - if self.component_id == '11' or self.component_id == '13': - raise exceptions.CommandSyntaxError() - else: - return self._model.get_card('name', self.component_id) - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError() + return self._model.get_card('name', self.component_name) def set(self, command, *args, context=None): try: diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 00baae4..11059ba 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -13,6 +13,7 @@ from nesi import exceptions from nesi.softbox.cli import base import re +import importlib class BaseCommandProcessor(base.CommandProcessor): @@ -31,26 +32,6 @@ def set_component_id(self, id): def set_component_name(self, name): self.component_name = name - def get_component(self, component_type, component_name): - if component_type == 'unit': - self._model.get_card('name', component_name) - if component_type == 'mgmtunit': - self._model.get_mgmt_card('name', component_name) - elif component_type == 'port': - self._model.get_port('name', component_name) - elif component_type == 'chan': - self._model.get_chan('name', component_name) - elif component_type == 'mgmtport': - self._model.get_mgmt_port('name', component_name) - elif component_type == 'interface' or component_type == 'vcc': - self._model.get_interface('name', component_name) - elif component_type == 'logport': - self._model.get_logport('name', component_name) - elif component_type == 'srvc': - self._model.get_srvc('name', component_name) - elif component_type == 'portgroupport': - self._model.get_portgroupport('name', component_name) - main = {} cfgm = {} @@ -319,6 +300,8 @@ def change_directory(self, path, context=None): if component_type == 'unit': if component_id == '11' or component_id == '13': component_type = 'mgmtunit' + if component_type == 'vcc': + component_type = 'interface' command_processor = component_type.capitalize() + 'CommandProcessor' else: @@ -334,57 +317,12 @@ def change_directory(self, path, context=None): else: command_processor = components[0].capitalize() + 'CommandProcessor' - def validate_relation(component_type, name): - relations = { - 'root': ('unit', 'mgmtunit', 'fan', 'eoam', 'tdmconnections', 'multicast', 'services'), - 'unit': ('port', 'portgroup', 'logports', 'huntgroup'), - 'mgmtunit': ('mgmtport',), - 'fan': ('alarm',), - 'services': ('packet', 'macaccessctrl'), - 'port': ('chan', 'interface'), - 'portgroup': ('portgroupport',), - 'chan': ('vcc', 'interface',), - 'logports': ('logport',), - 'logport': ('interface',), - 'packet': ('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'), - 'subpacket': ('srvc',), - } - - try: - if component_type not in relations[name]: - return False - except KeyError: - return False - - return True - - def check_for_component(component_type, component_name): - if component_type in ('portgroup', 'unit', 'mgmtunit'): - return True - - try: - self.get_component(component_type, component_name) - except exceptions.InvalidInputError: - return False - - return True - if component_type: - validation = validate_relation(component_type, self.__name__) - if validation: - if self.component_name: - if component_type == 'srvc': - validation = check_for_component(component_type, components[0]) - elif component_type == 'logport': - validation = check_for_component(component_type, self.component_name + '/L/' + component_id) - else: - validation = check_for_component(component_type, self.component_name + '/' + component_id) - else: - validation = check_for_component(component_type, component_id) + relation_is_valid = self._validate_layer_relation(component_type, self.__name__) else: - validation = validate_relation(components[0], self.__name__) + relation_is_valid = self._validate_layer_relation(components[0], self.__name__) if components[0] not in ('main', 'cfgm', 'fm', 'pm', 'status'): - if validation is False: + if relation_is_valid is False: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty @@ -409,33 +347,7 @@ def check_for_component(component_type, component_name): self.set_prompt_end_pos(context=context) return self - from vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor import UnitCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.chan.chanCommandProcessor import ChanCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor import \ - InterfaceCommandProcessor - from vendors.KeyMile.accessPoints.root.fan.fanCommandProcessor import FanCommandProcessor - from vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor import AlarmCommandProcessor - from vendors.KeyMile.accessPoints.root.eoamCommandProcessor import EoamCommandProcessor - from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor - from vendors.KeyMile.accessPoints.root.tdmconnectionsCommandProcessor import TdmconnectionsCommandProcessor - from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import \ - PortgroupCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import \ - PortgroupportCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.logport.logportsCommandProcessor import LogportsCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ - LogportCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.chan.vcc.vccCommandProcessor import VccCommandProcessor - from vendors.KeyMile.accessPoints.root.services.packetCommandProcessor import PacketCommandProcessor - from vendors.KeyMile.accessPoints.root.services.macaccessctrlCommandProcessor import \ - MacaccessctrlCommandProcessor - from vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor import SubpacketCommandProcessor - from vendors.KeyMile.accessPoints.root.services.srvcCommandProcessor import SrvcCommandProcessor - from vendors.KeyMile.accessPoints.root.mgmt_unit.mgmtunitCommandProcessor import MgmtunitCommandProcessor - from vendors.KeyMile.accessPoints.root.mgmt_unit.mgmt_port.mgmtportCommandProcessor import MgmtportCommandProcessor - subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') + subprocessor = self._create_command_processor_obj(command_processor) if component_id is not None: subprocessor.set_component_id(component_id) @@ -453,6 +365,12 @@ def check_for_component(component_type, component_name): else: subprocessor.set_component_name(component_id) + if component_type: + component_exists = self._check_for_component(subprocessor) + if component_exists is False: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if context['path'] == '/': new_path = components[0] else: @@ -464,6 +382,68 @@ def check_for_component(component_type, component_name): return subprocessor + def _validate_layer_relation(self, component_type, name): + relations = { + 'root': ('unit', 'mgmtunit', 'fan', 'eoam', 'tdmconnections', 'multicast', 'services'), + 'unit': ('port', 'portgroup', 'logports', 'huntgroup'), + 'mgmtunit': ('mgmtport',), + 'fan': ('alarm',), + 'services': ('packet', 'macaccessctrl'), + 'port': ('chan', 'interface'), + 'portgroup': ('portgroupport',), + 'chan': ('vcc', 'interface',), + 'logports': ('logport',), + 'logport': ('interface',), + 'packet': ('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'), + 'subpacket': ('srvc',), + } + + try: + if component_type not in relations[name]: + return False + except KeyError: + return False + + return True + + def _check_for_component(self, command_processor): + if command_processor.__name__ in ('portgroup', 'unit', 'mgmtunit'): + return True + + try: + command_processor.get_component() + except exceptions.InvalidInputError: + return False + + return True + + def _create_command_processor_obj(self, command_processor): + module_paths = { + 'UnitCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor', + 'PortCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor', + 'ChanCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.port.chan.chanCommandProcessor', + 'InterfaceCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor', + 'FanCommandProcessor': 'vendors.KeyMile.accessPoints.root.fan.fanCommandProcessor', + 'AlarmCommandProcessor': 'vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor', + 'EoamCommandProcessor': 'vendors.KeyMile.accessPoints.root.eoamCommandProcessor', + 'MulticastCommandProcessor': 'vendors.KeyMile.accessPoints.root.multicastCommandProcessor', + 'TdmconnectionsCommandProcessor': 'vendors.KeyMile.accessPoints.root.tdmconnectionsCommandProcessor', + 'ServicesCommandProcessor': 'vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor', + 'PortgroupCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor', + 'PortgroupportCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor', + 'LogportsCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.logport.logportsCommandProcessor', + 'LogportCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor', + 'PacketCommandProcessor': 'vendors.KeyMile.accessPoints.root.services.packetCommandProcessor', + 'MacaccessctrlCommandProcessor': 'vendors.KeyMile.accessPoints.root.services.macaccessctrlCommandProcessor', + 'SubpacketCommandProcessor': 'vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor', + 'SrvcCommandProcessor': 'vendors.KeyMile.accessPoints.root.services.srvcCommandProcessor', + 'MgmtunitCommandProcessor': 'vendors.KeyMile.accessPoints.root.mgmt_unit.mgmtunitCommandProcessor', + 'MgmtportCommandProcessor': 'vendors.KeyMile.accessPoints.root.mgmt_unit.mgmt_port.mgmtportCommandProcessor', + } + + return self._create_subprocessor( + getattr(importlib.import_module(module_paths[command_processor]), command_processor), 'login', 'base') + def do_get(self, command, *args, context=None): if len(args) >= 1: if '/' in args[0]: From 48e3df336864b44a30d08c66c22f730b8e2f3597 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 22 Oct 2020 11:19:46 +0200 Subject: [PATCH 147/318] Fixed a bug where switching between two component layers the component name and id wouldn't change --- vendors/KeyMile/baseCommandProcessor.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 11059ba..6d6b13b 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -500,8 +500,7 @@ def do_cd(self, command, *args, context=None): except: context['path'] = current_path raise - if not isinstance(subprocessor, self.__class__): - subprocessor.loop(context=context, return_to=subprocessor._parent) + subprocessor.loop(context=context, return_to=subprocessor._parent) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), From 44d4d9ad5508b7c2e9d8a11c7097db077b1b0c4a Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 22 Oct 2020 13:12:29 +0200 Subject: [PATCH 148/318] Removed now obsolete field component_id and changed all occurences to a call with component_name --- .../mgmt_port/mgmtportCommandProcessor.py | 6 ++-- .../accessPoints/root/rootCommandProcessor.py | 2 -- .../root/services/srvcCommandProcessor.py | 16 +++++++++-- .../unit/logport/logportsCommandProcessor.py | 11 ++++---- .../logport/port/logportCommandProcessor.py | 15 ++++------ .../unit/port/chan/chanCommandProcessor.py | 28 +++++++++---------- .../root/unit/port/portCommandProcessor.py | 24 ++++++++-------- .../port/portgroupportCommandProcessor.py | 12 ++++---- .../portgroup/portgroupCommandProcessor.py | 4 +-- vendors/KeyMile/baseCommandProcessor.py | 15 ++++------ 10 files changed, 67 insertions(+), 66 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py index 8edc2f4..71ac67c 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py @@ -27,8 +27,8 @@ class MgmtportCommandProcessor(BaseCommandProcessor): from .mgmtportManagementFunctions import status def get_property(self, command, *args, context=None): - port = self.get_port_component() - card = self._parent.get_component() + port = self.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -70,7 +70,7 @@ def get_component(self): def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 674f148..424554a 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -31,8 +31,6 @@ def do_get(self, command, *args, context=None): context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' self._write(self._render('currTemperature', 'login', 'base', 'get', context=context)) - - def _init_access_points(self, context=None): self.access_points = ('eoam', 'fan', 'multicast', 'services', 'tdmConnections') for card in self._model.cards: diff --git a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py index a35ef8f..efaf10c 100644 --- a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py @@ -25,13 +25,19 @@ class SrvcCommandProcessor(BaseCommandProcessor): from .srvcManagementFunctions import status def get_property(self, command, *args, context=None): - service_name = 'srvc-' + self.component_id + service_name = self.component_name services = self._model.get_srvcs('name', service_name) + service = None for s in services: if s.service_type.lower() == context['ServiceType'] and s.name == service_name: service = s context['service'] = service break + + if not service: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + scopes = ('login', 'base', 'get') if self._validate((args[0],), 'Service') and context['path'].split('/')[-1] == 'cfgm': # TODO: Find missing templates, and replace placeholder templates @@ -68,12 +74,18 @@ def set(self, command, *args, context=None): elif self._validate(args, 'Service', str, str, str, str) and context['path'].split('/')[-1] == 'cfgm': address, svid, stag, vlan = self._dissect(args, 'Service', str, str, str, str) try: - service_name = 'srvc-' + self.component_id + service_name = self.component_name services = self._model.get_srvcs('name', service_name) + service = None for s in services: if s.service_type.lower() == context['ServiceType'] and s.name == service_name: service = s break + + if not service: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + service.set_service(address, int(svid), stag, vlan) except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 5a36410..f7a1383 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -24,7 +24,7 @@ class LogportsCommandProcessor(BaseCommandProcessor): def _init_access_points(self, context=None): # work in progress self.access_points = () - card = self._model.get_card('name', self._parent.component_id) + card = self._model.get_card('name', self.component_name.split('/')[0]) for logport in self._model.get_logports('card_id', card.id): if logport.name.count('/') == 2: @@ -45,7 +45,7 @@ def do_delete(self, command, *args, context=None): if name.startswith('logport-'): id = name.split('-')[1] try: - port = self._model.get_logport('name', self._parent.component_id + '/L/' + id) + port = self._model.get_logport('name', self._parent.component_name + '/L/' + id) port.delete() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -66,14 +66,15 @@ def do_create(self, command, *args, context=None): ids.sort() try: for x in ids: - _ = self._model.get_logport('name', self._parent.component_id + '/L/' + str(x)) + self._model.get_logport('name', self._parent.component_name + '/L/' + str(x)) break except exceptions.SoftboxenError: - name = self._parent.component_id + '/L/' + str(ids[0]) + name = self._parent.component_name + '/L/' + str(ids[0]) ports = 'ports: ' for x in ids: ports += str(x) + ', ' - logport = self._model.add_logport(card_id=self._parent.component_id, name=name, ports=ports[:-2]) + card = self._model.get_card('name', self._parent.component_name) + logport = self._model.add_logport(card_id=card.id, name=name, ports=ports[:-2]) else: raise exceptions.CommandSyntaxError(command=command) else: diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 36de9cd..dc57db1 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -57,19 +57,18 @@ def _init_access_points(self, context=None): self.access_points += (identifier,) def do_deleteinterface(self, command, *args, context=None): - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': # all or interface_id name, = self._dissect(args, str) if name == 'all': - logport_name = self._parent._parent.component_id + '/L/' + self.component_id - logport = self._model.get_logport('name', logport_name) + logport = self._model.get_logport('name', self.component_name) for interface in self._model.get_interfaces('logport_id', logport.id): interface.delete() elif name.startswith('interface-'): id = name.split('-')[1] try: - interface = self._model.get_interface('name', self._parent._parent.component_id + '/L/' + self.component_id + '/' + id) + interface = self._model.get_interface('name', self.component_name + '/' + id) interface.delete() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -80,22 +79,20 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names try: - logport_name = self._parent._parent.component_id + '/L/' + self.component_id - logport = self._model.get_logport('name', logport_name) + logport = self._model.get_logport('name', self.component_name) id = 1 for interface in self._model.get_interfaces('logport_id', logport.id): if interface.logport_id is not None: new_id = int(interface.name[-1]) + 1 id = new_id if new_id > id else id try: - name = self._parent._parent.component_id + '/L/' + self.component_id + '/' + str(id) - _ = self._model.get_interface('name', name) + self._model.get_interface('name', self.component_name) assert False except exceptions.SoftboxenError as exe: vcc = self._model.add_interface(name=name, logport_id=logport.id, vlan_profile=vlan_prof) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index bcfc005..e6acac7 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -28,7 +28,7 @@ class ChanCommandProcessor(BaseCommandProcessor): def _init_access_points(self, context=None): self.access_points = () chan = self.get_component() - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self.component_name.split('/')[0]) for interface in self._model.get_interfaces('chan_id', chan.id): if interface.chan_id is not None: @@ -42,7 +42,7 @@ def _init_access_points(self, context=None): self.access_points += (identifier,) def do_deletevcc(self, command, *args, context=None): - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': # all or vcc_id name, = self._dissect(args, str) @@ -53,7 +53,7 @@ def do_deletevcc(self, command, *args, context=None): elif name.startswith('vcc-'): id = name.split('-')[1] try: - vcc = self._model.get_interface('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + id) + vcc = self._model.get_interface('name', self.component_name + '/' + id) vcc.delete() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -63,7 +63,7 @@ def do_deletevcc(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_deleteinterface(self, command, *args, context=None): - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product != 'adsl' and card.product != 'sdsl': # all or interface_id name, = self._dissect(args, str) @@ -74,7 +74,7 @@ def do_deleteinterface(self, command, *args, context=None): elif name.startswith('interface-'): id = name.split('-')[1] try: - interface = self._model.get_interface('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + id) + interface = self._model.get_interface('name', self.component_name + '/' + id) interface.delete() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -85,7 +85,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name: # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) @@ -98,8 +98,7 @@ def do_createinterface(self, command, *args, context=None): new_id = int(interface.name[-1]) + 1 id = new_id if new_id > id else id try: - name = self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + str(id) - _ = self._model.get_interface('name', name) + self._model.get_interface('name', self.component_name + '/' + str(id)) assert False except exceptions.SoftboxenError as exe: interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof) @@ -125,8 +124,7 @@ def do_createinterface(self, command, *args, context=None): new_id = int(interface.name[-1]) + 1 id = new_id if new_id > id else id try: - name = self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + str(id) - _ = self._model.get_interface('name', name) + self._model.get_interface('name', self.component_name + '/' + str(id)) assert False except exceptions.SoftboxenError as exe: interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof, @@ -146,7 +144,7 @@ def do_createinterface(self, command, *args, context=None): def do_createvcc(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': # vcc profile and vlan profile vcc_prof, vlan_prof = self._dissect(args, str, str) @@ -159,8 +157,8 @@ def do_createvcc(self, command, *args, context=None): new_id = int(vcc.name[-1]) + 1 id = new_id if new_id > id else id try: - name = self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + str(id) - _ = self._model.get_interface('name', name) + name = self.component_name + '/' + str(id) + self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: vcc = self._model.add_interface(name=name, chan_id=chan.id, vcc_profile=vcc_prof, @@ -182,7 +180,7 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def set(self, command, *args, context=None): - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' @@ -211,7 +209,7 @@ def get_component(self): return self._model.get_chan('name', self.component_name) def get_property(self, command, *args, context=None): - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index be2247b..f80794e 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -29,7 +29,7 @@ class PortCommandProcessor(BaseCommandProcessor): def get_property(self, command, *args, context=None): port = self.get_component() context['port'] = port - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -125,7 +125,7 @@ def _init_access_points(self, context=None): self.access_points += (identifier,) def do_lock(self, command, *args, context=None): - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: @@ -137,7 +137,7 @@ def do_lock(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_startquickloopbacktest(self, command, *args, context=None): - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: @@ -151,7 +151,7 @@ def do_startquickloopbacktest(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_startlinetest(self, command, *args, context=None): - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if len(args) == 0 and context['path'].split('/')[-1] == 'status' and 'SUP' in card.board_name \ and self.__name__ == 'port': try: @@ -165,7 +165,7 @@ def do_startlinetest(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_startmeltmeasurement(self, command, *args, context=None): - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product != 'isdn' \ and self.__name__ == 'port': try: @@ -179,7 +179,7 @@ def do_startmeltmeasurement(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_unlock(self, command, *args, context=None): - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: @@ -194,7 +194,7 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_deleteinterface(self, command, *args, context=None): - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'ftth': # all or interface_id name, = self._dissect(args, str) @@ -205,7 +205,7 @@ def do_deleteinterface(self, command, *args, context=None): elif name.startswith('interface-'): id = name.split('-')[1] try: - interface = self._model.get_interface('name', self._parent.component_id + '/' + self.component_id + '/' + id) + interface = self._model.get_interface('name', self.component_name + '/' + id) interface.delete() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -216,7 +216,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUE' in card.board_name: # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) @@ -229,8 +229,8 @@ def do_createinterface(self, command, *args, context=None): new_id = int(interface.name[-1]) + 1 id = new_id if new_id > id else id try: - name = self._parent.component_id + '/' + self.component_id + '/' + str(id) - _ = self._model.get_interface('name', name) + name = self.component_name + '/' + str(id) + self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: interf = self._model.add_interface(name=name, port_id=port.id, vlan_profile=vlan_prof) @@ -252,7 +252,7 @@ def get_component(self): def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 391cc16..0476629 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -33,7 +33,7 @@ def get_property(self, command, *args, context=None): super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: if self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ - self._model.get_card('name', self._parent._parent.component_id).product == 'isdn': + self._model.get_card('name', self._parent._parent.component_name).product == 'isdn': text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: @@ -62,7 +62,7 @@ def get_property(self, command, *args, context=None): i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'port' and subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id: + if subscriber.type == 'port' and subscriber.address == self.component_name: context['i'] = i context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' context['spacer11'] = self.create_spacers((63,), (subscriber.autorisation_user_name,))[0] * ' ' @@ -88,7 +88,7 @@ def get_property(self, command, *args, context=None): i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'port' and subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id: + if subscriber.type == 'port' and subscriber.address == self.component_name: context['i'] = i context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' context['spacer11'] = self.create_spacers((63,), (subscriber.autorisation_user_name,))[0] * ' ' @@ -151,7 +151,7 @@ def set(self, command, *args, context=None): subscriber.set('display_name', displayname) subscriber.set('privacy', privacy) except exceptions.SoftboxenError: - address = self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id + address = self.component_name subscriber = self._model.add_subscriber(number=int(number), autorisation_user_name=username, address=address, privacy=privacy, type='port', display_name=displayname, autorisation_password=password) @@ -170,13 +170,13 @@ def set(self, command, *args, context=None): port = self.get_component() try: subscriber = self._model.get_subscriber('number', int(number)) - assert subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id + assert subscriber.address == self.component_name subscriber.set('autorisation_user_name', username) subscriber.set('autorisation_password', password) subscriber.set('display_name', displayname) subscriber.set('privacy', privacy) except exceptions.SoftboxenError: - address = self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id + address = self.component_name subscriber = self._model.add_subscriber(number=int(number), autorisation_user_name=username, address=address, privacy=privacy, type='port', display_name=displayname, autorisation_password=password) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index 9c51c4c..0919a53 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -24,10 +24,10 @@ class PortgroupCommandProcessor(BaseCommandProcessor): def _init_access_points(self, context=None): # work in progress self.access_points = () - card = self._model.get_card('name', self._parent.component_id) + card = self._model.get_card('name', self.component_name.split('/')[0]) for gport in self._model.get_portgroupports('card_id', card.id): - if gport.name.split('/')[1] == 'G' + self.component_id: + if gport.name.split('/')[1] == 'G' + self.component_name.split('/')[-1][1:]: identifier = 'port-' + gport.name.split('/')[-1] if identifier in self.access_points: continue diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 6d6b13b..e44e1ec 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -22,13 +22,9 @@ class BaseCommandProcessor(base.CommandProcessor): management_functions = () access_points = () - component_id = None component_name = None - def set_component_id(self, id): - self.component_id = id - def set_component_name(self, name): self.component_name = name @@ -349,21 +345,20 @@ def change_directory(self, path, context=None): subprocessor = self._create_command_processor_obj(command_processor) - if component_id is not None: - subprocessor.set_component_id(component_id) - if self.component_name: if components[0] == 'logports': component_name = self.component_name + '/L' elif component_type == 'portgroup': component_name = self.component_name + '/G' + component_id - elif component_type == 'srvc': - component_name = 'srvc' + component_id else: component_name = self.component_name + '/' + component_id subprocessor.set_component_name(component_name) else: - subprocessor.set_component_name(component_id) + if component_type == 'srvc': + component_name = 'srvc-' + component_id + else: + component_name = component_id + subprocessor.set_component_name(component_name) if component_type: component_exists = self._check_for_component(subprocessor) From 2d40f8a111df407268162493e33ad2119c09cd15 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Thu, 22 Oct 2020 13:37:22 +0200 Subject: [PATCH 149/318] Fixed ls header to display relevant fields --- .../conf/bootstraps/create-keymile-MG2500.sh | 3 --- templates/KeyMile/login/base/ls/ls_header.j2 | 6 ++--- .../root/fan/fanCommandProcessor.py | 5 ++++ .../mgmt_port/mgmtportCommandProcessor.py | 5 ++++ .../mgmt_unit/mgmtunitCommandProcessor.py | 6 +++++ .../accessPoints/root/rootCommandProcessor.py | 5 ++++ .../logport/port/logportCommandProcessor.py | 6 +++++ .../root/unit/port/portCommandProcessor.py | 27 +++++++++++++++++++ .../port/portgroupportCommandProcessor.py | 5 ++++ .../portgroup/portgroupCommandProcessor.py | 5 ++++ .../root/unit/unitCommandProcessor.py | 12 +++++++++ vendors/KeyMile/baseCommandProcessor.py | 6 +++++ 12 files changed, 85 insertions(+), 6 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 8716102..b300cc2 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -580,7 +580,6 @@ req='{ unit_8=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - ### Mgmt-Unit-11 ### # Create a physical card at the network device (admin operation) @@ -618,8 +617,6 @@ req='{ port_11_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/mgmt_ports) - - ### Unit-19 ### # Create a physical card at the network device (admin operation) diff --git a/templates/KeyMile/login/base/ls/ls_header.j2 b/templates/KeyMile/login/base/ls/ls_header.j2 index e0a8150..ab51e15 100644 --- a/templates/KeyMile/login/base/ls/ls_header.j2 +++ b/templates/KeyMile/login/base/ls/ls_header.j2 @@ -1,7 +1,7 @@ Infos of AP: {{ context.path }} - Name : MileGate 2200 - Main Mode : - Equipment State : Ok + Name : {{ context.ls_Name }} + Main Mode : {{ context.ls_MainMode }} + Equipment State : {{ context.ls_EquipmentState }} Alarm Severity : Cleared Propagated Alarm Severity : Major User Label : diff --git a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py index cd8dff8..ced2583 100644 --- a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py @@ -30,5 +30,10 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) + def _init_context(self, context=None): + context['ls_Name'] = 'FANU4' + context['ls_MainMode'] = '' + context['ls_EquipmentState'] = 'Ok' + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py index 71ac67c..16e9877 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py @@ -62,6 +62,11 @@ def _init_access_points(self, context=None): self.access_points = () return + def _init_context(self, context=None): + context['ls_Name'] = '10/100/1000BASE-T' + context['ls_MainMode'] = 'Management' + context['ls_EquipmentState'] = '' + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py index 8b0f59f..ace3e3f 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py @@ -41,6 +41,12 @@ def _init_access_points(self, context=None): except exceptions.InvalidInputError: pass + def _init_context(self, context=None): + card = self.get_component() + context['ls_Name'] = card.board_name + ' ' + card.supplier_build_state + context['ls_MainMode'] = card.software[:-4] + context['ls_EquipmentState'] = 'Ok' + def get_property(self, command, *args, context=None): card = self.get_component() scopes = ('login', 'base', 'get') diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 424554a..991b3f7 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -59,6 +59,11 @@ def _init_access_points(self, context=None): else: self.access_points = self.access_points[:self.access_points.index('unit-' + str(i - 1)) + 1] + ('unit-' + str(i),) + self.access_points[self.access_points.index('unit-' + str(i - 1)) + 1:] + def _init_context(self, context=None): + context['ls_Name'] = self._model.model + ' ' + self._model.version + context['ls_MainMode'] = '' + context['ls_EquipmentState'] = 'Ok' + def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index dc57db1..c36aea3 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -56,6 +56,12 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) + def _init_context(self, context=None): + logport = self.get_component() + context['ls_Name'] = 'SHDSL Spam' + context['ls_MainMode'] = logport.ports + context['ls_EquipmentState'] = '' + def do_deleteinterface(self, command, *args, context=None): card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index f80794e..8d925eb 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -124,6 +124,33 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) + def _init_context(self, context=None): + port = self.get_component() + card = self._model.get_card('id', port.card_id) + print(card.product) + if card.product == 'vdsl' or card.product == 'xdsl': + context['ls_Name'] = 'VDSL' + context['ls_MainMode'] = 'VDSL2' + elif card.product == 'sdsl': + context['ls_Name'] = 'SHDSL' + context['ls_MainMode'] = '' + elif card.product == 'adsl': + context['ls_Name'] = 'ADSL' + context['ls_MainMode'] = '' + elif card.product == 'isdn': + context['ls_Name'] = 'ISDN' + context['ls_MainMode'] = 'BA' + elif card.product == 'analog': + context['ls_Name'] = 'PSTN' + context['ls_MainMode'] = '' + elif card.product == 'ftth': + context['ls_Name'] = '100/1000Base-BX10 cSFP' + context['ls_MainMode'] = '' + else: + context['ls_Name'] = '' + context['ls_MainMode'] = '' + context['ls_EquipmentState'] = '' + def do_lock(self, command, *args, context=None): card = self._model.get_card('name', self.component_name.split('/')[0]) if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 0476629..83b8e0c 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -107,6 +107,11 @@ def get_property(self, command, *args, context=None): def _init_access_points(self, context=None): pass + def _init_context(self, context=None): + context['ls_Name'] = 'ISDN-BA' + context['ls_MainMode'] = '' + context['ls_EquipmentState'] = '' + def do_deleteinterface(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index 0919a53..1eaa4f3 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -33,6 +33,11 @@ def _init_access_points(self, context=None): # work in progress continue self.access_points += (identifier,) + def _init_context(self, context=None): + context['ls_Name'] = 'ISDN-BA' + context['ls_MainMode'] = '16 Ports' + context['ls_EquipmentState'] = '' + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index cd69007..bc60d77 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -53,6 +53,18 @@ def _init_access_points(self, context=None): except exceptions.InvalidInputError: pass + def _init_context(self, context=None): + try: + card = self.get_component() + except exceptions.SoftboxenError: + context['ls_Name'] = '' + context['ls_MainMode'] = '' + context['ls_EquipmentState'] = 'Empty' + else: + context['ls_Name'] = card.board_name + ' ' + card.supplier_build_state + context['ls_MainMode'] = card.software[:-4] + context['ls_EquipmentState'] = 'Ok' + def get_property(self, command, *args, context=None): card = self.get_component() scopes = ('login', 'base', 'get') diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index e44e1ec..b74ce31 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -160,6 +160,7 @@ def generate_ls_text(layers, depth): self._write(text) else: + self._init_context(context=context) text = self._render('ls_header', *scopes, context=context) self._init_access_points(context=context) @@ -509,6 +510,11 @@ def do_exit(self, command, *args, context=None): def _init_access_points(self, context=None): pass # Abstract method not implemented + def _init_context(self, context=None): + context['ls_Name'] = '' + context['ls_MainMode'] = '' + context['ls_EquipmentState'] = '' + def args_in_quotes_joiner(self, args): saved_args = [] save = False From 7164f5a206271b545712acc2ac5c2cf203a2afae Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 22 Oct 2020 14:46:21 +0200 Subject: [PATCH 150/318] Now ignoring alarm cmdProcessors when checking for component, added pre-check to validate if unit-13 is a management_card --- vendors/KeyMile/baseCommandProcessor.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index b74ce31..58ae051 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -295,8 +295,15 @@ def change_directory(self, path, context=None): elif self.__name__ == 'mgmtunit': component_type = 'mgmtport' if component_type == 'unit': - if component_id == '11' or component_id == '13': + if component_id == '11': component_type = 'mgmtunit' + if component_id == '13': + try: + self._model.get_mgmt_card('name', '13') + except exceptions.InvalidInputError: + component_type = 'unit' + else: + component_type = 'mgmtunit' if component_type == 'vcc': component_type = 'interface' @@ -403,7 +410,7 @@ def _validate_layer_relation(self, component_type, name): return True def _check_for_component(self, command_processor): - if command_processor.__name__ in ('portgroup', 'unit', 'mgmtunit'): + if command_processor.__name__ in ('portgroup', 'unit', 'mgmtunit', 'alarm'): return True try: From 48bf5373f993ae7de00a54362c76dce09a5b13da Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 22 Oct 2020 16:54:52 +0200 Subject: [PATCH 151/318] Fixed a problem where some management functions of active cards weren't reachable, also now allowing more args as tokens for set Proxy command --- vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py | 2 +- vendors/KeyMile/baseCommandProcessor.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index bc60d77..0588df2 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -294,7 +294,7 @@ def set(self, command, *args, context=None): card.set_registrar(ra, int(rp), rm, int(rt)) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args, 'Proxy', str, str, str, str, str, str, str, str) and \ + elif self._validate(args[:9], 'Proxy', str, str, str, str, str, str, str, str) and \ context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): pm, pa1, pp1, pa2, pp2, pe, pmethod, pi = self._dissect(args, 'Proxy', str, str, str, str, str, str, str, str) try: diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 58ae051..701b1c8 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -339,6 +339,8 @@ def change_directory(self, path, context=None): if context['path'].split('/')[-1] in ('main', 'cfgm', 'fm', 'pm', 'status'): raise exceptions.CommandExecutionError(command=None, template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors')) + self._init_access_points() # make sure all management_functions are loaded correctly + if components[0] not in self.management_functions: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty From deeece8387585632a4987e794e3c1bd3f41b5c50 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 23 Oct 2020 14:49:11 +0200 Subject: [PATCH 152/318] Implemented on_unknown_command method to process command execution when given with a path --- .../accessPoints/root/eoamCommandProcessor.py | 3 --- .../root/fan/alarmCommandProcessor.py | 3 --- .../root/fan/fanCommandProcessor.py | 3 --- .../mgmt_port/mgmtportCommandProcessor.py | 3 --- .../mgmt_unit/mgmtunitCommandProcessor.py | 3 --- .../root/multicastCommandProcessor.py | 3 --- .../accessPoints/root/rootCommandProcessor.py | 3 --- .../services/macaccessctrlCommandProcessor.py | 3 --- .../root/services/packetCommandProcessor.py | 3 --- .../root/services/servicesCommandProcessor.py | 3 --- .../root/services/srvcCommandProcessor.py | 3 --- .../services/subpacketCommandProcessor.py | 3 --- .../root/tdmconnectionsCommandProcessor.py | 3 --- .../unit/logport/logportsCommandProcessor.py | 3 --- .../logport/port/logportCommandProcessor.py | 3 --- .../unit/port/chan/chanCommandProcessor.py | 3 --- .../interface/interfaceCommandProcessor.py | 3 --- .../root/unit/port/portCommandProcessor.py | 3 --- .../port/portgroupportCommandProcessor.py | 3 --- .../portgroup/portgroupCommandProcessor.py | 3 --- .../root/unit/unitCommandProcessor.py | 3 --- vendors/KeyMile/baseCommandProcessor.py | 27 ++++++++++++++++++- 22 files changed, 26 insertions(+), 64 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py index ea461fb..b93f9c8 100644 --- a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py @@ -23,9 +23,6 @@ class EoamCommandProcessor(BaseCommandProcessor): from .eoamManagementFunctions import cfgm from .eoamManagementFunctions import status - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py index a88d5ef..22266a9 100644 --- a/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py @@ -22,6 +22,3 @@ class AlarmCommandProcessor(BaseCommandProcessor): from .alarmManagementFunctions import main from .alarmManagementFunctions import cfgm from .alarmManagementFunctions import fm - - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py index ced2583..bffb664 100644 --- a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py @@ -34,6 +34,3 @@ def _init_context(self, context=None): context['ls_Name'] = 'FANU4' context['ls_MainMode'] = '' context['ls_EquipmentState'] = 'Ok' - - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py index 16e9877..a4e50c1 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py @@ -67,9 +67,6 @@ def _init_context(self, context=None): context['ls_MainMode'] = 'Management' context['ls_EquipmentState'] = '' - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def get_component(self): return self._model.get_mgmt_port('name', self.component_name) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py index ace3e3f..1a0edf5 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py @@ -110,9 +110,6 @@ def get_property(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def get_component(self): return self._model.get_mgmt_card('name', self.component_name) diff --git a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py index c724daf..f431b36 100644 --- a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py @@ -25,9 +25,6 @@ class MulticastCommandProcessor(BaseCommandProcessor): from .multicastManagementFunctions import pm from .multicastManagementFunctions import status - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 991b3f7..46bf7b0 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -104,9 +104,6 @@ def do_upload(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def get_property(self, command, *args, context=None): scopes = ('login', 'base', 'set') if self._validate(args, "CurrTemperature"): diff --git a/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py index a2e56c6..62a9227 100644 --- a/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py @@ -24,9 +24,6 @@ class MacaccessctrlCommandProcessor(BaseCommandProcessor): from .macaccessctrlManagementFunctions import fm from .macaccessctrlManagementFunctions import status - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') try: diff --git a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py index a8dffac..68d1d83 100644 --- a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py @@ -21,9 +21,6 @@ class PacketCommandProcessor(BaseCommandProcessor): from .packetManagementFunctions import main - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') try: diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py index 0604db8..522103d 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -23,9 +23,6 @@ class ServicesCommandProcessor(BaseCommandProcessor): from .servicesManagementFunctions import fm from .servicesManagementFunctions import status - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') try: diff --git a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py index efaf10c..8681383 100644 --- a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py @@ -91,8 +91,5 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def get_component(self): return self._model.get_srvcs('name', self.component_name) diff --git a/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py index 10db20e..9d46cbb 100644 --- a/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py @@ -75,6 +75,3 @@ def do_createservice(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) else: raise exceptions.CommandSyntaxError(command=command) - - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py index a50788a..2c3ff28 100644 --- a/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py @@ -22,9 +22,6 @@ class TdmconnectionsCommandProcessor(BaseCommandProcessor): from .tdmconnectionsManagementFunctions import main from .tdmconnectionsManagementFunctions import cfgm - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index f7a1383..22233c0 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -36,9 +36,6 @@ def _init_access_points(self, context=None): # work in progress accpoint.sort(key=lambda x: int(x.split('-')[1])) self.access_points = tuple(accpoint) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def do_delete(self, command, *args, context=None): if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm': name, = self._dissect(args, str) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index c36aea3..1776404 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -115,9 +115,6 @@ def do_createinterface(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') try: diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index e6acac7..8716789 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -176,9 +176,6 @@ def do_createvcc(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, *()): diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index b73c2a6..c876d7f 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -24,9 +24,6 @@ class InterfaceCommandProcessor(BaseCommandProcessor): from .interfaceManagementFunctions import pm from .interfaceManagementFunctions import status - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 8d925eb..2fda6b1 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -217,9 +217,6 @@ def do_unlock(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def do_deleteinterface(self, command, *args, context=None): card = self._model.get_card('name', self.component_name.split('/')[0]) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'ftth': diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 83b8e0c..2f92f60 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -118,9 +118,6 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') try: diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index 1eaa4f3..96d132c 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -38,9 +38,6 @@ def _init_context(self, context=None): context['ls_MainMode'] = '16 Ports' context['ls_EquipmentState'] = '' - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 0588df2..a13d52b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -238,9 +238,6 @@ def get_property(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def get_component(self): return self._model.get_card('name', self.component_name) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 701b1c8..90f8903 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -22,7 +22,6 @@ class BaseCommandProcessor(base.CommandProcessor): management_functions = () access_points = () - component_name = None def set_component_name(self, name): @@ -38,6 +37,32 @@ def set_component_name(self, name): status = {} + def on_unknown_command(self, command, *args, context=None): + if len(args) == 0: + if '/' in command: + path = '/'.join([x for x in command.split('/') if x][:-1]).replace('_', '-') + command = [x for x in command.split('/') if x][-1] + + current_path = context['path'] + try: + command_proc = self.change_directory(path, context=context) + command_proc._parse_and_execute_command(command, context=context) + except exceptions.SoftboxenError: + context['path'] = current_path + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + context['path'] = current_path + else: + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + else: + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + + def map_states(self, object, type): if object.admin_state == '0': if type == 'port': From 0de3f878545b6e68704fd50fcdb259b0cde838c4 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 23 Oct 2020 16:56:33 +0200 Subject: [PATCH 153/318] Fixes for tests --- .../conf/bootstraps/create-keymile-MG2500.sh | 19 +++++++++++++- .../api/schemas/keymile_channel_schemas.py | 3 ++- .../keymile_resources/keymile_channel.py | 6 +++++ .../keymile_resources/keymile_interface.py | 5 +++- nesi/softbox/api/models/channel_models.py | 6 +++++ nesi/softbox/api/models/interface_models.py | 9 ++++--- nesi/softbox/api/schemas/channel_schemas.py | 4 +-- nesi/softbox/api/schemas/interface_schemas.py | 5 ++-- .../login/base/get/configured_profiles.j2 | 6 +++++ templates/KeyMile/login/base/get/ip.j2 | 6 ++--- .../KeyMile/login/base/get/service_status.j2 | 5 ++++ templates/KeyMile/login/base/get/status.j2 | 10 ++++++++ .../keymile/getInventory2.txt | 4 +-- .../integration_tests/keymile/getState1.txt | 1 - .../keymile/setChannelProfile14.txt | 2 +- .../accessPoints/root/rootCommandProcessor.py | 2 +- .../unit/port/chan/chanCommandProcessor.py | 10 ++++++++ .../interface/interfaceCommandProcessor.py | 25 +++++++++++++++++++ .../root/unit/port/portCommandProcessor.py | 1 - 19 files changed, 110 insertions(+), 19 deletions(-) create mode 100644 templates/KeyMile/login/base/get/configured_profiles.j2 create mode 100644 templates/KeyMile/login/base/get/service_status.j2 create mode 100644 templates/KeyMile/login/base/get/status.j2 diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index b300cc2..b48ac37 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -623,7 +623,24 @@ port_11_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/mgmt_ports) req='{ "subrack_id": '$subrack_id', "product": "isdn", - "name": "19" + "name": "19", + "board_name": "IPSX3", + "supplier_build_state": "R2B", + "board_id": "308", + "hardware_key": 105, + "software": "ipss2_r4e05_02.esw", + "software_name": "IPSS2", + "software_revision": "R4E05_02", + "state": "Ok", + "serial_number": "4936551973", + "manufacturer_name": "KEYMILE", + "model_name": "37900315", + "short_text": "MG IPSX3 VoIP SMG 912ch", + "manufacturer_id": "100989", + "manufacturer_part_number": "37900315", + "manufacturer_build_state": "09", + "boot_loader": "BLSU2_R1J01/CT40500", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_19=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) diff --git a/nesi/keymile/api/schemas/keymile_channel_schemas.py b/nesi/keymile/api/schemas/keymile_channel_schemas.py index 8d4555b..010810c 100644 --- a/nesi/keymile/api/schemas/keymile_channel_schemas.py +++ b/nesi/keymile/api/schemas/keymile_channel_schemas.py @@ -16,4 +16,5 @@ class KeyMileChannelSchema(ChannelSchema): class Meta: model = Channel - fields = ChannelSchema.Meta.fields + ('vccs', 'interfaces', 'chan_profile_name') + fields = ChannelSchema.Meta.fields + ('interfaces', 'chan_profile_name', 'curr_rate_u', 'curr_rate_d', + 'prev_rate_u', 'prev_rate_d', 'curr_delay_u') diff --git a/nesi/keymile/keymile_resources/keymile_channel.py b/nesi/keymile/keymile_resources/keymile_channel.py index 1fc9462..62acb04 100644 --- a/nesi/keymile/keymile_resources/keymile_channel.py +++ b/nesi/keymile/keymile_resources/keymile_channel.py @@ -25,6 +25,12 @@ class KeyMileChannel(base.Resource): name = base.Field('name') description = base.Field('description') chan_profile_name = base.Field('chan_profile_name') + curr_rate_u = base.Field('curr_rate_u') + curr_rate_d = base.Field('curr_rate_d') + prev_rate_u = base.Field('prev_rate_u') + prev_rate_d = base.Field('prev_rate_d') + curr_delay_u = base.Field('curr_delay_u') + curr_delay_d = base.Field('curr_delay_d') def set_profile_name(self, name): self.update(chan_profile_name=name) diff --git a/nesi/keymile/keymile_resources/keymile_interface.py b/nesi/keymile/keymile_resources/keymile_interface.py index b827fbe..dc1c446 100644 --- a/nesi/keymile/keymile_resources/keymile_interface.py +++ b/nesi/keymile/keymile_resources/keymile_interface.py @@ -27,9 +27,12 @@ class KeyMileInterface(base.Resource): chan_id = base.Field('chan_id') logport_id = base.Field('logport_id') - #vcc + # vcc vcc_profile = base.Field('vcc_profile') vlan_profile = base.Field('vlan_profile') + number_of_conn_services = base.Field('number_of_conn_services') + reconfiguration_allowed = base.Field('reconfiguration_allowed') + services_connected = base.Field('services_connected') class KeyMileInterfaceCollection(base.ResourceCollection): diff --git a/nesi/softbox/api/models/channel_models.py b/nesi/softbox/api/models/channel_models.py index 4c3cc18..bbbed86 100644 --- a/nesi/softbox/api/models/channel_models.py +++ b/nesi/softbox/api/models/channel_models.py @@ -19,6 +19,12 @@ class Channel(db.Model): name = db.Column(db.String(64)) description = db.Column(db.String()) chan_profile_name = db.Column(db.String(), default='') + curr_rate_u = db.Column(db.String(), default=0) + curr_rate_d = db.Column(db.String(), default=0) + prev_rate_u = db.Column(db.String(), default=0) + prev_rate_d = db.Column(db.String(), default=0) + curr_delay_u = db.Column(db.String(), default=0) + curr_delay_d = db.Column(db.String(), default=0) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) port_id = db.Column(db.Integer, db.ForeignKey('port.id')) interfaces = db.relationship('Interface', backref='Channel', lazy='dynamic') diff --git a/nesi/softbox/api/models/interface_models.py b/nesi/softbox/api/models/interface_models.py index b8e3322..cb24720 100644 --- a/nesi/softbox/api/models/interface_models.py +++ b/nesi/softbox/api/models/interface_models.py @@ -22,6 +22,9 @@ class Interface(db.Model): port_id = db.Column(db.Integer, db.ForeignKey('port.id')) logport_id = db.Column(db.Integer, db.ForeignKey('log_port.id')) - #vcc - vcc_profile = db.Column(db.String(), default=None) # default or profile_name, default:= vpi=0 and vci=33 - vlan_profile = db.Column(db.String(), default=None) # default or profile_name, must be untagged + # vcc + vcc_profile = db.Column(db.String(), default='') # default or profile_name, default:= vpi=0 and vci=33 + vlan_profile = db.Column(db.String(), default='') # default or profile_name, must be untagged + number_of_conn_services = db.Column(db.Integer(), default=0) + reconfiguration_allowed = db.Column(db.Enum('true', 'false'), default='true') + services_connected = db.Column(db.String(), default='') diff --git a/nesi/softbox/api/schemas/channel_schemas.py b/nesi/softbox/api/schemas/channel_schemas.py index d496e3a..a9842ee 100644 --- a/nesi/softbox/api/schemas/channel_schemas.py +++ b/nesi/softbox/api/schemas/channel_schemas.py @@ -18,8 +18,8 @@ class ChannelSchema(ma.ModelSchema): class Meta: model = Channel - fields = ('id', 'box_id', 'box', 'port_id', 'interfaces', - 'name', 'description', '_links') + fields = ('id', 'box_id', 'box', 'port_id', 'interfaces', 'curr_rate_u', 'curr_rate_d', 'prev_rate_u', + 'name', 'description', 'prev_rate_d', 'curr_delay_u', 'curr_delay_d', '_links') interfaces = ma.Nested(InterfacesSchema.InterfaceSchema, many=True) diff --git a/nesi/softbox/api/schemas/interface_schemas.py b/nesi/softbox/api/schemas/interface_schemas.py index 159b4e3..a93ba52 100644 --- a/nesi/softbox/api/schemas/interface_schemas.py +++ b/nesi/softbox/api/schemas/interface_schemas.py @@ -17,8 +17,9 @@ class InterfaceSchema(ma.ModelSchema): class Meta: model = Interface - fields = ('id', 'box_id', 'box', 'chan_id', 'port_id', 'logport_id', - 'name', 'description', 'vcc_profile', 'vlan_profile', '_links') + fields = ('id', 'box_id', 'box', 'chan_id', 'port_id', 'logport_id', 'number_of_conn_services', + 'name', 'description', 'reconfiguration_allowed', 'vcc_profile', 'vlan_profile', 'services_connected', + '_links') box = ma.Hyperlinks( {'_links': { diff --git a/templates/KeyMile/login/base/get/configured_profiles.j2 b/templates/KeyMile/login/base/get/configured_profiles.j2 new file mode 100644 index 0000000..ae4c784 --- /dev/null +++ b/templates/KeyMile/login/base/get/configured_profiles.j2 @@ -0,0 +1,6 @@ + \ # configuredProfiles + \ # vccProfile +{{ context.vcc.vcc_profile }}{{ context.spacer1 }}\ # name + \ # vlanProfile +{{ context.vcc.vlan_profile }}{{ context.spacer2 }}\ # Name + diff --git a/templates/KeyMile/login/base/get/ip.j2 b/templates/KeyMile/login/base/get/ip.j2 index e9fe969..b6082d3 100644 --- a/templates/KeyMile/login/base/get/ip.j2 +++ b/templates/KeyMile/login/base/get/ip.j2 @@ -1,5 +1,5 @@ \ # Ip -{{ context.card.gateway_ipaddress }}{{ context.spacer1 }}\ # GatewayIpAddress -{{ context.card.subnet_mask }}{{ context.spacer2 }}\ # SubnetMask -{{ context.card.default_gateway }}{{ context.spacer3 }}\ # DefaultGateway +{{ context.card.gateway_ipaddress | safe }}{{ context.spacer1 }}\ # GatewayIpAddress +{{ context.card.subnet_mask | safe }}{{ context.spacer2 }}\ # SubnetMask +{{ context.card.default_gateway | safe }}{{ context.spacer3 }}\ # DefaultGateway diff --git a/templates/KeyMile/login/base/get/service_status.j2 b/templates/KeyMile/login/base/get/service_status.j2 new file mode 100644 index 0000000..a5ce7f6 --- /dev/null +++ b/templates/KeyMile/login/base/get/service_status.j2 @@ -0,0 +1,5 @@ + \ # serviceStatus +{{ context.vcc.number_of_conn_services }}{{ context.spacer1 }}\ # NumberOfConnectedServices +{{ context.vcc.reconfiguration_allowed }}{{ context.spacer2 }}\ # ReconfigurationAllowed +{{ context.vcc_services_connected | safe }}{{ context.spacer3 }}\ # ServicesCurrentConnected + diff --git a/templates/KeyMile/login/base/get/status.j2 b/templates/KeyMile/login/base/get/status.j2 new file mode 100644 index 0000000..aa19e07 --- /dev/null +++ b/templates/KeyMile/login/base/get/status.j2 @@ -0,0 +1,10 @@ + \ # Status + \ # Downstream +{{ context.channel.curr_rate_d }}{{ context.spacer1 }}\ # CurrentRate +{{ context.channel.prev_rate_d }}{{ context.spacer2 }}\ # PreviousRate +{{ context.channel.curr_delay_d }}{{ context.spacer3 }}\ # CurrentDelay + \ # Upstream +{{ context.channel.curr_rate_u }}{{ context.spacer4 }}\ # CurrentRate +{{ context.channel.prev_rate_u }}{{ context.spacer5 }}\ # PreviousRate +{{ context.channel.curr_delay_u }}{{ context.spacer6 }}\ # CurrentDelay + diff --git a/test_cases/integration_tests/keymile/getInventory2.txt b/test_cases/integration_tests/keymile/getInventory2.txt index 27a0277..9af6ec6 100644 --- a/test_cases/integration_tests/keymile/getInventory2.txt +++ b/test_cases/integration_tests/keymile/getInventory2.txt @@ -11,8 +11,8 @@ cd /unit-19/main get HardwareAndSoftware get CurrentStatus get EquipmentInventory -cd /unit-1/port-1} +cd /unit-1/port-1 ls -cd /unit-1/port-{1/main +cd /unit-1/port-1/main get OperationalStatus exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getState1.txt b/test_cases/integration_tests/keymile/getState1.txt index 542cbd6..b314dba 100644 --- a/test_cases/integration_tests/keymile/getState1.txt +++ b/test_cases/integration_tests/keymile/getState1.txt @@ -7,7 +7,6 @@ get AdministrativeStatus get OperationalStatus cd /unit-1/port-1/chan-1/cfgm get ProfileName -get ChanProfile cd /unit-1/port-1/chan-1/status get status cd /unit-1/port-1/chan-1/vcc-1/cfgm diff --git a/test_cases/integration_tests/keymile/setChannelProfile14.txt b/test_cases/integration_tests/keymile/setChannelProfile14.txt index 5135d50..52f2a2d 100644 --- a/test_cases/integration_tests/keymile/setChannelProfile14.txt +++ b/test_cases/integration_tests/keymile/setChannelProfile14.txt @@ -1,7 +1,7 @@ manager secret cd /unit-5/port-1/chan-1/cfgm -set chanprofile rofile +set chanprofile profile set chanprofile default #else cd /unit-5/port-1/chan-1/cfgm diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 46bf7b0..525dfa8 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -112,4 +112,4 @@ def get_property(self, command, *args, context=None): self._write(self._render('currTemperature', *scopes, context=context)) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', - template_scopes=('login', 'base', 'execution_errors')) + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 8716789..b4caf46 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -225,6 +225,16 @@ def get_property(self, command, *args, context=None): context['profile_name'] = channel.chan_profile_name text = self._render('chan_profile', *scopes, context=context) self._write(text) + elif self._validate(args, 'Status') and context['path'].split('/')[-1] == 'status': + channel = self.get_component() + context['spacer1'] = self.create_spacers((67,), (channel.curr_rate_d,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (channel.prev_rate_d,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (channel.curr_delay_d,))[0] * ' ' + context['spacer4'] = self.create_spacers((67,), (channel.curr_rate_u,))[0] * ' ' + context['spacer5'] = self.create_spacers((67,), (channel.prev_rate_u,))[0] * ' ' + context['spacer6'] = self.create_spacers((67,), (channel.curr_delay_u,))[0] * ' ' + text = self._render('status', *scopes, context=dict(context, channel=channel)) + self._write(text) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index c876d7f..32af8ca 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -39,3 +39,28 @@ def set(self, command, *args, context=None): def get_component(self): return self._model.get_interface('name', self.component_name) + + def get_property(self, command, *args, context=None): + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'ServiceStatus') and context['path'].split('/')[-1] == 'status': + vcc = self.get_component() + context['spacer1'] = self.create_spacers((67,), (vcc.vcc_profile,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (vcc.vlan_profile,))[0] * ' ' + text = self._render('configured_profiles', *scopes, context=dict(context, vcc=vcc)) + self._write(text) + elif self._validate(args, 'configuredProfiles') and context['path'].split('/')[-1] == 'cfgm': + vcc = self.get_component() + services_connected = '"' + vcc.services_connected + '"' + context['vcc_services_connected'] = services_connected + context['spacer1'] = self.create_spacers((67,), (vcc.number_of_conn_services,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (vcc.reconfiguration_allowed,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (services_connected,))[0] * ' ' + text = self._render('service_status', *scopes, context=dict(context, vcc=vcc)) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 2fda6b1..d41b4e2 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -127,7 +127,6 @@ def _init_access_points(self, context=None): def _init_context(self, context=None): port = self.get_component() card = self._model.get_card('id', port.card_id) - print(card.product) if card.product == 'vdsl' or card.product == 'xdsl': context['ls_Name'] = 'VDSL' context['ls_MainMode'] = 'VDSL2' From e1a957e5e69bd10495994938b19dc30268b4b3bc Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 26 Oct 2020 10:26:09 +0100 Subject: [PATCH 154/318] Fixed a bug where giving an absolut path to execute a command while in a directory wouldn't work --- vendors/KeyMile/baseCommandProcessor.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 90f8903..4b006ac 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -40,7 +40,10 @@ def set_component_name(self, name): def on_unknown_command(self, command, *args, context=None): if len(args) == 0: if '/' in command: - path = '/'.join([x for x in command.split('/') if x][:-1]).replace('_', '-') + if command.startswith('/'): + path = '/' + '/'.join([x for x in command.split('/') if x][:-1]).replace('_', '-') + else: + path = '/'.join([x for x in command.split('/') if x][:-1]).replace('_', '-') command = [x for x in command.split('/') if x][-1] current_path = context['path'] From 6b79f75f9f9a37fbd85e98ba28ce57f2ee3b4ba3 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 26 Oct 2020 11:24:03 +0100 Subject: [PATCH 155/318] Fixed some integration tests --- .../integration_tests/alcatel/configureTrafficVlanOnPort.txt | 4 ++-- test_cases/integration_tests/keymile/getState1.txt | 2 ++ test_cases/integration_tests/keymile/testLoopback3.txt | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/test_cases/integration_tests/alcatel/configureTrafficVlanOnPort.txt b/test_cases/integration_tests/alcatel/configureTrafficVlanOnPort.txt index 6fd8515..a464a68 100644 --- a/test_cases/integration_tests/alcatel/configureTrafficVlanOnPort.txt +++ b/test_cases/integration_tests/alcatel/configureTrafficVlanOnPort.txt @@ -4,10 +4,10 @@ configure bridge port 1/1/1/1 no pvid configure bridge port 1/1/1/1 no vlan-id 7 configure bridge port 1/1/1/1:1:32 no pvid configure bridge port 1/1/1/1:1:32 noi vlan-id 7 -confiugre bridge port 1/1/1/1:1:32 vlan-id 7 network-vlan 2620 vlan-scope local +configure bridge port 1/1/1/1:1:32 vlan-id 7 network-vlan 2620 vlan-scope local configure bridge port 1/1/1/1 pvid 7 configure bridge port 1/1/1/1:1:32 pvid 7 -configure birdge port 1/1/4/1 vlan-id 2620 tag single-tagged +configure bridge port 1/1/4/1 vlan-id 2620 tag single-tagged configure bridge port 1/1/4/1 vlan-id 2620 l2fwder-vlan 2620 vlan-scope local tag single-tagged configure bridge port 1/1/4/1 vlan-id 7 l2fwder-vlan 2620 vlan-scope local tag single-tagged configure bridge port 1/1/4/1 vlan-id 7 network-vlan 2620 vlan-scope local single-tagged diff --git a/test_cases/integration_tests/keymile/getState1.txt b/test_cases/integration_tests/keymile/getState1.txt index b314dba..0cd3a14 100644 --- a/test_cases/integration_tests/keymile/getState1.txt +++ b/test_cases/integration_tests/keymile/getState1.txt @@ -7,6 +7,8 @@ get AdministrativeStatus get OperationalStatus cd /unit-1/port-1/chan-1/cfgm get ProfileName +cd /unit-5/port-1/chan-1/cfgm +get ChanProfile cd /unit-1/port-1/chan-1/status get status cd /unit-1/port-1/chan-1/vcc-1/cfgm diff --git a/test_cases/integration_tests/keymile/testLoopback3.txt b/test_cases/integration_tests/keymile/testLoopback3.txt index 6e41de5..898cae6 100644 --- a/test_cases/integration_tests/keymile/testLoopback3.txt +++ b/test_cases/integration_tests/keymile/testLoopback3.txt @@ -2,7 +2,7 @@ manager secret cd /unit-19/port-1/status Lock -StartQuickLoopbackTest +/unit-19/port-1/status/StartQuickLoopbackTest get QuickLoopbackTest Unlock exit \ No newline at end of file From cdbf92a5cdbe90d5e9b47824ff51e92c977a6aad Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 26 Oct 2020 12:07:59 +0100 Subject: [PATCH 156/318] Fixed an huawei command issue where the command wasn't available in the correct layer --- vendors/Huawei/baseCommandProcessor.py | 2 +- vendors/Huawei/configCommandProcessor.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/vendors/Huawei/baseCommandProcessor.py b/vendors/Huawei/baseCommandProcessor.py index 88b6ad3..5c4e9c9 100644 --- a/vendors/Huawei/baseCommandProcessor.py +++ b/vendors/Huawei/baseCommandProcessor.py @@ -97,7 +97,7 @@ def do_quit(self, command, *args, context=None): def do_undo(self, command, *args, context=None): if self._validate(args, 'alarm', 'output', 'all'): - # importend for future snmp interactions + # important for future snmp interactions return elif self._validate(args, 'event', 'output', 'all'): return diff --git a/vendors/Huawei/configCommandProcessor.py b/vendors/Huawei/configCommandProcessor.py index 2b8821f..b948005 100644 --- a/vendors/Huawei/configCommandProcessor.py +++ b/vendors/Huawei/configCommandProcessor.py @@ -778,7 +778,12 @@ def do_raio_anid(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_undo(self, command, *args, context=None): - if self._validate(args, 'system', 'snmp-user', 'password', 'security'): + if self._validate(args, 'alarm', 'output', 'all'): + # important for future snmp interactions + return + elif self._validate(args, 'event', 'output', 'all'): + return + elif self._validate(args, 'system', 'snmp-user', 'password', 'security'): # importend for future snmp interactions return elif self._validate(args, 'smart'): From 2c9cd9c85f86c9ee23eea2878c79107435938e97 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Mon, 26 Oct 2020 12:25:16 +0100 Subject: [PATCH 157/318] added Commands and fixed small issues --- .../conf/bootstraps/create-keymile-MG2500.sh | 33 ++++++++++- .../api/schemas/keymile_port_schemas.py | 2 +- .../keymile_resources/keymile_logport.py | 4 ++ .../keymile/keymile_resources/keymile_port.py | 2 + nesi/softbox/api/models/logport_models.py | 1 + nesi/softbox/api/schemas/logport_schemas.py | 2 +- .../KeyMile/login/base/get/actual_status.j2 | 5 ++ .../KeyMile/login/base/get/attainable_rate.j2 | 4 +- .../KeyMile/login/base/get/ddm_status.j2 | 8 +++ .../login/base/get/if_rate_limiting.j2 | 8 +++ .../login/base/get/line_actual_state.j2 | 6 ++ .../login/base/get/line_operation_state.j2 | 3 + .../login/base/get/operational_wire_state.j2 | 4 ++ .../login/base/get/port_general_status.j2 | 5 ++ .../KeyMile/login/base/get/port_mac_status.j2 | 4 ++ .../KeyMile/login/base/get/span_profiles.j2 | 3 + templates/KeyMile/login/base/get/vendor_id.j2 | 12 ++++ .../KeyMile/login/base/get/vlan_profile.j2 | 3 + .../integration_tests/keymile/setconfDsl2.txt | 2 +- .../keymile/setdeconfVoicePort17.txt | 2 +- .../unit/logport/logportsCommandProcessor.py | 58 ++++++++++++------- .../logport/port/logportCommandProcessor.py | 13 ++++- .../unit/port/chan/chanCommandProcessor.py | 6 +- .../interface/interfaceCommandProcessor.py | 13 ++++- .../root/unit/port/portCommandProcessor.py | 27 ++++++++- vendors/KeyMile/baseCommandProcessor.py | 2 +- 26 files changed, 196 insertions(+), 36 deletions(-) create mode 100644 templates/KeyMile/login/base/get/actual_status.j2 create mode 100644 templates/KeyMile/login/base/get/ddm_status.j2 create mode 100644 templates/KeyMile/login/base/get/if_rate_limiting.j2 create mode 100644 templates/KeyMile/login/base/get/line_actual_state.j2 create mode 100644 templates/KeyMile/login/base/get/line_operation_state.j2 create mode 100644 templates/KeyMile/login/base/get/operational_wire_state.j2 create mode 100644 templates/KeyMile/login/base/get/port_general_status.j2 create mode 100644 templates/KeyMile/login/base/get/port_mac_status.j2 create mode 100644 templates/KeyMile/login/base/get/span_profiles.j2 create mode 100644 templates/KeyMile/login/base/get/vendor_id.j2 create mode 100644 templates/KeyMile/login/base/get/vlan_profile.j2 diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index b48ac37..7999af6 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -27,7 +27,7 @@ path="`dirname \"$0\"`" # |---> Unit-1 (adsl) (SUAD2) # # | |-> Port-1 # # | | |-> Chan-1 # -# | | |-> Interface-1 # +# | | |-> VCC-1 # # | # # |---> Unit-2 (sdsl) (SUSE1) # # | |-> Port-1 # @@ -42,6 +42,8 @@ path="`dirname \"$0\"`" # | # # |---> Unit-4 (adsl) (SUAD2) # # | |-> Port-1 # +# | | |-> Chan-1 # +# | | |-> VCC-1 # # | # # |---> Unit-5 (vdsl) (SUVM4) # # | |-> Port-1 # @@ -52,6 +54,7 @@ path="`dirname \"$0\"`" # | # # |---> Unit-7 (ftth) (SUEN3) # # | |-> Port-1 # +# | | |-> Interface-1 # # | # # |---> Unit-8 (vdsl) (SUVM6) # # | # @@ -429,6 +432,25 @@ req='{ port_4_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +### Chan-1 ### + +# Create a logical channel at the network device (admin operation) +req='{ + "port_id": '$port_4_1', + "description": "Channel #1" +}' + +chan_4_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/channels) + +### VCC-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "chan_id": '$chan_4_1_1' +}' + +interface_4_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) + ### Unit-5 ### # Create a physical card at the network device (admin operation) @@ -553,6 +575,15 @@ req='{ port_7_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +### Interface-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "port_id": '$port_7_1' +}' + +interface_7_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) + ### Unit-8 ### # Create a physical card at the network device (admin operation) diff --git a/nesi/keymile/api/schemas/keymile_port_schemas.py b/nesi/keymile/api/schemas/keymile_port_schemas.py index d10607c..cd8dd4b 100644 --- a/nesi/keymile/api/schemas/keymile_port_schemas.py +++ b/nesi/keymile/api/schemas/keymile_port_schemas.py @@ -20,6 +20,6 @@ class Meta: 'linetest_state', 'profile1_enable', 'profile1_name', 'profile1_elength', 'profile2_enable', 'profile2_name', 'profile2_elength', 'profile3_enable', 'profile3_name', 'profile3_elength', 'profile4_enable', 'profile4_name', - 'profile_mode', 'mode', 'flow_control') + 'profile_mode', 'mode', 'flow_control', 'upstream', 'downstream') channels = ma.Nested(CpesSchema.CpeSchema, many=True) diff --git a/nesi/keymile/keymile_resources/keymile_logport.py b/nesi/keymile/keymile_resources/keymile_logport.py index e619636..c9d424b 100644 --- a/nesi/keymile/keymile_resources/keymile_logport.py +++ b/nesi/keymile/keymile_resources/keymile_logport.py @@ -28,6 +28,7 @@ class KeyMileLogPort(base.Resource): description = base.Field('description') admin_state = base.Field('admin_state') operational_state = base.Field('operational_state') + profile = base.Field('profile') def admin_up(self): """Set the admin port state to up""" @@ -45,6 +46,9 @@ def up(self): """Set the port state to down""" self.update(operational_state='1') + def set_profile(self, profile): + self.update(profile=profile) + def set_label(self, l1, l2, desc): self.update(label1=l1) self.update(label2=l2) diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py index 81a248d..c976869 100644 --- a/nesi/keymile/keymile_resources/keymile_port.py +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -36,6 +36,8 @@ class KeyMilePort(Port): profile4_enable = base.Field('profile4_enable') profile4_name = base.Field('profile4_name') profile_mode = base.Field('profile_mode') + upstream = base.Field('upstream') + downstream = base.Field('downstream') def set_profile(self, name): self.update(profile1_name=name) diff --git a/nesi/softbox/api/models/logport_models.py b/nesi/softbox/api/models/logport_models.py index c5d471d..7b9b6f8 100644 --- a/nesi/softbox/api/models/logport_models.py +++ b/nesi/softbox/api/models/logport_models.py @@ -26,3 +26,4 @@ class LogPort(db.Model): description = db.Column(db.String(), default='""') operational_state = db.Column(db.Enum('0', '1'), default='0') admin_state = db.Column(db.Enum('0', '1'), default='0') + profile = db.Column(db.String(), default='default') diff --git a/nesi/softbox/api/schemas/logport_schemas.py b/nesi/softbox/api/schemas/logport_schemas.py index 28b634e..7c09372 100644 --- a/nesi/softbox/api/schemas/logport_schemas.py +++ b/nesi/softbox/api/schemas/logport_schemas.py @@ -19,7 +19,7 @@ class LogPortSchema(ma.ModelSchema): class Meta: model = LogPort fields = ('id', 'box_id', 'box', 'card_id', 'name', 'ports', 'interfaces', 'description', 'admin_state', - 'operational_state', 'label1', 'label2', + 'operational_state', 'label1', 'label2', 'profile', '_links') interfaces = ma.Nested(InterfacesSchema.InterfaceSchema, many=True) diff --git a/templates/KeyMile/login/base/get/actual_status.j2 b/templates/KeyMile/login/base/get/actual_status.j2 new file mode 100644 index 0000000..97fd17a --- /dev/null +++ b/templates/KeyMile/login/base/get/actual_status.j2 @@ -0,0 +1,5 @@ + \ # OverallLinePayloadRate + \ # PayloadRate +0 \ # CurrentOverallPayloadRate +0 \ # AttainableOverallPayloadRate + diff --git a/templates/KeyMile/login/base/get/attainable_rate.j2 b/templates/KeyMile/login/base/get/attainable_rate.j2 index dc5e135..e5eb709 100644 --- a/templates/KeyMile/login/base/get/attainable_rate.j2 +++ b/templates/KeyMile/login/base/get/attainable_rate.j2 @@ -1,4 +1,4 @@ \ # AttainableRate -{{ context.port.downstream_max }}{{ context.spacer1 }}\ # Downstream -{{ context.port.upstream_max }}{{ context.spacer2 }}\ # Upstream +{{ context.port.downstream }}{{ context.spacer1 }}\ # Downstream +{{ context.port.upstream }}{{ context.spacer2 }}\ # Upstream diff --git a/templates/KeyMile/login/base/get/ddm_status.j2 b/templates/KeyMile/login/base/get/ddm_status.j2 new file mode 100644 index 0000000..6cf2a61 --- /dev/null +++ b/templates/KeyMile/login/base/get/ddm_status.j2 @@ -0,0 +1,8 @@ + \ # DdmStatus +Supported \ # DdmInterfaceSupport +35 \ # ModuleTemperature +3.34E0 \ # SupplyVoltage +0.0E0 \ # TxBiasCurrent +-9 \ # TxOutputPower +-40 \ # RxInputPower + diff --git a/templates/KeyMile/login/base/get/if_rate_limiting.j2 b/templates/KeyMile/login/base/get/if_rate_limiting.j2 new file mode 100644 index 0000000..0cac93a --- /dev/null +++ b/templates/KeyMile/login/base/get/if_rate_limiting.j2 @@ -0,0 +1,8 @@ + \ # IfRateLimiter + \ # UpstreamProfile +false \ # Enabled +default \ # Name + \ # DownstreamProfile +false \ # Enabled +default \ # Name + diff --git a/templates/KeyMile/login/base/get/line_actual_state.j2 b/templates/KeyMile/login/base/get/line_actual_state.j2 new file mode 100644 index 0000000..00a44f6 --- /dev/null +++ b/templates/KeyMile/login/base/get/line_actual_state.j2 @@ -0,0 +1,6 @@ + \ # LinePayloadRate + \ # PayloadRate +0 \ # ActualPayloadRate +0 \ # MaxAttainablePayloadRate +Auto \ # Tcpam + diff --git a/templates/KeyMile/login/base/get/line_operation_state.j2 b/templates/KeyMile/login/base/get/line_operation_state.j2 new file mode 100644 index 0000000..2ffbc06 --- /dev/null +++ b/templates/KeyMile/login/base/get/line_operation_state.j2 @@ -0,0 +1,3 @@ + \ # LineOperationalStatus +WaitForG.Handshaking \ # State + diff --git a/templates/KeyMile/login/base/get/operational_wire_state.j2 b/templates/KeyMile/login/base/get/operational_wire_state.j2 new file mode 100644 index 0000000..7d825a6 --- /dev/null +++ b/templates/KeyMile/login/base/get/operational_wire_state.j2 @@ -0,0 +1,4 @@ + \ # OperationalWireState +NO-WIRE \ # CurrentState +2wire \ # Attainable + diff --git a/templates/KeyMile/login/base/get/port_general_status.j2 b/templates/KeyMile/login/base/get/port_general_status.j2 new file mode 100644 index 0000000..cb6881a --- /dev/null +++ b/templates/KeyMile/login/base/get/port_general_status.j2 @@ -0,0 +1,5 @@ + \ # PHYState +LinkDown \ # Speed +LinkDown \ # Duplex +false \ # IEEE802_3FlowControl + diff --git a/templates/KeyMile/login/base/get/port_mac_status.j2 b/templates/KeyMile/login/base/get/port_mac_status.j2 new file mode 100644 index 0000000..9778239 --- /dev/null +++ b/templates/KeyMile/login/base/get/port_mac_status.j2 @@ -0,0 +1,4 @@ + \ # PortMacStatus +2000 \ # MaxPacketLength +00W0DACF4D79 \ # MACAddress + diff --git a/templates/KeyMile/login/base/get/span_profiles.j2 b/templates/KeyMile/login/base/get/span_profiles.j2 new file mode 100644 index 0000000..75e6eab --- /dev/null +++ b/templates/KeyMile/login/base/get/span_profiles.j2 @@ -0,0 +1,3 @@ + \ # LogicalPort +{{ context.port.profile }}{{ context.spacer1 }}\ # Name + diff --git a/templates/KeyMile/login/base/get/vendor_id.j2 b/templates/KeyMile/login/base/get/vendor_id.j2 new file mode 100644 index 0000000..57149cb --- /dev/null +++ b/templates/KeyMile/login/base/get/vendor_id.j2 @@ -0,0 +1,12 @@ + \ # DSLvendor + \ # CO +"B400/ITTN/0001" \ # VendorId +"14.3.3.60.0.22" \ # VersionNumber +"5610864561" \ # SerialNumber +"0x07 40 00 00 00 18 00 11" \ # DslLineTransCap + \ # CPE +"B400/ITTN/2F0A" \ # VendorId +"1.283.5.17 AB" \ # VersionNumber +"3CDH5F478B7B F!Box7550 165.70.10" \ # SerialNumber +"0x00 11 40 11 50 10 03 00" \ # DslLineTransCap + diff --git a/templates/KeyMile/login/base/get/vlan_profile.j2 b/templates/KeyMile/login/base/get/vlan_profile.j2 new file mode 100644 index 0000000..0c5d04b --- /dev/null +++ b/templates/KeyMile/login/base/get/vlan_profile.j2 @@ -0,0 +1,3 @@ + \ # vlanProfile +{{ context.vcc.vlan_profile }}{{ context.spacer1 }}\ # Name + diff --git a/test_cases/integration_tests/keymile/setconfDsl2.txt b/test_cases/integration_tests/keymile/setconfDsl2.txt index 70dd24b..fe71c9a 100644 --- a/test_cases/integration_tests/keymile/setconfDsl2.txt +++ b/test_cases/integration_tests/keymile/setconfDsl2.txt @@ -10,7 +10,7 @@ cd /unit-7/port-1/main Set Labels "ctId" "d" "" set AdministrativeStatus up cd /unit-2/logports/cfgm -create port-1 +create port-1 default cd /unit-2/logports/logport-1/cfgm CreateInterface name cd /unit-2/logports/logport-1/main diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt index 9b41b86..4af0ac6 100644 --- a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt @@ -1,6 +1,6 @@ manager secret -cd /unit-$card/port-$port/main +cd /unit-19/port-1/main set AdministrativeStatus down Set Labels "" "" "" cd /unit-19/portgroup-1/port-1/cfgm diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 22233c0..9b16d08 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -52,28 +52,42 @@ def do_delete(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_create(self, command, *args, context=None): - if self._validate(args, str, str, str, str) and context['path'].split('/')[-1] == 'cfgm': - p1, p2, p3, p4, = self._dissect(args, str, str, str, str) - ids = [] - ids.append(int(p1.split('-')[1])) if p1.startswith('port-') else ids - ids.append(int(p2.split('-')[1])) if p2.startswith('port-') else ids - ids.append(int(p3.split('-')[1])) if p3.startswith('port-') else ids - ids.append(int(p4.split('-')[1])) if p4.startswith('port-') else ids - if len(ids) >= 0: - ids.sort() - try: - for x in ids: - self._model.get_logport('name', self._parent.component_name + '/L/' + str(x)) - break - except exceptions.SoftboxenError: - name = self._parent.component_name + '/L/' + str(ids[0]) - ports = 'ports: ' - for x in ids: - ports += str(x) + ', ' - card = self._model.get_card('name', self._parent.component_name) - logport = self._model.add_logport(card_id=card.id, name=name, ports=ports[:-2]) - else: - raise exceptions.CommandSyntaxError(command=command) + if self._validate(args, str, str, str, str, str) and context['path'].split('/')[-1] == 'cfgm': + p1, p2, p3, p4, profile = self._dissect(args, str, str, str, str, str) + self.create(p1, p2, p3, p4, profile, command) + elif self._validate(args, str, str, str, str) and context['path'].split('/')[-1] == 'cfgm': + p1, p2, p3, profile = self._dissect(args, str, str, str, str) + self.create(p1, p2, p3, '', profile, command) + elif self._validate(args, str, str, str) and context['path'].split('/')[-1] == 'cfgm': + p1, p2, profile = self._dissect(args, str, str, str) + self.create(p1, p2, '', '', profile, command) + elif self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm': + p1, profile = self._dissect(args, str, str) + self.create(p1, '', '', '', profile, command) + else: + raise exceptions.CommandSyntaxError(command=command) + + def create(self, p1, p2, p3, p4, profile, command): + ids = [] + ids.append(int(p1.split('-')[1])) if p1.startswith('port-') else ids + ids.append(int(p2.split('-')[1])) if p2.startswith('port-') else ids + ids.append(int(p3.split('-')[1])) if p3.startswith('port-') else ids + ids.append(int(p4.split('-')[1])) if p4.startswith('port-') else ids + if len(ids) > 0: + ids.sort() + try: + for x in ids: + self._model.get_logport('name', self._parent.component_name + '/L/' + str(x)) + break + except exceptions.SoftboxenError: + name = self._parent.component_name + '/L/' + str(ids[0]) + ports = 'ports: ' + for x in ids: + ports += str(x) + ', ' + card = self._model.get_card('name', self._parent.component_name) + logport = self._model.add_logport(card_id=card.id, name=name, ports=ports[:-2]) + logport = self._model.get_logport('name', name) + logport.set_profile(profile) else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 1776404..c4a9a61 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -28,6 +28,7 @@ class LogportCommandProcessor(PortCommandProcessor): def get_property(self, command, *args, context=None): port = self.get_component() + context['port'] = port scopes = ('login', 'base', 'get') try: super().get_property(command, *args, context=context) @@ -35,6 +36,16 @@ def get_property(self, command, *args, context=None): if self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) + elif self._validate((args[0],), 'ActualStatus') and context['path'].split('/')[-1] == 'status': + text = self._render('actual_status', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'OperationalWireState') and context['path'].split('/')[-1] == 'status': + text = self._render('operational_wire_state', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'SpanProfiles') and context['path'].split('/')[-1] == 'cfgm': + context['spacer1'] = self.create_spacers((67,), (port.profile,))[0] * ' ' + text = self._render('span_profiles', *scopes, context=context) + self._write(text) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) @@ -101,7 +112,7 @@ def do_createinterface(self, command, *args, context=None): self._model.get_interface('name', self.component_name) assert False except exceptions.SoftboxenError as exe: - vcc = self._model.add_interface(name=name, logport_id=logport.id, vlan_profile=vlan_prof) + vcc = self._model.add_interface(name=self.component_name, logport_id=logport.id, vlan_profile=vlan_prof) context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' context['id'] = str(id) # TODO: Template is unknown diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index b4caf46..27e1e46 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -98,7 +98,8 @@ def do_createinterface(self, command, *args, context=None): new_id = int(interface.name[-1]) + 1 id = new_id if new_id > id else id try: - self._model.get_interface('name', self.component_name + '/' + str(id)) + name = self.component_name + '/' + str(id) + self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof) @@ -124,7 +125,8 @@ def do_createinterface(self, command, *args, context=None): new_id = int(interface.name[-1]) + 1 id = new_id if new_id > id else id try: - self._model.get_interface('name', self.component_name + '/' + str(id)) + name = self.component_name + '/' + str(id) + self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof, diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index 32af8ca..09b833f 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -51,7 +51,7 @@ def get_property(self, command, *args, context=None): vcc = self.get_component() context['spacer1'] = self.create_spacers((67,), (vcc.vcc_profile,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (vcc.vlan_profile,))[0] * ' ' - text = self._render('configured_profiles', *scopes, context=dict(context, vcc=vcc)) + text = self._render('service_status', *scopes, context=dict(context, vcc=vcc)) self._write(text) elif self._validate(args, 'configuredProfiles') and context['path'].split('/')[-1] == 'cfgm': vcc = self.get_component() @@ -60,7 +60,16 @@ def get_property(self, command, *args, context=None): context['spacer1'] = self.create_spacers((67,), (vcc.number_of_conn_services,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (vcc.reconfiguration_allowed,))[0] * ' ' context['spacer3'] = self.create_spacers((67,), (services_connected,))[0] * ' ' - text = self._render('service_status', *scopes, context=dict(context, vcc=vcc)) + text = self._render('configured_profiles', *scopes, context=dict(context, vcc=vcc)) + self._write(text) + elif self._validate(args, 'VlanProfile') and context['path'].split('/')[-1] == 'cfgm': + vcc = self.get_component() + context['spacer1'] = self.create_spacers((67,), (vcc.vlan_profile,))[0] * ' ' + text = self._render('vlan_profile', *scopes, context=dict(context, vcc=vcc)) + self._write(text) + elif self._validate(args, 'IfRateLimiting') and context['path'].split('/')[-1] == 'cfgm': + vcc = self.get_component() + text = self._render('if_rate_limiting', *scopes, context=dict(context, vcc=vcc)) self._write(text) else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index d41b4e2..a4d16a9 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -66,7 +66,32 @@ def get_property(self, command, *args, context=None): text = self._render('port_profiles', *scopes, context=dict(context, port=port)) self._write(text) elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': - text = self._render('attainable_rate', *scopes, context=context) + context['spacer1'] = self.create_spacers((67,), (port.downstream,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (port.upstream,))[0] * ' ' + text = self._render('attainable_rate', *scopes, context=dict(context, port=port)) + self._write(text) + elif self._validate((args[0],), 'PortMacStatus') and context['path'].split('/')[-1] == 'status' and \ + card.product == 'ftth': + text = self._render('port_mac_status', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'DDMStatus') and context['path'].split('/')[-1] == 'status' and \ + card.product == 'ftth': + text = self._render('ddm_status', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'PortGeneralStatus') and context['path'].split('/')[-1] == 'status' and \ + card.product == 'ftth': + text = self._render('port_general_status', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'VendorId') and context['path'].split('/')[-1] == 'status': + text = self._render('vendor_id', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'LineActualState') and context['path'].split('/')[-1] == 'status' and \ + card.product == 'sdsl': + text = self._render('line_actual_state', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'LineOperationState') and context['path'].split('/')[-1] == 'status' and \ + card.product == 'sdsl': + text = self._render('line_operation_state', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'QuickLoopbackTest') and context['path'].split('/')[-1] == 'status'\ and (card.product == 'isdn' or 'SUI' in card.board_name) and self.__name__ == 'port': diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 4b006ac..5e82c2b 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -486,7 +486,7 @@ def do_get(self, command, *args, context=None): prop = args[0].split('/')[-1] try: tmp_cmdproc = self.change_directory(path, context=context) - tmp_cmdproc.get_property(command, *prop, context=context) + tmp_cmdproc.get_property(command, prop, context=context) except exceptions.CommandExecutionError: raise exceptions.CommandExecutionError(template='syntax_error', template_scopes=('login', 'base', 'syntax_errors'), From 3bab905788be0489a9f390b84e4da3ad67b658e7 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 26 Oct 2020 14:10:22 +0100 Subject: [PATCH 158/318] Added a bit of code that allows the cli to append the line entered by the user to stdout so a socket stream can read the given command aswell --- nesi/softbox/cli/base.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 500f646..1632d66 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -348,6 +348,9 @@ def loop(self, context=None, return_to=None, command=None): self.line_buffer = line.split('\r\n') continue context['raw_line'] = line + + if self.daemon: + self._write(line) # write line to stdout if box is in daemon mode else: line = command command = None From 2b935b7d95ff001e8e1bae0698ccc30a680ae603 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 26 Oct 2020 15:47:58 +0100 Subject: [PATCH 159/318] Fixed naming convention of get_property in rootCommandprocessor aswell as some minor bugfixes regarding do_get and do_set, also implemented get UnicastList for ports --- .../KeyMile/login/base/get/unicast_list.j2 | 10 ++++++++++ .../login/base/get/unicast_list_empty.j2 | 3 +++ .../accessPoints/root/rootCommandProcessor.py | 2 +- .../root/unit/port/portCommandProcessor.py | 10 ++++++++++ vendors/KeyMile/baseCommandProcessor.py | 17 ++++++++++++++--- 5 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 templates/KeyMile/login/base/get/unicast_list.j2 create mode 100644 templates/KeyMile/login/base/get/unicast_list_empty.j2 diff --git a/templates/KeyMile/login/base/get/unicast_list.j2 b/templates/KeyMile/login/base/get/unicast_list.j2 new file mode 100644 index 0000000..3a6dfad --- /dev/null +++ b/templates/KeyMile/login/base/get/unicast_list.j2 @@ -0,0 +1,10 @@ +{ \ # UnicastList + \ # [0] # + \ # PortDynamicListEntry + 1 \ # Index + 00A38EA34DD0 \ # MacAddress + 2620 \ # VlanId + 0.0.0.0 \ # IpAddress +; \ +} \ + diff --git a/templates/KeyMile/login/base/get/unicast_list_empty.j2 b/templates/KeyMile/login/base/get/unicast_list_empty.j2 new file mode 100644 index 0000000..a8d7a8e --- /dev/null +++ b/templates/KeyMile/login/base/get/unicast_list_empty.j2 @@ -0,0 +1,3 @@ +{ \ # UnicastList +} \ + diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 525dfa8..8f2b740 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -25,7 +25,7 @@ class RootCommandProcessor(BaseCommandProcessor): from .rootManagementFunctions import fm from .rootManagementFunctions import status - def do_get(self, command, *args, context=None): + def get_property(self, command, *args, context=None): if self._validate(args, "CurrTemperature"): context['currTemperature'] = self._model.currTemperature context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index a4d16a9..ae27fe7 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -122,6 +122,16 @@ def get_property(self, command, *args, context=None): context['spacer3'] = self.create_spacers((67,), (port.description,))[0] * ' ' text = self._render('labels', *scopes, context=dict(context, port=port)) self._write(text) + elif self._validate(args, 'UnicastList') and context['path'].split('/')[-1] == 'status': + port = self.get_component() + try: + chan = self._model.get_chan('port_id', port.id) + self._model.get_interface('chan_id', chan.id) + except exceptions.InvalidInputError: + text = self._render('unicast_list_empty', *scopes, context=context) + else: + text = self._render('unicast_list', *scopes, context=context) # where does the templates mac-address come from + self._write(text) elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': self.map_states(port, 'port') port_operational_state = port.operational_state diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 5e82c2b..9c48044 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -484,13 +484,16 @@ def do_get(self, command, *args, context=None): for component in args[0].split('/')[:-1]: path += component + '/' prop = args[0].split('/')[-1] + current_path = context['path'] try: tmp_cmdproc = self.change_directory(path, context=context) tmp_cmdproc.get_property(command, prop, context=context) except exceptions.CommandExecutionError: + context['path'] = current_path raise exceptions.CommandExecutionError(template='syntax_error', template_scopes=('login', 'base', 'syntax_errors'), command=None) + context['path'] = current_path else: self.get_property(command, args[0], context=context) else: @@ -510,9 +513,17 @@ def do_set(self, command, *args, context=None): path = '' for el in args[0].split('/')[:-1]: path += el + '/' - proc = self.change_directory(str(path[:-1]), context=context) - res = (args[0].split('/')[-1],) + args[1:] - proc.set(command, *res, context=context) + current_path = context['path'] + try: + proc = self.change_directory(str(path[:-1]), context=context) + res = (args[0].split('/')[-1],) + args[1:] + proc.set(command, *res, context=context) + except exceptions.CommandExecutionError: + context['path'] = current_path + raise exceptions.CommandExecutionError(template='syntax_error', + template_scopes=('login', 'base', 'syntax_errors'), + command=None) + context['path'] = current_path elif args[0].count('/') == 0: self.set(command, *args, context=context) From b01c8b9424f6a482e5d0e33791770fedae590a43 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 26 Oct 2020 15:53:13 +0100 Subject: [PATCH 160/318] Added interface to port on unit-5 --- bootup/conf/bootstraps/create-keymile-MG2500.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 7999af6..f54a548 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -48,6 +48,7 @@ path="`dirname \"$0\"`" # |---> Unit-5 (vdsl) (SUVM4) # # | |-> Port-1 # # | | |-> Chan-1 # +# | | |-> Interface-1 # # | # # |---> Unit-6 (vdsl) (SUVM6) # # | |-> Port-1 # @@ -499,6 +500,15 @@ req='{ chan_5_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/channels) +### Interface-1 ### + +# Create a physical interface at the network device (admin operation) +req='{ + "chan_id": 'chan_5_1_1' +}' + +interface_5_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) + ### Unit-6 ### # Create a physical card at the network device (admin operation) From 8bd7b8b35c4abe3ed8b3da3a38be84d413e396a6 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 27 Oct 2020 10:45:51 +0100 Subject: [PATCH 161/318] Fixed error handling for get functio --- vendors/KeyMile/baseCommandProcessor.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 9c48044..4a6ea49 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -488,14 +488,19 @@ def do_get(self, command, *args, context=None): try: tmp_cmdproc = self.change_directory(path, context=context) tmp_cmdproc.get_property(command, prop, context=context) - except exceptions.CommandExecutionError: + except exceptions.SoftboxenError: context['path'] = current_path - raise exceptions.CommandExecutionError(template='syntax_error', + raise exceptions.CommandExecutionError(template='invalid_property', template_scopes=('login', 'base', 'syntax_errors'), command=None) context['path'] = current_path else: - self.get_property(command, args[0], context=context) + try: + self.get_property(command, args[0], context=context) + except exceptions.SoftboxenError: + raise exceptions.CommandExecutionError(template='invalid_property', + template_scopes=('login', 'base', 'execution_errors'), + command=None) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), From 1fdaa51dfd882e955970d040f1a8d7c91ab260f7 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 27 Oct 2020 10:50:44 +0100 Subject: [PATCH 162/318] refactored specific api Interfaces into keymile interfaces and general interfaces --- .../api/schemas/keymile_interface_schemas.py | 21 ++++++++++++ .../keymile_resources/keymile_interface.py | 10 ++---- nesi/softbox/api/models/interface_models.py | 5 ++- nesi/softbox/api/schemas/interface_schemas.py | 4 +-- nesi/softbox/base_resources/interface.py | 33 +++++++++++++++++++ 5 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 nesi/keymile/api/schemas/keymile_interface_schemas.py create mode 100644 nesi/softbox/base_resources/interface.py diff --git a/nesi/keymile/api/schemas/keymile_interface_schemas.py b/nesi/keymile/api/schemas/keymile_interface_schemas.py new file mode 100644 index 0000000..960a086 --- /dev/null +++ b/nesi/keymile/api/schemas/keymile_interface_schemas.py @@ -0,0 +1,21 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.interface_schemas import * + + +class KeyMileInterfaceSchema(InterfaceSchema): + class Meta: + model = Interface + fields = InterfaceSchema.Meta.fields + ('chan_id', 'port_id', 'logport_id', 'number_of_conn_services', + 'reconfiguration_allowed', 'vcc_profile', 'vlan_profile', + 'services_connected') diff --git a/nesi/keymile/keymile_resources/keymile_interface.py b/nesi/keymile/keymile_resources/keymile_interface.py index dc1c446..e5c62a3 100644 --- a/nesi/keymile/keymile_resources/keymile_interface.py +++ b/nesi/keymile/keymile_resources/keymile_interface.py @@ -10,20 +10,16 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -import logging -from nesi.softbox.base_resources import base +from nesi.softbox.base_resources.interface import Interface, InterfaceCollection, logging, base LOG = logging.getLogger(__name__) -class KeyMileInterface(base.Resource): +class KeyMileInterface(Interface): """Represent logical interface resource.""" - id = base.Field('id') port_id = base.Field('port_id') - name = base.Field('name') - description = base.Field('description') chan_id = base.Field('chan_id') logport_id = base.Field('logport_id') @@ -35,7 +31,7 @@ class KeyMileInterface(base.Resource): services_connected = base.Field('services_connected') -class KeyMileInterfaceCollection(base.ResourceCollection): +class KeyMileInterfaceCollection(InterfaceCollection): """Represent a collection of interfaces.""" @property diff --git a/nesi/softbox/api/models/interface_models.py b/nesi/softbox/api/models/interface_models.py index cb24720..cd68d95 100644 --- a/nesi/softbox/api/models/interface_models.py +++ b/nesi/softbox/api/models/interface_models.py @@ -18,13 +18,16 @@ class Interface(db.Model): name = db.Column(db.String(64)) description = db.Column(db.String()) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + + # KeyMile chan_id = db.Column(db.Integer, db.ForeignKey('channel.id')) port_id = db.Column(db.Integer, db.ForeignKey('port.id')) logport_id = db.Column(db.Integer, db.ForeignKey('log_port.id')) - # vcc vcc_profile = db.Column(db.String(), default='') # default or profile_name, default:= vpi=0 and vci=33 vlan_profile = db.Column(db.String(), default='') # default or profile_name, must be untagged number_of_conn_services = db.Column(db.Integer(), default=0) reconfiguration_allowed = db.Column(db.Enum('true', 'false'), default='true') services_connected = db.Column(db.String(), default='') + + diff --git a/nesi/softbox/api/schemas/interface_schemas.py b/nesi/softbox/api/schemas/interface_schemas.py index a93ba52..1c68aec 100644 --- a/nesi/softbox/api/schemas/interface_schemas.py +++ b/nesi/softbox/api/schemas/interface_schemas.py @@ -17,9 +17,7 @@ class InterfaceSchema(ma.ModelSchema): class Meta: model = Interface - fields = ('id', 'box_id', 'box', 'chan_id', 'port_id', 'logport_id', 'number_of_conn_services', - 'name', 'description', 'reconfiguration_allowed', 'vcc_profile', 'vlan_profile', 'services_connected', - '_links') + fields = ('id', 'box_id', 'box', 'name', 'description', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/base_resources/interface.py b/nesi/softbox/base_resources/interface.py new file mode 100644 index 0000000..a95d664 --- /dev/null +++ b/nesi/softbox/base_resources/interface.py @@ -0,0 +1,33 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import logging + +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class Interface(base.Resource): + """Represent logical interface resource.""" + + id = base.Field('id') + name = base.Field('name') + description = base.Field('description') + + +class InterfaceCollection(base.ResourceCollection): + """Represent a collection of interfaces.""" + + @property + def _resource_type(self): + return Interface From 3d26d93167641f02763b918938bfc6691685fb25 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 27 Oct 2020 11:31:38 +0100 Subject: [PATCH 163/318] Added templates and functionality for some properties on empty cards --- .../login/base/get/current_status_empty.j2 | 8 + .../base/get/equipment_inventory_empty.j2 | 16 ++ .../root/unit/unitCommandProcessor.py | 140 ++++++++++-------- 3 files changed, 101 insertions(+), 63 deletions(-) create mode 100644 templates/KeyMile/login/base/get/current_status_empty.j2 create mode 100644 templates/KeyMile/login/base/get/equipment_inventory_empty.j2 diff --git a/templates/KeyMile/login/base/get/current_status_empty.j2 b/templates/KeyMile/login/base/get/current_status_empty.j2 new file mode 100644 index 0000000..73a5a02 --- /dev/null +++ b/templates/KeyMile/login/base/get/current_status_empty.j2 @@ -0,0 +1,8 @@ + \ # EquipmentStatus +Empty \ # State +"" \ # Hardware +"" \ # Software +"" \ # SerialNumber +"" \ # ManufacturerName +"" \ # ModelName + diff --git a/templates/KeyMile/login/base/get/equipment_inventory_empty.j2 b/templates/KeyMile/login/base/get/equipment_inventory_empty.j2 new file mode 100644 index 0000000..d28b60d --- /dev/null +++ b/templates/KeyMile/login/base/get/equipment_inventory_empty.j2 @@ -0,0 +1,16 @@ + \ # EquipmentInventory +"" \ # Symbol +"" \ # ShortText +0 \ # BoardId +0 \ # HardwareKey +"" \ # ManufacturerId +"" \ # ManufacturerSerialNumber +"" \ # ManufacturerPartNumber +"" \ # ManufacturerBuildState +"" \ # SupplierPartNumber +"" \ # SupplierBuildState +"" \ # CustomerId +"" \ # CustomerProductId +"" \ # Bootloader +"" \ # Processor + diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index a13d52b..7aa21cd 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -66,7 +66,13 @@ def _init_context(self, context=None): context['ls_EquipmentState'] = 'Ok' def get_property(self, command, *args, context=None): - card = self.get_component() + try: + card = self.get_component() + except exceptions.InvalidInputError: + if args[0] in ('CurrentStatus', 'EquipmentInventory'): + card = None + else: + raise scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -167,71 +173,79 @@ def get_property(self, command, *args, context=None): self._write(text) elif self._validate(args, 'CurrentStatus') and context['path'].split('/')[-1] == 'main': - unit_state = card.state - context['unit_state'] = unit_state - context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' - unit_hardware = '"' + card.board_name + ' ' + card.supplier_build_state + '"' - context['unit_hardware'] = unit_hardware - context['spacer_2'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' - unit_software = '"' + card.software[:-4] + '"' - context['unit_software'] = unit_software - context['spacer_3'] = self.create_spacers((67,), (unit_software,))[0] * ' ' - unit_serial_number = '"' + card.serial_number + '"' - context['unit_serial_number'] = unit_serial_number - context['spacer_4'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' - unit_manufacturer_name = '"' + card.manufacturer_name + '"' - context['unit_manufacturer_name'] = unit_manufacturer_name - context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_name,))[0] * ' ' - unit_model_name = '"' + card.model_name + '"' - context['unit_model_name'] = unit_model_name - context['spacer_6'] = self.create_spacers((67,), (unit_model_name,))[0] * ' ' - text = self._render('current_status', *scopes, context=context) + if card is None: + text = self._render('current_status_empty', *scopes, context=context) + else: + unit_state = card.state + context['unit_state'] = unit_state + context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' + unit_hardware = '"' + card.board_name + ' ' + card.supplier_build_state + '"' + context['unit_hardware'] = unit_hardware + context['spacer_2'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' + unit_software = '"' + card.software[:-4] + '"' + context['unit_software'] = unit_software + context['spacer_3'] = self.create_spacers((67,), (unit_software,))[0] * ' ' + unit_serial_number = '"' + card.serial_number + '"' + context['unit_serial_number'] = unit_serial_number + context['spacer_4'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' + unit_manufacturer_name = '"' + card.manufacturer_name + '"' + context['unit_manufacturer_name'] = unit_manufacturer_name + context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_name,))[0] * ' ' + unit_model_name = '"' + card.model_name + '"' + context['unit_model_name'] = unit_model_name + context['spacer_6'] = self.create_spacers((67,), (unit_model_name,))[0] * ' ' + text = self._render('current_status', *scopes, context=context) + self._write(text) elif self._validate(args, 'EquipmentInventory') and context['path'].split('/')[-1] == 'main': - unit_symbol = '"' + card.board_name + '"' - context['unit_symbol'] = unit_symbol - context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' - unit_short_text = '"' + card.short_text + '"' - context['unit_short_text'] = unit_short_text - context['spacer_2'] = self.create_spacers((67,), (unit_short_text,))[0] * ' ' - unit_board_id = card.board_id - context['unit_board_id'] = unit_board_id - context['spacer_3'] = self.create_spacers((67,), (unit_board_id,))[0] * ' ' - unit_hardware_key = card.hardware_key - context['unit_hardware_key'] = unit_hardware_key - context['spacer_4'] = self.create_spacers((67,), (unit_hardware_key,))[0] * ' ' - unit_manufacturer_id = '"' + card.manufacturer_id + '"' - context['unit_manufacturer_id'] = unit_manufacturer_id - context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_id,))[0] * ' ' - unit_serial_number = '"' + card.serial_number + '"' - context['unit_serial_number'] = unit_serial_number - context['spacer_6'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' - unit_manufacturer_part_number = '"' + card.manufacturer_part_number + '"' - context['unit_manufacturer_part_number'] = unit_manufacturer_part_number - context['spacer_7'] = self.create_spacers((67,), (unit_manufacturer_part_number,))[0] * ' ' - unit_manufacturer_build_state = '"' + card.manufacturer_build_state + '"' - context['unit_manufacturer_build_state'] = unit_manufacturer_build_state - context['spacer_8'] = self.create_spacers((67,), (unit_manufacturer_build_state,))[0] * ' ' - unit_supplier_part_number = '"' + card.model_name + '"' - context['unit_supplier_part_number'] = unit_supplier_part_number - context['spacer_9'] = self.create_spacers((67,), (unit_supplier_part_number,))[0] * ' ' - unit_supplier_build_state = '"' + card.supplier_build_state + '"' - context['unit_supplier_build_state'] = unit_supplier_build_state - context['spacer_10'] = self.create_spacers((67,), (unit_supplier_build_state,))[0] * ' ' - unit_customer_id = '"' + card.customer_id + '"' - context['unit_customer_id'] = unit_customer_id - context['spacer_11'] = self.create_spacers((67,), (unit_customer_id,))[0] * ' ' - unit_customer_product_id = '"' + card.customer_product_id + '"' - context['unit_customer_product_id'] = unit_customer_product_id - context['spacer_12'] = self.create_spacers((67,), (unit_customer_product_id,))[0] * ' ' - unit_boot_loader = '"' + card.boot_loader + '"' - context['unit_boot_loader'] = unit_boot_loader - context['spacer_13'] = self.create_spacers((67,), (unit_boot_loader,))[0] * ' ' - unit_processor = '"' + card.processor + '"' - context['unit_processor'] = unit_processor - context['spacer_14'] = self.create_spacers((67,), (unit_processor,))[0] * ' ' - text = self._render('equipment_inventory', *scopes, context=context) + if card is None: + text = self._render('equipment_inventory_empty', *scopes, context=context) + else: + unit_symbol = '"' + card.board_name + '"' + context['unit_symbol'] = unit_symbol + context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' + unit_short_text = '"' + card.short_text + '"' + context['unit_short_text'] = unit_short_text + context['spacer_2'] = self.create_spacers((67,), (unit_short_text,))[0] * ' ' + unit_board_id = card.board_id + context['unit_board_id'] = unit_board_id + context['spacer_3'] = self.create_spacers((67,), (unit_board_id,))[0] * ' ' + unit_hardware_key = card.hardware_key + context['unit_hardware_key'] = unit_hardware_key + context['spacer_4'] = self.create_spacers((67,), (unit_hardware_key,))[0] * ' ' + unit_manufacturer_id = '"' + card.manufacturer_id + '"' + context['unit_manufacturer_id'] = unit_manufacturer_id + context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_id,))[0] * ' ' + unit_serial_number = '"' + card.serial_number + '"' + context['unit_serial_number'] = unit_serial_number + context['spacer_6'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' + unit_manufacturer_part_number = '"' + card.manufacturer_part_number + '"' + context['unit_manufacturer_part_number'] = unit_manufacturer_part_number + context['spacer_7'] = self.create_spacers((67,), (unit_manufacturer_part_number,))[0] * ' ' + unit_manufacturer_build_state = '"' + card.manufacturer_build_state + '"' + context['unit_manufacturer_build_state'] = unit_manufacturer_build_state + context['spacer_8'] = self.create_spacers((67,), (unit_manufacturer_build_state,))[0] * ' ' + unit_supplier_part_number = '"' + card.model_name + '"' + context['unit_supplier_part_number'] = unit_supplier_part_number + context['spacer_9'] = self.create_spacers((67,), (unit_supplier_part_number,))[0] * ' ' + unit_supplier_build_state = '"' + card.supplier_build_state + '"' + context['unit_supplier_build_state'] = unit_supplier_build_state + context['spacer_10'] = self.create_spacers((67,), (unit_supplier_build_state,))[0] * ' ' + unit_customer_id = '"' + card.customer_id + '"' + context['unit_customer_id'] = unit_customer_id + context['spacer_11'] = self.create_spacers((67,), (unit_customer_id,))[0] * ' ' + unit_customer_product_id = '"' + card.customer_product_id + '"' + context['unit_customer_product_id'] = unit_customer_product_id + context['spacer_12'] = self.create_spacers((67,), (unit_customer_product_id,))[0] * ' ' + unit_boot_loader = '"' + card.boot_loader + '"' + context['unit_boot_loader'] = unit_boot_loader + context['spacer_13'] = self.create_spacers((67,), (unit_boot_loader,))[0] * ' ' + unit_processor = '"' + card.processor + '"' + context['unit_processor'] = unit_processor + context['spacer_14'] = self.create_spacers((67,), (unit_processor,))[0] * ' ' + text = self._render('equipment_inventory', *scopes, context=context) + self._write(text) else: From 21eede2bb26137c3dbde379617b5623b3bbf9821 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 27 Oct 2020 11:43:07 +0100 Subject: [PATCH 164/318] Added get CurrentStatus for management cards --- .../mgmt_unit/mgmtunitCommandProcessor.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py index 1a0edf5..e62b6e3 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py @@ -105,6 +105,28 @@ def get_property(self, command, *args, context=None): context['unit_processor'] = unit_processor context['spacer_14'] = self.create_spacers((67,), (unit_processor,))[0] * ' ' text = self._render('equipment_inventory', *scopes, context=context) + self._write(text) + elif self._validate(args, 'CurrentStatus') and context['path'].split('/')[-1] == 'main': + unit_state = card.state + context['unit_state'] = unit_state + context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' + unit_hardware = '"' + card.board_name + ' ' + card.supplier_build_state + '"' + context['unit_hardware'] = unit_hardware + context['spacer_2'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' + unit_software = '"' + card.software[:-4] + '"' + context['unit_software'] = unit_software + context['spacer_3'] = self.create_spacers((67,), (unit_software,))[0] * ' ' + unit_serial_number = '"' + card.serial_number + '"' + context['unit_serial_number'] = unit_serial_number + context['spacer_4'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' + unit_manufacturer_name = '"' + card.manufacturer_name + '"' + context['unit_manufacturer_name'] = unit_manufacturer_name + context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_name,))[0] * ' ' + unit_model_name = '"' + card.model_name + '"' + context['unit_model_name'] = unit_model_name + context['spacer_6'] = self.create_spacers((67,), (unit_model_name,))[0] * ' ' + text = self._render('current_status', *scopes, context=context) + self._write(text) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', From 1691604fa098415f53329ec091e5a2e42c7b99f3 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 27 Oct 2020 12:34:45 +0100 Subject: [PATCH 165/318] Corrected template outputs for 'get IsdnPort' and get 'PstnPort' --- .../conf/bootstraps/create-keymile-MG2500.sh | 2 +- .../api/models/portgroupport_models.py | 20 +++++++++---------- .../KeyMile/login/base/get/isdnport_bottom.j2 | 6 +++--- .../KeyMile/login/base/get/isdnport_top.j2 | 2 +- .../KeyMile/login/base/get/pstnport_bottom.j2 | 4 ++-- .../KeyMile/login/base/get/pstnport_top.j2 | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index f54a548..91ee2b7 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -504,7 +504,7 @@ chan_5_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/channels) # Create a physical interface at the network device (admin operation) req='{ - "chan_id": 'chan_5_1_1' + "chan_id": '$chan_5_1_1' }' interface_5_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) diff --git a/nesi/softbox/api/models/portgroupport_models.py b/nesi/softbox/api/models/portgroupport_models.py index 4a1a0f9..88a86f6 100644 --- a/nesi/softbox/api/models/portgroupport_models.py +++ b/nesi/softbox/api/models/portgroupport_models.py @@ -15,15 +15,15 @@ class PortGroupPort(db.Model): #isdn enable = db.Column(db.Boolean(), default=False) - register_as_global = db.Column(db.Boolean, default=None) - register_default_number_only = db.Column(db.Boolean, default=None) - layer_1_permanently_activated = db.Column(db.Boolean, default=None) - sip_profile = db.Column(db.String(), default=None) - proxy_registrar_profile = db.Column(db.String(), default=None) - codec_sdp_profile = db.Column(db.String(), default=None) - isdnba_profile = db.Column(db.String(), default=None) + register_as_global = db.Column(db.Boolean, default=True) + register_default_number_only = db.Column(db.Boolean, default=False) + layer_1_permanently_activated = db.Column(db.Boolean, default=False) + sip_profile = db.Column(db.String(), default='none') + proxy_registrar_profile = db.Column(db.String(), default='none') + codec_sdp_profile = db.Column(db.String(), default='none') + isdnba_profile = db.Column(db.String(), default='none') #pstn - pay_phone = db.Column(db.Boolean(), default= None) - pstn_profile = db.Column(db.String(), default=None) - enterprise_profile = db.Column(db.String(), default=None) + pay_phone = db.Column(db.Boolean(), default=False) + pstn_profile = db.Column(db.String(), default='none') + enterprise_profile = db.Column(db.String(), default='none') diff --git a/templates/KeyMile/login/base/get/isdnport_bottom.j2 b/templates/KeyMile/login/base/get/isdnport_bottom.j2 index 97c6e19..a6ca59f 100644 --- a/templates/KeyMile/login/base/get/isdnport_bottom.j2 +++ b/templates/KeyMile/login/base/get/isdnport_bottom.j2 @@ -1,7 +1,7 @@ } \ -{{ context.port.register_as_global }}{{ context.spacer2 }}\ # RegisterAsGlobal -{{ context.port.register_default_number_only }}{{ context.spacer3 }}\ # RegisterDefaultNumberOnly -{{ context.port.layer_1_permanently_activated }}{{ context.spacer8 }}\ # Layer1PermanentlyActivated +{{ context.port.register_as_global | lower }}{{ context.spacer2 }}\ # RegisterAsGlobal +{{ context.port.register_default_number_only | lower }}{{ context.spacer3 }}\ # RegisterDefaultNumberOnly +{{ context.port.layer_1_permanently_activated | lower }}{{ context.spacer8 }}\ # Layer1PermanentlyActivated {{ context.port.sip_profile }}{{ context.spacer4 }}\ # SipProfile {{ context.port.proxy_registrar_profile }}{{ context.spacer5 }}\ # ProxyRegistrarProfile {{ context.port.codec_sdp_profile }}{{ context.spacer6 }}\ # CodecSdpProfile diff --git a/templates/KeyMile/login/base/get/isdnport_top.j2 b/templates/KeyMile/login/base/get/isdnport_top.j2 index 6f7ea38..96dd3bf 100644 --- a/templates/KeyMile/login/base/get/isdnport_top.j2 +++ b/templates/KeyMile/login/base/get/isdnport_top.j2 @@ -1,4 +1,4 @@ \ # IsdnPort -{{ context.port.enable }}{{ context.spacer1 }}\ # Enable +{{ context.port.enable | lower }}{{ context.spacer1 }}\ # Enable { \ # SubscriberIdentifications diff --git a/templates/KeyMile/login/base/get/pstnport_bottom.j2 b/templates/KeyMile/login/base/get/pstnport_bottom.j2 index 88b7918..adb8176 100644 --- a/templates/KeyMile/login/base/get/pstnport_bottom.j2 +++ b/templates/KeyMile/login/base/get/pstnport_bottom.j2 @@ -1,6 +1,6 @@ } \ -{{ context.port.register_as_global }}{{ context.spacer2 }}\ # RegisterAsGlobal -{{ context.port.pay_phone }}{{ context.spacer3 }}\ # PayPhone +{{ context.port.register_as_global | lower }}{{ context.spacer2 }}\ # RegisterAsGlobal +{{ context.port.pay_phone | lower }}{{ context.spacer3 }}\ # PayPhone {{ context.port.sip_profile }}{{ context.spacer4 }}\ # SipProfile {{ context.port.proxy_registrar_profile }}{{ context.spacer5 }}\ # ProxyRegistrarProfile {{ context.port.codec_sdp_profile }}{{ context.spacer6 }}\ # CodecSdpProfile diff --git a/templates/KeyMile/login/base/get/pstnport_top.j2 b/templates/KeyMile/login/base/get/pstnport_top.j2 index 9aab7aa..f470f1b 100644 --- a/templates/KeyMile/login/base/get/pstnport_top.j2 +++ b/templates/KeyMile/login/base/get/pstnport_top.j2 @@ -1,4 +1,4 @@ \ # PstnPort -{{ context.port.enable }}{{ context.spacer1 }}\ # Enable +{{ context.port.enable | lower }}{{ context.spacer1 }}\ # Enable { \ # SubscriberIdentifications From b07fff7d0001e0b0ff3b2aca887e81c2ef96bc30 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 27 Oct 2020 15:05:55 +0100 Subject: [PATCH 166/318] Added new testsubscribers, relocated subscriber from card to portgroupport --- .../conf/bootstraps/create-keymile-MG2500.sh | 53 +++++++++++++++---- .../keymile_resources/keymile_subscriber.py | 1 + .../api/models/portgroupport_models.py | 14 +++++ nesi/softbox/api/models/subscriber_models.py | 8 +-- .../api/schemas/portgroupport_schemas.py | 5 +- .../softbox/api/schemas/subscriber_schemas.py | 4 +- .../KeyMile/login/base/get/isdnport_middle.j2 | 2 +- .../KeyMile/login/base/get/pstnport_middle.j2 | 2 +- .../port/portgroupportCommandProcessor.py | 10 ++-- 9 files changed, 74 insertions(+), 25 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 91ee2b7..cfa8d67 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -168,15 +168,6 @@ req='{ information_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) -# test subscriber -req='{ - "name": "tester", - "number": 9023, - "type": "unit" -}' - -subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) - ### Nto1-Service-1 ### # Create a physical port at the network device (admin operation) @@ -681,7 +672,11 @@ req='{ "manufacturer_part_number": "37900315", "manufacturer_build_state": "09", "boot_loader": "BLSU2_R1J01/CT40500", - "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB", + "gateway_ipaddress": "10.0.0.20", + "subnet_mask": "255.255.255.0", + "default_gateway": "10.0.0.1", + "country_code": "+672" }' unit_19=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -710,6 +705,18 @@ req='{ port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) +# test subscriber 1 +req='{ + "name": "tester", + "number": 9023, + "portgroupport_id": '$port_19_G1_1', + "autorisation_user_name": "Test User", + "autorisation_password": "topsecret", + "display_name": "Mr. Testuser" +}' + +subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) + ### PortGroupPort-2 ### # Create a physical port at the network device (admin operation) @@ -721,4 +728,28 @@ req='{ "type": "ISDN" }' -port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) +port_19_G2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) + +# test subscriber 3 +req='{ + "name": "tester2", + "number": 7653312, + "portgroupport_id": '$port_19_G2_1', + "autorisation_user_name": "Test User 2", + "autorisation_password": "topsecret", + "display_name": "Mrs. Testuser" +}' + +subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) + +# test subscriber 3 +req='{ + "name": "tester3", + "number": 1234567, + "portgroupport_id": '$port_19_G2_1', + "autorisation_user_name": "Test User 3", + "autorisation_password": "topsecret", + "display_name": "Mr. & Mrs. Testuser" +}' + +subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) diff --git a/nesi/keymile/keymile_resources/keymile_subscriber.py b/nesi/keymile/keymile_resources/keymile_subscriber.py index 6eaefbf..82c7231 100644 --- a/nesi/keymile/keymile_resources/keymile_subscriber.py +++ b/nesi/keymile/keymile_resources/keymile_subscriber.py @@ -30,6 +30,7 @@ class KeyMileSubscriber(base.Resource): autorisation_password = base.Field('autorisation_password') display_name = base.Field('display_name') privacy = base.Field('privacy') + portgroupport_id = base.Field('portgroupport_id') def set(self, field, value): mapping = {field: value} diff --git a/nesi/softbox/api/models/portgroupport_models.py b/nesi/softbox/api/models/portgroupport_models.py index 88a86f6..fdb9554 100644 --- a/nesi/softbox/api/models/portgroupport_models.py +++ b/nesi/softbox/api/models/portgroupport_models.py @@ -1,4 +1,17 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst from nesi.softbox.api import db +from .subscriber_models import Subscriber class PortGroupPort(db.Model): @@ -12,6 +25,7 @@ class PortGroupPort(db.Model): label2 = db.Column(db.String(), default='""') card_id = db.Column(db.Integer, db.ForeignKey('card.id')) type = db.Column(db.Enum('ISDN', 'PSTN'), default='ISDN') + subscribers = db.relationship('Subscriber', backref='PortGroupPort', lazy='dynamic') #isdn enable = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/models/subscriber_models.py b/nesi/softbox/api/models/subscriber_models.py index ec22ecf..7670311 100644 --- a/nesi/softbox/api/models/subscriber_models.py +++ b/nesi/softbox/api/models/subscriber_models.py @@ -9,7 +9,7 @@ # - Alexander Dincher # - Philipp-Noah Groß # -# License: https://github.com/inexio/NESi/LICENSE.rst +# License: https://github.com/inexio/NESi/LICENSE.rst< from nesi.softbox.api import db @@ -18,13 +18,13 @@ class Subscriber(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + portgroupport_id = db.Column(db.Integer(), db.ForeignKey('port_group_port.id')) number = db.Column(db.Integer(), nullable=False, unique=True) - type = db.Column(db.Enum('unit', 'port'), default='port') address = db.Column(db.String(), default='') registration_state = db.Column(db.Enum('registered'), default='registered') autorisation_user_name = db.Column(db.String(), default='') - autorisation_password = db.Column(db.String(), default='""') + autorisation_password = db.Column(db.String(), default='') display_name = db.Column(db.String(), default='') - privacy = db.Column(db.String(), default=None) + privacy = db.Column(db.String(), default='None') diff --git a/nesi/softbox/api/schemas/portgroupport_schemas.py b/nesi/softbox/api/schemas/portgroupport_schemas.py index 5ef8f85..39cd17e 100644 --- a/nesi/softbox/api/schemas/portgroupport_schemas.py +++ b/nesi/softbox/api/schemas/portgroupport_schemas.py @@ -12,17 +12,20 @@ from nesi.softbox.api import ma from ..models.portgroupport_models import PortGroupPort +from .subscriber_schemas import SubscribersSchema class PortGroupPortSchema(ma.ModelSchema): class Meta: model = PortGroupPort fields = ('id', 'name', 'box_id', 'card_id', 'operational_state', 'admin_state', 'description', 'label1', - 'label2', 'type', 'enable', 'register_as_global', + 'label2', 'type', 'enable', 'register_as_global', 'subscribers', 'register_default_number_only', 'layer_1_permanently_activated', 'sip_profile', 'isdnba_profile', 'proxy_registrar_profile', 'codec_sdp_profile', 'pay_phone', 'pstn_profile', 'enterprise_profile', '_links') + subscribers = ma.Nested(SubscribersSchema.SubscriberSchema, many=True) + box = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_box', id='')}}) diff --git a/nesi/softbox/api/schemas/subscriber_schemas.py b/nesi/softbox/api/schemas/subscriber_schemas.py index 98c07b8..581acfc 100644 --- a/nesi/softbox/api/schemas/subscriber_schemas.py +++ b/nesi/softbox/api/schemas/subscriber_schemas.py @@ -17,8 +17,8 @@ class SubscriberSchema(ma.ModelSchema): class Meta: model = Subscriber - fields = ('id', 'name', 'box', 'box_id', 'number', 'type', 'address', 'registration_state', 'display_name', - 'autorisation_user_name', 'autorisation_password', 'privacy', + fields = ('id', 'name', 'box', 'box_id', 'number', 'address', 'registration_state', 'display_name', + 'autorisation_user_name', 'autorisation_password', 'privacy', 'portgroupport_id', '_links') box = ma.Hyperlinks( diff --git a/templates/KeyMile/login/base/get/isdnport_middle.j2 b/templates/KeyMile/login/base/get/isdnport_middle.j2 index 051b842..2336e11 100644 --- a/templates/KeyMile/login/base/get/isdnport_middle.j2 +++ b/templates/KeyMile/login/base/get/isdnport_middle.j2 @@ -3,7 +3,7 @@ "{{ context.subscriber.number }}"{{ context.spacer10 }}\ # SubscriberNumber "{{ context.subscriber.autorisation_user_name }}"{{ context.spacer11 }}\ # AuthorisationUserName "{{ context.subscriber.autorisation_password }}"{{ context.spacer12 }}\ # AuthorisationPassword - "{{ context.subscriber.display_name }}"{{ context.spacer13 }}\ # DisplayName + "{{ context.subscriber.display_name | safe }}"{{ context.spacer13 }}\ # DisplayName {{ context.subscriber.privacy }}{{ context.spacer14 }}\ # privacy ; \ diff --git a/templates/KeyMile/login/base/get/pstnport_middle.j2 b/templates/KeyMile/login/base/get/pstnport_middle.j2 index 051b842..2336e11 100644 --- a/templates/KeyMile/login/base/get/pstnport_middle.j2 +++ b/templates/KeyMile/login/base/get/pstnport_middle.j2 @@ -3,7 +3,7 @@ "{{ context.subscriber.number }}"{{ context.spacer10 }}\ # SubscriberNumber "{{ context.subscriber.autorisation_user_name }}"{{ context.spacer11 }}\ # AuthorisationUserName "{{ context.subscriber.autorisation_password }}"{{ context.spacer12 }}\ # AuthorisationPassword - "{{ context.subscriber.display_name }}"{{ context.spacer13 }}\ # DisplayName + "{{ context.subscriber.display_name | safe }}"{{ context.spacer13 }}\ # DisplayName {{ context.subscriber.privacy }}{{ context.spacer14 }}\ # privacy ; \ diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 2f92f60..0bcd0d0 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -33,11 +33,11 @@ def get_property(self, command, *args, context=None): super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: if self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ - self._model.get_card('name', self._parent._parent.component_name).product == 'isdn': + self._model.get_card('name', self._parent._parent.component_name).product in ('isdn', 'analog'): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'port' and subscriber.address == self.component_name: + if subscriber.portgroupport_id == port.id: context['i'] = i context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' @@ -62,13 +62,13 @@ def get_property(self, command, *args, context=None): i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'port' and subscriber.address == self.component_name: + if subscriber.portgroupport_id == port.id: context['i'] = i context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' context['spacer11'] = self.create_spacers((63,), (subscriber.autorisation_user_name,))[0] * ' ' context['spacer12'] = self.create_spacers((63,), (subscriber.autorisation_password,))[0] * ' ' context['spacer13'] = self.create_spacers((63,), (subscriber.display_name,))[0] * ' ' - context['spacer14'] = self.create_spacers((63,), (subscriber.privacy,))[0] * ' ' + context['spacer14'] = self.create_spacers((65,), (subscriber.privacy,))[0] * ' ' i += 1 text += self._render('isdnport_middle', *scopes, context=dict(context, subscriber=subscriber)) @@ -88,7 +88,7 @@ def get_property(self, command, *args, context=None): i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'port' and subscriber.address == self.component_name: + if subscriber.portgroupport_id == port.id: context['i'] = i context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' context['spacer11'] = self.create_spacers((63,), (subscriber.autorisation_user_name,))[0] * ' ' From bf63a841cf072c63135f633504dcd1e0f2644c1d Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 28 Oct 2020 10:04:00 +0100 Subject: [PATCH 167/318] Added further registration states and changed the way subscribers are loaded when executing 'get IsdnPort/PstnPort', also changed the behaviour of get SubscriberList when in unit-19 to only display subsribers with registration state 'Unregistered' --- bootup/conf/bootstraps/create-keymile-MG2500.sh | 3 ++- nesi/softbox/api/models/subscriber_models.py | 5 ++++- nesi/softbox/api/views/subscriber_views.py | 3 +++ .../unit/portgroup/port/portgroupportCommandProcessor.py | 7 +++---- .../KeyMile/accessPoints/root/unit/unitCommandProcessor.py | 2 +- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index cfa8d67..c32e56d 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -749,7 +749,8 @@ req='{ "portgroupport_id": '$port_19_G2_1', "autorisation_user_name": "Test User 3", "autorisation_password": "topsecret", - "display_name": "Mr. & Mrs. Testuser" + "display_name": "Mr. & Mrs. Testuser", + "registration_state": "Unregistered" }' subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) diff --git a/nesi/softbox/api/models/subscriber_models.py b/nesi/softbox/api/models/subscriber_models.py index 7670311..9e1f8dd 100644 --- a/nesi/softbox/api/models/subscriber_models.py +++ b/nesi/softbox/api/models/subscriber_models.py @@ -22,7 +22,10 @@ class Subscriber(db.Model): number = db.Column(db.Integer(), nullable=False, unique=True) address = db.Column(db.String(), default='') - registration_state = db.Column(db.Enum('registered'), default='registered') + registration_state = db.Column( + db.Enum('Registered', 'Registering', 'RegisteringWith-Cred', + 'DeRegInRegistering', 'DeRegistering', 'Reregistering', + 'Unregistered'), default='Registered') autorisation_user_name = db.Column(db.String(), default='') autorisation_password = db.Column(db.String(), default='') display_name = db.Column(db.String(), default='') diff --git a/nesi/softbox/api/views/subscriber_views.py b/nesi/softbox/api/views/subscriber_views.py index 4b46e43..545d218 100644 --- a/nesi/softbox/api/views/subscriber_views.py +++ b/nesi/softbox/api/views/subscriber_views.py @@ -12,6 +12,7 @@ from .base_views import * from ..schemas.subscriber_schemas import * +from ..models.portgroupport_models import PortGroupPort PREFIX = '/nesi/v1' @@ -43,6 +44,8 @@ def update_subscriber(box_id, id): @app.route(PREFIX + '/boxen//subscribers', methods=['POST']) def new_subscriber(box_id): req = flask.request.json + portgroupport = json.loads(show_component(PortGroupPort, box_id, req['portgroupport_id']).data.decode('utf-8')) + req['address'] = '/portgroup-' + portgroupport['name'].split('/')[1][1:] + '/port-' + portgroupport['name'].split('/')[2] response = new_component(SubscriberSchema(), Subscriber, req, box_id) return response, 201 diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 0bcd0d0..795e78f 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -36,8 +36,7 @@ def get_property(self, command, *args, context=None): self._model.get_card('name', self._parent._parent.component_name).product in ('isdn', 'analog'): text = self._render('subscriberList_top', *scopes, context=context) i = 0 - for subscriber in self._model.subscribers: - if subscriber.portgroupport_id == port.id: + for subscriber in self._model.get_subscribers('portgroupport_id', port.id): context['i'] = i context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' @@ -61,7 +60,7 @@ def get_property(self, command, *args, context=None): text = self._render('isdnport_top', *scopes, context=dict(context, port=port)) i = 0 - for subscriber in self._model.subscribers: + for subscriber in self._model.get_subscribers('portgroupport_id', port.id): if subscriber.portgroupport_id == port.id: context['i'] = i context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' @@ -87,7 +86,7 @@ def get_property(self, command, *args, context=None): text = self._render('pstnport_top', *scopes, context=dict(context, port=port)) i = 0 - for subscriber in self._model.subscribers: + for subscriber in self._model.get_subscribers('portgroupport_id', port.id): if subscriber.portgroupport_id == port.id: context['i'] = i context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 7aa21cd..856b376 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -84,7 +84,7 @@ def get_property(self, command, *args, context=None): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'unit': + if subscriber.registration_state == 'Unregistered': context['i'] = i context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' context['spacer2'] = self.create_spacers((63,), (subscriber.registration_state,))[0] * ' ' From 74c1b6314d6ba53b6dff54b49d6b4bf378d633c9 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 28 Oct 2020 10:24:52 +0100 Subject: [PATCH 168/318] Fixed a bug with 'get CurrTemperature' --- vendors/KeyMile/accessPoints/root/rootCommandProcessor.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 8f2b740..53cc66a 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -25,12 +25,6 @@ class RootCommandProcessor(BaseCommandProcessor): from .rootManagementFunctions import fm from .rootManagementFunctions import status - def get_property(self, command, *args, context=None): - if self._validate(args, "CurrTemperature"): - context['currTemperature'] = self._model.currTemperature - context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' - self._write(self._render('currTemperature', 'login', 'base', 'get', context=context)) - def _init_access_points(self, context=None): self.access_points = ('eoam', 'fan', 'multicast', 'services', 'tdmConnections') for card in self._model.cards: @@ -105,7 +99,7 @@ def do_upload(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def get_property(self, command, *args, context=None): - scopes = ('login', 'base', 'set') + scopes = ('login', 'base', 'get') if self._validate(args, "CurrTemperature"): context['currTemperature'] = self._model.currTemperature context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' From 9c9ee503a8829c884696cef42dc01a251f9614f9 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 28 Oct 2020 12:04:12 +0100 Subject: [PATCH 169/318] Fixed a bug where the context was missing from init_accespoints() --- vendors/KeyMile/baseCommandProcessor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 4a6ea49..dbac8a0 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -367,7 +367,7 @@ def change_directory(self, path, context=None): if context['path'].split('/')[-1] in ('main', 'cfgm', 'fm', 'pm', 'status'): raise exceptions.CommandExecutionError(command=None, template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors')) - self._init_access_points() # make sure all management_functions are loaded correctly + self._init_access_points(context=context) # make sure all management_functions are loaded correctly if components[0] not in self.management_functions: raise exceptions.CommandExecutionError(command=None, template=None, From 8875a0659b53b2c29398be5277852053c411f194 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 28 Oct 2020 14:15:05 +0100 Subject: [PATCH 170/318] Refactored args_in_quotes_joiner function and fixed a bug on 'set Labels' --- .../root/unit/port/portCommandProcessor.py | 8 ++++---- vendors/KeyMile/baseCommandProcessor.py | 12 ++++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index ae27fe7..ca398cd 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -364,8 +364,8 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': - label1, label2, description = self._dissect(args, 'Labels', str, str, str) + elif self._validate(self.args_in_quotes_joiner(args=args), 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': + label1, label2, description = self._dissect(self.args_in_quotes_joiner(args=args), 'Labels', str, str, str) try: port = self.get_component() port.set_label(label1, label2, description) @@ -376,7 +376,7 @@ def set(self, command, *args, context=None): elif self._validate(args, 'Mode', str) and context['path'].split('/')[-1] == 'cfgm' and "SUE" in \ card.board_name and self.__name__ == 'port' and card.product == 'ftth': if '"' in args[1]: - mode = self.args_in_quotes_joiner((args[1],)) + _, mode = self.args_in_quotes_joiner(args=args) else: mode, = self._dissect(args, 'Mode', str) try: @@ -389,7 +389,7 @@ def set(self, command, *args, context=None): elif self._validate(args, 'Mode', str, str, str) and context['path'].split('/')[-1] == 'cfgm' and "SUE" in \ card.board_name and self.__name__ == 'port' and card.product == 'ftth': if '"' in args[1]: - mode = self.args_in_quotes_joiner(args[1:]) + _, mode = self.args_in_quotes_joiner(args=args) else: mode, = self._dissect(args, 'Mode', str) try: diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index dbac8a0..b155631 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -569,15 +569,19 @@ def _init_context(self, context=None): context['ls_EquipmentState'] = '' def args_in_quotes_joiner(self, args): - saved_args = [] + quoted_args = [] + new_args = [] save = False for i in range(len(args)): if args[i].startswith("\""): save = True if save: - saved_args.append(args[i]) + quoted_args.append(args[i]) + else: + new_args.append(args[i]) if args[i].endswith("\""): save = False - name = ' '.join(saved_args).replace("\"", "") + new_args.append(' '.join(quoted_args).replace("\"", "")) + quoted_args = [] - return name + return new_args From 2d8b2a2fc397171c0b0a383d49b741437d8c31b7 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 29 Oct 2020 14:36:39 +0100 Subject: [PATCH 171/318] Fixed a bug with CreateInterface on logports --- .../root/unit/logport/port/logportCommandProcessor.py | 6 +++--- .../root/unit/port/chan/chanCommandProcessor.py | 6 +++--- .../accessPoints/root/unit/port/portCommandProcessor.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index c4a9a61..87cc57b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -109,10 +109,10 @@ def do_createinterface(self, command, *args, context=None): new_id = int(interface.name[-1]) + 1 id = new_id if new_id > id else id try: - self._model.get_interface('name', self.component_name) + self._model.get_interface('name', self.component_name + '/' + str(id)) assert False - except exceptions.SoftboxenError as exe: - vcc = self._model.add_interface(name=self.component_name, logport_id=logport.id, vlan_profile=vlan_prof) + except exceptions.SoftboxenError: + self._model.add_interface(logport_id=logport.id, vlan_profile=vlan_prof) context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' context['id'] = str(id) # TODO: Template is unknown diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 27e1e46..6f3771c 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -102,7 +102,7 @@ def do_createinterface(self, command, *args, context=None): self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: - interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof) + interf = self._model.add_interface(chan_id=chan.id, vlan_profile=vlan_prof) context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' context['id'] = str(id) # TODO: Template is unknown @@ -129,7 +129,7 @@ def do_createinterface(self, command, *args, context=None): self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: - interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof, + interf = self._model.add_interface(chan_id=chan.id, vlan_profile=vlan_prof, vcc_profile=vcc_prof) context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' context['id'] = str(id) @@ -163,7 +163,7 @@ def do_createvcc(self, command, *args, context=None): self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: - vcc = self._model.add_interface(name=name, chan_id=chan.id, vcc_profile=vcc_prof, + vcc = self._model.add_interface(chan_id=chan.id, vcc_profile=vcc_prof, vlan_profile=vlan_prof) context['spacer1'] = self.create_spacers((63,), (str(id),))[0] * ' ' context['id'] = str(id) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index ca398cd..68c914b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -291,7 +291,7 @@ def do_createinterface(self, command, *args, context=None): self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: - interf = self._model.add_interface(name=name, port_id=port.id, vlan_profile=vlan_prof) + interf = self._model.add_interface(port_id=port.id, vlan_profile=vlan_prof) context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' context['id'] = str(id) # TODO: unknown Template From 27ff4c66702faa1c37724757127284ee7a3d1b23 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 30 Oct 2020 11:48:26 +0100 Subject: [PATCH 172/318] Implemented get IP_Address for root/cfgm and fixed a bug with prompt_end_pos --- nesi/softbox/api/models/box_models.py | 2 ++ nesi/softbox/api/schemas/box_schemas.py | 3 ++- nesi/softbox/base_resources/box.py | 18 ++++++++++++++++++ templates/KeyMile/login/base/get/ip_address.j2 | 5 +++++ .../accessPoints/root/rootCommandProcessor.py | 16 ++++++++++++++++ vendors/KeyMile/baseCommandProcessor.py | 6 ++++++ 6 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 templates/KeyMile/login/base/get/ip_address.j2 diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 9ed22a9..ed49b65 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -53,6 +53,8 @@ class Box(db.Model): description = db.Column(db.String()) hostname = db.Column(db.String(64)) mgmt_address = db.Column(db.String(32)) + default_gateway = db.Column(db.String(32), default='0.0.0.0') + net_mask = db.Column(db.String(32), default='255.255.255.0') contact_person = db.Column(db.String(), default=None, nullable=True) isam_id = db.Column(db.String(), default=None, nullable=True) isam_location = db.Column(db.String(), default=None, nullable=True) diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index 7aa238e..2d5f6e9 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -36,7 +36,8 @@ class Meta: 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'currTemperature', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'mgmt_cards', - 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') + 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', + 'net_mask', 'default_gateway', '_links') credentials = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/base_resources/box.py b/nesi/softbox/base_resources/box.py index b050b5c..006e1a5 100644 --- a/nesi/softbox/base_resources/box.py +++ b/nesi/softbox/base_resources/box.py @@ -56,6 +56,12 @@ class Box(base.Resource): mgmt_address = base.Field('mgmt_address') """Management IP address""" + net_mask = base.Field('net_mask') + """Network Mask of the device""" + + default_gateway = base.Field('default_gateway') + """Default network gateway of the device""" + software_version = base.Field('software_version') """Software Version""" @@ -75,6 +81,18 @@ def set_hostname(self, name): """Change the hostname value.""" self.update(hostname=name) + def set_mgmt_address(self, ip): + """Change the mgmt_address value.""" + self.update(mgmt_address=ip) + + def set_net_mask(self, mask): + """Change the net_mask value.""" + self.update(net_mask=mask) + + def set_default_gateway(self, gateway): + """Change the default_gateway value.""" + self.update(default_gateway=gateway) + def set_last_login(self, time): """Change last_login value.""" self.update(last_login=time) diff --git a/templates/KeyMile/login/base/get/ip_address.j2 b/templates/KeyMile/login/base/get/ip_address.j2 new file mode 100644 index 0000000..4baceff --- /dev/null +++ b/templates/KeyMile/login/base/get/ip_address.j2 @@ -0,0 +1,5 @@ + \ # ManagementInterface +{{ context.ip_address }}{{ context.spacer1 }}\ # IpAddress +{{ context.net_mask }}{{ context.spacer2 }}\ # NetworkMask +{{ context.default_gateway }}{{ context.spacer3 }}\ # DefaultGateway + diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 53cc66a..b7fe8b4 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -64,6 +64,12 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'IP_Address', str, str, str): + new_ip, net_mask, gateway = self._dissect(args, 'IP_Address', str, str, str) + + self._model.set_mgmt_address(new_ip) + self._model.set_net_mask(net_mask) + self._model.set_default_gateway(gateway) elif self._validate(args, 'test', str): ip, = self._dissect(args, 'test', str) #TODO test case @@ -104,6 +110,16 @@ def get_property(self, command, *args, context=None): context['currTemperature'] = self._model.currTemperature context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' self._write(self._render('currTemperature', *scopes, context=context)) + elif self._validate(args, 'IP_Address'): + context['ip_address'] = self._model.mgmt_address + context['spacer1'] = self.create_spacers((67,), (self._model.mgmt_address,))[0] * ' ' + + context['net_mask'] = self._model.net_mask + context['spacer2'] = self.create_spacers((67,), (self._model.net_mask,))[0] * ' ' + + context['default_gateway'] = self._model.default_gateway + context['spacer3'] = self.create_spacers((67,), (self._model.default_gateway,))[0] * ' ' + self._write(self._render('ip_address', *scopes, context=context)) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index b155631..660457a 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -220,11 +220,13 @@ def do_ls(self, command, *args, context=None): tmp_cmdproc.ls(context=context) except exceptions.CommandExecutionError: context['path'] = current_path + self.set_prompt_end_pos(context=context) raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) context['path'] = current_path + self.set_prompt_end_pos(context=context) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), @@ -490,10 +492,12 @@ def do_get(self, command, *args, context=None): tmp_cmdproc.get_property(command, prop, context=context) except exceptions.SoftboxenError: context['path'] = current_path + self.set_prompt_end_pos(context=context) raise exceptions.CommandExecutionError(template='invalid_property', template_scopes=('login', 'base', 'syntax_errors'), command=None) context['path'] = current_path + self.set_prompt_end_pos(context=context) else: try: self.get_property(command, args[0], context=context) @@ -525,10 +529,12 @@ def do_set(self, command, *args, context=None): proc.set(command, *res, context=context) except exceptions.CommandExecutionError: context['path'] = current_path + self.set_prompt_end_pos(context=context) raise exceptions.CommandExecutionError(template='syntax_error', template_scopes=('login', 'base', 'syntax_errors'), command=None) context['path'] = current_path + self.set_prompt_end_pos(context=context) elif args[0].count('/') == 0: self.set(command, *args, context=context) From 1c576c4668e398bec759799c03cecaa41a2d6218 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 30 Oct 2020 12:25:28 +0100 Subject: [PATCH 173/318] Fixed an issue with creating interfaces on non VDSL cards --- .../accessPoints/root/unit/port/chan/chanCommandProcessor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 6f3771c..bcfc07d 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -113,7 +113,7 @@ def do_createinterface(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name: + elif self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm': # vcc profile and vlan profile vlan_prof, vcc_prof = self._dissect(args, str, str) # TODO: Check if profiles := default or profile names From 5b6de4f3b4742498d9779e51232fb89090ba0198 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 30 Oct 2020 13:06:41 +0100 Subject: [PATCH 174/318] Fixed a bug with get digitmap --- vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 856b376..5f4cdc3 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -295,7 +295,7 @@ def set(self, command, *args, context=None): card.set_sip(gw, hd, int(spn), cc, ac, int(rt), int(mri), se, aim, os, int(ot), uac, uas, int(sessione)) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args[0], 'Digitmap') and \ + elif self._validate((args[0],), 'Digitmap') and \ context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): pass elif self._validate(args, 'Registrar', str, str, str, str) and \ From 3b7bf529caa233c50549307188708e71d17fced0 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 4 Nov 2020 15:25:24 +0100 Subject: [PATCH 175/318] Fixed line and melt-test templates according to real device output --- .../keymile_portgroupport.py | 2 +- .../login/base/get/line_results_device.j2 | 63 ++++++++++++++++ ...{line__results.j2 => line_results_docu.j2} | 0 .../login/base/get/melt_results_device.j2 | 71 +++++++++++++++++++ .../{melt_results.j2 => melt_results_docu.j2} | 0 .../root/unit/port/portCommandProcessor.py | 8 +-- 6 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 templates/KeyMile/login/base/get/line_results_device.j2 rename templates/KeyMile/login/base/get/{line__results.j2 => line_results_docu.j2} (100%) create mode 100644 templates/KeyMile/login/base/get/melt_results_device.j2 rename templates/KeyMile/login/base/get/{melt_results.j2 => melt_results_docu.j2} (100%) diff --git a/nesi/keymile/keymile_resources/keymile_portgroupport.py b/nesi/keymile/keymile_resources/keymile_portgroupport.py index ce52bb6..7cbf510 100644 --- a/nesi/keymile/keymile_resources/keymile_portgroupport.py +++ b/nesi/keymile/keymile_resources/keymile_portgroupport.py @@ -73,7 +73,7 @@ def set_pstnport(self, enable, registerglobal, phone, sip, proxy, codec, pstn, e self.update(enterprise_profile=enterprise) def set_isdnport(self, enable, registerglobal, regdefault, layer1, sip, proxy, codec, isdn): - """Set the pstnport""" + """Set the isdnport""" self.update(enable=enable) self.update(register_as_global=registerglobal) self.update(register_default_number_only=regdefault) diff --git a/templates/KeyMile/login/base/get/line_results_device.j2 b/templates/KeyMile/login/base/get/line_results_device.j2 new file mode 100644 index 0000000..86eceee --- /dev/null +++ b/templates/KeyMile/login/base/get/line_results_device.j2 @@ -0,0 +1,63 @@ + \ # LineTestStatus +1970-01-01T00:00:00 \ # TimeStamp +{{ context.test_state }}{{ context.spacer }}\ # State +{ \ # Results + \ # [0] # + "Foreign DC Voltage a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [1] # + "Foreign DC Voltage b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [2] # + "Foreign DC Voltage a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [3] # + "Foreign AC Voltage a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [4] # + "Foreign AC Voltage b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [5] # + "Foreign AC Voltage a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [6] # + "Isolation a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [7] # + "Isolation b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [8] # + "Resistance b-a" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [9] # + "Resistance a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [10] # + "Capacitance a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [11] # + "Capacitance b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [12] # + "Capacitance a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [13] # + "Noise" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ +} \ + diff --git a/templates/KeyMile/login/base/get/line__results.j2 b/templates/KeyMile/login/base/get/line_results_docu.j2 similarity index 100% rename from templates/KeyMile/login/base/get/line__results.j2 rename to templates/KeyMile/login/base/get/line_results_docu.j2 diff --git a/templates/KeyMile/login/base/get/melt_results_device.j2 b/templates/KeyMile/login/base/get/melt_results_device.j2 new file mode 100644 index 0000000..6eeceff --- /dev/null +++ b/templates/KeyMile/login/base/get/melt_results_device.j2 @@ -0,0 +1,71 @@ + \ # MeasurementStatus +1970-01-01T00:00:27 \ # TimeStamp +{{ context.test_state }}{{ context.spacer }}\ # State +{ \ # Results + \ # [0] # + "Foreign DC Voltage a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [1] # + "Foreign DC Voltage a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [2] # + "Foreign DC Voltage b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [3] # + "Foreign AC Voltage a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [4] # + "Foreign AC Voltage a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [5] # + "Foreign AC Voltage b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [6] # + "Resistance a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [7] # + "Resistance a-b (pos)" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [8] # + "Resistance a-b (neg)" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [9] # + "Isolation a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [10] # + "Isolation b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [11] # + "Capacitance a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [12] # + "Capacitance a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [13] # + "Capacitance b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [14] # + "PPA detected" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [15] # + "PPA Resistance" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ +} \ + diff --git a/templates/KeyMile/login/base/get/melt_results.j2 b/templates/KeyMile/login/base/get/melt_results_docu.j2 similarity index 100% rename from templates/KeyMile/login/base/get/melt_results.j2 rename to templates/KeyMile/login/base/get/melt_results_docu.j2 diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 68c914b..5fd42bf 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -101,15 +101,15 @@ def get_property(self, command, *args, context=None): self._write(text) elif self._validate((args[0],), 'LineTestResults') and context['path'].split('/')[-1] == 'status'\ and 'SUP' in card.board_name and self.__name__ == 'port': - context['spacer1'] = self.create_spacers((67,), (port.linetest_state,))[0] * ' ' + context['spacer'] = self.create_spacers((67,), (port.linetest_state,))[0] * ' ' context['test_state'] = port.linetest_state - text = self._render('line_results', *scopes, context=context) + text = self._render('line_results_device', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'MeltResults') and context['path'].split('/')[-1] == 'status'\ and card.product != 'isdn' and self.__name__ == 'port': - context['spacer1'] = self.create_spacers((67,), (port.melttest_state,))[0] * ' ' + context['spacer'] = self.create_spacers((67,), (port.melttest_state,))[0] * ' ' context['test_state'] = port.melttest_state - text = self._render('melt_results', *scopes, context=context) + text = self._render('melt_results_device', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': self.map_states(port, 'port') From 2868e0048adf4a031aaee3ffddae7fe623eda45a Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 4 Nov 2020 15:57:57 +0100 Subject: [PATCH 176/318] Fixed access to lock and unlock functions --- templates/KeyMile/login/base/get/quickloopbacktest.j2 | 2 +- .../accessPoints/root/unit/port/portCommandProcessor.py | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/templates/KeyMile/login/base/get/quickloopbacktest.j2 b/templates/KeyMile/login/base/get/quickloopbacktest.j2 index 38b4f82..126938e 100644 --- a/templates/KeyMile/login/base/get/quickloopbacktest.j2 +++ b/templates/KeyMile/login/base/get/quickloopbacktest.j2 @@ -1,3 +1,3 @@ \ # QuickLoopbackTest -{{ context.loopbacktest_state }}{{ context.spacer1 }}\ # State +{{ context.loopbacktest_state }}{{ context.spacer }}\ # State diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 5fd42bf..eb97fa2 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -95,7 +95,7 @@ def get_property(self, command, *args, context=None): self._write(text) elif self._validate((args[0],), 'QuickLoopbackTest') and context['path'].split('/')[-1] == 'status'\ and (card.product == 'isdn' or 'SUI' in card.board_name) and self.__name__ == 'port': - context['spacer1'] = self.create_spacers((67,), (port.loopbacktest_state,))[0] * ' ' + context['spacer'] = self.create_spacers((67,), (port.loopbacktest_state,))[0] * ' ' context['loopbacktest_state'] = port.loopbacktest_state text = self._render('quickloopbacktest', *scopes, context=context) self._write(text) @@ -187,8 +187,7 @@ def _init_context(self, context=None): def do_lock(self, command, *args, context=None): card = self._model.get_card('name', self.component_name.split('/')[0]) - if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ - and self.__name__ == 'port': + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and (card.board_name.startswith('SUP') or card.board_name.startswith('SUI')) and self.__name__ == 'port': try: port = self.get_component() port.lock_admin() @@ -241,8 +240,7 @@ def do_startmeltmeasurement(self, command, *args, context=None): def do_unlock(self, command, *args, context=None): card = self._model.get_card('name', self.component_name.split('/')[0]) - if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ - and self.__name__ == 'port': + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and (card.board_name.startswith('SUP') or card.board_name.startswith('SUI')) and self.__name__ == 'port': try: port = self.get_component() port.unlock_admin() From 47cf084a1dd6518424f5b1f4b8ea6eed9ed09edd Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 4 Nov 2020 16:00:29 +0100 Subject: [PATCH 177/318] Only allowing quickloopbacktest on cards of type SUIxx --- .../KeyMile/accessPoints/root/unit/port/portCommandProcessor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index eb97fa2..7449412 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -198,7 +198,7 @@ def do_lock(self, command, *args, context=None): def do_startquickloopbacktest(self, command, *args, context=None): card = self._model.get_card('name', self.component_name.split('/')[0]) - if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.board_name.startswith('SUI') \ and self.__name__ == 'port': try: port = self.get_component() From f1770caa997780e46cf18a334080ab3a8694eb49 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 10 Nov 2020 14:41:03 +0100 Subject: [PATCH 178/318] Minor changes on ftpserver and upload command structures --- .../api/schemas/keymile_box_schemas.py | 4 ++-- nesi/keymile/keymile_resources/keymile_box.py | 20 ++++++++----------- nesi/softbox/api/models/box_models.py | 7 +++---- .../accessPoints/root/rootCommandProcessor.py | 20 ------------------- vendors/KeyMile/baseCommandProcessor.py | 20 +++++++++++++++++++ 5 files changed, 33 insertions(+), 38 deletions(-) diff --git a/nesi/keymile/api/schemas/keymile_box_schemas.py b/nesi/keymile/api/schemas/keymile_box_schemas.py index de66bed..303bd0c 100644 --- a/nesi/keymile/api/schemas/keymile_box_schemas.py +++ b/nesi/keymile/api/schemas/keymile_box_schemas.py @@ -17,8 +17,8 @@ class KeyMileBoxSchema(BoxSchema): class Meta: model = Box - fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature', 'logports', 'backup_ip', 'login', - 'password', 'backup_path') + fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature', 'logports', 'ftp_server_ip', 'ftp_login', + 'ftp_password') interfaces = ma.Hyperlinks( {'_links': { diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 09f1e61..2ffdcca 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -28,18 +28,14 @@ class KeyMileBox(Box): """ currTemperature = base.Field("currTemperature") - backup_ip = base.Field("backup_ip") - login = base.Field("login") - password = base.Field("password") - backup_path = base.Field("backup_path") - - def set_backup(self, backup_ip, login, password): - self.update(backup_ip=backup_ip) - self.update(login=login) - self.update(password=password) - - def set_path(self, path): - self.update(backup_path=path) + ftp_server_ip = base.Field("backup_ip") + ftp_login = base.Field("login") + ftp_password = base.Field("password") + + def set_ftp_data(self, ftp_server_ip, login, password): + self.update(ftp_server_ip=ftp_server_ip) + self.update(ftp_login=login) + self.update(ftp_password=password) @property def channels(self): diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index ed49b65..14c60df 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -130,7 +130,6 @@ class Box(db.Model): dsl_mode = db.Column(db.Enum('tr165', 'tr129'), default='tr165') currTemperature = db.Column(db.Integer(), default=15) - backup_ip = db.Column(db.String(), default='') - login = db.Column(db.String(), default='') - password = db.Column(db.String(), default='') - backup_path = db.Column(db.String(), default='') + ftp_server_ip = db.Column(db.String(), default='') + ftp_login = db.Column(db.String(), default='') + ftp_password = db.Column(db.String(), default='') diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index b7fe8b4..6461133 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -84,26 +84,6 @@ def do_save(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def do_ftpserver(self, command, *args, context=None): - if self._validate(args, str, str, str) and context['path'].split('/')[-1] != 'cfgm': - ip, login, pw = self._dissect(args, str, str, str) - try: - self._model.set_backup(ip, login, pw) - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError(command=command) - else: - raise exceptions.CommandSyntaxError(command=command) - - def do_upload(self, command, *args, context=None): - if self._validate(args, '/cfgm/configuration', str) and context['path'].split('/')[-1] != 'cfgm': - path, = self._dissect(args, '/cfgm/configuration', str) - try: - self._model.set_path(path) - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError(command=command) - else: - raise exceptions.CommandSyntaxError(command=command) - def get_property(self, command, *args, context=None): scopes = ('login', 'base', 'get') if self._validate(args, "CurrTemperature"): diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 660457a..071caed 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -10,6 +10,7 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst +from time import sleep from nesi import exceptions from nesi.softbox.cli import base import re @@ -52,10 +53,12 @@ def on_unknown_command(self, command, *args, context=None): command_proc._parse_and_execute_command(command, context=context) except exceptions.SoftboxenError: context['path'] = current_path + self.set_prompt_end_pos(context=context) raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) context['path'] = current_path + self.set_prompt_end_pos(context=context) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), @@ -65,6 +68,23 @@ def on_unknown_command(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors'), command=None) + def do_ftpserver(self, command, *args, context=None): + if self._validate(args, str, str, str): + ip, login, pw = self._dissect(args, str, str, str) + try: + self._model.set_ftp_data(ip, login, pw) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_upload(self, command, *args, context=None): + if self._validate(args, '/cfgm/configuration', str) and context['path'].split('/')[-1] != 'cfgm': + path, = self._dissect(args, '/cfgm/configuration', str) + sleep(10) # NOTE: as of now there is no ftp server mocking + # mechanism so the only way to simulate an upload is by doing a sleep + else: + raise exceptions.CommandSyntaxError(command=command) def map_states(self, object, type): if object.admin_state == '0': From 0a42764a7e1139e35d169158d95974a1b7ab92e1 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 12 Nov 2020 14:45:22 +0100 Subject: [PATCH 179/318] Restructured code of set pstnport/isdnport --- .../port/portgroupportCommandProcessor.py | 124 +++++++----------- 1 file changed, 51 insertions(+), 73 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 795e78f..ddfc0a7 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -127,82 +127,60 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'pstnport', str, str, str, str, str, str, str, str, str) and \ - context['path'].split('/')[-1] == 'cfgm': - enable, subident, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', - str, str, str, str, str, str, str, str, str) - try: - port = self.get_component() - enable = True if enable.lower() == 'true' else False - register = True if register.lower() == 'true' else False - phone = True if phone.lower() == 'true' else False - port.set_pstnport(enable, register, phone, sip, proxy, codec, pstn, enterprise) - except exceptions.SoftboxenError: - raise exceptions.CommandExecutionError(command=command, template='invalid_property', - template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'pstnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, - str) and context['path'].split('/')[-1] == 'cfgm': - enable, number, username, password, displayname, privacy, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) - try: - port = self.get_component() - try: - subscriber = self._model.get_subscriber('number', int(number)) - subscriber.set('autorisation_user_name', username) - subscriber.set('autorisation_password', password) - subscriber.set('display_name', displayname) - subscriber.set('privacy', privacy) - except exceptions.SoftboxenError: - address = self.component_name - subscriber = self._model.add_subscriber(number=int(number), autorisation_user_name=username, - address=address, privacy=privacy, type='port', - display_name=displayname, autorisation_password=password) - pass - enable = True if enable.lower() == 'true' else False - register = True if register.lower() == 'true' else False - phone = True if phone.lower() == 'true' else False - port.set_pstnport(enable, register, phone, sip, proxy, codec, pstn, enterprise) - except exceptions.SoftboxenError as exe: - raise exceptions.CommandExecutionError(command=command, template='invalid_property', - template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'isdnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, - str) and context['path'].split('/')[-1] == 'cfgm': - enable, number, username, password, displayname, privacy, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) + elif args[0] in ('pstnport', 'isdnport') and context['path'].split('/')[-1] == 'cfgm': + enable = True if args[1].lower() == 'true' else False + number = None + username = '' + password = '' + displayname = '' + privacy = 'None' + index_end = 2 + if args[2] != '{}': + index_start = args.index('{') + index_end = args.index('}') + number = args[index_start + 1] if index_start + 1 < index_end else None + username = args[index_start + 2] if index_start + 2 < index_end else '' + password = args[index_start + 3] if index_start + 3 < index_end else '' + displayname = args[index_start + 4] if index_start + 4 < index_end else '' + privacy = args[index_start + 5] if index_start + 5 < index_end else 'None' + + register = True if args[index_end + 1].lower() == 'true' else False + try: port = self.get_component() - try: - subscriber = self._model.get_subscriber('number', int(number)) - assert subscriber.address == self.component_name - subscriber.set('autorisation_user_name', username) - subscriber.set('autorisation_password', password) - subscriber.set('display_name', displayname) - subscriber.set('privacy', privacy) - except exceptions.SoftboxenError: - address = self.component_name - subscriber = self._model.add_subscriber(number=int(number), autorisation_user_name=username, - address=address, privacy=privacy, type='port', - display_name=displayname, autorisation_password=password) + if number is not None: + try: + subscriber = self._model.get_subscriber('number', int(number)) + if username is not None: + subscriber.set('autorisation_user_name', username) + if password is not None: + subscriber.set('autorisation_password', password) + if displayname is not None: + subscriber.set('display_name', displayname) + if privacy is not None: + subscriber.set('privacy', privacy) + except exceptions.SoftboxenError: + address = self.component_name + self._model.add_subscriber(number=int(number), autorisation_user_name=username, + address=address, privacy=privacy, display_name=displayname, + autorisation_password=password, portgroupport_id=port.id) pass - except AssertionError: - raise exceptions.SoftboxenError() - enable = True if enable.lower() == 'true' else False - register = True if register.lower() == 'true' else False - regdefault = True if regdefault.lower() == 'true' else False - layer1 = True if layer1.lower() == 'true' else False - port.set_isdnport(enable, register, regdefault, layer1, sip, proxy, codec, isdnba) - except exceptions.SoftboxenError as exe: - raise exceptions.CommandExecutionError(command=command, template='invalid_property', - template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'isdnport', str, str, str, str, str, str, str, str, str) and \ - context['path'].split('/')[-1] == 'cfgm': - enable, subident, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', - str, str, str, str, str, str, str, str, str) - try: - port = self.get_component() - enable = True if enable.lower() == 'true' else False - register = True if register.lower() == 'true' else False - regdefault = True if regdefault.lower() == 'true' else False - layer1 = True if layer1.lower() == 'true' else False - port.set_isdnport(enable, register, regdefault, layer1, sip, proxy, codec, isdnba) + if args[0] == 'isdnport': + regdefault = True if args[index_end + 2].lower().lower() == 'true' else False + layer1 = True if args[index_end + 3].lower() == 'true' else False + sip = args[index_end + 4] + proxy = args[index_end + 5] + codec = args[index_end + 6] + isdnba = args[index_end + 7] + port.set_isdnport(enable, register, regdefault, layer1, sip, proxy, codec, isdnba) + elif args[0] == 'pstnport': + phone = True if args[index_end + 2].lower() == 'true' else False + sip = args[index_end + 3] + proxy = args[index_end + 4] + codec = args[index_end + 5] + pstn = args[index_end + 6] + enterprise = args[index_end + 7] + port.set_pstnport(enable, register, phone, sip, proxy, codec, pstn, enterprise) except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) From a16f97fdf9f6eb63c001533c5f768777cccb4959 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 12 Nov 2020 15:15:08 +0100 Subject: [PATCH 180/318] Changed the accepted command structure for set pstnport/isdnport --- .../port/portgroupportCommandProcessor.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index ddfc0a7..126721d 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -136,13 +136,16 @@ def set(self, command, *args, context=None): privacy = 'None' index_end = 2 if args[2] != '{}': - index_start = args.index('{') - index_end = args.index('}') - number = args[index_start + 1] if index_start + 1 < index_end else None - username = args[index_start + 2] if index_start + 2 < index_end else '' - password = args[index_start + 3] if index_start + 3 < index_end else '' - displayname = args[index_start + 4] if index_start + 4 < index_end else '' - privacy = args[index_start + 5] if index_start + 5 < index_end else 'None' + if args[2].startswith('{') and args[2].endswith('}'): + number = args[2][1:-1] + else: + index_start = args.index('{') + index_end = args.index('}') + number = args[index_start + 1] if index_start + 1 < index_end else None + username = args[index_start + 2] if index_start + 2 < index_end else '' + password = args[index_start + 3] if index_start + 3 < index_end else '' + displayname = args[index_start + 4] if index_start + 4 < index_end else '' + privacy = args[index_start + 5] if index_start + 5 < index_end else 'None' register = True if args[index_end + 1].lower() == 'true' else False From 8ec539693fd71778959888e1dc20146f4a0f87a7 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 12 Nov 2020 15:39:26 +0100 Subject: [PATCH 181/318] Removed cases from set functions --- vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py | 4 ---- .../KeyMile/accessPoints/root/multicastCommandProcessor.py | 4 ---- vendors/KeyMile/accessPoints/root/rootCommandProcessor.py | 4 ---- .../root/services/macaccessctrlCommandProcessor.py | 4 ---- .../accessPoints/root/services/packetCommandProcessor.py | 4 ---- .../accessPoints/root/services/servicesCommandProcessor.py | 4 ---- .../accessPoints/root/tdmconnectionsCommandProcessor.py | 4 ---- .../root/unit/logport/logportsCommandProcessor.py | 4 ---- .../root/unit/logport/port/logportCommandProcessor.py | 4 ---- .../root/unit/port/interface/interfaceCommandProcessor.py | 4 ---- .../root/unit/portgroup/portgroupCommandProcessor.py | 4 ---- 11 files changed, 44 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py index b93f9c8..5c9dd85 100644 --- a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py @@ -29,9 +29,5 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py index f431b36..940da1d 100644 --- a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py @@ -31,9 +31,5 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 6461133..a28f43d 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -70,10 +70,6 @@ def set(self, command, *args, context=None): self._model.set_mgmt_address(new_ip) self._model.set_net_mask(net_mask) self._model.set_default_gateway(gateway) - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py index 62a9227..995a39c 100644 --- a/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py @@ -34,10 +34,6 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - # TODO test case - return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py index 68d1d83..51173c3 100644 --- a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py @@ -31,10 +31,6 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - # TODO test case - return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py index 522103d..c2ff987 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -33,10 +33,6 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - # TODO test case - return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py index 2c3ff28..0cd0f2e 100644 --- a/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py @@ -28,9 +28,5 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return else: raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 9b16d08..acae680 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -97,9 +97,5 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - name, = self._dissect(args, 'test', str) - #todo testcase - return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 87cc57b..524347e 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -136,10 +136,6 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - # TODO test case - return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index 09b833f..012f532 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -30,10 +30,6 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index 96d132c..74fc2e6 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -44,9 +44,5 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return else: raise exceptions.CommandSyntaxError(command=command) From 3963a80201c9c07842b611b2dd676c167fd01610 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 12 Nov 2020 16:21:37 +0100 Subject: [PATCH 182/318] Added set/get VlanId command options and functionalities --- .../api/schemas/keymile_box_schemas.py | 2 +- nesi/keymile/keymile_resources/keymile_box.py | 5 +++++ nesi/softbox/api/models/box_models.py | 1 + templates/KeyMile/login/base/get/vlan_id.j2 | 3 +++ .../accessPoints/root/rootCommandProcessor.py | 19 ++++++++++++++++--- 5 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 templates/KeyMile/login/base/get/vlan_id.j2 diff --git a/nesi/keymile/api/schemas/keymile_box_schemas.py b/nesi/keymile/api/schemas/keymile_box_schemas.py index 303bd0c..55234d1 100644 --- a/nesi/keymile/api/schemas/keymile_box_schemas.py +++ b/nesi/keymile/api/schemas/keymile_box_schemas.py @@ -18,7 +18,7 @@ class KeyMileBoxSchema(BoxSchema): class Meta: model = Box fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature', 'logports', 'ftp_server_ip', 'ftp_login', - 'ftp_password') + 'ftp_password', 'network_element_management_vlan_id') interfaces = ma.Hyperlinks( {'_links': { diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 2ffdcca..18bccea 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -31,6 +31,7 @@ class KeyMileBox(Box): ftp_server_ip = base.Field("backup_ip") ftp_login = base.Field("login") ftp_password = base.Field("password") + network_element_management_vlan_id = base.Field('network_element_management_vlan_id') def set_ftp_data(self, ftp_server_ip, login, password): self.update(ftp_server_ip=ftp_server_ip) @@ -242,6 +243,10 @@ def add_srvc(self, **fields): os.path.join(self.path, 'srvcs'), **fields) + def set_vlan_id(self, vlan_id): + """Change the network element management vlan.""" + self.update(network_element_management_vlan_id=vlan_id) + class KeyMileBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 14c60df..ffd91c9 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -133,3 +133,4 @@ class Box(db.Model): ftp_server_ip = db.Column(db.String(), default='') ftp_login = db.Column(db.String(), default='') ftp_password = db.Column(db.String(), default='') + network_element_management_vlan_id = db.Column(db.Integer(), default=None) diff --git a/templates/KeyMile/login/base/get/vlan_id.j2 b/templates/KeyMile/login/base/get/vlan_id.j2 new file mode 100644 index 0000000..0d643c3 --- /dev/null +++ b/templates/KeyMile/login/base/get/vlan_id.j2 @@ -0,0 +1,3 @@ + \ # ManagementVlan +{{ context.vlan_id }}{{ context.spacer }}\ # VlanId + diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index a28f43d..091b9aa 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -64,7 +64,16 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'IP_Address', str, str, str): + elif self._validate(args, 'VlanId', str) and context['path'].split('/')[-1] == 'cfgm': + vlan_id, = self._dissect(args, 'VlanId', str) + vlan_id = int(vlan_id) + if not 1 < vlan_id < 4089: + raise exceptions.CommandExecutionError(template='syntax_error', + template_scopes=('login', 'base', 'syntax_errors'), + command=None) + + self._model.set_vlan_id(vlan_id) + elif self._validate(args, 'IP_Address', str, str, str) and context['path'].split('/')[-1] == 'cfgm': new_ip, net_mask, gateway = self._dissect(args, 'IP_Address', str, str, str) self._model.set_mgmt_address(new_ip) @@ -82,11 +91,11 @@ def do_save(self, command, *args, context=None): def get_property(self, command, *args, context=None): scopes = ('login', 'base', 'get') - if self._validate(args, "CurrTemperature"): + if self._validate(args, "CurrTemperature") and context['path'].split('/')[-1] == 'status': context['currTemperature'] = self._model.currTemperature context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' self._write(self._render('currTemperature', *scopes, context=context)) - elif self._validate(args, 'IP_Address'): + elif self._validate(args, 'IP_Address') and context['path'].split('/')[-1] == 'cfgm': context['ip_address'] = self._model.mgmt_address context['spacer1'] = self.create_spacers((67,), (self._model.mgmt_address,))[0] * ' ' @@ -96,6 +105,10 @@ def get_property(self, command, *args, context=None): context['default_gateway'] = self._model.default_gateway context['spacer3'] = self.create_spacers((67,), (self._model.default_gateway,))[0] * ' ' self._write(self._render('ip_address', *scopes, context=context)) + elif self._validate(args, 'VlanId') and context['path'].split('/')[-1] == 'cfgm': + context['vlan_id'] = self._model.network_element_management_vlan_id + context['spacer'] = self.create_spacers((67,), (context['vlan_id'],))[0] * ' ' + self._write(self._render('vlan_id', *scopes, context=context)) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) From 24fae91618f18da2ef1fb6f9d2bc7d4aa01c4aa3 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 13 Nov 2020 09:02:28 +0100 Subject: [PATCH 183/318] Removed obsolete numbers from test case filenames --- .../integration_tests/keymile/{getDslam4.txt => getDslam.txt} | 0 .../keymile/{getInventory2.txt => getInventory.txt} | 0 .../integration_tests/keymile/{getIpsx7.txt => getIpsx.txt} | 0 .../keymile/{getMonitoring3.txt => getMonitoring.txt} | 0 .../integration_tests/keymile/{getState1.txt => getState.txt} | 0 .../keymile/{getSubscriber6.txt => getSubscriber.txt} | 0 .../integration_tests/keymile/{getVoice5.txt => getVoice.txt} | 0 .../keymile/{setChannelProfile14.txt => setChannelProfile.txt} | 1 - .../keymile/{setDslProfile8.txt => setDslProfile.txt} | 0 .../keymile/{setInterface16.txt => setInterface.txt} | 0 .../integration_tests/keymile/{setIpAddr6.txt => setIpAddr.txt} | 0 .../keymile/{setportaktiv4.txt => setPortActive.txt} | 0 .../keymile/{setportdeactiv5.txt => setPortDeactive.txt} | 0 .../keymile/{setPortProfile13.txt => setPortProfile.txt} | 0 .../keymile/{setSIPDomain12.txt => setSIPDomain.txt} | 0 .../keymile/{setTraffic1.txt => setTraffic.txt} | 0 .../integration_tests/keymile/{setVCC15.txt => setVCC.txt} | 0 .../keymile/{setconfDsl2.txt => setconfDsl.txt} | 0 .../keymile/{setconfVoice9.txt => setconfVoice.txt} | 0 .../keymile/{setdeconfVoicePort11.txt => setdeconfVoicePort.txt} | 0 .../{setdeconfVoicePort17.txt => setdeconfVoicePortIsdn.txt} | 0 .../keymile/{setunconfDsl3.txt => setunconfDsl.txt} | 0 .../keymile/{testLoopback3.txt => testLoopback.txt} | 0 .../keymile/{testVoicePort2.txt => testVoicePort.txt} | 0 .../keymile/{testmelting4.txt => testmelting.txt} | 0 25 files changed, 1 deletion(-) rename test_cases/integration_tests/keymile/{getDslam4.txt => getDslam.txt} (100%) rename test_cases/integration_tests/keymile/{getInventory2.txt => getInventory.txt} (100%) rename test_cases/integration_tests/keymile/{getIpsx7.txt => getIpsx.txt} (100%) rename test_cases/integration_tests/keymile/{getMonitoring3.txt => getMonitoring.txt} (100%) rename test_cases/integration_tests/keymile/{getState1.txt => getState.txt} (100%) rename test_cases/integration_tests/keymile/{getSubscriber6.txt => getSubscriber.txt} (100%) rename test_cases/integration_tests/keymile/{getVoice5.txt => getVoice.txt} (100%) rename test_cases/integration_tests/keymile/{setChannelProfile14.txt => setChannelProfile.txt} (96%) rename test_cases/integration_tests/keymile/{setDslProfile8.txt => setDslProfile.txt} (100%) rename test_cases/integration_tests/keymile/{setInterface16.txt => setInterface.txt} (100%) rename test_cases/integration_tests/keymile/{setIpAddr6.txt => setIpAddr.txt} (100%) rename test_cases/integration_tests/keymile/{setportaktiv4.txt => setPortActive.txt} (100%) rename test_cases/integration_tests/keymile/{setportdeactiv5.txt => setPortDeactive.txt} (100%) rename test_cases/integration_tests/keymile/{setPortProfile13.txt => setPortProfile.txt} (100%) rename test_cases/integration_tests/keymile/{setSIPDomain12.txt => setSIPDomain.txt} (100%) rename test_cases/integration_tests/keymile/{setTraffic1.txt => setTraffic.txt} (100%) rename test_cases/integration_tests/keymile/{setVCC15.txt => setVCC.txt} (100%) rename test_cases/integration_tests/keymile/{setconfDsl2.txt => setconfDsl.txt} (100%) rename test_cases/integration_tests/keymile/{setconfVoice9.txt => setconfVoice.txt} (100%) rename test_cases/integration_tests/keymile/{setdeconfVoicePort11.txt => setdeconfVoicePort.txt} (100%) rename test_cases/integration_tests/keymile/{setdeconfVoicePort17.txt => setdeconfVoicePortIsdn.txt} (100%) rename test_cases/integration_tests/keymile/{setunconfDsl3.txt => setunconfDsl.txt} (100%) rename test_cases/integration_tests/keymile/{testLoopback3.txt => testLoopback.txt} (100%) rename test_cases/integration_tests/keymile/{testVoicePort2.txt => testVoicePort.txt} (100%) rename test_cases/integration_tests/keymile/{testmelting4.txt => testmelting.txt} (100%) diff --git a/test_cases/integration_tests/keymile/getDslam4.txt b/test_cases/integration_tests/keymile/getDslam.txt similarity index 100% rename from test_cases/integration_tests/keymile/getDslam4.txt rename to test_cases/integration_tests/keymile/getDslam.txt diff --git a/test_cases/integration_tests/keymile/getInventory2.txt b/test_cases/integration_tests/keymile/getInventory.txt similarity index 100% rename from test_cases/integration_tests/keymile/getInventory2.txt rename to test_cases/integration_tests/keymile/getInventory.txt diff --git a/test_cases/integration_tests/keymile/getIpsx7.txt b/test_cases/integration_tests/keymile/getIpsx.txt similarity index 100% rename from test_cases/integration_tests/keymile/getIpsx7.txt rename to test_cases/integration_tests/keymile/getIpsx.txt diff --git a/test_cases/integration_tests/keymile/getMonitoring3.txt b/test_cases/integration_tests/keymile/getMonitoring.txt similarity index 100% rename from test_cases/integration_tests/keymile/getMonitoring3.txt rename to test_cases/integration_tests/keymile/getMonitoring.txt diff --git a/test_cases/integration_tests/keymile/getState1.txt b/test_cases/integration_tests/keymile/getState.txt similarity index 100% rename from test_cases/integration_tests/keymile/getState1.txt rename to test_cases/integration_tests/keymile/getState.txt diff --git a/test_cases/integration_tests/keymile/getSubscriber6.txt b/test_cases/integration_tests/keymile/getSubscriber.txt similarity index 100% rename from test_cases/integration_tests/keymile/getSubscriber6.txt rename to test_cases/integration_tests/keymile/getSubscriber.txt diff --git a/test_cases/integration_tests/keymile/getVoice5.txt b/test_cases/integration_tests/keymile/getVoice.txt similarity index 100% rename from test_cases/integration_tests/keymile/getVoice5.txt rename to test_cases/integration_tests/keymile/getVoice.txt diff --git a/test_cases/integration_tests/keymile/setChannelProfile14.txt b/test_cases/integration_tests/keymile/setChannelProfile.txt similarity index 96% rename from test_cases/integration_tests/keymile/setChannelProfile14.txt rename to test_cases/integration_tests/keymile/setChannelProfile.txt index 52f2a2d..1697bff 100644 --- a/test_cases/integration_tests/keymile/setChannelProfile14.txt +++ b/test_cases/integration_tests/keymile/setChannelProfile.txt @@ -3,7 +3,6 @@ secret cd /unit-5/port-1/chan-1/cfgm set chanprofile profile set chanprofile default -#else cd /unit-5/port-1/chan-1/cfgm set ProfileName $profile set ProfileName default diff --git a/test_cases/integration_tests/keymile/setDslProfile8.txt b/test_cases/integration_tests/keymile/setDslProfile.txt similarity index 100% rename from test_cases/integration_tests/keymile/setDslProfile8.txt rename to test_cases/integration_tests/keymile/setDslProfile.txt diff --git a/test_cases/integration_tests/keymile/setInterface16.txt b/test_cases/integration_tests/keymile/setInterface.txt similarity index 100% rename from test_cases/integration_tests/keymile/setInterface16.txt rename to test_cases/integration_tests/keymile/setInterface.txt diff --git a/test_cases/integration_tests/keymile/setIpAddr6.txt b/test_cases/integration_tests/keymile/setIpAddr.txt similarity index 100% rename from test_cases/integration_tests/keymile/setIpAddr6.txt rename to test_cases/integration_tests/keymile/setIpAddr.txt diff --git a/test_cases/integration_tests/keymile/setportaktiv4.txt b/test_cases/integration_tests/keymile/setPortActive.txt similarity index 100% rename from test_cases/integration_tests/keymile/setportaktiv4.txt rename to test_cases/integration_tests/keymile/setPortActive.txt diff --git a/test_cases/integration_tests/keymile/setportdeactiv5.txt b/test_cases/integration_tests/keymile/setPortDeactive.txt similarity index 100% rename from test_cases/integration_tests/keymile/setportdeactiv5.txt rename to test_cases/integration_tests/keymile/setPortDeactive.txt diff --git a/test_cases/integration_tests/keymile/setPortProfile13.txt b/test_cases/integration_tests/keymile/setPortProfile.txt similarity index 100% rename from test_cases/integration_tests/keymile/setPortProfile13.txt rename to test_cases/integration_tests/keymile/setPortProfile.txt diff --git a/test_cases/integration_tests/keymile/setSIPDomain12.txt b/test_cases/integration_tests/keymile/setSIPDomain.txt similarity index 100% rename from test_cases/integration_tests/keymile/setSIPDomain12.txt rename to test_cases/integration_tests/keymile/setSIPDomain.txt diff --git a/test_cases/integration_tests/keymile/setTraffic1.txt b/test_cases/integration_tests/keymile/setTraffic.txt similarity index 100% rename from test_cases/integration_tests/keymile/setTraffic1.txt rename to test_cases/integration_tests/keymile/setTraffic.txt diff --git a/test_cases/integration_tests/keymile/setVCC15.txt b/test_cases/integration_tests/keymile/setVCC.txt similarity index 100% rename from test_cases/integration_tests/keymile/setVCC15.txt rename to test_cases/integration_tests/keymile/setVCC.txt diff --git a/test_cases/integration_tests/keymile/setconfDsl2.txt b/test_cases/integration_tests/keymile/setconfDsl.txt similarity index 100% rename from test_cases/integration_tests/keymile/setconfDsl2.txt rename to test_cases/integration_tests/keymile/setconfDsl.txt diff --git a/test_cases/integration_tests/keymile/setconfVoice9.txt b/test_cases/integration_tests/keymile/setconfVoice.txt similarity index 100% rename from test_cases/integration_tests/keymile/setconfVoice9.txt rename to test_cases/integration_tests/keymile/setconfVoice.txt diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort.txt similarity index 100% rename from test_cases/integration_tests/keymile/setdeconfVoicePort11.txt rename to test_cases/integration_tests/keymile/setdeconfVoicePort.txt diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt b/test_cases/integration_tests/keymile/setdeconfVoicePortIsdn.txt similarity index 100% rename from test_cases/integration_tests/keymile/setdeconfVoicePort17.txt rename to test_cases/integration_tests/keymile/setdeconfVoicePortIsdn.txt diff --git a/test_cases/integration_tests/keymile/setunconfDsl3.txt b/test_cases/integration_tests/keymile/setunconfDsl.txt similarity index 100% rename from test_cases/integration_tests/keymile/setunconfDsl3.txt rename to test_cases/integration_tests/keymile/setunconfDsl.txt diff --git a/test_cases/integration_tests/keymile/testLoopback3.txt b/test_cases/integration_tests/keymile/testLoopback.txt similarity index 100% rename from test_cases/integration_tests/keymile/testLoopback3.txt rename to test_cases/integration_tests/keymile/testLoopback.txt diff --git a/test_cases/integration_tests/keymile/testVoicePort2.txt b/test_cases/integration_tests/keymile/testVoicePort.txt similarity index 100% rename from test_cases/integration_tests/keymile/testVoicePort2.txt rename to test_cases/integration_tests/keymile/testVoicePort.txt diff --git a/test_cases/integration_tests/keymile/testmelting4.txt b/test_cases/integration_tests/keymile/testmelting.txt similarity index 100% rename from test_cases/integration_tests/keymile/testmelting4.txt rename to test_cases/integration_tests/keymile/testmelting.txt From 413e8ccefe924da798083823765515d9a4e185ca Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 13 Nov 2020 09:14:43 +0100 Subject: [PATCH 184/318] Fixed some integration tests --- test_cases/integration_tests/keymile/backup.txt | 4 ++++ test_cases/integration_tests/keymile/setDslProfile.txt | 3 --- test_cases/integration_tests/keymile/setconfVoice.txt | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) delete mode 100644 test_cases/integration_tests/keymile/setDslProfile.txt diff --git a/test_cases/integration_tests/keymile/backup.txt b/test_cases/integration_tests/keymile/backup.txt index 5db5c11..df2a0c5 100644 --- a/test_cases/integration_tests/keymile/backup.txt +++ b/test_cases/integration_tests/keymile/backup.txt @@ -1,3 +1,7 @@ manager secret +ftpserver 128.0.0.2 testuser testpass +cd /cfgm +save +upload /cfgm/configuration /testtftp/backups/keymilebackup.conf exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setDslProfile.txt b/test_cases/integration_tests/keymile/setDslProfile.txt deleted file mode 100644 index 5db5c11..0000000 --- a/test_cases/integration_tests/keymile/setDslProfile.txt +++ /dev/null @@ -1,3 +0,0 @@ -manager -secret -exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfVoice.txt b/test_cases/integration_tests/keymile/setconfVoice.txt index c25801f..66632b0 100644 --- a/test_cases/integration_tests/keymile/setconfVoice.txt +++ b/test_cases/integration_tests/keymile/setconfVoice.txt @@ -1,14 +1,14 @@ manager secret cd /unit-19/portgroup-1/port-1/cfgm -set pstnport true 11 true false none none none none none +set pstnport true { 11 } true false none none none none none cd /unit-19/portgroup-1/port-1/main Set Labels "ssdd" "sssd" "" cd /unit-19/port-1/main set AdministrativeStatus up Set Labels www "carrierLineId" "" cd /unit-19/portgroup-2/port-1/cfgm -set isdnport true 112 true false none none none none none +set isdnport true {112} true false none none none none none cd /unit-19/portgroup-2/port-1/main Set Labels dada "test" "" cd /unit-19/port-1/main From 01d0025d649cd8ec37ac583176442e4314bd57b4 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 18 Nov 2020 18:03:50 +0100 Subject: [PATCH 185/318] Removed credential_id from user and added user_id to credentials, several changes regarding this topic --- bootup/conf/bootstraps/create-alcatel-7360.sh | 16 ++--- bootup/conf/bootstraps/create-huawei-5623.sh | 20 +++---- .../conf/bootstraps/create-keymile-MG2500.sh | 58 +++++++++---------- nesi/softbox/api/models/box_models.py | 2 +- nesi/softbox/api/models/credential_models.py | 1 + nesi/softbox/api/models/mgmt_port_models.py | 1 + nesi/softbox/api/models/user_models.py | 3 +- nesi/softbox/api/schemas/box_schemas.py | 3 + .../softbox/api/schemas/credential_schemas.py | 2 +- nesi/softbox/api/schemas/mgmt_card_schemas.py | 4 +- nesi/softbox/api/schemas/user_schemas.py | 7 ++- nesi/softbox/base_resources/credentials.py | 1 + nesi/softbox/base_resources/user.py | 1 - test_cases/unit_tests/huawei/test_huawei.py | 2 +- vendors/Huawei/configCommandProcessor.py | 10 +--- vendors/Huawei/main.py | 2 +- 16 files changed, 70 insertions(+), 63 deletions(-) diff --git a/bootup/conf/bootstraps/create-alcatel-7360.sh b/bootup/conf/bootstraps/create-alcatel-7360.sh index a1b2009..fbad234 100755 --- a/bootup/conf/bootstraps/create-alcatel-7360.sh +++ b/bootup/conf/bootstraps/create-alcatel-7360.sh @@ -101,21 +101,21 @@ req='{ box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 -# Create login credentials at the switch (admin operation) +# Admin user req='{ - "username": "admin", - "password": "secret" + "name": "Admin" }' -admin_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) +admin_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) -# Admin user +# Create login credentials at the switch (admin operation) req='{ - "name": "admin", - "credentials_id": '$admin_credential_id' + "username": "admin", + "password": "secret", + "user_id": '$admin_id' }' -admin_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) +admin_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) # PortProfile 1 req='{ diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index fe9b521..0e8b9dc 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -123,18 +123,9 @@ req='{ box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 -# Super Admin credentials -req='{ - "username": "root", - "password": "secret" -}' - -root_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) - # Super Admin user req='{ - "name": "root", - "credentials_id": '$root_credential_id', + "name": "Root", "level": "Super", "profile": "root", "append_info": "Super Admin", @@ -145,6 +136,15 @@ req='{ root_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) +# Super Admin credentials +req='{ + "username": "root", + "password": "secret", + "user_id": '$root_id' +}' + +root_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + # Service Profile req='{ "name": "line_spectrum_1", diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index c32e56d..9a1c66a 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -79,7 +79,7 @@ req='{ "hostname": "KeyMileMG2500", "mgmt_address": "10.0.0.12", "software_version": "MG2500V800R016C00", - "network_protocol": "telnet", + "network_protocol": "ssh", "network_address": "127.0.0.1", "network_port": 9023, "uuid": "2500", @@ -88,18 +88,9 @@ req='{ box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 -# Sessionmanager credentials -req='{ - "username": "sessionmanager", - "password": "secret" -}' - -sessionmanager_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) - # Sessionmanager user req='{ - "name": "sessionmanager", - "credentials_id": '$sessionmanager_credential_id', + "name": "Session Manager", "level": "Super", "profile": "root", "append_info": "Sessionmanager", @@ -108,18 +99,18 @@ req='{ sessionmanager_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) -# Manager credentials +# Sessionmanager credentials req='{ - "username": "manager", - "password": "secret" + "username": "sessionmanager", + "password": "secret", + "user_id": '$sessionmanager_id' }' -manager_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) +sessionmanager_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) # Manager user req='{ - "name": "manager", - "credentials_id": '$manager_credential_id', + "name": "Manager", "level": "Admin", "profile": "admin", "append_info": "Manager", @@ -128,18 +119,18 @@ req='{ manager_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) -# Maintenance credentials +# Manager credentials req='{ - "username": "maintenance", - "password": "secret" + "username": "manager", + "password": "secret", + "user_id": '$manager_id' }' -maintenance_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) +manager_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) # Manager user req='{ - "name": "maintenance", - "credentials_id": '$maintenance_credential_id', + "name": "Maintenance", "level": "Operator", "profile": "operator", "append_info": "Maintenance", @@ -148,18 +139,18 @@ req='{ maintenance_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) -# Information credentials +# Maintenance credentials req='{ - "username": "information", - "password": "secret" + "username": "maintenance", + "password": "secret", + "user_id": '$maintenance_id' }' -information_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) +maintenance_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) # Manager user req='{ - "name": "information", - "credentials_id": '$information_credential_id', + "name": "Information", "level": "User", "profile": "commonuser", "append_info": "Information", @@ -168,6 +159,15 @@ req='{ information_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) +# Information credentials +req='{ + "username": "information", + "password": "secret", + "user_id": '$information_id' +}' + +information_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + ### Nto1-Service-1 ### # Create a physical port at the network device (admin operation) diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index ffd91c9..4e39385 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -63,7 +63,7 @@ class Box(db.Model): credentials = db.relationship('Credential', backref='Box', lazy='dynamic') credential_details = db.relationship('Credential', backref='credentials', lazy='dynamic') users = db.relationship('User', backref='Box', lazy='dynamic') - + user_details = db.relationship('User', backref='users', lazy='dynamic') subracks = db.relationship('Subrack', backref='Box', lazy='dynamic') subrack_details = db.relationship('Subrack', backref='subracks', lazy='dynamic') cards = db.relationship('Card', backref='Box', lazy='dynamic') diff --git a/nesi/softbox/api/models/credential_models.py b/nesi/softbox/api/models/credential_models.py index 7271d64..242d925 100644 --- a/nesi/softbox/api/models/credential_models.py +++ b/nesi/softbox/api/models/credential_models.py @@ -17,6 +17,7 @@ class Credential(db.Model): id = db.Column(db.Integer(), primary_key=True) protocol = db.Column( db.Enum('password'), nullable=False, default='password') + user_id = db.Column(db.Integer, db.ForeignKey('user.id')) username = db.Column(db.String(64), nullable=True) password = db.Column(db.String(32), nullable=True) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) diff --git a/nesi/softbox/api/models/mgmt_port_models.py b/nesi/softbox/api/models/mgmt_port_models.py index eb1b56e..85ca3ca 100644 --- a/nesi/softbox/api/models/mgmt_port_models.py +++ b/nesi/softbox/api/models/mgmt_port_models.py @@ -12,6 +12,7 @@ # License: https://github.com/inexio/NESi/LICENSE.rst from nesi.softbox.api import db + class MgmtPort(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) diff --git a/nesi/softbox/api/models/user_models.py b/nesi/softbox/api/models/user_models.py index 2add0be..860ed31 100644 --- a/nesi/softbox/api/models/user_models.py +++ b/nesi/softbox/api/models/user_models.py @@ -9,6 +9,7 @@ # - Alexander Dincher # # License: https://github.com/inexio/NESi/LICENSE.rst +from .credential_models import Credential from nesi.softbox.api import db @@ -17,7 +18,7 @@ class User(db.Model): id = db.Column(db.Integer(), primary_key=True) box_id = db.Column(db.Integer(), db.ForeignKey('box.id')) - credentials_id = db.Column(db.Integer(), db.ForeignKey('credential.id')) + credential_details = db.relationship('Credential', backref='User', lazy='dynamic') name = db.Column(db.String(), default='user') level = db.Column(db.Enum('Super', 'Admin', 'Operator', 'User'), default='User') status = db.Column(db.Enum('Online', 'Offline'), default='Offline') diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index 2d5f6e9..62f6fe3 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -17,6 +17,7 @@ from ..schemas.credential_schemas import CredentialsSchema from ..schemas.vlan_schemas import VlansSchema from ..schemas.portprofile_schemas import PortProfilesSchema +from ..schemas.user_schemas import UsersSchema class RootSchema(ma.ModelSchema): @@ -49,6 +50,8 @@ class Meta: {'_links': { 'self': ma.URLFor('show_users', box_id='')}}) + user_details = ma.Nested(UsersSchema.UserSchema, many=True) + subracks = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_subracks', box_id='')}}) diff --git a/nesi/softbox/api/schemas/credential_schemas.py b/nesi/softbox/api/schemas/credential_schemas.py index 7259d53..c81a5a7 100644 --- a/nesi/softbox/api/schemas/credential_schemas.py +++ b/nesi/softbox/api/schemas/credential_schemas.py @@ -18,7 +18,7 @@ class CredentialSchema(ma.ModelSchema): class Meta: model = Credential fields = ('id', 'protocol', 'credential', 'username', 'password', - 'box', 'box_id', '_links') + 'box', 'box_id', 'user_id', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/mgmt_card_schemas.py b/nesi/softbox/api/schemas/mgmt_card_schemas.py index c03f1c5..e455a6f 100644 --- a/nesi/softbox/api/schemas/mgmt_card_schemas.py +++ b/nesi/softbox/api/schemas/mgmt_card_schemas.py @@ -40,7 +40,9 @@ class Meta: class MgmtCardSchema(ma.ModelSchema): class Meta: model = MgmtCard - fields = ('id', 'name', '_links') + fields = ('id', 'name', 'operational_state', 'mgmt_ports', '_links') + + mgmt_ports = ma.Nested(MgmtPortsSchema.MgmtPortSchema, many=True) _links = ma.Hyperlinks( {'self': ma.URLFor( diff --git a/nesi/softbox/api/schemas/user_schemas.py b/nesi/softbox/api/schemas/user_schemas.py index 6341cd0..b574ef6 100644 --- a/nesi/softbox/api/schemas/user_schemas.py +++ b/nesi/softbox/api/schemas/user_schemas.py @@ -12,12 +12,15 @@ from nesi.softbox.api import ma from ..models.user_models import User +from ..schemas.credential_schemas import CredentialsSchema class UserSchema(ma.ModelSchema): class Meta: model = User - fields = ('id', 'box', 'box_id', 'credentials_id', 'name', '_links') + fields = ('id', 'box', 'box_id', 'credential_details', 'name', '_links') + + credential_details = ma.Nested(CredentialsSchema.CredentialSchema, many=True) box = ma.Hyperlinks( {'_links': { @@ -35,7 +38,7 @@ class Meta: class UserSchema(ma.ModelSchema): class Meta: model = User - fields = ('id', 'name', '_links') + fields = ('id', 'name', 'status', '_links') _links = ma.Hyperlinks( {'self': ma.URLFor( diff --git a/nesi/softbox/base_resources/credentials.py b/nesi/softbox/base_resources/credentials.py index dc48bd6..271f97d 100644 --- a/nesi/softbox/base_resources/credentials.py +++ b/nesi/softbox/base_resources/credentials.py @@ -21,6 +21,7 @@ class Credentials(base.Resource): """Represent user credentials.""" id = base.Field('id') + user_id = base.Field('user_id') protocol = base.Field('protocol') username = base.Field('username') password = base.Field('password') diff --git a/nesi/softbox/base_resources/user.py b/nesi/softbox/base_resources/user.py index a82a0eb..a8368a2 100644 --- a/nesi/softbox/base_resources/user.py +++ b/nesi/softbox/base_resources/user.py @@ -20,7 +20,6 @@ class User(base.Resource): """Represents a logical User resource""" id = base.Field('id') - credentials_id = base.Field('credentials_id') name = base.Field('name') diff --git a/test_cases/unit_tests/huawei/test_huawei.py b/test_cases/unit_tests/huawei/test_huawei.py index dc2d5e9..41989b7 100644 --- a/test_cases/unit_tests/huawei/test_huawei.py +++ b/test_cases/unit_tests/huawei/test_huawei.py @@ -192,7 +192,7 @@ def test_service_vlan(self): assert True def test_user(self): - user = self.model.get_user("name", 'root') + user = self.model.get_user("name", 'Root') assert user.lock_status == 'Unlocked' user.lock() assert user.lock_status == 'Locked' diff --git a/vendors/Huawei/configCommandProcessor.py b/vendors/Huawei/configCommandProcessor.py index b948005..bc4fb7b 100644 --- a/vendors/Huawei/configCommandProcessor.py +++ b/vendors/Huawei/configCommandProcessor.py @@ -962,19 +962,15 @@ def do_terminal(self, command, *args, context=None): info = self.user_input(" User's Appended Info(<=30 chars):", False, 30) box = self._model - box.add_credentials(username=login, password=password) - try: - creds = self._model.get_credentials('username', login) - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError(command=command) - - box.add_user(name=login, credentials_id=creds.id, level=lvl, profile=profile, reenter_num=reenter_num, + box.add_user(name=login, level=lvl, profile=profile, reenter_num=reenter_num, reenter_num_temp=reenter_num, append_info=info, lock_status='Unlocked') try: user = self._model.get_user('name', login) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) + box.add_credentials(username=login, password=password, user_id=user.id) + text = self._render('user_created', context=context) self._write(text) diff --git a/vendors/Huawei/main.py b/vendors/Huawei/main.py index a93ce3f..ae00fd4 100644 --- a/vendors/Huawei/main.py +++ b/vendors/Huawei/main.py @@ -43,7 +43,7 @@ def on_unknown_command(self, command, *args, context=None): for creds in self._model.credentials: if creds.username == username and creds.password == password: - user = self._model.get_user('credentials_id', creds.id) + user = self._model.get_user('id', creds.user_id) if user.lock_status == 'Locked': text = self._render('user_locked', context=context) self._write(text) From a8f6acf7067ee4a9ea8ee42faffd998ce36daa9c Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 19 Nov 2020 08:57:29 +0100 Subject: [PATCH 186/318] Added user_details to box fields --- nesi/softbox/api/schemas/box_schemas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index 62f6fe3..eb5b802 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -36,7 +36,7 @@ class Meta: 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', 'mgmt_ports', 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'currTemperature', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', - 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'mgmt_cards', + 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'user_details', 'portgroupports', 'mgmt_cards', 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', 'net_mask', 'default_gateway', '_links') From f598a336ebc527b18de5f49da3073c28efe6399b Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 20 Nov 2020 10:01:16 +0100 Subject: [PATCH 187/318] Changes according to UI --- bootup/conf/bootstraps/create-huawei-5623.sh | 2 +- bootup/conf/bootstraps/create-keymile-MG2500.sh | 10 +++++----- nesi/huawei/api/schemas/huawei_user_schemas.py | 4 ++-- nesi/huawei/huawei_resources/huawei_user.py | 10 ++++------ nesi/softbox/api/models/user_models.py | 4 ++-- nesi/softbox/api/schemas/user_schemas.py | 2 +- nesi/softbox/base_resources/user.py | 2 ++ test_cases/unit_tests/huawei/test_huawei.py | 12 ++++++------ vendors/Huawei/baseMixIn.py | 2 +- vendors/Huawei/configCommandProcessor.py | 8 ++++---- vendors/Huawei/diagnoseCommandProcessor.py | 4 ++-- vendors/Huawei/enableCommandProcessor.py | 6 +++--- vendors/Huawei/huaweiBaseCommandProcessor.py | 3 ++- vendors/Huawei/main.py | 2 +- vendors/Huawei/userViewCommandProcessor.py | 2 +- 15 files changed, 37 insertions(+), 36 deletions(-) diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 0e8b9dc..a95a429 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -131,7 +131,7 @@ req='{ "append_info": "Super Admin", "reenter_num": 3, "reenter_num_temp": 3, - "lock_status": "Unlocked" + "lock_status": "unlocked" }' root_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 9a1c66a..f87a252 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -79,7 +79,7 @@ req='{ "hostname": "KeyMileMG2500", "mgmt_address": "10.0.0.12", "software_version": "MG2500V800R016C00", - "network_protocol": "ssh", + "network_protocol": "telnet", "network_address": "127.0.0.1", "network_port": 9023, "uuid": "2500", @@ -94,7 +94,7 @@ req='{ "level": "Super", "profile": "root", "append_info": "Sessionmanager", - "lock_status": "Unlocked" + "lock_status": "unlocked" }' sessionmanager_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) @@ -114,7 +114,7 @@ req='{ "level": "Admin", "profile": "admin", "append_info": "Manager", - "lock_status": "Unlocked" + "lock_status": "unlocked" }' manager_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) @@ -134,7 +134,7 @@ req='{ "level": "Operator", "profile": "operator", "append_info": "Maintenance", - "lock_status": "Unlocked" + "lock_status": "unlocked" }' maintenance_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) @@ -154,7 +154,7 @@ req='{ "level": "User", "profile": "commonuser", "append_info": "Information", - "lock_status": "Unlocked" + "lock_status": "unlocked" }' information_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) diff --git a/nesi/huawei/api/schemas/huawei_user_schemas.py b/nesi/huawei/api/schemas/huawei_user_schemas.py index 2ab3e86..4264e1a 100644 --- a/nesi/huawei/api/schemas/huawei_user_schemas.py +++ b/nesi/huawei/api/schemas/huawei_user_schemas.py @@ -4,5 +4,5 @@ class HuaweiUserSchema(UserSchema): class Meta: model = User - fields = UserSchema.Meta.fields + ('level', 'status', 'profile', 'append_info', 'reenter_num', - 'reenter_num_temp', 'lock_status') + fields = UserSchema.Meta.fields + ('level', 'profile', 'append_info', 'reenter_num', + 'reenter_num_temp') diff --git a/nesi/huawei/huawei_resources/huawei_user.py b/nesi/huawei/huawei_resources/huawei_user.py index 090f2cf..d3acc6b 100644 --- a/nesi/huawei/huawei_resources/huawei_user.py +++ b/nesi/huawei/huawei_resources/huawei_user.py @@ -20,24 +20,22 @@ class HuaweiUser(User): """Represents a logical User resource""" level = base.Field('level') - status = base.Field('status') profile = base.Field('profile') append_info = base.Field('append_info') reenter_num = base.Field('reenter_num') reenter_num_temp = base.Field('reenter_num_temp') - lock_status = base.Field('lock_status') def set_online(self): - self.update(status='Online') + self.update(status='online') def set_offline(self): - self.update(status='Offline') + self.update(status='offline') def lock(self): - self.update(lock_status='Locked') + self.update(lock_status='locked') def unlock(self): - self.update(lock_status='Unlocked') + self.update(lock_status='unlocked') def set_reenter_num_temp(self, num): self.update(reenter_num_temp=num) diff --git a/nesi/softbox/api/models/user_models.py b/nesi/softbox/api/models/user_models.py index 860ed31..aef11d0 100644 --- a/nesi/softbox/api/models/user_models.py +++ b/nesi/softbox/api/models/user_models.py @@ -21,9 +21,9 @@ class User(db.Model): credential_details = db.relationship('Credential', backref='User', lazy='dynamic') name = db.Column(db.String(), default='user') level = db.Column(db.Enum('Super', 'Admin', 'Operator', 'User'), default='User') - status = db.Column(db.Enum('Online', 'Offline'), default='Offline') + status = db.Column(db.Enum('online', 'offline'), default='offline') profile = db.Column(db.Enum('root', 'admin', 'operator', 'commonuser'), default='commonuser') append_info = db.Column(db.String(), default='-----') reenter_num = db.Column(db.Integer(), default=3) reenter_num_temp = db.Column(db.Integer(), default=3) - lock_status = db.Column(db.Enum('Locked', 'Unlocked'), default='Unlocked') + lock_status = db.Column(db.Enum('locked', 'unlocked'), default='unlocked') diff --git a/nesi/softbox/api/schemas/user_schemas.py b/nesi/softbox/api/schemas/user_schemas.py index b574ef6..6bd71c0 100644 --- a/nesi/softbox/api/schemas/user_schemas.py +++ b/nesi/softbox/api/schemas/user_schemas.py @@ -18,7 +18,7 @@ class UserSchema(ma.ModelSchema): class Meta: model = User - fields = ('id', 'box', 'box_id', 'credential_details', 'name', '_links') + fields = ('id', 'box', 'box_id', 'credential_details', 'name', 'status', 'lock_status', '_links') credential_details = ma.Nested(CredentialsSchema.CredentialSchema, many=True) diff --git a/nesi/softbox/base_resources/user.py b/nesi/softbox/base_resources/user.py index a8368a2..9e13703 100644 --- a/nesi/softbox/base_resources/user.py +++ b/nesi/softbox/base_resources/user.py @@ -21,6 +21,8 @@ class User(base.Resource): id = base.Field('id') name = base.Field('name') + status = base.Field('status') + lock_status = base.Field('lock_status') class UserCollection(base.ResourceCollection): diff --git a/test_cases/unit_tests/huawei/test_huawei.py b/test_cases/unit_tests/huawei/test_huawei.py index 41989b7..e836525 100644 --- a/test_cases/unit_tests/huawei/test_huawei.py +++ b/test_cases/unit_tests/huawei/test_huawei.py @@ -193,11 +193,11 @@ def test_service_vlan(self): def test_user(self): user = self.model.get_user("name", 'Root') - assert user.lock_status == 'Unlocked' + assert user.lock_status == 'unlocked' user.lock() - assert user.lock_status == 'Locked' + assert user.lock_status == 'locked' user.unlock() - assert user.lock_status == 'Unlocked' + assert user.lock_status == 'unlocked' assert user.reenter_num_temp == 3 user.set_reenter_num_temp(1) @@ -208,11 +208,11 @@ def test_user(self): except exceptions.SoftboxenError: assert True - assert user.status == 'Offline' + assert user.status == 'offline' user.set_online() - assert user.status == 'Online' + assert user.status == 'online' user.set_offline() - assert user.status == 'Offline' + assert user.status == 'offline' def test_vlan(self): vlan = self.model.get_vlan('number', 2620) diff --git a/vendors/Huawei/baseMixIn.py b/vendors/Huawei/baseMixIn.py index 2c80975..b1a8035 100644 --- a/vendors/Huawei/baseMixIn.py +++ b/vendors/Huawei/baseMixIn.py @@ -34,7 +34,7 @@ def do_config(self, command, *args, context=None): try: - admin = self._model.get_user('status', 'Online') + admin = self._model.get_user('status', 'online') assert admin.level != 'User' except (exceptions.SoftboxenError, AssertionError): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/Huawei/configCommandProcessor.py b/vendors/Huawei/configCommandProcessor.py index bc4fb7b..bf18286 100644 --- a/vendors/Huawei/configCommandProcessor.py +++ b/vendors/Huawei/configCommandProcessor.py @@ -888,7 +888,7 @@ def do_system(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_terminal(self, command, *args, context=None): - creating_user = self._model.get_user('status', 'Online') + creating_user = self._model.get_user('status', 'online') if creating_user.level != 'Super' and creating_user.level != 'Admin': raise exceptions.CommandSyntaxError(command=command) if self._validate(args, 'user', 'name'): @@ -963,7 +963,7 @@ def do_terminal(self, command, *args, context=None): box = self._model box.add_user(name=login, level=lvl, profile=profile, reenter_num=reenter_num, - reenter_num_temp=reenter_num, append_info=info, lock_status='Unlocked') + reenter_num_temp=reenter_num, append_info=info, lock_status='unlocked') try: user = self._model.get_user('name', login) except exceptions.SoftboxenError: @@ -991,11 +991,11 @@ def do_terminal(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - if locked_user.lock_status == 'Locked': + if locked_user.lock_status == 'locked': locked_user.set_reenter_num_temp(locked_user.reenter_num) locked_user.unlock() return - elif locked_user.lock_status == 'Unlocked': + elif locked_user.lock_status == 'unlocked': text = self._render('user_already_unlocked', context=context) self._write(text) else: diff --git a/vendors/Huawei/diagnoseCommandProcessor.py b/vendors/Huawei/diagnoseCommandProcessor.py index 911369a..8df1c24 100644 --- a/vendors/Huawei/diagnoseCommandProcessor.py +++ b/vendors/Huawei/diagnoseCommandProcessor.py @@ -108,7 +108,7 @@ def on_unknown_command(self, command, *args, context=None): def do_switch(self, command, *args, context=None): if self._validate(args, 'vdsl', 'mode', 'to', str): - user = self._model.get_user('status', 'Online') + user = self._model.get_user('status', 'online') if user.level != 'Super': raise exceptions.CommandSyntaxError(command=command) @@ -166,7 +166,7 @@ def do_switch(self, command, *args, context=None): self.on_cycle(context=context) time.sleep(10) self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) - user = self._model.get_user('status', 'Online') + user = self._model.get_user('status', 'online') user.set_offline() exc = exceptions.TerminalExitError() exc.return_to = 'sysreboot' diff --git a/vendors/Huawei/enableCommandProcessor.py b/vendors/Huawei/enableCommandProcessor.py index e7d93b4..bbca42d 100644 --- a/vendors/Huawei/enableCommandProcessor.py +++ b/vendors/Huawei/enableCommandProcessor.py @@ -33,7 +33,7 @@ def do_quit(self, command, *args, context=None): answer = self.user_input("Are you sure to log out? (y/n)[n]:", False, 1) if answer == "y": self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) - user = self._model.get_user('status', 'Online') + user = self._model.get_user('status', 'online') user.set_offline() self._model.enable_smart() self._model.enable_interactive() @@ -54,7 +54,7 @@ def do_config(self, command, *args, context=None): from .configCommandProcessor import ConfigCommandProcessor try: - admin = self._model.get_user('status', 'Online') + admin = self._model.get_user('status', 'online') assert admin.level != 'User' except (exceptions.SoftboxenError, AssertionError): raise exceptions.CommandSyntaxError(command=command) @@ -250,7 +250,7 @@ def do_reboot(self, command, *args, context=None): self.on_cycle(context=context) time.sleep(10) self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) - user = self._model.get_user('status', 'Online') + user = self._model.get_user('status', 'online') user.set_offline() exc = exceptions.TerminalExitError() exc.return_to = 'sysreboot' diff --git a/vendors/Huawei/huaweiBaseCommandProcessor.py b/vendors/Huawei/huaweiBaseCommandProcessor.py index 572ebe0..b09a18d 100644 --- a/vendors/Huawei/huaweiBaseCommandProcessor.py +++ b/vendors/Huawei/huaweiBaseCommandProcessor.py @@ -587,7 +587,7 @@ def display_terminal_user(self, command, context): user_counter = 0 try: - exec_user = self._model.get_user('status', 'Online') + exec_user = self._model.get_user('status', 'online') except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -610,6 +610,7 @@ def display_terminal_user(self, command, context): context['spacer4'] = self.create_spacers((1,), ('',))[0] * ' ' context['spacer5'] = self.create_spacers((16,), (user.profile,))[0] * ' ' + user.status = user.status.capitalize() text += self._render('display_terminal_user_all_middle', context=dict(context, user=user)) user_counter += 1 diff --git a/vendors/Huawei/main.py b/vendors/Huawei/main.py index ae00fd4..e7dda0f 100644 --- a/vendors/Huawei/main.py +++ b/vendors/Huawei/main.py @@ -44,7 +44,7 @@ def on_unknown_command(self, command, *args, context=None): for creds in self._model.credentials: if creds.username == username and creds.password == password: user = self._model.get_user('id', creds.user_id) - if user.lock_status == 'Locked': + if user.lock_status == 'locked': text = self._render('user_locked', context=context) self._write(text) raise exceptions.TerminalExitError() diff --git a/vendors/Huawei/userViewCommandProcessor.py b/vendors/Huawei/userViewCommandProcessor.py index ac1a067..e1c3c95 100644 --- a/vendors/Huawei/userViewCommandProcessor.py +++ b/vendors/Huawei/userViewCommandProcessor.py @@ -42,7 +42,7 @@ def do_quit(self, command, *args, context=None): answer = self.user_input("Are you sure to log out? (y/n)[n]:", False, 1) if answer == "y": self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) - user = self._model.get_user('status', 'Online') + user = self._model.get_user('status', 'online') user.set_offline() self._model.enable_smart() self._model.enable_interactive() From 545c5dd087875ce8bbc53d4c2b03ebdcebe485d0 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 20 Nov 2020 15:15:24 +0100 Subject: [PATCH 188/318] Bugfix related to card name generation --- nesi/softbox/api/views/card_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nesi/softbox/api/views/card_views.py b/nesi/softbox/api/views/card_views.py index 9852947..1d96791 100644 --- a/nesi/softbox/api/views/card_views.py +++ b/nesi/softbox/api/views/card_views.py @@ -78,7 +78,7 @@ def new_card(box_id): else: if vendor == 'Huawei': req['name'] = "0" - if vendor == 'KeyMile': + elif vendor == 'KeyMile': if box['version'] == '2500': req['name'] = "1" elif box['version'] == '2300': From 81909b6b46a601aa8f81b1e2a953a703a93080e5 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 25 Nov 2020 13:48:58 +0100 Subject: [PATCH 189/318] Updated delete and clone box functions and limited credentials so user_id can't have multiple entries --- nesi/softbox/api/models/box_models.py | 4 ++++ nesi/softbox/api/views/box_views.py | 26 +++++++++------------- nesi/softbox/api/views/credential_views.py | 4 ++++ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 4e39385..f4d3f9c 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -34,6 +34,8 @@ from .logport_models import LogPort from .interface_models import Interface from .srvc_models import Srvc +from .service_vlan_models import ServiceVlan +from .service_port_models import ServicePort from .mgmt_card_models import MgmtCard from .mgmt_port_models import MgmtPort @@ -87,6 +89,8 @@ class Box(db.Model): portgroupports = db.relationship('PortGroupPort', backref='Box', lazy='dynamic') logports = db.relationship('LogPort', backref='Box', lazy='dynamic') srvcs = db.relationship('Srvc', backref='Box', lazy='dynamic') + service_vlans = db.relationship('ServiceVlan', backref='Box', lazy='dynamic') + service_ports = db.relationship('ServicePort', backref='Box', lazy='dynamic') board_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_instl_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_init_reporting_logging = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/views/box_views.py b/nesi/softbox/api/views/box_views.py index ba6c867..2c3a01b 100644 --- a/nesi/softbox/api/views/box_views.py +++ b/nesi/softbox/api/views/box_views.py @@ -25,6 +25,7 @@ from ..models.vlan_models import Vlan from ..models.portprofile_models import PortProfile from ..models.route_models import Route +from ..models.user_models import User from ..schemas.box_schemas import * # KNAUP @@ -185,7 +186,7 @@ def clone_components(components, component_model, reference_field=None, referenc component_mapping[component.id] = component_new.id return component_mapping - _ = clone_components(box.credentials, Credential) + clone_components(box.credentials, Credential) subrack_mapping = clone_components(box.subracks, Subrack) card_mapping = clone_components(box.cards, Card, 'subrack_id', subrack_mapping) port_mapping = clone_components(box.ports, Port, 'card_id', card_mapping) @@ -194,6 +195,8 @@ def clone_components(components, component_model, reference_field=None, referenc cpe_mapping = clone_components(box.cpes, Cpe, 'port_id', port_mapping, 'ont_port_id', ont_port_mapping) clone_components(box.cpe_ports, CpePort, 'cpe_id', cpe_mapping) clone_components(box.vlans, Vlan) + user_mapping = clone_components(box.users, User) + clone_components(box.credentials, Credential, 'user_id', user_mapping) clone_components(box.port_profiles, PortProfile) clone_components(box.routes, Route) @@ -237,21 +240,12 @@ def del_sub_components(component_collection): for component in component_collection: db.session.delete(component) - del_sub_components(box.credentials) - del_sub_components(box.subracks) - del_sub_components(box.cards) - del_sub_components(box.ports) - del_sub_components(box.cpes) - del_sub_components(box.cpe_ports) - del_sub_components(box.onts) - del_sub_components(box.ont_ports) - del_sub_components(box.vlans) - del_sub_components(box.port_profiles) - del_sub_components(box.routes) - del_sub_components(box.vlan_interfaces) - del_sub_components(box.emus) - del_sub_components(box.qos_interfaces) - del_sub_components(box.users) + for element in (box.credentials, box.subracks, box.cards, box.ports, box.cpes, box.cpe_ports, + box.onts, box.ont_ports, box.vlans, box.port_profiles, box.routes, box.vlan_interfaces, + box.emus, box.users, box.channels, box.interfaces, box.logports, box.mgmt_cards, + box.mgmt_ports, box.portgroupports, box.srvcs, box.service_ports, box.service_vlans + ): + del_sub_components(element) db.session.delete(box) db.session.commit() diff --git a/nesi/softbox/api/views/credential_views.py b/nesi/softbox/api/views/credential_views.py index 9021636..7491df6 100644 --- a/nesi/softbox/api/views/credential_views.py +++ b/nesi/softbox/api/views/credential_views.py @@ -36,6 +36,10 @@ def show_credential(box_id, id): @app.route(PREFIX + '/boxen//credentials', methods=['POST']) def new_credential(box_id): req = flask.request.json + credentials = json.loads(show_components(CredentialsSchema(), Credential, {'user_id': req['user_id']}, box_id).data.decode('utf-8'))['members'] + if len(credentials) >= 1: + return flask.Response(status=500) + response = new_component(CredentialSchema(), Credential, req, box_id) return response, 201 From ca9151c446a9ca3128479f295bb64e2db78f5a45 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 26 Nov 2020 17:36:26 +0100 Subject: [PATCH 190/318] Implemented Vendor Edgecore --- README.md | 7 +- .../conf/bootstraps/create-edgecore-xxxx.sh | 154 +++++++++++++ bootup/restapi.sh | 5 +- nesi/edgecore/api/__init__.py | 0 nesi/edgecore/api/schemas/__init__.py | 17 ++ .../api/schemas/edgecore_box_schemas.py | 24 ++ .../api/schemas/edgecore_card_schemas.py | 19 ++ .../api/schemas/edgecore_interface_schemas.py | 21 ++ .../api/schemas/edgecore_port_schemas.py | 19 ++ .../api/schemas/edgecore_user_schemas.py | 7 + .../api/schemas/edgecore_vlan_schemas.py | 19 ++ nesi/edgecore/edgecore_resources/__init__.py | 2 +- .../edgecore_resources/edgecore_box.py | 119 +++++++++- .../edgecore_resources/edgecore_card.py | 36 +++ .../edgecore_resources/edgecore_interface.py | 42 ++++ .../edgecore_resources/edgecore_port.py | 34 +++ .../edgecore_resources/edgecore_user.py | 30 +++ .../edgecore_resources/edgecore_vlan.py | 32 +++ nesi/softbox/api/models/box_models.py | 14 ++ nesi/softbox/api/models/card_models.py | 3 + nesi/softbox/api/models/interface_models.py | 10 +- nesi/softbox/api/models/port_models.py | 3 + nesi/softbox/api/models/user_models.py | 2 +- nesi/softbox/api/models/vlan_models.py | 2 +- nesi/softbox/api/schemas/user_schemas.py | 2 +- nesi/softbox/api/schemas/vlan_schemas.py | 2 +- nesi/softbox/api/views/base_views.py | 3 + nesi/softbox/api/views/interface_views.py | 26 ++- nesi/softbox/cli/base.py | 4 +- templates/EdgeCore/login/mainloop/?.j2 | 14 ++ templates/EdgeCore/login/mainloop/enable/?.j2 | 43 ++++ .../enable/config/interface/on_cycle.j2 | 1 + .../enable/config/interface/on_error.j2 | 3 + .../login/mainloop/enable/config/on_cycle.j2 | 1 + .../login/mainloop/enable/config/on_error.j2 | 3 + .../mainloop/enable/config/vlan/on_cycle.j2 | 1 + .../mainloop/enable/config/vlan/on_error.j2 | 3 + .../enable/copy_startup_config_ftp_failure.j2 | 3 + .../enable/copy_startup_config_ftp_success.j2 | 4 + .../EdgeCore/login/mainloop/enable/help.j2 | 12 + .../login/mainloop/enable/on_cycle.j2 | 1 + .../login/mainloop/enable/on_error.j2 | 3 + .../EdgeCore/login/mainloop/enable/show_?.j2 | 92 ++++++++ .../mainloop/enable/show_interface_status.j2 | 29 +++ .../enable/show_interface_switchport.j2 | 22 ++ .../enable/show_interface_transceiver.j2 | 26 +++ .../mainloop/enable/show_mac_address_table.j2 | 3 + .../enable/show_mac_address_table_entry.j2 | 2 + .../enable/show_mac_address_table_unit.j2 | 3 + .../login/mainloop/enable/show_memory.j2 | 10 + .../login/mainloop/enable/show_process_cpu.j2 | 16 ++ .../login/mainloop/enable/show_system.j2 | 28 +++ .../login/mainloop/enable_password.j2 | 2 + templates/EdgeCore/login/mainloop/help.j2 | 12 + templates/EdgeCore/login/mainloop/on_cycle.j2 | 1 + templates/EdgeCore/login/mainloop/on_enter.j2 | 24 ++ templates/EdgeCore/login/mainloop/on_error.j2 | 3 + templates/EdgeCore/login/mainloop/show_?.j2 | 17 ++ templates/EdgeCore/login/on_cycle.j2 | 0 templates/EdgeCore/login/on_enter.j2 | 1 + templates/EdgeCore/login/password.j2 | 2 + templates/EdgeCore/on_cycle.j2 | 1 + templates/EdgeCore/on_enter.j2 | 0 templates/EdgeCore/on_exit.j2 | 4 + .../integration_tests/edgecore/backup.txt | 10 + .../edgecore/configureBox7.txt | 9 + .../edgecore/configureBoxName10.txt | 8 + .../edgecore/configureClock9.txt | 10 + .../edgecore/configureInternet2.txt | 12 + .../edgecore/configureLog11.txt | 8 + .../edgecore/configureMVlan12.txt | 13 ++ .../edgecore/configurePort4.txt | 8 + .../edgecore/configureRelay13.txt | 7 + .../edgecore/configureRelayOnPort14.txt | 13 ++ .../edgecore/configureTVlan8.txt | 8 + .../edgecore/configureTVlanPort1.txt | 8 + .../edgecore/configureUVlan15.txt | 9 + .../edgecore/display_data2.txt | 8 + .../edgecore/display_information4.txt | 6 + .../edgecore/display_model3.txt | 6 + .../edgecore/display_state1.txt | 8 + .../edgecore/unconfigureInternet3.txt | 20 ++ .../edgecore/unconfigurePort5.txt | 8 + .../unit_tests/edgecore/test_edgecore.py | 91 ++++++-- vendors/EdgeCore/__init__.py | 0 vendors/EdgeCore/baseCommandProcessor.py | 74 ++++++ vendors/EdgeCore/configCommandProcessor.py | 182 +++++++++++++++ vendors/EdgeCore/enableCommandProcessor.py | 155 +++++++++++++ vendors/EdgeCore/interfaceCommandProcessor.py | 212 ++++++++++++++++++ vendors/EdgeCore/main.py | 63 ++++++ vendors/EdgeCore/userViewCommandProcessor.py | 71 ++++++ vendors/EdgeCore/vlanCommandProcessor.py | 32 +++ 92 files changed, 2067 insertions(+), 40 deletions(-) create mode 100644 bootup/conf/bootstraps/create-edgecore-xxxx.sh create mode 100644 nesi/edgecore/api/__init__.py create mode 100644 nesi/edgecore/api/schemas/__init__.py create mode 100644 nesi/edgecore/api/schemas/edgecore_box_schemas.py create mode 100644 nesi/edgecore/api/schemas/edgecore_card_schemas.py create mode 100644 nesi/edgecore/api/schemas/edgecore_interface_schemas.py create mode 100644 nesi/edgecore/api/schemas/edgecore_port_schemas.py create mode 100644 nesi/edgecore/api/schemas/edgecore_user_schemas.py create mode 100644 nesi/edgecore/api/schemas/edgecore_vlan_schemas.py create mode 100644 nesi/edgecore/edgecore_resources/edgecore_card.py create mode 100644 nesi/edgecore/edgecore_resources/edgecore_interface.py create mode 100644 nesi/edgecore/edgecore_resources/edgecore_port.py create mode 100644 nesi/edgecore/edgecore_resources/edgecore_user.py create mode 100644 nesi/edgecore/edgecore_resources/edgecore_vlan.py create mode 100644 templates/EdgeCore/login/mainloop/?.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/?.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/config/interface/on_cycle.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/config/interface/on_error.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/config/on_cycle.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/config/on_error.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/config/vlan/on_cycle.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/config/vlan/on_error.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_failure.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_success.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/help.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/on_cycle.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/on_error.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_?.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_interface_status.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_interface_switchport.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_interface_transceiver.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_mac_address_table.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_mac_address_table_entry.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_mac_address_table_unit.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_memory.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_process_cpu.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_system.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable_password.j2 create mode 100644 templates/EdgeCore/login/mainloop/help.j2 create mode 100644 templates/EdgeCore/login/mainloop/on_cycle.j2 create mode 100644 templates/EdgeCore/login/mainloop/on_enter.j2 create mode 100644 templates/EdgeCore/login/mainloop/on_error.j2 create mode 100644 templates/EdgeCore/login/mainloop/show_?.j2 create mode 100644 templates/EdgeCore/login/on_cycle.j2 create mode 100644 templates/EdgeCore/login/on_enter.j2 create mode 100644 templates/EdgeCore/login/password.j2 create mode 100644 templates/EdgeCore/on_cycle.j2 create mode 100644 templates/EdgeCore/on_enter.j2 create mode 100644 templates/EdgeCore/on_exit.j2 create mode 100644 test_cases/integration_tests/edgecore/backup.txt create mode 100644 test_cases/integration_tests/edgecore/configureBox7.txt create mode 100644 test_cases/integration_tests/edgecore/configureBoxName10.txt create mode 100644 test_cases/integration_tests/edgecore/configureClock9.txt create mode 100644 test_cases/integration_tests/edgecore/configureInternet2.txt create mode 100644 test_cases/integration_tests/edgecore/configureLog11.txt create mode 100644 test_cases/integration_tests/edgecore/configureMVlan12.txt create mode 100644 test_cases/integration_tests/edgecore/configurePort4.txt create mode 100644 test_cases/integration_tests/edgecore/configureRelay13.txt create mode 100644 test_cases/integration_tests/edgecore/configureRelayOnPort14.txt create mode 100644 test_cases/integration_tests/edgecore/configureTVlan8.txt create mode 100644 test_cases/integration_tests/edgecore/configureTVlanPort1.txt create mode 100644 test_cases/integration_tests/edgecore/configureUVlan15.txt create mode 100644 test_cases/integration_tests/edgecore/display_data2.txt create mode 100644 test_cases/integration_tests/edgecore/display_information4.txt create mode 100644 test_cases/integration_tests/edgecore/display_model3.txt create mode 100644 test_cases/integration_tests/edgecore/display_state1.txt create mode 100644 test_cases/integration_tests/edgecore/unconfigureInternet3.txt create mode 100644 test_cases/integration_tests/edgecore/unconfigurePort5.txt create mode 100644 vendors/EdgeCore/__init__.py create mode 100644 vendors/EdgeCore/baseCommandProcessor.py create mode 100644 vendors/EdgeCore/configCommandProcessor.py create mode 100644 vendors/EdgeCore/enableCommandProcessor.py create mode 100644 vendors/EdgeCore/interfaceCommandProcessor.py create mode 100644 vendors/EdgeCore/main.py create mode 100644 vendors/EdgeCore/userViewCommandProcessor.py create mode 100644 vendors/EdgeCore/vlanCommandProcessor.py diff --git a/README.md b/README.md index 53f7a13..1cb238b 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,10 @@ For more information on `softboxen` or `NESi` please refer to our local [documen ### Supported Vendors - Alcatel (nearly feature complete) - Huawei (nearly feature complete) - - Edgecore (not implemented yet) - - Keymile (work in progress) + - Edgecore (nearly feature complete) + - Keymile (nearly feature complete) - Pbn (not implemented yet) - - Zhone (not implemented yet) + - Zhone (work in progress) ### Supported network components @@ -47,6 +47,7 @@ For more information on `softboxen` or `NESi` please refer to our local [documen - ONTs - CPEs - Vlans +- Interfaces ## Download diff --git a/bootup/conf/bootstraps/create-edgecore-xxxx.sh b/bootup/conf/bootstraps/create-edgecore-xxxx.sh new file mode 100644 index 0000000..847ef39 --- /dev/null +++ b/bootup/conf/bootstraps/create-edgecore-xxxx.sh @@ -0,0 +1,154 @@ +#!/bin/bash +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst +# +# Example NESi REST API server bootstrapping +# +ENDPOINT=http://localhost:5000/nesi/v1 + +path="`dirname \"$0\"`" + +. $path/functions.sh + +#--------------------------------------------------------# +# # +# Subrack 0 # +# |---> Card 1 # +# | |-> Port 1/1 # +# | | |-> Interface 1/1 # +# # +#--------------------------------------------------------# +# # +# default Vlan 1 # +# Enable Credentials # +# Backup Credentials # +# # +#--------------------------------------------------------# + +# Create a network device (admin operation) +req='{ + "vendor": "EdgeCore", + "model": "ECS4120-28Fv2-I", + "version": "A", + "description": "EdgeCore ECS4120-28Fv2-I box", + "hostname": "ed-ge-co-re-1", + "mgmt_address": "10.0.0.12", + "software_version": "MA5623V800R016C00", + "network_protocol": "telnet", + "network_address": "127.0.0.1", + "network_port": 9023, + "dsl_mode": "tr165", + "uuid": "1111" +}' + +box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 + +# Admin user +req='{ + "name": "Admin", + "profile": "root" +}' + +admin_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) + +# Admin credentials +req='{ + "username": "admin", + "password": "secret", + "user_id": '$admin_id' +}' + +admin_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# enable user +req='{ + "name": "Enable", + "profile": "enable" +}' + +enable_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) + +# Super enable credentials +req='{ + "username": "enable", + "password": "enable", + "user_id": '$enable_id' +}' + +enable_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# backup user +req='{ + "name": "Backuo", + "profile": "backup" +}' + +backup_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) + +# Super backup credentials +req='{ + "username": "backup", + "password": "backup", + "user_id": '$backup_id' +}' + +backup_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +### Subrack 0 ### + +# Create a physical subrack at the network device (admin operation) +req='{ + "name": "", + "description": "Pseudo Subrack" +}' + +subrack_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks) + +### Unit-1 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "name": "1", + "product": "adsl" +}' + +unit_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_1', + "admin_state": "1", + "operational_state": "1" +}' + +port_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Interface-1 ### + +# Create a physical interface at the network device (admin operation) +req='{ + "port_id": '$port_1_1' +}' + +interface_3_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) + +# default Vlan +req='{ + "number": 1, + "name": "default", + "description": "The standard Vlan" +}' + +vlan_pppoe=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlans) \ No newline at end of file diff --git a/bootup/restapi.sh b/bootup/restapi.sh index 6d8dd93..aea0175 100755 --- a/bootup/restapi.sh +++ b/bootup/restapi.sh @@ -181,7 +181,8 @@ if [ $recreate_db = "yes" ]; then #bash bootup/conf/bootstraps/create-box-port-vlan.sh #bash bootup/conf/bootstraps/create-alcatel-7360.sh #bash bootup/conf/bootstraps/create-huawei-5623.sh - bash bootup/conf/bootstraps/create-keymile-MG2500.sh + #bash bootup/conf/bootstraps/create-keymile-MG2500.sh + bash bootup/conf/bootstraps/create-edgecore-xxxx.sh fi if [ $alcatel_api = "yes" ]; then @@ -194,7 +195,7 @@ if [ $keymile_api = "yes" ]; then bash bootup/conf/bootstraps/create-keymile-MG2500.sh fi if [ $edgecore_api = "yes" ]; then - bash bootup/conf/bootstraps/create-alcatel-7360.sh #work_in_progress + bash bootup/conf/bootstraps/create-edgecore-xxxx.sh fi if [ $pbn_api = "yes" ]; then bash bootup/conf/bootstraps/create-alcatel-7360.sh #work_in_progress diff --git a/nesi/edgecore/api/__init__.py b/nesi/edgecore/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nesi/edgecore/api/schemas/__init__.py b/nesi/edgecore/api/schemas/__init__.py new file mode 100644 index 0000000..04e408d --- /dev/null +++ b/nesi/edgecore/api/schemas/__init__.py @@ -0,0 +1,17 @@ +from inspect import isclass +from pkgutil import iter_modules +from pathlib import Path +from importlib import import_module + +# iterate through the modules in the current package +package_dir = Path(__file__).resolve().parent +for (_, module_name, _) in iter_modules([package_dir]): + + # import the module and iterate through its attributes + module = import_module(f"{__name__}.{module_name}") + for attribute_name in dir(module): + attribute = getattr(module, attribute_name) + + if isclass(attribute): + # Add the class to this package's variables + globals()[attribute_name] = attribute \ No newline at end of file diff --git a/nesi/edgecore/api/schemas/edgecore_box_schemas.py b/nesi/edgecore/api/schemas/edgecore_box_schemas.py new file mode 100644 index 0000000..85d2896 --- /dev/null +++ b/nesi/edgecore/api/schemas/edgecore_box_schemas.py @@ -0,0 +1,24 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.box_schemas import * + + +class EdgeCoreBoxSchema(BoxSchema): + class Meta: + model = Box + fields = BoxSchema.Meta.fields + ('management_start_address', 'management_end_address', 'logging_host', + 'loopback_detection_action', 'logging_port', 'logging_level', + 'sntp_server_ip', 'sntp_client', 'timezone_name', 'timezone_time', + 'summer_time_name', 'summer_time_region') + + diff --git a/nesi/edgecore/api/schemas/edgecore_card_schemas.py b/nesi/edgecore/api/schemas/edgecore_card_schemas.py new file mode 100644 index 0000000..5f3b4bf --- /dev/null +++ b/nesi/edgecore/api/schemas/edgecore_card_schemas.py @@ -0,0 +1,19 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.card_schemas import * + + +class EdgeCoreCardSchema(CardSchema): + class Meta: + model = Card + fields = CardSchema.Meta.fields + ('mac_address', 'admin_state', 'operational_state') diff --git a/nesi/edgecore/api/schemas/edgecore_interface_schemas.py b/nesi/edgecore/api/schemas/edgecore_interface_schemas.py new file mode 100644 index 0000000..da8e696 --- /dev/null +++ b/nesi/edgecore/api/schemas/edgecore_interface_schemas.py @@ -0,0 +1,21 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.interface_schemas import * + + +class EdgeCoreInterfaceSchema(InterfaceSchema): + class Meta: + model = Interface + fields = InterfaceSchema.Meta.fields + ('port_id', 'ingress_state', 'ingress_rate', 'egress_state', + 'egress_rate', 'vlan_membership_mode', 'native_vlan', 'allowed_vlan', + 'mac_address') diff --git a/nesi/edgecore/api/schemas/edgecore_port_schemas.py b/nesi/edgecore/api/schemas/edgecore_port_schemas.py new file mode 100644 index 0000000..b5cfe93 --- /dev/null +++ b/nesi/edgecore/api/schemas/edgecore_port_schemas.py @@ -0,0 +1,19 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.port_schemas import * + + +class EdgeCorePortSchema(PortSchema): + class Meta: + model = Port + fields = PortSchema.Meta.fields + ('mac_address', ) diff --git a/nesi/edgecore/api/schemas/edgecore_user_schemas.py b/nesi/edgecore/api/schemas/edgecore_user_schemas.py new file mode 100644 index 0000000..30f905c --- /dev/null +++ b/nesi/edgecore/api/schemas/edgecore_user_schemas.py @@ -0,0 +1,7 @@ +from nesi.softbox.api.schemas.user_schemas import * + + +class EdgecoreUserSchema(UserSchema): + class Meta: + model = User + fields = UserSchema.Meta.fields + ('profile',) diff --git a/nesi/edgecore/api/schemas/edgecore_vlan_schemas.py b/nesi/edgecore/api/schemas/edgecore_vlan_schemas.py new file mode 100644 index 0000000..fcba3da --- /dev/null +++ b/nesi/edgecore/api/schemas/edgecore_vlan_schemas.py @@ -0,0 +1,19 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.vlan_schemas import * + + +class EdgeCoreVlanSchema(VlanSchema): + class Meta: + model = Vlan + fields = VlanSchema.Meta.fields diff --git a/nesi/edgecore/edgecore_resources/__init__.py b/nesi/edgecore/edgecore_resources/__init__.py index a9a2c5b..2cc22c0 100644 --- a/nesi/edgecore/edgecore_resources/__init__.py +++ b/nesi/edgecore/edgecore_resources/__init__.py @@ -1 +1 @@ -__all__ = [] +__all__ = ["edgecore_card", "edgecore_interface", "edgecore_port", "edgecore_vlan", "edgecore_user"] diff --git a/nesi/edgecore/edgecore_resources/edgecore_box.py b/nesi/edgecore/edgecore_resources/edgecore_box.py index 47b29b7..ea2c8ce 100644 --- a/nesi/edgecore/edgecore_resources/edgecore_box.py +++ b/nesi/edgecore/edgecore_resources/edgecore_box.py @@ -9,10 +9,9 @@ # - Alexander Dincher # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.huawei.huawei_resources import * +from nesi.edgecore.edgecore_resources import * from nesi.softbox.base_resources import credentials -from nesi.softbox.base_resources import route from nesi.softbox.base_resources.box import * LOG = logging.getLogger(__name__) @@ -25,6 +24,122 @@ class EdgeCoreBox(Box): :param identity: The identity of the System resource """ # Define Edgecore Properties + management_start_address = base.Field('management_start_address') + management_end_address = base.Field('management_end_address') + logging_host = base.Field('logging_host') + logging_port = base.Field('logging_port') + logging_level = base.Field('logging_level') + loopback_detection_action = base.Field('loopback_detection_action') + sntp_server_ip = base.Field('sntp_server_ip') + sntp_client = base.Field('sntp_client') + timezone_name = base.Field('timezone_name') + timezone_time = base.Field('timezone_time') + summer_time_name = base.Field('summer_time_name') + summer_time_region = base.Field('summer_time_region') + + @property + def credentials(self): + """Return `CredentialsCollection` object.""" + return credentials.CredentialsCollection( + self._conn, base.get_sub_resource_path_by( + self, 'credentials')) + + @property + def users(self): + """Return `UserCollection` object.""" + return edgecore_user.UserCollection( + self._conn, base.get_sub_resource_path_by( + self, 'users')) + + def get_user(self, field, value): + """Get specific user object.""" + return edgecore_user.EdgecoreUserCollection( + self._conn, base.get_sub_resource_path_by(self, 'users'), + params={field: value}).find_by_field_value(field, value) + + @property + def cards(self): + """Return `CardCollection` object.""" + return edgecore_card.EdgeCoreCardCollection( + self._conn, base.get_sub_resource_path_by(self, 'cards')) + + def get_card(self, field, value): + """Get specific card object.""" + return edgecore_card.EdgeCoreCardCollection( + self._conn, base.get_sub_resource_path_by(self, 'cards'), + params={field: value}).find_by_field_value(field, value) + + def get_cards(self, field, value): + """Get all cards.""" + return edgecore_card.EdgeCoreCardCollection( + self._conn, base.get_sub_resource_path_by(self, 'cards'), + params={field: value}) + + @property + def ports(self): + """Return `PortCollection` object.""" + return edgecore_port.EdgeCorePortCollection( + self._conn, base.get_sub_resource_path_by(self, 'ports')) + + def get_port(self, field, value): + """Get specific port object.""" + return edgecore_port.EdgeCorePortCollection( + self._conn, base.get_sub_resource_path_by(self, 'ports'), + params={field: value}).find_by_field_value(field, value) + + def get_ports(self, field, value): + """Get specific port object.""" + return edgecore_port.EdgeCorePortCollection( + self._conn, base.get_sub_resource_path_by(self, 'ports'), + params={field: value}) + + @property + def interfaces(self): + """Return `InterfaceCollection` object.""" + return edgecore_interface.EdgeCoreInterfaceCollection( + self._conn, base.get_sub_resource_path_by(self, 'interfaces')) + + def get_interface(self, field, value): + """Get specific interface object.""" + return edgecore_interface.EdgeCoreInterfaceCollection( + self._conn, base.get_sub_resource_path_by(self, 'interfaces'), + params={field: value}).find_by_field_value(field, value) + + def get_interfaces(self, field, value): + """Get specific interface object.""" + return edgecore_interface.EdgeCoreInterfaceCollection( + self._conn, base.get_sub_resource_path_by(self, 'interfaces'), + params={field: value}) + + @property + def vlans(self): + """Return `VlanCollection` object.""" + return edgecore_vlan.EdgeCoreVlanCollection( + self._conn, base.get_sub_resource_path_by(self, 'vlans')) + + def get_vlan(self, field, value): + """Get specific vlan object.""" + return edgecore_vlan.EdgeCoreVlanCollection( + self._conn, base.get_sub_resource_path_by(self, 'vlans'), + params={field: value}).find_by_field_value(field, value) + + def get_vlans(self, field, value): + """Get specific vlan object.""" + return edgecore_vlan.EdgeCoreVlanCollection( + self._conn, base.get_sub_resource_path_by(self, 'vlans'), + params={field: value}) + + def add_vlan(self, **fields): + """Add new vlan.""" + edgecore_vlan.EdgeCoreVlan.create( + self._conn, + os.path.join(self.path, 'vlans'), + **fields + ) + + def set(self, field, value): + mapping = {field: value} + self.update(**mapping) class EdgeCoreBoxCollection(BoxCollection): diff --git a/nesi/edgecore/edgecore_resources/edgecore_card.py b/nesi/edgecore/edgecore_resources/edgecore_card.py new file mode 100644 index 0000000..e431f77 --- /dev/null +++ b/nesi/edgecore/edgecore_resources/edgecore_card.py @@ -0,0 +1,36 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.card import Card, CardCollection, logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class EdgeCoreCard(Card): + """Represent physical shelf resource.""" + + mac_address = base.Field('mac_address') + admin_state = base.Field('admin_state') + operational_state = base.Field('operational_state') + + def set(self, field, value): + mapping = {field: value} + self.update(**mapping) + + +class EdgeCoreCardCollection(CardCollection): + """Represent a collection of cards.""" + + @property + def _resource_type(self): + return EdgeCoreCard diff --git a/nesi/edgecore/edgecore_resources/edgecore_interface.py b/nesi/edgecore/edgecore_resources/edgecore_interface.py new file mode 100644 index 0000000..9571240 --- /dev/null +++ b/nesi/edgecore/edgecore_resources/edgecore_interface.py @@ -0,0 +1,42 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.interface import Interface, InterfaceCollection, logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class EdgeCoreInterface(Interface): + """Represent a VlanInterface resource.""" + + port_id = base.Field('port_id') + ingress_state = base.Field('ingress_state') + ingress_rate = base.Field('ingress_rate') + egress_state = base.Field('egress_state') + egress_rate = base.Field('egress_rate') + vlan_membership_mode = base.Field('vlan_membership_mode') + native_vlan = base.Field('native_vlan') + allowed_vlan = base.Field('allowed_vlan') + mac_address = base.Field('mac_address') + + def set(self, field, value): + mapping = {field: value} + self.update(**mapping) + + +class EdgeCoreInterfaceCollection(InterfaceCollection): + """Represent the collection of VlanInterfaces.""" + + @property + def _resource_type(self): + return EdgeCoreInterface diff --git a/nesi/edgecore/edgecore_resources/edgecore_port.py b/nesi/edgecore/edgecore_resources/edgecore_port.py new file mode 100644 index 0000000..f49f4b2 --- /dev/null +++ b/nesi/edgecore/edgecore_resources/edgecore_port.py @@ -0,0 +1,34 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.port import Port, PortCollection, logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class EdgeCorePort(Port): + """Represent physical port resource.""" + + mac_address = base.Field('mac_address') + + def set(self, field, value): + mapping = {field: value} + self.update(**mapping) + + +class EdgeCorePortCollection(PortCollection): + """Represent a collection of ports.""" + + @property + def _resource_type(self): + return EdgeCorePort diff --git a/nesi/edgecore/edgecore_resources/edgecore_user.py b/nesi/edgecore/edgecore_resources/edgecore_user.py new file mode 100644 index 0000000..fb56e38 --- /dev/null +++ b/nesi/edgecore/edgecore_resources/edgecore_user.py @@ -0,0 +1,30 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.user import User, UserCollection, logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class EdgecoreUser(User): + """Represents a logical User resource""" + + profile = base.Field('profile') + + +class EdgecoreUserCollection(UserCollection): + """Represent the collection of Users.""" + + @property + def _resource_type(self): + return EdgecoreUser diff --git a/nesi/edgecore/edgecore_resources/edgecore_vlan.py b/nesi/edgecore/edgecore_resources/edgecore_vlan.py new file mode 100644 index 0000000..16b90ab --- /dev/null +++ b/nesi/edgecore/edgecore_resources/edgecore_vlan.py @@ -0,0 +1,32 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.vlan import Vlan, VlanCollection, logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class EdgeCoreVlan(Vlan): + """Represent a VLAN resource.""" + + def set(self, field, value): + mapping = {field: value} + self.update(**mapping) + + +class EdgeCoreVlanCollection(VlanCollection): + """Represent the collection of VLANs.""" + + @property + def _resource_type(self): + return EdgeCoreVlan diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index f4d3f9c..223b94e 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -138,3 +138,17 @@ class Box(db.Model): ftp_login = db.Column(db.String(), default='') ftp_password = db.Column(db.String(), default='') network_element_management_vlan_id = db.Column(db.Integer(), default=None) + + #EdgeCore + management_start_address = db.Column(db.String(), default='') + management_end_address = db.Column(db.String(), default='') + logging_host = db.Column(db.String(), default='') + logging_port = db.Column(db.String(), default='') + logging_level = db.Column(db.Integer(), default=7) + loopback_detection_action = db.Column(db.String(), default='shutdown') + sntp_server_ip = db.Column(db.String(), default='None') + sntp_client = db.Column(db.Enum('Disabled', 'Enabled'), default='Disabled') + timezone_name = db.Column(db.String(), default='None') + timezone_time = db.Column(db.String(), default='None') + summer_time_name = db.Column(db.String(), default='') + summer_time_region = db.Column(db.String(), default='') diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index efbadfd..4d26ffb 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -144,3 +144,6 @@ class Card(db.Model): #digimap_domain_phone_context = db.Column(db.String(), default='') #digimap_prestrip = db.Column(db.Integer(), default=0) #digimap_prepend = db.Column(db.String(), default='') + + #Edgecore + mac_address = db.Column(db.String(), default='A8-2B-B5-7F-E3-C0') diff --git a/nesi/softbox/api/models/interface_models.py b/nesi/softbox/api/models/interface_models.py index cd68d95..e73d2f7 100644 --- a/nesi/softbox/api/models/interface_models.py +++ b/nesi/softbox/api/models/interface_models.py @@ -30,4 +30,12 @@ class Interface(db.Model): reconfiguration_allowed = db.Column(db.Enum('true', 'false'), default='true') services_connected = db.Column(db.String(), default='') - + #EdgeCore + ingress_state = db.Column(db.Enum('Disabled', 'Enabled'), default='Disabled') + ingress_rate = db.Column(db.Integer(), default=1000000) + egress_state = db.Column(db.Enum('Disabled', 'Enabled'), default='Disabled') + egress_rate = db.Column(db.Integer(), default=1000000) + vlan_membership_mode = db.Column(db.Enum('Hybrid', 'Access', 'Trunk'), default='Hybrid') + native_vlan = db.Column(db.Integer(), default=1) + allowed_vlan = db.Column(db.String(), default='1(u)') + mac_address = db.Column(db.String(), default='A8-2B-B5-7F-E3-C0') diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 6ed09a0..3136913 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -331,3 +331,6 @@ class Port(db.Model): profile4_enable = db.Column(db.Boolean(), default=False) profile4_name = db.Column(db.String(), default='') profile_mode = db.Column(db.Enum('Priority', 'ElectricalLoopLength'), default=None) + + #Edgecore + mac_address = db.Column(db.String(), default='A8-2B-B5-7F-E3-C0') \ No newline at end of file diff --git a/nesi/softbox/api/models/user_models.py b/nesi/softbox/api/models/user_models.py index aef11d0..74805e5 100644 --- a/nesi/softbox/api/models/user_models.py +++ b/nesi/softbox/api/models/user_models.py @@ -22,7 +22,7 @@ class User(db.Model): name = db.Column(db.String(), default='user') level = db.Column(db.Enum('Super', 'Admin', 'Operator', 'User'), default='User') status = db.Column(db.Enum('online', 'offline'), default='offline') - profile = db.Column(db.Enum('root', 'admin', 'operator', 'commonuser'), default='commonuser') + profile = db.Column(db.Enum('root', 'admin', 'operator', 'commonuser', 'enable', 'backup'), default='commonuser') append_info = db.Column(db.String(), default='-----') reenter_num = db.Column(db.Integer(), default=3) reenter_num_temp = db.Column(db.Integer(), default=3) diff --git a/nesi/softbox/api/models/vlan_models.py b/nesi/softbox/api/models/vlan_models.py index 13a4bc9..e9f5fd6 100644 --- a/nesi/softbox/api/models/vlan_models.py +++ b/nesi/softbox/api/models/vlan_models.py @@ -19,6 +19,7 @@ class Vlan(db.Model): name = db.Column(db.String(64), nullable=False) number = db.Column(db.Integer(), nullable=False) description = db.Column(db.String()) + mtu = db.Column(db.Integer(), default=1500) role = db.Column( db.Enum('access', 'trunk', 'native'), nullable=False, default='access') @@ -29,7 +30,6 @@ class Vlan(db.Model): egress_port = db.Column(db.String(), default='') fdb_id = db.Column(db.Integer, default=2620) shutdown = db.Column(db.Boolean(), default=False) - mtu = db.Column(db.Integer(), default=1500) access_group_in = db.Column(db.String(64), default='') access_group_out = db.Column(db.String(64), default='') ip_redirect = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/schemas/user_schemas.py b/nesi/softbox/api/schemas/user_schemas.py index 6bd71c0..fadd4e8 100644 --- a/nesi/softbox/api/schemas/user_schemas.py +++ b/nesi/softbox/api/schemas/user_schemas.py @@ -18,7 +18,7 @@ class UserSchema(ma.ModelSchema): class Meta: model = User - fields = ('id', 'box', 'box_id', 'credential_details', 'name', 'status', 'lock_status', '_links') + fields = ('id', 'box', 'box_id', 'credential_details', 'name', 'status', 'lock_status', 'profile', '_links') credential_details = ma.Nested(CredentialsSchema.CredentialSchema, many=True) diff --git a/nesi/softbox/api/schemas/vlan_schemas.py b/nesi/softbox/api/schemas/vlan_schemas.py index 49ca8d7..1620b34 100644 --- a/nesi/softbox/api/schemas/vlan_schemas.py +++ b/nesi/softbox/api/schemas/vlan_schemas.py @@ -17,7 +17,7 @@ class VlanSchema(ma.ModelSchema): class Meta: model = Vlan - fields = ('id', 'box_id', 'number', 'mtu', 'box' + fields = ('id', 'box_id', 'number', 'mtu', 'box', 'description', 'name', '_links') box = ma.Hyperlinks( diff --git a/nesi/softbox/api/views/base_views.py b/nesi/softbox/api/views/base_views.py index 4259e94..47b60df 100644 --- a/nesi/softbox/api/views/base_views.py +++ b/nesi/softbox/api/views/base_views.py @@ -21,6 +21,9 @@ from nesi.alcatel.api.schemas import * from nesi.huawei.api.schemas import * from nesi.keymile.api.schemas import * +from nesi.edgecore.api.schemas import * +from nesi.pbn.api.schemas import * +from nesi.zhone.api.schemas import * # important for other view classes from nesi.softbox.api import db diff --git a/nesi/softbox/api/views/interface_views.py b/nesi/softbox/api/views/interface_views.py index 74159f2..8d140c3 100644 --- a/nesi/softbox/api/views/interface_views.py +++ b/nesi/softbox/api/views/interface_views.py @@ -11,6 +11,7 @@ # License: https://github.com/inexio/NESi/LICENSE.rst from .base_views import * +from .box_views import show_box from ..models.port_models import Port from ..models.channel_models import Channel from ..models.logport_models import LogPort @@ -39,19 +40,24 @@ def show_interface(box_id, id): @app.route(PREFIX + '/boxen//interfaces', methods=['POST']) def new_interface(box_id): req = flask.request.json + box = json.loads(show_box(box_id)[0].data.decode('utf-8')) if 'name' not in req or req['name'] == "": - if 'port_id' in req: + if box['vendor'] == 'KeyMile': + if 'port_id' in req: + port = json.loads(show_component(Port, box_id, req['port_id']).data.decode('utf-8')) + req['name'] = port['name'] + "/" + str(len(port['interfaces']) + 1) + elif 'chan_id' in req: + channel = json.loads(show_component(Channel, box_id, req['chan_id']).data.decode('utf-8')) + req['name'] = channel['name'] + "/" + str(len(channel['interfaces']) + 1) + elif 'logport_id' in req: + logport = json.loads(show_component(LogPort, box_id, req['logport_id']).data.decode('utf-8')) + req['name'] = logport['name'] + "/" + str(len(logport['interfaces']) + 1) + else: + raise exceptions.Forbidden('can not have port and channel as parent') + elif box['vendor'] == 'EdgeCore': port = json.loads(show_component(Port, box_id, req['port_id']).data.decode('utf-8')) - req['name'] = port['name'] + "/" + str(len(port['interfaces']) + 1) - elif 'chan_id' in req: - channel = json.loads(show_component(Channel, box_id, req['chan_id']).data.decode('utf-8')) - req['name'] = channel['name'] + "/" + str(len(channel['interfaces']) + 1) - elif 'logport_id' in req: - logport = json.loads(show_component(LogPort, box_id, req['logport_id']).data.decode('utf-8')) - req['name'] = logport['name'] + "/" + str(len(logport['interfaces']) + 1) - else: - raise exceptions.Forbidden('can not have port and channel as parent') + req['name'] = port['name'] response = new_component(InterfaceSchema(), Interface, req, box_id) return response, 201 diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 1632d66..9a4566b 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -284,8 +284,8 @@ def _get_command_func(self, line): if self.case_sensitive is False: command = command.lower() - if command == self.negation: - command += "_" + args.pop(0) + #if command == self.negation: + #command += "_" + args.pop(0) command = command.replace('-', '_') diff --git a/templates/EdgeCore/login/mainloop/?.j2 b/templates/EdgeCore/login/mainloop/?.j2 new file mode 100644 index 0000000..a184270 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/?.j2 @@ -0,0 +1,14 @@ +EXEC commands: + disable Returns to normal mode from privileged mode + disconnect Terminates an SSH, Telnet, or a console connection + enable Turns on privileged commands + exit Exits from privileged EXEC mode + help Description of the interactive help system + ping Sends ICMP echo request packets to another host + ping6 Sends ICMPv6 echo request packets to another host + quit Exits a CLI session + show Shows information + terminal Terminal setting + traceroute Traces routing path + traceroute6 Traces routing path + diff --git a/templates/EdgeCore/login/mainloop/enable/?.j2 b/templates/EdgeCore/login/mainloop/enable/?.j2 new file mode 100644 index 0000000..4b455cf --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/?.j2 @@ -0,0 +1,43 @@ +EXEC commands: + auto-traffic-control Auto traffic control configuration + calendar Date and time information + clear Resets functions + configure Enters configuration mode + copy Copies from one file to another + debug Debugging functions + delete Deletes a file + dir Lists files on the file system + disable Returns to normal mode from privileged mode + disconnect Terminates an SSH, Telnet, or a console connection + dot1x Configures 802.1X port-based access control + efm Ethernet First Mile feature + enable Turns on privileged commands + erps Ethernet Ring Protection Switching + ethernet Metro Ethernet + exit Exits from privileged EXEC mode + hardware Hardware ralated functions + help Description of the interactive help system + ip Internet protocol + ipv6 IPv6 configuration commands + loopback-detection Performs loopback detection privileged operations + no Negates a command or sets its defaults + ping Sends ICMP echo request packets to another host + ping6 Sends ICMPv6 echo request packets to another host + port Configures the characteristics of the port + quit Exits a CLI session + rcommand telnet to member + reload Halts and performs a warm restart + sflow Configures sFlow + show Shows information + smart-pair Specifies a smart pair + spanning-tree Specifies spanning-tree configuration + telnet Telnet to a specified host + terminal Terminal setting + test Tests subsystem + traceroute Traces routing path + traceroute6 Traces routing path + transceiver-eeprom Access transceiver EEPROM data + watchdog Configures watchdog setting + web-auth Configures web authentication parameters + whichboot Shows which files booted on system power up + diff --git a/templates/EdgeCore/login/mainloop/enable/config/interface/on_cycle.j2 b/templates/EdgeCore/login/mainloop/enable/config/interface/on_cycle.j2 new file mode 100644 index 0000000..7496ed2 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/config/interface/on_cycle.j2 @@ -0,0 +1 @@ +{{ model.hostname }}(config-if)# diff --git a/templates/EdgeCore/login/mainloop/enable/config/interface/on_error.j2 b/templates/EdgeCore/login/mainloop/enable/config/interface/on_error.j2 new file mode 100644 index 0000000..d965dc6 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/config/interface/on_error.j2 @@ -0,0 +1,3 @@ + ^ +% Invalid input detected at '^' marker. + diff --git a/templates/EdgeCore/login/mainloop/enable/config/on_cycle.j2 b/templates/EdgeCore/login/mainloop/enable/config/on_cycle.j2 new file mode 100644 index 0000000..ece1f7f --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/config/on_cycle.j2 @@ -0,0 +1 @@ +{{ model.hostname }}(config)# diff --git a/templates/EdgeCore/login/mainloop/enable/config/on_error.j2 b/templates/EdgeCore/login/mainloop/enable/config/on_error.j2 new file mode 100644 index 0000000..d965dc6 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/config/on_error.j2 @@ -0,0 +1,3 @@ + ^ +% Invalid input detected at '^' marker. + diff --git a/templates/EdgeCore/login/mainloop/enable/config/vlan/on_cycle.j2 b/templates/EdgeCore/login/mainloop/enable/config/vlan/on_cycle.j2 new file mode 100644 index 0000000..7c17cd7 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/config/vlan/on_cycle.j2 @@ -0,0 +1 @@ +{{ model.hostname }}(config-vlan)# diff --git a/templates/EdgeCore/login/mainloop/enable/config/vlan/on_error.j2 b/templates/EdgeCore/login/mainloop/enable/config/vlan/on_error.j2 new file mode 100644 index 0000000..e13e225 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/config/vlan/on_error.j2 @@ -0,0 +1,3 @@ + ^ +% Invalid input detected at '^' marker. + diff --git a/templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_failure.j2 b/templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_failure.j2 new file mode 100644 index 0000000..639e9d9 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_failure.j2 @@ -0,0 +1,3 @@ +Failed to connect to server. +Error. + diff --git a/templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_success.j2 b/templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_success.j2 new file mode 100644 index 0000000..ff46f1d --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_success.j2 @@ -0,0 +1,4 @@ +Flash Programming started. +Flash Programming completed. +Success. + diff --git a/templates/EdgeCore/login/mainloop/enable/help.j2 b/templates/EdgeCore/login/mainloop/enable/help.j2 new file mode 100644 index 0000000..800b1a8 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/help.j2 @@ -0,0 +1,12 @@ +Help may be requested at any point in a command by entering +a question mark '?'. If nothing matches, the help list will +be empty and you must backup until entering a '?' shows the +available options. +Two styles of help are provided: +1. Full help is available when you are ready to enter a + command argument (e.g. 'show ?') and describes each possible + argument. +2. Partial help is provided when an abbreviated argument is entered + and you want to know what arguments match the input + (e.g. 'show br?'.) + diff --git a/templates/EdgeCore/login/mainloop/enable/on_cycle.j2 b/templates/EdgeCore/login/mainloop/enable/on_cycle.j2 new file mode 100644 index 0000000..d8fe528 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/on_cycle.j2 @@ -0,0 +1 @@ +{{ model.hostname }}# \ No newline at end of file diff --git a/templates/EdgeCore/login/mainloop/enable/on_error.j2 b/templates/EdgeCore/login/mainloop/enable/on_error.j2 new file mode 100644 index 0000000..d965dc6 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/on_error.j2 @@ -0,0 +1,3 @@ + ^ +% Invalid input detected at '^' marker. + diff --git a/templates/EdgeCore/login/mainloop/enable/show_?.j2 b/templates/EdgeCore/login/mainloop/enable/show_?.j2 new file mode 100644 index 0000000..036b300 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_?.j2 @@ -0,0 +1,92 @@ + access-group Access groups + access-list Access lists + accounting Uses the specified accounting list + arp Information of ARP cache + authorization Authorization configurations + auto-traffic-control Auto traffic control information + banner Banner info + bridge-ext Bridge extension information + cable-diagnostics Shows the information of cable diagnostics + calendar Date and time information + class-map Displays class maps + cluster Display cluster + debug State of each debugging option + discard Discard packet + dns DNS information + dos-protection Shows the system dos-protection summary information + dot1q-tunnel 802.1Q tunnel + dot1x 802.1X content + dying-gasp Dying gasp information + efm Ethernet First Mile feature + erps Displays ERPS configuration + ethernet Shows Metro Ethernet information + garp GARP properties + gvrp GVRP interface information + hardware Hardware ralated functions + history Shows history information + hosts Host information + interfaces Shows interface information + ip IP information + ipv6 IPv6 information + l2protocol-tunnel Layer 2 protocol tunneling configuration + lacp LACP statistics + line TTY line information + lldp LLDP + log Log records + logging Logging setting + loop Shows the information of loopback + loopback-detection Shows loopback detection information + mac MAC access list + mac-address-table Configuration of the address table + mac-vlan MAC-based VLAN information + management Shows management information + memory Memory utilization + mvr multicast VLAN registration + mvr6 IPv6 Multicast VLAN registration + network-access Shows the entries of the secure port + nlm Show notification log + ntp Network Time Protocol configuration + policy-map Displays policy maps + port Port characteristics + port-channel Port channel information + power Shows power + power-save Shows the power saving information + pppoe Displays PPPoE configuration + privilege Shows current privilege level + process Device process + protocol-vlan Protocol-VLAN information + public-key Public key information + qos Quality of Service + queue Priority queue information + radius-server RADIUS server information + reload Shows the reload settings + rmon Remote monitoring information + rspan Display status of the current RSPAN configuration + running-config Information on the running configuration + sflow Shows the sflow information + smart-pair Displays backup port information + snmp Simple Network Management Protocol configuration and + statistics + snmp-server Displays SNMP server configuration + sntp Simple Network Time Protocol configuration + spanning-tree Spanning-tree configuration + ssh Secure shell server connections + startup-config Startup system configuration + subnet-vlan IP subnet-based VLAN information + system System information + tacacs-server TACACS server information + tech-support Technical information + time-range Time range + traffic-segmentation Traffic segmentation information + transceiver-eeprom Access transceiver EEPROM data configuration + twamp TWAMP configuration, statistics and session information + udld Displays UDLD information + upgrade Shows upgrade information + users Information about users logged in + version System hardware and software versions + vlan Shows virtual LAN settings + vlan-translation VLAN translation information + voice Shows the voice VLAN information + watchdog Displays watchdog status + web-auth Shows web authentication configuration + diff --git a/templates/EdgeCore/login/mainloop/enable/show_interface_status.j2 b/templates/EdgeCore/login/mainloop/enable/show_interface_status.j2 new file mode 100644 index 0000000..456249d --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_interface_status.j2 @@ -0,0 +1,29 @@ +Information of Eth {{ context.port.name }} + Basic Information: + Port Type : 1000BASE SFP + MAC Address : {{ context.port.mac_address }} +Configuration: + Name : {{ context.port.description }} + Port Admin : {{ context.port.admin_state }} + Speed-duplex : Auto + Capabilities : 1000full + Broadcast Storm : Disabled + Broadcast Storm Limit : 500 packets/second + Multicast Storm : Disabled + Multicast Storm Limit : 262143 packets/second + Unknown Unicast Storm : Disabled + Unknown Unicast Storm Limit : 262143 packets/second + Flow Control : Disabled + VLAN Trunking : Disabled + LACP : Disabled + MAC Learning : Enabled + Link-up-down Trap : Enabled + Media Type : None + MTU : 1518 +Current Status: + Link Status : {{ context.port.operational_state }} + Operation Speed-duplex : 1000full + Flow Control Type : None + Max Frame Size : 1518 bytes (1522 bytes for tagged frames) + MAC Learning Status : Enabled + diff --git a/templates/EdgeCore/login/mainloop/enable/show_interface_switchport.j2 b/templates/EdgeCore/login/mainloop/enable/show_interface_switchport.j2 new file mode 100644 index 0000000..ccf7204 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_interface_switchport.j2 @@ -0,0 +1,22 @@ +Information of Eth {{ context.interface.name }} + Broadcast Threshold : Enabled, 500 packets/second + Multicast Threshold : Disabled + Unknown Unicast Threshold : Disabled + LACP Status : Disabled + Ingress Rate Limit : {{ context.interface.ingress_state }}, {{ context.interface.ingress_rate }} kbits/second + Egress Rate Limit : {{ context.interface.egress_state }}, {{ context.interface.egress_rate }} kbits/second + VLAN Membership Mode : {{ context.interface.vlan_membership_mode }} + Ingress Rule : Disabled + Acceptable Frame Type : All frames + Native VLAN : {{ context.interface.native_vlan }} + Priority for Untagged Traffic : 0 + GVRP Status : Disabled + Allowed VLAN : {{ context.interface.allowed_vlan }} + Forbidden VLAN : + 802.1Q Tunnel Status : Disabled + 802.1Q Tunnel Mode : Normal + 802.1Q Tunnel TPID : 8100 (Hex) + Broadcast Block : Disabled + Unknown Multicast Block : Disabled + Unknown Unicast Block : Disabled + diff --git a/templates/EdgeCore/login/mainloop/enable/show_interface_transceiver.j2 b/templates/EdgeCore/login/mainloop/enable/show_interface_transceiver.j2 new file mode 100644 index 0000000..271b17d --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_interface_transceiver.j2 @@ -0,0 +1,26 @@ +Information of Eth {{ context.port.name }} + Connector Type : LC + Fiber Type : Multimode 50um (M5), Multimode 62.5um (M6) + Eth Compliance Codes : 1000BASE-SX + Baud Rate : 2100 MBd + Vendor OUI : 00-90-65 + Vendor Name : FINISAR CORP. + Vendor PN : FTLF8519P2BNL + Vendor Rev : A + Vendor SN : PFS4U5F + Date Code : 09-07-02 +DDM Information + Temperature : 31.36 degree C + Vcc : 3.32 V + Bias Current : 25.61 mA + TX Power : -3.11 dBm + RX Power : -40.00 dBm +DDM Thresholds + Low Alarm Low Warning High Warning High Alarm + ----------- ------------ ------------ ------------ ------------ + Temperature(Celsius) -25.00 -20.00 90.00 95.00 + Voltage(Volts) 2.80 2.90 3.70 3.80 + Current(mA) 2.00 3.00 80.00 90.00 + TxPower(dBm) -7.96 -6.99 1.00 2.01 + RxPower(dBm) -20.00 -19.00 0.00 1.00 + diff --git a/templates/EdgeCore/login/mainloop/enable/show_mac_address_table.j2 b/templates/EdgeCore/login/mainloop/enable/show_mac_address_table.j2 new file mode 100644 index 0000000..82e2ff6 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_mac_address_table.j2 @@ -0,0 +1,3 @@ + Interface MAC Address VLAN Type Life Time + --------- ----------------- ---- -------- ----------------- + diff --git a/templates/EdgeCore/login/mainloop/enable/show_mac_address_table_entry.j2 b/templates/EdgeCore/login/mainloop/enable/show_mac_address_table_entry.j2 new file mode 100644 index 0000000..413ac00 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_mac_address_table_entry.j2 @@ -0,0 +1,2 @@ + Eth {{ context.interface.name }} {{ context.interface.mac_address }} {{ context.interface.native_vlan }} Learn Delete on Timeout + diff --git a/templates/EdgeCore/login/mainloop/enable/show_mac_address_table_unit.j2 b/templates/EdgeCore/login/mainloop/enable/show_mac_address_table_unit.j2 new file mode 100644 index 0000000..769a7e1 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_mac_address_table_unit.j2 @@ -0,0 +1,3 @@ + CPU {{ context.card.mac_address }} 1 CPU Delete on Reset + + diff --git a/templates/EdgeCore/login/mainloop/enable/show_memory.j2 b/templates/EdgeCore/login/mainloop/enable/show_memory.j2 new file mode 100644 index 0000000..a082ecb --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_memory.j2 @@ -0,0 +1,10 @@ + Status Bytes % + ------ ---------- --- + Free 236236800 44 + Used 300634112 56 + Total 536870912 + +Alarm Configuration + Rising Threshold : 90% + Falling Threshold : 70% + diff --git a/templates/EdgeCore/login/mainloop/enable/show_process_cpu.j2 b/templates/EdgeCore/login/mainloop/enable/show_process_cpu.j2 new file mode 100644 index 0000000..fe6c2bb --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_process_cpu.j2 @@ -0,0 +1,16 @@ + CPU Utilization in the past 5 seconds : 7% + + CPU Utilization in the past 60 seconds + Average Utilization : 8% + Maximum Utilization : 9% + + Alarm Status + Current Alarm Status : Off + Last Alarm Start Time : Jun 9 15:10:09 2011 + Last Alarm Duration Time : 10 seconds + + Alarm Configuration + Rising Threshold : 90% + Falling Threshold : 70% + + diff --git a/templates/EdgeCore/login/mainloop/enable/show_system.j2 b/templates/EdgeCore/login/mainloop/enable/show_system.j2 new file mode 100644 index 0000000..e9c9f14 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_system.j2 @@ -0,0 +1,28 @@ +System Description : {{ context.box.model }} +System OID String : 1.3.6.1.4.1.259.10.1.45.108 +System Information + System Up Time : 0 days, 5 hours, 44 minutes, and 42.28 seconds + System Name : + System Location : + System Contact : + MAC Address (Unit 1) : {{ context.card.mac_address }} + Web Server : Enabled + Web Server Port : 80 + Web Secure Server : Enabled + Web Secure Server Port : 443 + Telnet Server : Enabled + Telnet Server Port : 23 + Jumbo Frame : Disabled + +System Fan: + Force Fan Speed Full : Disabled +Unit 1 + Fan 1: Ok Fan 2: Ok + +System Temperature: +Unit 1 + Temperature 1: 35 degrees + +Unit 1 + Main Power Status : {{ context.card.admin_state }} + diff --git a/templates/EdgeCore/login/mainloop/enable_password.j2 b/templates/EdgeCore/login/mainloop/enable_password.j2 new file mode 100644 index 0000000..417a449 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable_password.j2 @@ -0,0 +1,2 @@ +% Bad passwords + diff --git a/templates/EdgeCore/login/mainloop/help.j2 b/templates/EdgeCore/login/mainloop/help.j2 new file mode 100644 index 0000000..800b1a8 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/help.j2 @@ -0,0 +1,12 @@ +Help may be requested at any point in a command by entering +a question mark '?'. If nothing matches, the help list will +be empty and you must backup until entering a '?' shows the +available options. +Two styles of help are provided: +1. Full help is available when you are ready to enter a + command argument (e.g. 'show ?') and describes each possible + argument. +2. Partial help is provided when an abbreviated argument is entered + and you want to know what arguments match the input + (e.g. 'show br?'.) + diff --git a/templates/EdgeCore/login/mainloop/on_cycle.j2 b/templates/EdgeCore/login/mainloop/on_cycle.j2 new file mode 100644 index 0000000..d9f093f --- /dev/null +++ b/templates/EdgeCore/login/mainloop/on_cycle.j2 @@ -0,0 +1 @@ +{{ model.hostname }}> \ No newline at end of file diff --git a/templates/EdgeCore/login/mainloop/on_enter.j2 b/templates/EdgeCore/login/mainloop/on_enter.j2 new file mode 100644 index 0000000..c148098 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/on_enter.j2 @@ -0,0 +1,24 @@ +*************************************************************** +WARNING - MONITORED ACTIONS AND ACCESSES +FNT + + +Station's information: + + +Floor / Row / Rack / Sub-Rack + / / / +DC power supply: +Power Source A: Floor / Row / Rack / Electrical circuit + / / / + +Number of LP: +Position MUX: +IP LAN: {{ context.ip }} +Note: {{ context.name }} +MOTD: +*************************************************************** + + CLI session with the ECS4120-28Fv2-I is opened. + To end the CLI session, enter [Exit]. + diff --git a/templates/EdgeCore/login/mainloop/on_error.j2 b/templates/EdgeCore/login/mainloop/on_error.j2 new file mode 100644 index 0000000..d965dc6 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/on_error.j2 @@ -0,0 +1,3 @@ + ^ +% Invalid input detected at '^' marker. + diff --git a/templates/EdgeCore/login/mainloop/show_?.j2 b/templates/EdgeCore/login/mainloop/show_?.j2 new file mode 100644 index 0000000..73ca696 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/show_?.j2 @@ -0,0 +1,17 @@ + banner Banner info + calendar Date and time information + history Shows history information + interfaces Shows interface information + ip IP information + lacp LACP statistics + line TTY line information + memory Memory utilization + privilege Shows current privilege level + process Device process + public-key Public key information + snmp Simple Network Management Protocol configuration and statistics + system System information + users Information about users logged in + version System hardware and software versions + vlan Shows virtual LAN settings + diff --git a/templates/EdgeCore/login/on_cycle.j2 b/templates/EdgeCore/login/on_cycle.j2 new file mode 100644 index 0000000..e69de29 diff --git a/templates/EdgeCore/login/on_enter.j2 b/templates/EdgeCore/login/on_enter.j2 new file mode 100644 index 0000000..3adfb18 --- /dev/null +++ b/templates/EdgeCore/login/on_enter.j2 @@ -0,0 +1 @@ +>>User password: \ No newline at end of file diff --git a/templates/EdgeCore/login/password.j2 b/templates/EdgeCore/login/password.j2 new file mode 100644 index 0000000..a64789f --- /dev/null +++ b/templates/EdgeCore/login/password.j2 @@ -0,0 +1,2 @@ +Bad username or password + diff --git a/templates/EdgeCore/on_cycle.j2 b/templates/EdgeCore/on_cycle.j2 new file mode 100644 index 0000000..b24a03e --- /dev/null +++ b/templates/EdgeCore/on_cycle.j2 @@ -0,0 +1 @@ +>>User name: \ No newline at end of file diff --git a/templates/EdgeCore/on_enter.j2 b/templates/EdgeCore/on_enter.j2 new file mode 100644 index 0000000..e69de29 diff --git a/templates/EdgeCore/on_exit.j2 b/templates/EdgeCore/on_exit.j2 new file mode 100644 index 0000000..b900707 --- /dev/null +++ b/templates/EdgeCore/on_exit.j2 @@ -0,0 +1,4 @@ +% CLI exit session +Connection to {{ context.ip }} closed by remote host. +Connection to {{ context.ip }} closed. + diff --git a/test_cases/integration_tests/edgecore/backup.txt b/test_cases/integration_tests/edgecore/backup.txt new file mode 100644 index 0000000..9b5d380 --- /dev/null +++ b/test_cases/integration_tests/edgecore/backup.txt @@ -0,0 +1,10 @@ +admin +secret +enable +enable +copy startup-config ftp +1.1.1.1 +backup +backup +/example.txt +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureBox7.txt b/test_cases/integration_tests/edgecore/configureBox7.txt new file mode 100644 index 0000000..1cc3455 --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureBox7.txt @@ -0,0 +1,9 @@ +admin +secret +enable +enable +configure +management all-client 10.218.20.21 10.218.20.22 +no logging host 10.10.103.254 +loopback-detection action shutdown +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureBoxName10.txt b/test_cases/integration_tests/edgecore/configureBoxName10.txt new file mode 100644 index 0000000..82f10c4 --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureBoxName10.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +configure +prompt name_prompt +hostname test_device +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureClock9.txt b/test_cases/integration_tests/edgecore/configureClock9.txt new file mode 100644 index 0000000..db1aa8b --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureClock9.txt @@ -0,0 +1,10 @@ +admin +secret +enable +enable +configure +sntp server 77.244.98.1 +sntp client +clock timezone gmt hours 1 minute 0 +clock summer-time MESZ predefined europe +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureInternet2.txt b/test_cases/integration_tests/edgecore/configureInternet2.txt new file mode 100644 index 0000000..445095c --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureInternet2.txt @@ -0,0 +1,12 @@ +admin +secret +enable +enable +configure +interface ethernet 1/1 +description test_description +switchport mode hybrid +no shutdown +rate-limit input 1 +rate-limit output 1 +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureLog11.txt b/test_cases/integration_tests/edgecore/configureLog11.txt new file mode 100644 index 0000000..af21cba --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureLog11.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +configure +logging host 10.218.23.2 port 514 +logging trap +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureMVlan12.txt b/test_cases/integration_tests/edgecore/configureMVlan12.txt new file mode 100644 index 0000000..3707bf4 --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureMVlan12.txt @@ -0,0 +1,13 @@ +admin +secret +enable +enable +configure +vlan database +vlan 22 name scription media ethernet +exit +ip dhcp snooping +ip dhcp snooping vlan 1 +ip dhcp snooping information option encode no-subtype +ip dhcp snooping information option remote-id string test sub-option port-description +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configurePort4.txt b/test_cases/integration_tests/edgecore/configurePort4.txt new file mode 100644 index 0000000..677408c --- /dev/null +++ b/test_cases/integration_tests/edgecore/configurePort4.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +configure +interface ethernet 1/1 +no shutdown +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureRelay13.txt b/test_cases/integration_tests/edgecore/configureRelay13.txt new file mode 100644 index 0000000..a074bb3 --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureRelay13.txt @@ -0,0 +1,7 @@ +admin +secret +enable +enable +configure +pppoe intermediate-agent +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureRelayOnPort14.txt b/test_cases/integration_tests/edgecore/configureRelayOnPort14.txt new file mode 100644 index 0000000..a30b7c1 --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureRelayOnPort14.txt @@ -0,0 +1,13 @@ +admin +secret +enable +enable +configure +interface ethernet 1/1 +pppoe intermediate-agent port-enable +pppoe intermediate-agent trust +ip dhcp snooping trust +pppoe intermediate-agent port-format-type circuit-id 1/1 +ip dhcp snooping information option circuit-id tr101 node-identifier ip +ip dhcp snooping information option circuit-id tr101 no-vlan-field +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureTVlan8.txt b/test_cases/integration_tests/edgecore/configureTVlan8.txt new file mode 100644 index 0000000..97c1a4b --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureTVlan8.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +configure +vlan database +vlan 1111 name scription media ethernet +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureTVlanPort1.txt b/test_cases/integration_tests/edgecore/configureTVlanPort1.txt new file mode 100644 index 0000000..fd6e597 --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureTVlanPort1.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +configure +interface ethernet 1/1 +switchport allowed vlan add 1 tagged +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureUVlan15.txt b/test_cases/integration_tests/edgecore/configureUVlan15.txt new file mode 100644 index 0000000..f08985c --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureUVlan15.txt @@ -0,0 +1,9 @@ +admin +secret +enable +enable +configure +interface ethernet 1/1 +switchport allowed vlan add 1 untagged +switchport native vlan 1 +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/display_data2.txt b/test_cases/integration_tests/edgecore/display_data2.txt new file mode 100644 index 0000000..ef5c230 --- /dev/null +++ b/test_cases/integration_tests/edgecore/display_data2.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +show system +show process cpu +show memory +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/display_information4.txt b/test_cases/integration_tests/edgecore/display_information4.txt new file mode 100644 index 0000000..7e24d3c --- /dev/null +++ b/test_cases/integration_tests/edgecore/display_information4.txt @@ -0,0 +1,6 @@ +admin +secret +enable +enable +show mac-address-table +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/display_model3.txt b/test_cases/integration_tests/edgecore/display_model3.txt new file mode 100644 index 0000000..461ab56 --- /dev/null +++ b/test_cases/integration_tests/edgecore/display_model3.txt @@ -0,0 +1,6 @@ +admin +secret +enable +enable +show system +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/display_state1.txt b/test_cases/integration_tests/edgecore/display_state1.txt new file mode 100644 index 0000000..a9897db --- /dev/null +++ b/test_cases/integration_tests/edgecore/display_state1.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +show interfaces status ethernet 1/1 +show interfaces switchport ethernet 1/1 +show interfaces transceiver ethernet 1/1 +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/unconfigureInternet3.txt b/test_cases/integration_tests/edgecore/unconfigureInternet3.txt new file mode 100644 index 0000000..0b8e7c5 --- /dev/null +++ b/test_cases/integration_tests/edgecore/unconfigureInternet3.txt @@ -0,0 +1,20 @@ +admin +secret +enable +enable +configure +interface ethernet 1/1 +rate-limit input 1000000 +rate-limit output 1000000 +no rate-limit input +no rate-limit output +shutdown +no description +no switchport mode +no switchport native vlan +no switchport allowed vlan +no pppoe intermediate-agent port-enable +no pppoe intermediate-agent port-format-type circuit-id +no ip dhcp snooping information option circuit-id tr101 no-vlan-field +no ip dhcp snooping information option circuit-id +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/unconfigurePort5.txt b/test_cases/integration_tests/edgecore/unconfigurePort5.txt new file mode 100644 index 0000000..0e66ce9 --- /dev/null +++ b/test_cases/integration_tests/edgecore/unconfigurePort5.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +configure +interface ethernet 1/1 +shutdown +quit \ No newline at end of file diff --git a/test_cases/unit_tests/edgecore/test_edgecore.py b/test_cases/unit_tests/edgecore/test_edgecore.py index 2bc31a7..1885d33 100644 --- a/test_cases/unit_tests/edgecore/test_edgecore.py +++ b/test_cases/unit_tests/edgecore/test_edgecore.py @@ -11,23 +11,84 @@ # License: https://github.com/inexio/NESi/LICENSE.rst from test_cases.unit_tests.test_core import TestCore +import pytest +from os import listdir +from os.path import isfile, join class TestEdgecore(TestCore): + PATH = 'test_cases/integration_tests/edgecore/' + DATA = [f for f in listdir('test_cases/integration_tests/edgecore/') if + isfile(join('test_cases/integration_tests/edgecore/', f)) and f != 'output.txt'] - def test_portup_portdown(self): - port = self.model.get_port("name", '1/1/1/1') - assert(self.model.get_port("name", '1/1/1/1').admin_state == '0') - port.admin_up() - assert(self.model.get_port("name", '1/1/1/1').admin_state == '1') - port.admin_down() - assert(self.model.get_port("name", '1/1/1/1').admin_state == '0') - - def test_ontportup_portdown(self): - port = self.model.get_ont_port("name", '1/1/4/1/1/1/1') - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '0') - port.admin_up() - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '1') - port.admin_down() - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '0') + def test_box(self): + box = self.model + box.set('management_start_address', 'test') + box.set('management_end_address', 'test') + box.set('logging_host', 'test') + box.set('logging_port', 'test') + box.set('logging_level', 8) + box.set('loopback_detection_action', 'shutdown') + box.set('sntp_server_ip', '') + box.set('sntp_client', 'Enabled') + box.set('timezone_name', '') + box.set('timezone_time', '') + box.set('summer_time_name', 'test') + box.set('summer_time_region', 'test') + assert box.management_start_address == 'test' + assert box.management_end_address == 'test' + assert box.logging_host == 'test' + assert box.logging_port == 'test' + assert box.logging_level == 8 + assert box.loopback_detection_action == 'shutdown' + assert box.sntp_server_ip == '' + assert box.sntp_client == 'Enabled' + assert box.timezone_name == '' + assert box.timezone_time == '' + assert box.summer_time_name == 'test' + assert box.summer_time_region == 'test' + + def test_card(self): + card = self.model.get_card("name", '1') + card.set('mac_address', '11-11-11-11') + card.set('admin_state', '1') + card.set('operational_state', '1') + + assert card.mac_address == '11-11-11-11' + assert card.admin_state == '1' + assert card.operational_state == '1' + + def test_port(self): + port = self.model.get_port("name", '1/1') + port.set('mac_address', '11-11-11-11') + port.set('admin_state', '1') + port.set('operational_state', '1') + + assert port.mac_address == '11-11-11-11' + assert port.admin_state == '1' + assert port.operational_state == '1' + + def test_interface(self): + interface = self.model.get_interface("name", '1/1') + interface.set('ingress_state', 'Enabled') + interface.set('ingress_rate', 1) + interface.set('egress_state', 'Enabled') + interface.set('egress_rate', 1) + interface.set('vlan_membership_mode', 'Access') + interface.set('native_vlan', 1010) + interface.set('mac_address', '11-11-11-11') + interface.set('allowed_vlan', '1,1010(u)') + + assert interface.ingress_state == 'Enabled' + assert interface.ingress_rate == 1 + assert interface.egress_state == 'Enabled' + assert interface.egress_rate == 1 + assert interface.vlan_membership_mode == 'Access' + assert interface.native_vlan == 1010 + assert interface.mac_address == '11-11-11-11' + assert interface.allowed_vlan == '1,1010(u)' + + @pytest.mark.parametrize("path", DATA) + def test_integration(self, path): + self.run(self.PATH + path, self.PATH + 'output.txt') diff --git a/vendors/EdgeCore/__init__.py b/vendors/EdgeCore/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/vendors/EdgeCore/baseCommandProcessor.py b/vendors/EdgeCore/baseCommandProcessor.py new file mode 100644 index 0000000..9dc0d3c --- /dev/null +++ b/vendors/EdgeCore/baseCommandProcessor.py @@ -0,0 +1,74 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from nesi.softbox.cli import base + + +class BaseCommandProcessor(base.CommandProcessor): + """Create CLI REPR loop for example switch.""" + + def map_states(self, object, type): + if object.admin_state == '0': + if type in ('port', 'card'): + object.admin_state = 'Down' + elif object.admin_state == '1': + if type in ('port', 'card'): + object.admin_state = 'Up' + + if object.operational_state == '0': + if type in 'port': + object.operational_state = 'Down' + + elif object.operational_state == '1': + if type in 'port': + object.operational_state = 'Up' + + def do_exit(self, command, *args, context=None): + exc = exceptions.TerminalExitError() + raise exc + + def do_quit(self, command, *args, context=None): + exc = exceptions.TerminalExitError() + exc.return_to = 'sysexit' + raise exc + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) + + def create_spacers(self, positions, args): + spacers = [] + previous_pos = 0 + i = 0 + for position in positions: + spacer = position - (previous_pos + len(str(args[i]))) + spacers.append(spacer) + previous_pos = position + i += 1 + + return spacers + + def user_input(self, prompt, allow_history=True, tmp_boundary=None): + self._write(prompt) + prompt_end_pos = self.prompt_end_pos + self.prompt_end_pos = len(prompt) - 1 + if not allow_history: + self.history_enabled = False + + if len(self.line_buffer) != 0: + input = self.line_buffer.pop(0) + else: + input = self._read(tmp_boundary).strip() + if not allow_history: + self.history_enabled = True + self.prompt_end_pos = prompt_end_pos + return input diff --git a/vendors/EdgeCore/configCommandProcessor.py b/vendors/EdgeCore/configCommandProcessor.py new file mode 100644 index 0000000..34f17c3 --- /dev/null +++ b/vendors/EdgeCore/configCommandProcessor.py @@ -0,0 +1,182 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst +import random +import datetime +import re +import time + +from nesi import exceptions +from .baseCommandProcessor import BaseCommandProcessor + + +class ConfigCommandProcessor(BaseCommandProcessor): + + def on_unknown_command(self, command, *args, context=None): + if self._validate(command, '?'): + text = self._render( + '?', + context=context) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_interface(self, command, *args, context=None): + if self._validate(args, 'ethernet', str): + interface_name, = self._dissect(args, 'ethernet', str) + + try: + _ = self._model.get_interface('name', interface_name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + from .interfaceCommandProcessor import InterfaceCommandProcessor + + subprocessor = self._create_subprocessor(InterfaceCommandProcessor, 'login', 'mainloop', 'enable', 'config', + 'interface') + subprocessor.set_interface_name(interface_name) + subprocessor.loop(return_to=ConfigCommandProcessor, context=dict(context)) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_vlan(self, command, *args, context=None): + if self._validate(args, 'database'): + from .vlanCommandProcessor import VlanCommandProcessor + + subprocessor = self._create_subprocessor(VlanCommandProcessor, 'login', 'mainloop', 'enable', 'config', + 'vlan') + subprocessor.loop(return_to=ConfigCommandProcessor, context=dict(context)) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_no(self, command, *args, context=None): + if self._validate(args, 'logging', 'host', str): + host, = self._dissect(args, 'logging', 'host', str) + box = self._model + if host in box.logging_host: + addresss = box.logging_host.split(', ') + ports = box.logging_port.split(', ') + index = 0 + for address in addresss: + if address == host: + break + index += 1 + addresss.remove(host) + ports.pop(index) + address_list = ', '.join(addresss) + port_list = ', '.join(ports) + box.set('logging_host', address_list) + box.set('logging_port', port_list) + else: + pass + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_management(self, command, *args, context=None): + if self._validate(args, 'all-client', str, str): + start, end = self._dissect(args, 'all-client', str, str) + box = self._model + box.set('management_start_address', start) + box.set('management_end_address', end) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_loopback_detection(self, command, *args, context=None): + if self._validate(args, 'action', str): + prop, = self._dissect(args, 'action', str) + box = self._model + box.set('loopback_detection_action', prop) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_sntp(self, command, *args, context=None): + if self._validate(args, 'server', str): + ip, = self._dissect(args, 'server', str) + box = self._model + box.set('sntp_server_ip', ip) + elif self._validate(args, 'client'): + box = self._model + box.set('sntp_client', 'Enabled') + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_clock(self, command, *args, context=None): + if self._validate(args, 'timezone', str, 'hours', str, 'minute', str): + name, h, m = self._dissect(args, 'timezone', str, 'hours', str, 'minute', str) + box = self._model + box.set('timezone_name', name) + box.set('timezone_time', (h + ',' + m)) + elif self._validate(args, 'summer-time', str, 'predefined', str): + name, region = self._dissect(args, 'summer-time', str, 'predefined', str) + box = self._model + box.set('summer_time_name', name) + box.set('summer_time_region', region) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_prompt(self, command, *args, context=None): + if self._validate(args, str): + name, = self._dissect(args, str) + box = self._model + box.set('hostname', name) + self.set_prompt_end_pos(context) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_hostname(self, command, *args, context=None): + if self._validate(args, str): + name, = self._dissect(args, str) + box = self._model + box.set('hostname', name) + self.set_prompt_end_pos(context) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_logging(self, command, *args, context=None): + if self._validate(args, 'host', str, 'port', str): + host, port = self._dissect(args, 'host', str, 'port', str) + box = self._model + if host not in box.logging_host: + address_list = box.logging_host + ', ' + host + port_list = box.logging_port + ', ' + port + box.set('logging_host', address_list) + box.set('logging_port', port_list) + + elif self._validate(args, 'trap'): + box = self._model + box.set('logging_level', 7) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_ip(self, command, *args, context=None): + if self._validate(args, 'dhcp', 'snooping'): + pass # No visible changes + + elif self._validate(args, 'dhcp', 'snooping', 'vlan', str): + pass # No visible changes + + elif self._validate(args, 'dhcp', 'snooping', 'information', 'option', 'encode', 'no-subtype'): + pass # No visible changes + + elif self._validate(args, 'dhcp', 'snooping', 'information', 'option', 'remote-id', 'string', str, 'sub-option', + 'port-description'): + pass # No visible changes + + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_pppoe(self, command, *args, context=None): + if self._validate(args, 'intermediate-agent'): + pass # No visible changes + + else: + raise exceptions.CommandSyntaxError(command=command) + diff --git a/vendors/EdgeCore/enableCommandProcessor.py b/vendors/EdgeCore/enableCommandProcessor.py new file mode 100644 index 0000000..e78bb09 --- /dev/null +++ b/vendors/EdgeCore/enableCommandProcessor.py @@ -0,0 +1,155 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst +from datetime import datetime + +from nesi import exceptions +from .baseCommandProcessor import BaseCommandProcessor +import time + + +class EnableCommandProcessor(BaseCommandProcessor): + + def do_disable(self, command, *args, context=None): + + from .userViewCommandProcessor import UserViewCommandProcessor + + exc = exceptions.TerminalExitError() + exc.return_to = UserViewCommandProcessor + raise exc + + def do_exit(self, command, *args, context=None): + exc = exceptions.TerminalExitError() + exc.return_to = 'sysexit' + raise exc + + def on_unknown_command(self, command, *args, context=None): + if command == '?' and args == (): + text = self._render('?', context=context) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_configure(self, command, *args, context=None): + + from .configCommandProcessor import ConfigCommandProcessor + + subprocessor = self._create_subprocessor( + ConfigCommandProcessor, 'login', 'mainloop', 'enable', 'config') + + subprocessor.loop(context=context, return_to=EnableCommandProcessor) + + def do_config(self, command, *args, context=None): + + from .configCommandProcessor import ConfigCommandProcessor + + subprocessor = self._create_subprocessor( + ConfigCommandProcessor, 'login', 'mainloop', 'enable', 'config') + + subprocessor.loop(context=context, return_to=EnableCommandProcessor) + + def do_show(self, command, *args, context=None): + if command == '?' and args == (): + text = self._render('show_?', context=context) + self._write(text) + elif self._validate(args, 'interfaces', 'status', 'ethernet', str): + port_name, = self._dissect(args, 'interfaces', 'status', 'ethernet', str) + try: + port = self._model.get_port('name', port_name) + self.map_states(port, 'port') + interface = self._model.get_interface('name', port_name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + # TODO: Information of Interface + text = self._render('show_interface_status', context=dict(context, port=port, interface=interface)) + self._write(text) + elif self._validate(args, 'interfaces', 'switchport', 'ethernet', str): + port_name, = self._dissect(args, 'interfaces', 'switchport', 'ethernet', str) + try: + port = self._model.get_port('name', port_name) + self.map_states(port, 'port') + interface = self._model.get_interface('name', port_name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + # TODO: Information of Interface + text = self._render('show_interface_switchport', context=dict(context, port=port, interface=interface)) + self._write(text) + elif self._validate(args, 'interfaces', 'transceiver', 'ethernet', str): + port_name, = self._dissect(args, 'interfaces', 'transceiver', 'ethernet', str) + try: + port = self._model.get_port('name', port_name) + self.map_states(port, 'port') + interface = self._model.get_interface('name', port_name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + # TODO: Information of Interface + # erst ab port 25-28 + text = self._render('show_interface_transceiver', context=dict(context, port=port, interface=interface)) + self._write(text) + elif self._validate(args, 'system'): + try: + card = self._model.get_card('name', "1") + self.map_states(card, 'card') + box = self._model + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + text = self._render('show_system', context=dict(context, card=card, box=box)) + self._write(text) + elif self._validate(args, 'process', 'cpu'): + text = self._render('show_process_cpu', context=context) + self._write(text) + elif self._validate(args, 'memory'): + text = self._render('show_memory', context=context) + self._write(text) + elif self._validate(args, 'mac-address-table'): + text = self._render('show_mac_address_table', context=context) + for interface in self._model.interfaces: + text += self._render('show_mac_address_table_entry', context=dict(context, interface=interface)) + card = self._model.get_card('name', "1") + self.map_states(card, 'card') + text += self._render('show_mac_address_table_unit', context=dict(context, card=card)) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_copy(self, command, *args, context=None): + if self._validate(args, 'startup-config', 'ftp'): # Work in progess + ip = self.user_input("FTP server IP address: ", False, None) + user = self.user_input("User[anonymous]: ", False, None) + self.hide_input = True + pw = self.user_input("Password: ", False, None) + self.hide_input = False + dest = self.user_input("Destination file name: ", False, None) + + for creds in self._model.credentials: + if creds.username == user: + user = self._model.get_user('id', creds.user_id) + if user.profile == 'backup': + break + + if creds.password != pw or '/' not in dest or ip.count('.') != 3: + text = self._render('copy_startup_config_ftp_failure', context=context) + self._write(text) + else: + text = self._render('copy_startup_config_ftp_success', context=context) + self._write(text) + + else: + raise exceptions.CommandSyntaxError(command=command) + + def on_help(self, command, *args, context=None): + if args == (): + text = self._render( + 'help', + context=context) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/EdgeCore/interfaceCommandProcessor.py b/vendors/EdgeCore/interfaceCommandProcessor.py new file mode 100644 index 0000000..3003971 --- /dev/null +++ b/vendors/EdgeCore/interfaceCommandProcessor.py @@ -0,0 +1,212 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import random +import re +from datetime import datetime, date +from ipaddress import IPv4Network +from nesi import exceptions +from .baseCommandProcessor import BaseCommandProcessor + + +class InterfaceCommandProcessor(BaseCommandProcessor): + + component_name = None + + def set_interface_name(self, name): + self.component_name = name + + def get_actual_interface(self, command): + if self.component_name is None: + raise exceptions.CommandExecutionError(command='Component name is None') + try: + return self._model.get_interface('name', self.component_name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + def get_actual_port(self, command): + if self.component_name is None: + raise exceptions.CommandExecutionError(command='Component name is None') + try: + return self._model.get_port('name', self.component_name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + def do_shutdown(self, command, *args, context=None): + if len(args) == 0: + port = self.get_actual_port(command) + port.admin_down() + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_no(self, command, *args, context=None): + if self._validate(args, 'shutdown'): + port = self.get_actual_port(command) + port.admin_up() + + elif self._validate(args, 'rate-limit', 'input'): + interface = self.get_actual_interface(command) + interface.set('ingress_state', 'Disabled') + + elif self._validate(args, 'rate-limit', 'output'): + interface = self.get_actual_interface(command) + interface.set('egress_state', 'Disabled') + + elif self._validate(args, 'description'): + port = self.get_actual_port(command) + port.set('description', '') + + elif self._validate(args, 'switchport', 'mode'): + interface = self.get_actual_interface(command) + interface.set('vlan_membership_mode', 'Hybrid') + interface.set('native_vlan', 1) + + elif self._validate(args, 'switchport', 'native', 'vlan'): + interface = self.get_actual_interface(command) + interface.set('native_vlan', 1) + + elif self._validate(args, 'switchport', 'allowed', 'vlan'): + interface = self.get_actual_interface(command) + interface.set('allowed_vlan', '1(u)') + + elif self._validate(args, 'pppoe', 'intermediate-agent', 'port-enable'): + pass # No visible changes + + elif self._validate(args, 'pppoe', 'intermediate-agent', 'port-format-type', 'circuit-id'): + pass # No visible changes + + elif self._validate(args, 'ip', 'dhcp', 'snooping', 'information', 'option', 'circuit-id', 'tr101', + 'no-vlan-field'): + pass # No visible changes + + elif self._validate(args, 'ip', 'dhcp', 'snooping', 'information', 'option', 'circuit-id'): + pass # No visible changes + + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_rate_limit(self, command, *args, context=None): + if self._validate(args, 'input', str): + rate, = self._dissect(args, 'input', str) + interface = self.get_actual_interface(command) + interface.set('ingress_state', 'Enabled') + interface.set('ingress_rate', int(rate)) + elif self._validate(args, 'output', str): + rate, = self._dissect(args, 'output', str) + interface = self.get_actual_interface(command) + interface.set('egress_state', 'Enabled') + interface.set('egress_rate', int(rate)) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_description(self, command, *args, context=None): + if self._validate(args, str): + descr, = self._dissect(args, str) + port = self.get_actual_port(command) + port.set('description', descr) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_switchport(self, command, *args, context=None): + if self._validate(args, 'mode', 'hybrid'): + interface = self.get_actual_interface(command) + interface.set('vlan_membership_mode', 'Hybrid') + + elif self._validate(args, 'mode', 'access'): + interface = self.get_actual_interface(command) + interface.set('vlan_membership_mode', 'Access') + + elif self._validate(args, 'mode', 'trunk'): + interface = self.get_actual_interface(command) + interface.set('vlan_membership_mode', 'Trunk') + + elif self._validate(args, 'allowed', 'vlan', 'add', str, 'tagged'): + interface = self.get_actual_interface(command) + id_list, = self._dissect(args, 'allowed', 'vlan', 'add', str, 'tagged') + if ',' in id_list: + ids = id_list.split(',') + for id in ids: + try: + id = int(id) + _ = self._model.get_vlan('number', id) + except Exception: + raise exceptions.CommandSyntaxError(command=command) + else: + try: + id = int(id_list) + _ = self._model.get_vlan('number', id) + except Exception: + raise exceptions.CommandSyntaxError(command=command) + id_list = id_list + '(t)' + interface.set('allowed_vlan', id_list) + + elif self._validate(args, 'allowed', 'vlan', 'add', str, 'untagged'): + interface = self.get_actual_interface(command) + id_list, = self._dissect(args, 'allowed', 'vlan', 'add', str, 'untagged') + if ',' in id_list: + ids = id_list.split(',') + for id in ids: + try: + id = int(id) + _ = self._model.get_vlan('number', id) + except Exception: + raise exceptions.CommandSyntaxError(command=command) + else: + try: + id = int(id_list) + _ = self._model.get_vlan('number', id) + except Exception: + raise exceptions.CommandSyntaxError(command=command) + id_list = id_list + '(u)' + interface.set('allowed_vlan', id_list) + + elif self._validate(args, 'native', 'vlan', str): #untagged + vlan_id, = self._dissect(args, 'native', 'vlan', str) + interface = self.get_actual_interface(command) + try: + vlan = self._model.get_vlan('number', int(vlan_id)) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + interface.set('native_vlan', int(vlan_id)) + + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_pppoe(self, command, *args, context=None): + if self._validate(args, 'intermediate-agent', 'port-enable'): + pass # No visible changes + + elif self._validate(args, 'intermediate-agent', 'trust'): + pass # No visible changes + + elif self._validate(args, 'intermediate-agent', 'port-format-type', 'circuit-id', str): + pass # No visible changes + + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_ip(self, command, *args, context=None): + if self._validate(args, 'dhcp', 'snooping'): + pass # No visible changes + + elif self._validate(args, 'dhcp', 'snooping', 'trust'): + pass # No visible changes + + elif self._validate(args, 'dhcp', 'snooping', 'information', 'option', 'circuit-id', 'tr101', 'node-identifier', + 'ip'): + pass # No visible changes + + elif self._validate(args, 'dhcp', 'snooping', 'information', 'option', 'circuit-id', 'tr101', 'no-vlan-field'): + pass # No visible changes + + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/EdgeCore/main.py b/vendors/EdgeCore/main.py new file mode 100644 index 0000000..b11b23e --- /dev/null +++ b/vendors/EdgeCore/main.py @@ -0,0 +1,63 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.cli import base +from vendors.EdgeCore.userViewCommandProcessor import * +from nesi import exceptions + + +class PreLoginCommandProcessor(base.CommandProcessor): + + def on_unknown_command(self, command, *args, context=None): + subprocessor = self._create_subprocessor( + LoginCommandProcessor, 'login') + + context['username'] = context['raw_line'].replace('\r', '').replace('\n', '') + + try: + subprocessor.history_enabled = False + subprocessor.hide_input = True + context['ip'] = self._model.network_address + context['name'] = self._model.hostname + subprocessor.loop(context=context) + except exceptions.TerminalExitError as exc: + if exc.return_to is not None and exc.return_to != 'sysexit': + raise exc + else: + context['ip'] = self._model.network_address + self.on_exit(context) + raise exc + + +class LoginCommandProcessor(base.CommandProcessor): + + def on_unknown_command(self, command, *args, context=None): + username = context.pop('username') + password = command + + for creds in self._model.credentials: + if creds.username == username and creds.password == password: + user = self._model.get_user('id', creds.user_id) + if user.profile == 'root': + break + else: + text = self._render('password', context=context) + self._write(text) + raise exceptions.TerminalExitError() + + self._output.write(bytes(False)) + self._output.write(bytes(False)) + + subprocessor = self._create_subprocessor( + UserViewCommandProcessor, 'login', 'mainloop') + + subprocessor.loop(context=context) diff --git a/vendors/EdgeCore/userViewCommandProcessor.py b/vendors/EdgeCore/userViewCommandProcessor.py new file mode 100644 index 0000000..4f61cae --- /dev/null +++ b/vendors/EdgeCore/userViewCommandProcessor.py @@ -0,0 +1,71 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst +from datetime import datetime + +from nesi import exceptions +from .baseCommandProcessor import BaseCommandProcessor + + +class UserViewCommandProcessor(BaseCommandProcessor): + + def do_enable(self, command, *args, context=None): + + for i in range(0, 3): + self.hide_input = True + enable_pw = self.user_input("Password:", False, None) + self.hide_input = False + + for creds in self._model.credentials: + if creds.username == 'enable': + user = self._model.get_user('id', creds.user_id) + if user.profile == 'enable': + break + + if creds.password == enable_pw: + break + else: + text = self._render('enable_password', context=context) + self._write(text) + return + + from .enableCommandProcessor import EnableCommandProcessor + + subprocessor = self._create_subprocessor( + EnableCommandProcessor, 'login', 'mainloop', 'enable') + + subprocessor.loop(context=context) + + def do_disable(self, command, *args, context=None): + return + + def on_unknown_command(self, command, *args, context=None): + if self._validate(command, '?'): + text = self._render( + '?', + context=context) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_exit(self, command, *args, context=None): + exc = exceptions.TerminalExitError() + exc.return_to = 'sysexit' + raise exc + + def on_help(self, command, *args, context=None): + if args == (): + text = self._render( + 'help', + context=context) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/EdgeCore/vlanCommandProcessor.py b/vendors/EdgeCore/vlanCommandProcessor.py new file mode 100644 index 0000000..b7f7f5b --- /dev/null +++ b/vendors/EdgeCore/vlanCommandProcessor.py @@ -0,0 +1,32 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + + +from .baseCommandProcessor import BaseCommandProcessor +from nesi import exceptions + + +class VlanCommandProcessor(BaseCommandProcessor): + + def do_vlan(self, command, *args, context=None): + # vlan $trafficVlan name $description media ethernet + # vlan $cpe_management_vlan name $description media ethernet + if self._validate(args, str, 'name', str, 'media', 'ethernet'): + number, name = self._dissect(args, str, 'name', str, 'media', 'ethernet') + try: + vlan = self._model.get_vlan('number', int(number)) + vlan.set('name', name) + except exceptions.SoftboxenError: + _ = self._model.add_vlan(number=int(number), name=name) + vlan = self._model.get_vlan('number', int(number)) + else: + raise exceptions.CommandSyntaxError(command=command) From 482a109977bd4ff43b8efce1daee5e0c50d080ee Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 3 Dec 2020 15:53:44 +0100 Subject: [PATCH 191/318] Added ssh socket class and implementation, changes to NESi backend according to ssh socket --- bootup/sockets/ssh.py | 137 +++++++++++++++++++++++++++++++++++++++ cli.py | 6 +- nesi/softbox/cli/base.py | 32 ++++++--- requirements.txt | 1 + 4 files changed, 166 insertions(+), 10 deletions(-) create mode 100644 bootup/sockets/ssh.py diff --git a/bootup/sockets/ssh.py b/bootup/sockets/ssh.py new file mode 100644 index 0000000..4f52202 --- /dev/null +++ b/bootup/sockets/ssh.py @@ -0,0 +1,137 @@ +from twisted.cred.portal import Portal +from twisted.cred import portal +from twisted.conch.ssh import factory, userauth, connection, keys, session +from twisted.conch.ssh.transport import SSHServerTransport +from twisted.conch import avatar +from twisted.cred.checkers import InMemoryUsernamePasswordDatabaseDontUse +from twisted.internet import reactor, protocol +from twisted.python import components +from zope.interface import implementer +import threading + +SERVER_RSA_PUBLIC = '~/.ssh/id_rsa.pub' +SERVER_RSA_PRIVATE = '~/.ssh/id_rsa' + +PRIMES = { + 2048: [(2, 24265446577633846575813468889658944748236936003103970778683933705240497295505367703330163384138799145013634794444597785054574812547990300691956176233759905976222978197624337271745471021764463536913188381724789737057413943758936963945487690939921001501857793275011598975080236860899147312097967655185795176036941141834185923290769258512343298744828216530595090471970401506268976911907264143910697166165795972459622410274890288999065530463691697692913935201628660686422182978481412651196163930383232742547281180277809475129220288755541335335798837173315854931040199943445285443708240639743407396610839820418936574217939)], + 4096: [(2, 889633836007296066695655481732069270550615298858522362356462966213994239650370532015908457586090329628589149803446849742862797136176274424808060302038380613106889959709419621954145635974564549892775660764058259799708313210328185716628794220535928019146593583870799700485371067763221569331286080322409646297706526831155237865417316423347898948704639476720848300063714856669054591377356454148165856508207919637875509861384449885655015865507939009502778968273879766962650318328175030623861285062331536562421699321671967257712201155508206384317725827233614202768771922547552398179887571989441353862786163421248709273143039795776049771538894478454203924099450796009937772259125621285287516787494652132525370682385152735699722849980820612370907638783461523042813880757771177423192559299945620284730833939896871200164312605489165789501830061187517738930123242873304901483476323853308396428713114053429620808491032573674192385488925866607192870249619437027459456991431298313382204980988971292641217854130156830941801474940667736066881036980286520892090232096545650051755799297658390763820738295370567143697617670291263734710392873823956589171067167839738896249891955689437111486748587887718882564384870583135509339695096218451174112035938859)], + } + + +class Avatar(avatar.ConchUser): + def __init__(self, username, cli, model, template_root): + avatar.ConchUser.__init__(self) + self.username = username + self.cli = cli + self.model = model + self.template_root = template_root + self.channelLookup.update({b'session': session.SSHSession}) + + +@implementer(portal.IRealm) +class Realm(object): + def __init__(self, cli, model, template_root): + self.cli = cli + self.model = model + self.template_root = template_root + + def requestAvatar(self, avatarId, mind, *interfaces): + return interfaces[0], Avatar(avatarId, self.cli, self.model, self.template_root), lambda: None + + +class SSHProtocol(protocol.Protocol): + char = b'' + + def connectionMade(self): + connection = self.transport.getPeer().address + print('%s:%s connected.' % (connection.host, connection.port)) + + def connectionLost(self, reason=None): + connection = self.transport.getPeer().address + print('%s:%s disconnected.' % (connection.host, connection.port)) + + def receiveData(self): + while self.char == b'': + pass + + return_val = self.char + self.char = b'' + return return_val + + def dataReceived(self, data): + if data == b'\r': + data = b'\r\n' + elif data == b'\x03': # ^C + self.transport.loseConnection() + return + self.char = data + + +class ExampleSession(object): + def __init__(self, avatar): + self.avatar = avatar + + def getPty(self, term, windowSize, attrs): + pass + + def execCommand(self, proto, cmd): + raise Exception("not executing commands") + + def openShell(self, transport): + protocol = SSHProtocol() + protocol.makeConnection(transport) + transport.makeConnection(session.wrapProtocol(protocol)) + + command_processor = self.avatar.cli( + self.avatar.model, protocol, transport, (), template_root=self.avatar.template_root, daemon=True) + command_processor.skipLogin = True + thread = threading.Thread(target=command_processor.loop, args=()) + thread.start() + + def eofReceived(self): + pass + + def closed(self): + pass + + +class Factory(factory.SSHFactory): + protocol = SSHServerTransport + publicKeys = { + b'ssh-rsa': keys.Key.fromFile(SERVER_RSA_PUBLIC) + } + privateKeys = { + b'ssh-rsa': keys.Key.fromFile(SERVER_RSA_PRIVATE) + } + services = { + b'ssh-userauth': userauth.SSHUserAuthServer, + b'ssh-connection': connection.SSHConnection + } + + def getPrimes(self): + return PRIMES + + +class SshSocket: + def __init__(self, cli, model, template_root, hostaddress, port): + self.hostaddress = hostaddress + self.port = port + self.cli = cli + self.model = model + self.template_root = template_root + + def start(self): + components.registerAdapter(ExampleSession, Avatar, session.ISession) + + portal = Portal(Realm(self.cli, self.model, self.template_root)) + passwdDB = InMemoryUsernamePasswordDatabaseDontUse() + + for credential in self.model.credentials: + passwdDB.addUser(credential.username.encode('utf-8'), credential.password.encode('utf-8')) + + portal.registerChecker(passwdDB) + Factory.portal = portal + + print("Starting ssh socket on " + self.hostaddress + ":" + str(self.port)) + reactor.listenTCP(self.port, Factory()) + reactor.run() diff --git a/cli.py b/cli.py index a64a13a..13526d2 100644 --- a/cli.py +++ b/cli.py @@ -23,6 +23,7 @@ from nesi.softbox.cli import rest_client from nesi.softbox.base_resources import root, base from bootup.sockets.telnet import TelnetSocket +from bootup.sockets.ssh import SshSocket import pytest import subprocess @@ -184,8 +185,9 @@ def main(): telnet = TelnetSocket(cli, model, template_root, ip_address, int(port)) telnet.start() elif model.network_protocol == 'ssh': - ssh = None - # TODO: add ssh-socket daemon + cli = main.PostLoginCommandProcessor + ssh = SshSocket(cli, model, template_root, ip_address, int(port)) + ssh.start() else: stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 9a4566b..535e944 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -18,6 +18,7 @@ import jinja2 from nesi import exceptions +from twisted.internet import reactor LOG = logging.getLogger(__name__) @@ -62,6 +63,7 @@ def __init__(self, model, input_stream, output_stream, history, self.daemon = daemon # CLI specific attributes + self.skipLogin = False self.case_sensitive = case_sensitive self.line_buffer = [] self.history_enabled = True @@ -116,10 +118,18 @@ def move_right(self): self.cursor_pos += 1 def get(self): - inkey = self._Getch() + inkey = None + if not self.daemon: + inkey = self._Getch() while (1): - k = inkey(self._input).decode('utf-8') - if k != '': break + if self.daemon: + k = self._input.receiveData().decode('utf-8') + if k == '\r\n': + k = '\r' + else: + k = inkey(self._input).decode('utf-8') + if k != '': + break if k == '\x1b[A': # up-arrow if self.history_enabled: return 'history', self.history_up() @@ -141,7 +151,7 @@ def get(self): return 'backspace', '' else: return None, None - elif k == '[3': # del-key + elif k == '[3' or k == '[3~': # del-key return 'del', '' elif k == '': # ctrl-v return 'paste', pyperclip.paste() @@ -263,15 +273,17 @@ def _default_command_handler(self, command, *args, context=None): self._write(text) def _read(self, tmp_boundary=None): - if self.daemon: + if self.daemon and self._model.network_protocol == 'telnet': line = self._input.readline().decode('utf-8') else: line = self.getline(tmp_boundary) - return line def _write(self, text): + text = text.replace('\n', '\r\n') self._output.write(text.encode('utf-8')) + if self.daemon and self._model.network_protocol == 'ssh': + reactor.iterate() def _get_command_func(self, line): if line.startswith(self.comment): @@ -349,8 +361,8 @@ def loop(self, context=None, return_to=None, command=None): continue context['raw_line'] = line - if self.daemon: - self._write(line) # write line to stdout if box is in daemon mode + #if self.daemon: + # self._write(line) # write line to stdout if box is in daemon mode else: line = command command = None @@ -368,6 +380,10 @@ def loop(self, context=None, return_to=None, command=None): exc.return_to = return_to if not exc.return_to or exc.return_to == 'sysexit' or exc.return_to == 'sysreboot' or not isinstance(self, exc.return_to): + if self.daemon and self._model.network_protocol == 'ssh': + self._output.loseConnection() + reactor.iterate() + return raise exc # set prompt_len anew in case of prompt_len change in command-processor beneath self.set_prompt_end_pos(context) diff --git a/requirements.txt b/requirements.txt index 5038a59..ed20d47 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,3 +9,4 @@ pydevd-pycharm~=201.7846.77 psutil pytest pyperclip +twisted From 64c955ae529b2262f5afd53235fcc3812dca2fcb Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 3 Dec 2020 16:12:23 +0100 Subject: [PATCH 192/318] Changes to get ssh-server running with EdgeCore simulated box --- bootup/conf/bootstraps/create-edgecore-xxxx.sh | 2 +- nesi/softbox/api/views/base_views.py | 2 -- vendors/EdgeCore/main.py | 9 +++++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/bootup/conf/bootstraps/create-edgecore-xxxx.sh b/bootup/conf/bootstraps/create-edgecore-xxxx.sh index 847ef39..970e776 100644 --- a/bootup/conf/bootstraps/create-edgecore-xxxx.sh +++ b/bootup/conf/bootstraps/create-edgecore-xxxx.sh @@ -43,7 +43,7 @@ req='{ "hostname": "ed-ge-co-re-1", "mgmt_address": "10.0.0.12", "software_version": "MA5623V800R016C00", - "network_protocol": "telnet", + "network_protocol": "ssh", "network_address": "127.0.0.1", "network_port": 9023, "dsl_mode": "tr165", diff --git a/nesi/softbox/api/views/base_views.py b/nesi/softbox/api/views/base_views.py index 47b60df..cd8d2b2 100644 --- a/nesi/softbox/api/views/base_views.py +++ b/nesi/softbox/api/views/base_views.py @@ -22,8 +22,6 @@ from nesi.huawei.api.schemas import * from nesi.keymile.api.schemas import * from nesi.edgecore.api.schemas import * -from nesi.pbn.api.schemas import * -from nesi.zhone.api.schemas import * # important for other view classes from nesi.softbox.api import db diff --git a/vendors/EdgeCore/main.py b/vendors/EdgeCore/main.py index b11b23e..77f1e67 100644 --- a/vendors/EdgeCore/main.py +++ b/vendors/EdgeCore/main.py @@ -61,3 +61,12 @@ def on_unknown_command(self, command, *args, context=None): UserViewCommandProcessor, 'login', 'mainloop') subprocessor.loop(context=context) + + +class PostLoginCommandProcessor(base.CommandProcessor): + + def loop(self, context=None, return_to=None, command=None): + subprocessor = self._create_subprocessor( + UserViewCommandProcessor, 'login', 'mainloop') + + subprocessor.loop(context=context) From f83e5716dd1864ac5d965eeb5cba03ed8f42bddc Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 17 Dec 2020 15:38:16 +0100 Subject: [PATCH 193/318] Fixed a bug where entering exit in ssh terminal would terminate box completely. --- bootup/conf/bootstraps/create-edgecore-xxxx.sh | 4 ++-- nesi/softbox/cli/base.py | 11 ++++++----- requirements.txt | 3 +++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/bootup/conf/bootstraps/create-edgecore-xxxx.sh b/bootup/conf/bootstraps/create-edgecore-xxxx.sh index 970e776..5d5699e 100644 --- a/bootup/conf/bootstraps/create-edgecore-xxxx.sh +++ b/bootup/conf/bootstraps/create-edgecore-xxxx.sh @@ -88,7 +88,7 @@ enable_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credential # backup user req='{ - "name": "Backuo", + "name": "Backup", "profile": "backup" }' @@ -151,4 +151,4 @@ req='{ "description": "The standard Vlan" }' -vlan_pppoe=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlans) \ No newline at end of file +vlan_pppoe=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlans) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 535e944..86426bb 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -177,15 +177,16 @@ def updateline(self, line): self._write('\033[' + str(self.cursor_pos) + 'C') # move cursor to correct position def getline(self, tmp_boundary=None): - char = None + char = '' line = '' self.history_pos = len(self.history) self.cursor_pos = self.prompt_end_pos + 1 self.cursor_boundary = self.prompt_end_pos + 1 - while char != '\r': + while '\r' not in char: option, char = self.get() if char is None: + char = '' continue elif char == '\r': continue @@ -282,8 +283,8 @@ def _read(self, tmp_boundary=None): def _write(self, text): text = text.replace('\n', '\r\n') self._output.write(text.encode('utf-8')) - if self.daemon and self._model.network_protocol == 'ssh': - reactor.iterate() + #if self.daemon and self._model.network_protocol == 'ssh': + # reactor.iterate() def _get_command_func(self, line): if line.startswith(self.comment): @@ -380,7 +381,7 @@ def loop(self, context=None, return_to=None, command=None): exc.return_to = return_to if not exc.return_to or exc.return_to == 'sysexit' or exc.return_to == 'sysreboot' or not isinstance(self, exc.return_to): - if self.daemon and self._model.network_protocol == 'ssh': + if self.daemon and self._model.network_protocol == 'ssh' and exc.return_to in ('sysexit', 'sysreboot'): self._output.loseConnection() reactor.iterate() return diff --git a/requirements.txt b/requirements.txt index ed20d47..ba89e83 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,3 +10,6 @@ psutil pytest pyperclip twisted +cryptography +bcrypt +pyasn1 From f5fef706a5762630ce7131d27a8b97a7aa24dc17 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 18 Dec 2020 11:59:23 +0100 Subject: [PATCH 194/318] Fixed an issue with line-ending special characters not being recognized correctly --- bootup/sockets/ssh.py | 16 ++++++++-------- nesi/softbox/cli/base.py | 6 +++++- vendors/EdgeCore/enableCommandProcessor.py | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/bootup/sockets/ssh.py b/bootup/sockets/ssh.py index 4f52202..55ba080 100644 --- a/bootup/sockets/ssh.py +++ b/bootup/sockets/ssh.py @@ -8,14 +8,19 @@ from twisted.python import components from zope.interface import implementer import threading +import os +from pathlib import Path -SERVER_RSA_PUBLIC = '~/.ssh/id_rsa.pub' -SERVER_RSA_PRIVATE = '~/.ssh/id_rsa' +full_path = os.path.dirname(os.path.abspath(__file__)) +path = str(Path(full_path).parents[0]) + +SERVER_RSA_PUBLIC = path + '/conf/ssh/id_rsa.pub' +SERVER_RSA_PRIVATE = path + '/conf/ssh/id_rsa' PRIMES = { 2048: [(2, 24265446577633846575813468889658944748236936003103970778683933705240497295505367703330163384138799145013634794444597785054574812547990300691956176233759905976222978197624337271745471021764463536913188381724789737057413943758936963945487690939921001501857793275011598975080236860899147312097967655185795176036941141834185923290769258512343298744828216530595090471970401506268976911907264143910697166165795972459622410274890288999065530463691697692913935201628660686422182978481412651196163930383232742547281180277809475129220288755541335335798837173315854931040199943445285443708240639743407396610839820418936574217939)], 4096: [(2, 889633836007296066695655481732069270550615298858522362356462966213994239650370532015908457586090329628589149803446849742862797136176274424808060302038380613106889959709419621954145635974564549892775660764058259799708313210328185716628794220535928019146593583870799700485371067763221569331286080322409646297706526831155237865417316423347898948704639476720848300063714856669054591377356454148165856508207919637875509861384449885655015865507939009502778968273879766962650318328175030623861285062331536562421699321671967257712201155508206384317725827233614202768771922547552398179887571989441353862786163421248709273143039795776049771538894478454203924099450796009937772259125621285287516787494652132525370682385152735699722849980820612370907638783461523042813880757771177423192559299945620284730833939896871200164312605489165789501830061187517738930123242873304901483476323853308396428713114053429620808491032573674192385488925866607192870249619437027459456991431298313382204980988971292641217854130156830941801474940667736066881036980286520892090232096545650051755799297658390763820738295370567143697617670291263734710392873823956589171067167839738896249891955689437111486748587887718882564384870583135509339695096218451174112035938859)], - } +} class Avatar(avatar.ConchUser): @@ -59,11 +64,6 @@ def receiveData(self): return return_val def dataReceived(self, data): - if data == b'\r': - data = b'\r\n' - elif data == b'\x03': # ^C - self.transport.loseConnection() - return self.char = data diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 86426bb..f39c52e 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -124,8 +124,12 @@ def get(self): while (1): if self.daemon: k = self._input.receiveData().decode('utf-8') - if k == '\r\n': + if k == '\r\n' or k == '\n\r': k = '\r' + if '\r\n' in k or '\n\r' in k: + k = k.replace('\n', '') + elif '\n' in k: + k = k.replace('\n', '\r') else: k = inkey(self._input).decode('utf-8') if k != '': diff --git a/vendors/EdgeCore/enableCommandProcessor.py b/vendors/EdgeCore/enableCommandProcessor.py index e78bb09..d3f392e 100644 --- a/vendors/EdgeCore/enableCommandProcessor.py +++ b/vendors/EdgeCore/enableCommandProcessor.py @@ -123,7 +123,7 @@ def do_show(self, command, *args, context=None): def do_copy(self, command, *args, context=None): if self._validate(args, 'startup-config', 'ftp'): # Work in progess ip = self.user_input("FTP server IP address: ", False, None) - user = self.user_input("User[anonymous]: ", False, None) + user = self.user_input("User [Anonymous]: ", False, None) self.hide_input = True pw = self.user_input("Password: ", False, None) self.hide_input = False From 721ea80a5f40c2c6b83cebe12e5decfdf786c37d Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 18 Dec 2020 12:00:19 +0100 Subject: [PATCH 195/318] Added public and private key for ssh-daemon --- bootup/conf/ssh/id_rsa | 28 ++++++++++++++++++++++++++++ bootup/conf/ssh/id_rsa.pub | 1 + 2 files changed, 29 insertions(+) create mode 100644 bootup/conf/ssh/id_rsa create mode 100644 bootup/conf/ssh/id_rsa.pub diff --git a/bootup/conf/ssh/id_rsa b/bootup/conf/ssh/id_rsa new file mode 100644 index 0000000..5c272a8 --- /dev/null +++ b/bootup/conf/ssh/id_rsa @@ -0,0 +1,28 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn +NhAAAAAwEAAQAAAQEA2m6f+W9xnt0mHvvJqzasFmIP1/z8gaDTYcgzwYhE4UItZeUXLUzx +3PGSiFd8GkRIjEhaPL9omFbL5E5q/SLNzu6AAg9eNOMKthy+EwyUYAC/Z36XSsjt89hXkv +SwzqIT7APl5hE4ZZIub3mA9q9YmLlo9bAi90UF11z7U3/jg0vlV45iDUj02Ont/QsvaxWr +EQG3XF4DWs5iid7RFqoHYdwEAMafi3nTZZKB8RGvsx9vpZkjLy5h+9Svgx1mFJZz2G4yJ0 +sEGOL/6QGCc6fp0L58+2rkVLGUZ0VT1o3WCp9ij8PKh24h1nuYXr1xHkG+ojVv1sXCnMxY +ww7g9BX3HwAAA+Ai4SmvIuEprwAAAAdzc2gtcnNhAAABAQDabp/5b3Ge3SYe+8mrNqwWYg +/X/PyBoNNhyDPBiEThQi1l5RctTPHc8ZKIV3waREiMSFo8v2iYVsvkTmr9Is3O7oACD140 +4wq2HL4TDJRgAL9nfpdKyO3z2FeS9LDOohPsA+XmEThlki5veYD2r1iYuWj1sCL3RQXXXP +tTf+ODS+VXjmINSPTY6e39Cy9rFasRAbdcXgNazmKJ3tEWqgdh3AQAxp+LedNlkoHxEa+z +H2+lmSMvLmH71K+DHWYUlnPYbjInSwQY4v/pAYJzp+nQvnz7auRUsZRnRVPWjdYKn2KPw8 +qHbiHWe5hevXEeQb6iNW/WxcKczFjDDuD0FfcfAAAAAwEAAQAAAQEA0i7ctJIuDKXURsAV +oDBtiuQ1Rqpi9wEgJdkVJEbRsMeTE5dLpAWEPgwd6h/0hPnrrUD5w7aTGPN8ImXqwUW6ME +KC3niXN+C4r+AcbgwOwgo2I4pGXmnVvmwQaJIXh92hudtOXwF2+RWepRmPpM+5Osw+WRtx +qem64y7Pj9thuzWGyKGuFmQ8ujb7zh6ovWwNlyTB64rM9zq+YFPh8QWiXocRwN7egOChtZ +fF+amgn/wkMi1Ja11PTIzVON/ajg0vnpPYOZ56boerPU3YhRHnzHXkSa34qvzd7XofiNee +2ybfFO7QxaEhDfcIXqztItPp6t1RvIUb89lUyCT4WkG3cQAAAIEAtiMJt2nkKL8UWbY6PT +wgEZ9D4RRuZzEk4SMnonXxGaFAXtnL2+sKlQiyJhGJEKQrWAyEBIXQtZNo2rZwLIvOOq7T +uXk9OjwCGPXT50jLrhD09yBNeWAR4fZsCqAYEq1cjLZgaXJxBGiBWfvk0vHADnz6PKPxfi +q7PJKn7WAIT/4AAACBAPrlmB0HOvFL0QAN4HnvLe3QMy7HuDVoYaQ9jz9uB9T7VTE+N7R9 +CxwDD8AUufU8gc88tw1FBUaWN1l6K8gSC0KIIKgIVtT+lttblKY1qJIakox2V/+qbtPU0T +DTSaC85znNkUJ4eqavRCitjPVnKke6v5JSePQO6Rag5/8Ww9KjAAAAgQDe3/0ca5btlE7n +iDEWQxfpzBYyED19VVb0HVM82BMYDb9rbgdmAu5vEWmIhtOyNTjkvOR5ZvZ5alsFY+FbcV +QVDWu5AqHGp+iUm1pfxCNB7UbJN664O+raL6UyHDQLZfjPT/rUCL2PX4ePsLaV4Cc8lQ5D +thL7QOgFiQ2Sx9JNVQAAACRqYW5pc19ncm9zc0BKYW5pc3MtTWFjQm9vay1Qcm8ubG9jYW +wBAgMEBQ== +-----END OPENSSH PRIVATE KEY----- diff --git a/bootup/conf/ssh/id_rsa.pub b/bootup/conf/ssh/id_rsa.pub new file mode 100644 index 0000000..3eb0b1b --- /dev/null +++ b/bootup/conf/ssh/id_rsa.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDabp/5b3Ge3SYe+8mrNqwWYg/X/PyBoNNhyDPBiEThQi1l5RctTPHc8ZKIV3waREiMSFo8v2iYVsvkTmr9Is3O7oACD1404wq2HL4TDJRgAL9nfpdKyO3z2FeS9LDOohPsA+XmEThlki5veYD2r1iYuWj1sCL3RQXXXPtTf+ODS+VXjmINSPTY6e39Cy9rFasRAbdcXgNazmKJ3tEWqgdh3AQAxp+LedNlkoHxEa+zH2+lmSMvLmH71K+DHWYUlnPYbjInSwQY4v/pAYJzp+nQvnz7auRUsZRnRVPWjdYKn2KPw8qHbiHWe5hevXEeQb6iNW/WxcKczFjDDuD0Ffcf janis_gross@Janiss-MacBook-Pro.local From 639d0e9b8f39e53ccc95b166e0b75b5b6349fde1 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 23 Sep 2020 10:13:26 +0200 Subject: [PATCH 196/318] Initial commit for vendor KeyMile --- .../conf/bootstraps/create-keymile-MG2200.sh | 135 ++++++++++++++++++ bootup/restapi.sh | 7 +- nesi/keymile/keymile_resources/keymile_box.py | 17 ++- .../keymile/keymile_resources/keymile_card.py | 27 ++++ .../keymile_resources/keymile_subrack.py | 27 ++++ nesi/softbox/api/views/card_views.py | 33 ++--- nesi/softbox/cli/base.py | 8 +- templates/KeyMile/login/mainloop/help.j2 | 19 +++ templates/KeyMile/login/mainloop/help_cd.j2 | 9 ++ .../KeyMile/login/mainloop/help_download.j2 | 10 ++ templates/KeyMile/login/mainloop/help_exit.j2 | 9 ++ .../KeyMile/login/mainloop/help_ftpserver.j2 | 11 ++ templates/KeyMile/login/mainloop/help_get.j2 | 9 ++ templates/KeyMile/login/mainloop/help_help.j2 | 28 ++++ templates/KeyMile/login/mainloop/help_ls.j2 | 10 ++ templates/KeyMile/login/mainloop/help_mode.j2 | 14 ++ .../KeyMile/login/mainloop/help_profile.j2 | 14 ++ templates/KeyMile/login/mainloop/help_pwd.j2 | 4 + templates/KeyMile/login/mainloop/help_set.j2 | 12 ++ templates/KeyMile/login/mainloop/help_show.j2 | 13 ++ .../KeyMile/login/mainloop/help_upload.j2 | 10 ++ templates/KeyMile/login/mainloop/ls_body.j2 | 2 + templates/KeyMile/login/mainloop/ls_header.j2 | 23 +++ templates/KeyMile/login/mainloop/on_cycle.j2 | 1 + templates/KeyMile/login/mainloop/on_enter.j2 | 2 + templates/KeyMile/login/mainloop/on_error.j2 | 2 + templates/KeyMile/login/mainloop/on_exit.j2 | 0 templates/KeyMile/login/on_cycle.j2 | 0 templates/KeyMile/login/on_enter.j2 | 1 + templates/KeyMile/login/on_exit.j2 | 0 templates/KeyMile/login/password.j2 | 2 + templates/KeyMile/on_cycle.j2 | 1 + templates/KeyMile/on_enter.j2 | 0 templates/KeyMile/on_exit.j2 | 2 + vendors/KeyMile/__init__.py | 0 vendors/KeyMile/baseCommandProcessor.py | 18 +++ vendors/KeyMile/changeDirectoryProcessor.py | 20 +++ vendors/KeyMile/main.py | 66 +++++++++ vendors/KeyMile/rootCommandProcessor.py | 74 ++++++++++ 39 files changed, 612 insertions(+), 28 deletions(-) create mode 100644 bootup/conf/bootstraps/create-keymile-MG2200.sh create mode 100644 nesi/keymile/keymile_resources/keymile_card.py create mode 100644 nesi/keymile/keymile_resources/keymile_subrack.py create mode 100644 templates/KeyMile/login/mainloop/help.j2 create mode 100644 templates/KeyMile/login/mainloop/help_cd.j2 create mode 100644 templates/KeyMile/login/mainloop/help_download.j2 create mode 100644 templates/KeyMile/login/mainloop/help_exit.j2 create mode 100644 templates/KeyMile/login/mainloop/help_ftpserver.j2 create mode 100644 templates/KeyMile/login/mainloop/help_get.j2 create mode 100644 templates/KeyMile/login/mainloop/help_help.j2 create mode 100644 templates/KeyMile/login/mainloop/help_ls.j2 create mode 100644 templates/KeyMile/login/mainloop/help_mode.j2 create mode 100644 templates/KeyMile/login/mainloop/help_profile.j2 create mode 100644 templates/KeyMile/login/mainloop/help_pwd.j2 create mode 100644 templates/KeyMile/login/mainloop/help_set.j2 create mode 100644 templates/KeyMile/login/mainloop/help_show.j2 create mode 100644 templates/KeyMile/login/mainloop/help_upload.j2 create mode 100644 templates/KeyMile/login/mainloop/ls_body.j2 create mode 100644 templates/KeyMile/login/mainloop/ls_header.j2 create mode 100644 templates/KeyMile/login/mainloop/on_cycle.j2 create mode 100644 templates/KeyMile/login/mainloop/on_enter.j2 create mode 100644 templates/KeyMile/login/mainloop/on_error.j2 create mode 100644 templates/KeyMile/login/mainloop/on_exit.j2 create mode 100644 templates/KeyMile/login/on_cycle.j2 create mode 100644 templates/KeyMile/login/on_enter.j2 create mode 100644 templates/KeyMile/login/on_exit.j2 create mode 100644 templates/KeyMile/login/password.j2 create mode 100644 templates/KeyMile/on_cycle.j2 create mode 100644 templates/KeyMile/on_enter.j2 create mode 100644 templates/KeyMile/on_exit.j2 create mode 100644 vendors/KeyMile/__init__.py create mode 100644 vendors/KeyMile/baseCommandProcessor.py create mode 100644 vendors/KeyMile/changeDirectoryProcessor.py create mode 100644 vendors/KeyMile/main.py create mode 100644 vendors/KeyMile/rootCommandProcessor.py diff --git a/bootup/conf/bootstraps/create-keymile-MG2200.sh b/bootup/conf/bootstraps/create-keymile-MG2200.sh new file mode 100644 index 0000000..89263b1 --- /dev/null +++ b/bootup/conf/bootstraps/create-keymile-MG2200.sh @@ -0,0 +1,135 @@ +#!/bin/bash +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst +# +# Example NESi REST API server bootstrapping +# +ENDPOINT=http://localhost:5000/nesi/v1 + +path="`dirname \"$0\"`" + +. $path/functions.sh + +# Create a network device (admin operation) +req='{ + "vendor": "KeyMile", + "model": "MG2200", + "version": "1", + "description": "Example Switch", + "hostname": "KeyMileMG2200", + "mgmt_address": "10.0.0.12", + "software_version": "MG2200V800R016C00", + "network_protocol": "telnet", + "network_address": "127.0.0.1", + "network_port": 9023, + "uuid": "2200" +}' + +box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 + +# Admin credentials +req='{ + "username": "admin", + "password": "secret" +}' + +root_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +### Subrack 0 ### + +# Create a physical subrack at the network device (admin operation) +req='{ + "name": "", + "description": "Pseudo Subrack" +}' + +subrack_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks) + +### Unit-1 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "xdsl" +}' + +unit_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-2 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "xdsl" +}' + +unit_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-3 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "xdsl" +}' + +unit_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-2 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "xdsl" +}' + +unit_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-5 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "vdsl" +}' + +unit_5=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-6 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "vdsl" +}' + +unit_6=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-7 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "vdsl" +}' + +unit_7=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-8 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "vdsl" +}' + +unit_8=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) \ No newline at end of file diff --git a/bootup/restapi.sh b/bootup/restapi.sh index 6c7d600..d14d657 100755 --- a/bootup/restapi.sh +++ b/bootup/restapi.sh @@ -179,8 +179,9 @@ bash bootup/conf/bootstraps/create-vendors-and-models.sh if [ $recreate_db = "yes" ]; then #bash bootup/conf/bootstraps/create-box-port-vlan.sh - bash bootup/conf/bootstraps/create-alcatel-7360.sh - bash bootup/conf/bootstraps/create-huawei-5623.sh + #bash bootup/conf/bootstraps/create-alcatel-7360.sh + #bash bootup/conf/bootstraps/create-huawei-5623.sh + bash bootup/conf/bootstraps/create-keymile-MG2200.sh fi if [ $alcatel_api = "yes" ]; then @@ -190,7 +191,7 @@ if [ $huawei_api = "yes" ]; then bash bootup/conf/bootstraps/create-huawei-5623.sh fi if [ $keymile_api = "yes" ]; then - bash bootup/conf/bootstraps/create-alcatel-7360.sh #work_in_progress + bash bootup/conf/bootstraps/create-keymile-MG2200.sh #work_in_progress fi if [ $edgecore_api = "yes" ]; then bash bootup/conf/bootstraps/create-alcatel-7360.sh #work_in_progress diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 710f68c..295f363 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -9,10 +9,9 @@ # - Alexander Dincher # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.keymile.keymile_resources import * +from nesi.keymile.keymile_resources import keymile_card from nesi.softbox.base_resources import credentials -from nesi.softbox.base_resources import route from nesi.softbox.base_resources.box import * LOG = logging.getLogger(__name__) @@ -26,6 +25,20 @@ class KeyMileBox(Box): """ # Define Keymile Properties + @property + def credentials(self): + """Return `CredentialsCollection` object.""" + return credentials.CredentialsCollection( + self._conn, base.get_sub_resource_path_by( + self, 'credentials')) + + @property + def cards(self): + """Return `CredentialsCollection` object.""" + return keymile_card.KeyMileCardCollection( + self._conn, base.get_sub_resource_path_by( + self, 'cards')) + class KeyMileBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/keymile/keymile_resources/keymile_card.py b/nesi/keymile/keymile_resources/keymile_card.py new file mode 100644 index 0000000..3870bc6 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_card.py @@ -0,0 +1,27 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.card import CardCollection, Card, logging, base + +LOG = logging.getLogger(__name__) + + +class KeyMileCard(Card): + """Represent physical shelf resource.""" + + +class KeyMileCardCollection(CardCollection): + """Represent a collection of cards.""" + + @property + def _resource_type(self): + return KeyMileCard \ No newline at end of file diff --git a/nesi/keymile/keymile_resources/keymile_subrack.py b/nesi/keymile/keymile_resources/keymile_subrack.py new file mode 100644 index 0000000..b228dc6 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_subrack.py @@ -0,0 +1,27 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.subrack import Subrack, SubrackCollection, logging, base + +LOG = logging.getLogger(__name__) + + +class KeyMileSubrack(Subrack): + """Represent physical shelf resource.""" + + +class KeyMileSubrackCollection(SubrackCollection): + """Represent a collection of subracks.""" + + @property + def _resource_type(self): + return KeyMileSubrack \ No newline at end of file diff --git a/nesi/softbox/api/views/card_views.py b/nesi/softbox/api/views/card_views.py index 5ebe026..c063e89 100644 --- a/nesi/softbox/api/views/card_views.py +++ b/nesi/softbox/api/views/card_views.py @@ -42,49 +42,40 @@ def show_card(box_id, id): def new_card(box_id): req = flask.request.json + vendor = '' if 'name' not in req or req['name'] == "": subrack = json.loads(show_component(Subrack, box_id, req['subrack_id']).data.decode('utf-8')) box = json.loads(show_box(box_id)[0].data.decode('utf-8')) + vendor = box['vendor'] if len(subrack['cards']) > 0: last_card = subrack['cards'][len(subrack['cards']) - 1] - if last_card['name'].startswith('nt-'): + if last_card['name'].startswith('nt-') and vendor == 'Alcatel': if subrack['name'] != "": - if box['vendor'] == 'Huawei': - req['name'] = subrack['name'] + "/0" - else: - req['name'] = subrack['name'] + "/1" + req['name'] = subrack['name'] + "/1" else: - if box['vendor'] == 'Huawei': - req['name'] = "0" - else: - req['name'] = "1" + req['name'] = "1" else: - p = re.compile('[0-9]+/([0-9]+(/)?([0-9]+)?)') - last_card_index = '' - check = p.match(last_card['name']).groups(1) - if len(check[0]) <= 2 and not check[0].endswith('/'): - last_card_index = check[0] - elif len(check[0]) > 2: - _, last_card_index = check[0].split('/', maxsplit=1) - else: - return flask.Response(status=400) + p = re.compile('^([0-9]+)?/?([0-9]+)?/?([0-9]+)?$') + match_groups = p.match(last_card['name']).groups() + filtered_match_groups = [x for x in match_groups if x is not None] # filter out None values + last_card_index = filtered_match_groups[len(filtered_match_groups) - 1] if subrack['name'] != "": req['name'] = subrack['name'] + "/" + str(int(last_card_index) + 1) else: req['name'] = str(int(last_card_index) + 1) else: if subrack['name'] != "": - if box['vendor'] == 'Huawei': + if vendor == 'Huawei': req['name'] = subrack['name'] + "/0" else: req['name'] = subrack['name'] + "/1" else: - if box['vendor'] == 'Huawei': + if vendor == 'Huawei': req['name'] = "0" else: req['name'] = "1" - if 'position' not in req or req['position'] == "": + if 'position' not in req or req['position'] == "" and vendor == 'Alcatel': req['position'] = 'lt:' + req['name'] response = new_component(CardSchema(), Card, req, box_id) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index c69e2d6..f1a1f42 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -64,6 +64,7 @@ def __init__(self, model, input_stream, output_stream, history, self.line_buffer = [] self.history_enabled = True self.hide_input = False + self.star_input = False self.history_pos = 0 self.history = history self.prompt_end_pos = self.get_prompt_len() - 1 @@ -209,7 +210,10 @@ def getline(self, tmp_boundary=None): break if not self.hide_input: - self.updateline(line) + out = line + if self.star_input: + out = len(line) * '*' + self.updateline(out) if line != '\r' and line != '' and self.history_enabled: self.history += (line.replace('\r', '').rstrip(),) @@ -382,7 +386,7 @@ def get_prompt_len(self): def set_prompt_end_pos(self, context): text = self._render('on_cycle', context=context, ignore_errors=True) - if len(text) == 0: + if text is None or len(text) == 0: text = self._render('on_enter', context=context, ignore_errors=True) self.prompt_end_pos = len(text.replace('\n', '')) - 1 diff --git a/templates/KeyMile/login/mainloop/help.j2 b/templates/KeyMile/login/mainloop/help.j2 new file mode 100644 index 0000000..7e32ef8 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help.j2 @@ -0,0 +1,19 @@ + +commands +-------- + +cd -- Change to specified node address and/or MF +pwd -- Show current address +ls -- Show infos for current address +show -- Show settings +mode -- Configure operation modes +ftpserver -- Configure the (s)ftp-server settings +upload -- Upload a file (filename) from the NE into the (s)ftp server (serverpath) +download -- Download a file (serverpath/filename) from the (s)ftp server into the NE +get -- Get property values from the node +set -- Define property values and send them to the node +profile -- profile utility +help -- Show CLI operation help +exit -- Exit CLI session + + diff --git a/templates/KeyMile/login/mainloop/help_cd.j2 b/templates/KeyMile/login/mainloop/help_cd.j2 new file mode 100644 index 0000000..fd008c8 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_cd.j2 @@ -0,0 +1,9 @@ + +Syntax: + cd
+ +Change to specified node address and/or MF + + address -- node address and/or MF (i.e. /unit-11/main) + + diff --git a/templates/KeyMile/login/mainloop/help_download.j2 b/templates/KeyMile/login/mainloop/help_download.j2 new file mode 100644 index 0000000..d649a27 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_download.j2 @@ -0,0 +1,10 @@ + +Syntax: + download
+ +Download a file (serverpath/filename) from the (s)ftp server into the NE + + address MO address -- MO address of a file node + remoteFile characters -- Filepath and -name on file server + + diff --git a/templates/KeyMile/login/mainloop/help_exit.j2 b/templates/KeyMile/login/mainloop/help_exit.j2 new file mode 100644 index 0000000..719f4cc --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_exit.j2 @@ -0,0 +1,9 @@ + +Syntax: + exit [-s] + +Exit CLI session + + -s -- Save configuration on exit + + diff --git a/templates/KeyMile/login/mainloop/help_ftpserver.j2 b/templates/KeyMile/login/mainloop/help_ftpserver.j2 new file mode 100644 index 0000000..e24ebb7 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_ftpserver.j2 @@ -0,0 +1,11 @@ + +Syntax: + ftpserver + +Configure the (s)ftp-server settings + + ipAddress IP address -- IP address of the server + user characters -- User to logon the server + password characters -- Password to logon the server + + diff --git a/templates/KeyMile/login/mainloop/help_get.j2 b/templates/KeyMile/login/mainloop/help_get.j2 new file mode 100644 index 0000000..629d1ad --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_get.j2 @@ -0,0 +1,9 @@ + +Syntax: + get + +Get property values from the node + + property -- MO Address of a property + + diff --git a/templates/KeyMile/login/mainloop/help_help.j2 b/templates/KeyMile/login/mainloop/help_help.j2 new file mode 100644 index 0000000..0219d12 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_help.j2 @@ -0,0 +1,28 @@ + +Syntax: + help [] + +Display a description for global commands or for the optionally specified operation + + operation -- any valid command or property operation + +Notation syntax: + - Parameters enclosed in square brackets [ ] are optional + - Parameter values enclosed in angle brackets < > must be specified by the user + - Predefined selections are enclosed in parantheses ( ) and separated by a vertical bar | + - Elements in tables are enclosed in curly brackets { } and separated by a semicolon ; + +MO address syntax: + - An absolute address notation always begins with the slash '/' + - The addition of a MF after the MO address is optional + + [(. | ..)]/[/(main | cfgm | fm | pm | status)] + + / forward-slash -- substitute for the AP root and separator for multiple address elements + MO-address -- The MO address consists of one or several node IDs, separated with a slash + (main | cfgm | fm | pm | status) keywords for MFs -- The management function may be appended to the MO-address + ./ dot forward-slash -- substitute for the current location in the AP tree + ../ dot dot forward-slash -- one step upwards in the AP tree + + + diff --git a/templates/KeyMile/login/mainloop/help_ls.j2 b/templates/KeyMile/login/mainloop/help_ls.j2 new file mode 100644 index 0000000..6f452c1 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_ls.j2 @@ -0,0 +1,10 @@ + +Syntax: + ls [
] [-e] + +Show infos for current address + + address -- node address and/or MF (i.e. /unit-11/main) + -e -- Extends infos about children + + diff --git a/templates/KeyMile/login/mainloop/help_mode.j2 b/templates/KeyMile/login/mainloop/help_mode.j2 new file mode 100644 index 0000000..245edc4 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_mode.j2 @@ -0,0 +1,14 @@ + +mode commands +------------- + +display -- Configure display operation mode +etx -- Configure ETX mode (cli output termination) +prompt -- Configure prompt mode +syntaxversion -- Configure CLI syntax version for script compatibility +warnings -- Configure warnings mode (warnings on/off in plain display mode) + +Syntax: + mode + + diff --git a/templates/KeyMile/login/mainloop/help_profile.j2 b/templates/KeyMile/login/mainloop/help_profile.j2 new file mode 100644 index 0000000..b72b7f9 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_profile.j2 @@ -0,0 +1,14 @@ + +profile commands +---------------- + +create -- create a profile +list -- list profiles +showDefaults -- show default values of a profile type +showTypes -- show available profile types +showValues -- show values of a profile + +Syntax: + profile + + diff --git a/templates/KeyMile/login/mainloop/help_pwd.j2 b/templates/KeyMile/login/mainloop/help_pwd.j2 new file mode 100644 index 0000000..4073496 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_pwd.j2 @@ -0,0 +1,4 @@ + +Show current address + + diff --git a/templates/KeyMile/login/mainloop/help_set.j2 b/templates/KeyMile/login/mainloop/help_set.j2 new file mode 100644 index 0000000..bf73063 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_set.j2 @@ -0,0 +1,12 @@ + +Syntax: + set ... + +Define property values and send them to the node + + property characters + attr1 characters + attr2 characters + ... + + diff --git a/templates/KeyMile/login/mainloop/help_show.j2 b/templates/KeyMile/login/mainloop/help_show.j2 new file mode 100644 index 0000000..d22768f --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_show.j2 @@ -0,0 +1,13 @@ + +show commands +------------- + +mode -- Show current modes +version -- Show CLI version +ftpserver -- Show (S)FTP server settings +sessionIf -- Show CLI sessionIf + +Syntax: + show + + diff --git a/templates/KeyMile/login/mainloop/help_upload.j2 b/templates/KeyMile/login/mainloop/help_upload.j2 new file mode 100644 index 0000000..2f04846 --- /dev/null +++ b/templates/KeyMile/login/mainloop/help_upload.j2 @@ -0,0 +1,10 @@ + +Syntax: + upload
+ +Upload a file (filename) from the NE into the (s)ftp server (serverpath) + + address MO address -- MO address of a file node + remoteFile characters -- Filepath and -name on file server + + diff --git a/templates/KeyMile/login/mainloop/ls_body.j2 b/templates/KeyMile/login/mainloop/ls_body.j2 new file mode 100644 index 0000000..75c88ef --- /dev/null +++ b/templates/KeyMile/login/mainloop/ls_body.j2 @@ -0,0 +1,2 @@ + unit-{{ context.card.name }} + diff --git a/templates/KeyMile/login/mainloop/ls_header.j2 b/templates/KeyMile/login/mainloop/ls_header.j2 new file mode 100644 index 0000000..6080a9f --- /dev/null +++ b/templates/KeyMile/login/mainloop/ls_header.j2 @@ -0,0 +1,23 @@ +Infos of AP: / + Name : MileGate 2200 + Main Mode : + Equipment State : Ok + Alarm Severity : Cleared + Propagated Alarm Severity : Major + User Label : + Service Label : + Description : + +MF List: + main + cfgm + fm + status + +AP List: + eoam + fan + multicast + services + tdmConnections + diff --git a/templates/KeyMile/login/mainloop/on_cycle.j2 b/templates/KeyMile/login/mainloop/on_cycle.j2 new file mode 100644 index 0000000..050587e --- /dev/null +++ b/templates/KeyMile/login/mainloop/on_cycle.j2 @@ -0,0 +1 @@ +/> diff --git a/templates/KeyMile/login/mainloop/on_enter.j2 b/templates/KeyMile/login/mainloop/on_enter.j2 new file mode 100644 index 0000000..84f6b7f --- /dev/null +++ b/templates/KeyMile/login/mainloop/on_enter.j2 @@ -0,0 +1,2 @@ +---===### CLI Release R2A20, Build 2014-01-31 ###===--- + diff --git a/templates/KeyMile/login/mainloop/on_error.j2 b/templates/KeyMile/login/mainloop/on_error.j2 new file mode 100644 index 0000000..c36472c --- /dev/null +++ b/templates/KeyMile/login/mainloop/on_error.j2 @@ -0,0 +1,2 @@ +error: invalid management function + diff --git a/templates/KeyMile/login/mainloop/on_exit.j2 b/templates/KeyMile/login/mainloop/on_exit.j2 new file mode 100644 index 0000000..e69de29 diff --git a/templates/KeyMile/login/on_cycle.j2 b/templates/KeyMile/login/on_cycle.j2 new file mode 100644 index 0000000..e69de29 diff --git a/templates/KeyMile/login/on_enter.j2 b/templates/KeyMile/login/on_enter.j2 new file mode 100644 index 0000000..fb31150 --- /dev/null +++ b/templates/KeyMile/login/on_enter.j2 @@ -0,0 +1 @@ +password: diff --git a/templates/KeyMile/login/on_exit.j2 b/templates/KeyMile/login/on_exit.j2 new file mode 100644 index 0000000..e69de29 diff --git a/templates/KeyMile/login/password.j2 b/templates/KeyMile/login/password.j2 new file mode 100644 index 0000000..5d94c41 --- /dev/null +++ b/templates/KeyMile/login/password.j2 @@ -0,0 +1,2 @@ +Login failure: Unknown userclass + diff --git a/templates/KeyMile/on_cycle.j2 b/templates/KeyMile/on_cycle.j2 new file mode 100644 index 0000000..2a6191f --- /dev/null +++ b/templates/KeyMile/on_cycle.j2 @@ -0,0 +1 @@ +login as: diff --git a/templates/KeyMile/on_enter.j2 b/templates/KeyMile/on_enter.j2 new file mode 100644 index 0000000..e69de29 diff --git a/templates/KeyMile/on_exit.j2 b/templates/KeyMile/on_exit.j2 new file mode 100644 index 0000000..989d95b --- /dev/null +++ b/templates/KeyMile/on_exit.j2 @@ -0,0 +1,2 @@ +SESSION CLOSED + diff --git a/vendors/KeyMile/__init__.py b/vendors/KeyMile/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py new file mode 100644 index 0000000..6edfcdd --- /dev/null +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -0,0 +1,18 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from nesi.softbox.cli import base + + +class BaseCommandProcessor(base.CommandProcessor): + """Create CLI REPR loop for example switch.""" diff --git a/vendors/KeyMile/changeDirectoryProcessor.py b/vendors/KeyMile/changeDirectoryProcessor.py new file mode 100644 index 0000000..19abce5 --- /dev/null +++ b/vendors/KeyMile/changeDirectoryProcessor.py @@ -0,0 +1,20 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import re +from nesi import exceptions + + +class ChangeDirectoryProcessor: + + def do_cd(self, command, *args, context=None): + pass \ No newline at end of file diff --git a/vendors/KeyMile/main.py b/vendors/KeyMile/main.py new file mode 100644 index 0000000..b3dcf3f --- /dev/null +++ b/vendors/KeyMile/main.py @@ -0,0 +1,66 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.cli import base +from nesi import exceptions +from vendors.KeyMile.rootCommandProcessor import RootCommandProcessor + + +class ReadInputCommandProcessor(base.CommandProcessor): + """Create CLI REPR loop for example switch.""" + + VENDOR = 'KeyMile' + MODEL = 'MG2200' + VERSION = '1' + + +class PreLoginCommandProcessor(ReadInputCommandProcessor): + + def on_unknown_command(self, command, *args, context=None): + subprocessor = self._create_subprocessor( + LoginCommandProcessor, 'login') + + context['username'] = context['raw_line'].replace('\r', '').replace('\n', '') + + try: + subprocessor.history_enabled = False + subprocessor.star_input = True + subprocessor.loop(context=context) + except exceptions.TerminalExitError as exc: + if exc.return_to is not None and exc.return_to != 'sysexit': + raise exc + else: + self.on_exit(context) + raise exc + + +class LoginCommandProcessor(ReadInputCommandProcessor): + + def on_unknown_command(self, command, *args, context=None): + username = context.pop('username') + password = command + + for creds in self._model.credentials: + if creds.username == username and creds.password == password: + break + + else: + text = self._render('password', context=context) + self._write(text) + raise exceptions.TerminalExitError() + + subprocessor = self._create_subprocessor( + RootCommandProcessor, 'login', 'mainloop') + + subprocessor.loop(context=context) + + self.on_exit(context) diff --git a/vendors/KeyMile/rootCommandProcessor.py b/vendors/KeyMile/rootCommandProcessor.py new file mode 100644 index 0000000..71c0edf --- /dev/null +++ b/vendors/KeyMile/rootCommandProcessor.py @@ -0,0 +1,74 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from .baseCommandProcessor import BaseCommandProcessor +from .changeDirectoryProcessor import ChangeDirectoryProcessor + + +class RootCommandProcessor(BaseCommandProcessor, ChangeDirectoryProcessor): + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) + + def do_help(self, command, *args, context=None): + if self._validate(args, str): + help_arg, = self._dissect(args, str) + + if help_arg == 'cd': + self._write(self._render('help_cd', context=context)) + elif help_arg == 'pwd': + self._write(self._render('help_pwd', context=context)) + elif help_arg == 'ls': + self._write(self._render('help_ls', context=context)) + elif help_arg == 'show': + self._write(self._render('help_show', context=context)) + elif help_arg == 'mode': + self._write(self._render('help_mode', context=context)) + elif help_arg == 'ftpserver': + self._write(self._render('help_ftpserver', context=context)) + elif help_arg == 'upload': + self._write(self._render('help_upload', context=context)) + elif help_arg == 'download': + self._write(self._render('help_download', context=context)) + elif help_arg == 'get': + self._write(self._render('help_get', context=context)) + elif help_arg == 'set': + self._write(self._render('help_set', context=context)) + elif help_arg == 'profile': + self._write(self._render('help_profile', context=context)) + elif help_arg == 'help': + self._write(self._render('help_help', context=context)) + elif help_arg == 'exit': + self._write(self._render('help_exit', context=context)) + else: + raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args,): + self._write(self._render('help', context=context)) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_exit(self, command, *args, context=None): + exc = exceptions.TerminalExitError() + exc.return_to = 'sysexit' + raise exc + + def do_ls(self, command, *args, context=None): + if self._validate(args,): + text = self._render('ls_header', context=context) + + for card in self._model.cards: + text += self._render('ls_body', context=dict(context, card=card)) + + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file From dca4689eae02044aa12abf6209ff7fb08ee52d3a Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 1 Oct 2020 10:09:20 +0200 Subject: [PATCH 197/318] Initial push for cd and ls commands --- .../conf/bootstraps/create-keymile-MG2200.sh | 74 ++++- nesi/exceptions.py | 23 ++ .../keymile/api/__init__.py | 0 .../keymile/api/schemas/__init__.py | 0 .../api/schemas/keymile_box_schemas.py | 27 ++ .../api/schemas/keymile_channel_schemas.py | 11 +- .../api/schemas/keymile_port_schemas.py | 21 ++ nesi/keymile/keymile_resources/__init__.py | 2 +- nesi/keymile/keymile_resources/keymile_box.py | 67 ++++- .../keymile_resources/keymile_channel.py | 34 +++ .../keymile_resources/keymile_interface.py | 34 +++ .../keymile/keymile_resources/keymile_port.py | 27 ++ nesi/softbox/api/models/box_models.py | 3 + nesi/softbox/api/models/channel_models.py | 23 ++ nesi/softbox/api/models/interface_models.py | 22 ++ nesi/softbox/api/models/port_models.py | 6 + nesi/softbox/api/schemas/box_schemas.py | 12 +- nesi/softbox/api/schemas/channel_schemas.py | 52 ++++ nesi/softbox/api/schemas/interface_schemas.py | 49 ++++ nesi/softbox/api/schemas/port_schemas.py | 8 +- nesi/softbox/api/views/__init__.py | 2 +- nesi/softbox/api/views/channel_views.py | 59 ++++ nesi/softbox/api/views/interface_views.py | 65 +++++ nesi/softbox/cli/base.py | 20 +- .../execution_errors/invalid_address_error.j2 | 2 + .../invalid_management_function_error.j2} | 0 .../login/{mainloop => base/help}/help.j2 | 0 .../login/{mainloop => base/help}/help_cd.j2 | 0 .../{mainloop => base/help}/help_download.j2 | 0 .../{mainloop => base/help}/help_exit.j2 | 0 .../{mainloop => base/help}/help_ftpserver.j2 | 0 .../login/{mainloop => base/help}/help_get.j2 | 0 .../{mainloop => base/help}/help_help.j2 | 0 .../login/{mainloop => base/help}/help_ls.j2 | 0 .../{mainloop => base/help}/help_mode.j2 | 0 .../{mainloop => base/help}/help_profile.j2 | 0 .../login/{mainloop => base/help}/help_pwd.j2 | 0 .../login/{mainloop => base/help}/help_set.j2 | 0 .../{mainloop => base/help}/help_show.j2 | 0 .../{mainloop => base/help}/help_upload.j2 | 0 .../on_enter.j2 => base/login_message.j2} | 0 templates/KeyMile/login/base/ls/ls_ap_list.j2 | 3 + .../login/{mainloop => base/ls}/ls_header.j2 | 15 +- .../KeyMile/login/base/ls/ls_list_body.j2 | 2 + templates/KeyMile/login/base/ls/ls_mf_body.j2 | 2 + .../KeyMile/login/base/ls/ls_mf_header.j2 | 2 + templates/KeyMile/login/base/ls/ls_mf_list.j2 | 3 + templates/KeyMile/login/base/on_cycle.j2 | 1 + templates/KeyMile/login/base/on_error.j2 | 2 + templates/KeyMile/login/base/pwd.j2 | 2 + .../login/base/syntax_errors/syntax_error.j2 | 2 + templates/KeyMile/login/mainloop/ls_body.j2 | 2 - templates/KeyMile/login/mainloop/on_cycle.j2 | 1 - templates/KeyMile/login/on_exit.j2 | 0 templates/KeyMile/on_enter.j2 | 0 .../accessPoints/root/eoamCommandProcessor.py | 29 ++ .../root/fan/fanAlarmCommandProcessor.py | 29 ++ .../root/fan/fanCommandProcessor.py | 29 ++ .../root/multicastCommandProcessor.py | 33 +++ .../accessPoints/root/rootCommandProcessor.py | 80 ++++++ .../root/services/servicesCommandProcessor.py | 29 ++ .../servicesMacAccessCtrlCommandProcessor.py | 31 ++ .../servicesPacketCommandProcessor.py | 25 ++ .../root/tdmConnectionsCommandProcessor.py | 27 ++ .../unit/port/chan/chanCommandProcessor.py | 47 ++++ .../unit/port/chan/vcc/vccCommandProcessor.py | 23 ++ .../interface/interfaceCommandProcessor.py | 34 +++ .../root/unit/port/portCommandProcessor.py | 42 +++ .../root/unit/unitCommandProcessor.py | 44 +++ vendors/KeyMile/baseCommandProcessor.py | 264 ++++++++++++++++++ vendors/KeyMile/main.py | 22 +- vendors/KeyMile/rootCommandProcessor.py | 74 ----- 72 files changed, 1420 insertions(+), 122 deletions(-) rename templates/KeyMile/login/mainloop/on_exit.j2 => nesi/keymile/api/__init__.py (100%) rename templates/KeyMile/login/on_cycle.j2 => nesi/keymile/api/schemas/__init__.py (100%) create mode 100644 nesi/keymile/api/schemas/keymile_box_schemas.py rename vendors/KeyMile/changeDirectoryProcessor.py => nesi/keymile/api/schemas/keymile_channel_schemas.py (66%) create mode 100644 nesi/keymile/api/schemas/keymile_port_schemas.py create mode 100644 nesi/keymile/keymile_resources/keymile_channel.py create mode 100644 nesi/keymile/keymile_resources/keymile_interface.py create mode 100644 nesi/keymile/keymile_resources/keymile_port.py create mode 100644 nesi/softbox/api/models/channel_models.py create mode 100644 nesi/softbox/api/models/interface_models.py create mode 100644 nesi/softbox/api/schemas/channel_schemas.py create mode 100644 nesi/softbox/api/schemas/interface_schemas.py create mode 100644 nesi/softbox/api/views/channel_views.py create mode 100644 nesi/softbox/api/views/interface_views.py create mode 100644 templates/KeyMile/login/base/execution_errors/invalid_address_error.j2 rename templates/KeyMile/login/{mainloop/on_error.j2 => base/execution_errors/invalid_management_function_error.j2} (100%) rename templates/KeyMile/login/{mainloop => base/help}/help.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_cd.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_download.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_exit.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_ftpserver.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_get.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_help.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_ls.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_mode.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_profile.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_pwd.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_set.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_show.j2 (100%) rename templates/KeyMile/login/{mainloop => base/help}/help_upload.j2 (100%) rename templates/KeyMile/login/{mainloop/on_enter.j2 => base/login_message.j2} (100%) create mode 100644 templates/KeyMile/login/base/ls/ls_ap_list.j2 rename templates/KeyMile/login/{mainloop => base/ls}/ls_header.j2 (70%) create mode 100644 templates/KeyMile/login/base/ls/ls_list_body.j2 create mode 100644 templates/KeyMile/login/base/ls/ls_mf_body.j2 create mode 100644 templates/KeyMile/login/base/ls/ls_mf_header.j2 create mode 100644 templates/KeyMile/login/base/ls/ls_mf_list.j2 create mode 100644 templates/KeyMile/login/base/on_cycle.j2 create mode 100644 templates/KeyMile/login/base/on_error.j2 create mode 100644 templates/KeyMile/login/base/pwd.j2 create mode 100644 templates/KeyMile/login/base/syntax_errors/syntax_error.j2 delete mode 100644 templates/KeyMile/login/mainloop/ls_body.j2 delete mode 100644 templates/KeyMile/login/mainloop/on_cycle.j2 delete mode 100644 templates/KeyMile/login/on_exit.j2 delete mode 100644 templates/KeyMile/on_enter.j2 create mode 100644 vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/rootCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py delete mode 100644 vendors/KeyMile/rootCommandProcessor.py diff --git a/bootup/conf/bootstraps/create-keymile-MG2200.sh b/bootup/conf/bootstraps/create-keymile-MG2200.sh index 89263b1..7bd564b 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2200.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2200.sh @@ -64,6 +64,36 @@ req='{ unit_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_1', + "admin_state": "1", + "operational_state": "1" +}' + +port_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Chan-1 ### + +# Create a logical channel at the network device (admin operation) +req='{ + "port_id": '$port_1_1', + "description": "Channel #1" +}' + +chan_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/channels) + +### Interface-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "chan_id": '$chan_1_1_1' +}' + +interface_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) + ### Unit-2 ### # Create a physical card at the network device (admin operation) @@ -74,6 +104,28 @@ req='{ unit_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_2', + "admin_state": "1", + "operational_state": "1" +}' + +port_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Port-2 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_2', + "admin_state": "1", + "operational_state": "1" +}' + +port_2_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + ### Unit-3 ### # Create a physical card at the network device (admin operation) @@ -84,7 +136,27 @@ req='{ unit_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) -### Unit-2 ### +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_3', + "admin_state": "1", + "operational_state": "1" +}' + +port_3_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Interface-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "port_id": '$port_3_1' +}' + +interface_3_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) + +### Unit-4 ### # Create a physical card at the network device (admin operation) req='{ diff --git a/nesi/exceptions.py b/nesi/exceptions.py index 4607f66..fd9c50c 100644 --- a/nesi/exceptions.py +++ b/nesi/exceptions.py @@ -76,15 +76,24 @@ class TerminalExitError(SoftboxenError): def __init__(self, **kwargs): super(TerminalExitError, self).__init__(**kwargs) self._return_to = None + self._command = None @property def return_to(self): return self._return_to + @property + def command(self): + return self._command + @return_to.setter def return_to(self, return_to): self._return_to = return_to + @command.setter + def command(self, command): + self._command = command + class TemplateError(SoftboxenError): """Raise on template rendering error.""" @@ -102,6 +111,20 @@ class CommandSyntaxError(SoftboxenError): def __init__(self, **kwargs): super(CommandSyntaxError, self).__init__(**kwargs) self.command = kwargs.get('command') + self.template = None + self.template_scopes = () + + +class CommandExecutionError(SoftboxenError): + """Raise on CLI command execution error.""" + + message = 'Command execution error: %(command)s' + + def __init__(self, **kwargs): + super(CommandExecutionError, self).__init__(**kwargs) + self.command = kwargs.get('command') + self.template = kwargs.get('template') + self.template_scopes = kwargs.get('template_scopes') class RestApiError(SoftboxenError): diff --git a/templates/KeyMile/login/mainloop/on_exit.j2 b/nesi/keymile/api/__init__.py similarity index 100% rename from templates/KeyMile/login/mainloop/on_exit.j2 rename to nesi/keymile/api/__init__.py diff --git a/templates/KeyMile/login/on_cycle.j2 b/nesi/keymile/api/schemas/__init__.py similarity index 100% rename from templates/KeyMile/login/on_cycle.j2 rename to nesi/keymile/api/schemas/__init__.py diff --git a/nesi/keymile/api/schemas/keymile_box_schemas.py b/nesi/keymile/api/schemas/keymile_box_schemas.py new file mode 100644 index 0000000..b4e571e --- /dev/null +++ b/nesi/keymile/api/schemas/keymile_box_schemas.py @@ -0,0 +1,27 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.box_schemas import * + + +class HuaweiBoxSchema(BoxSchema): + class Meta: + model = Box + fields = BoxSchema.Meta.fields + ('channels', 'interfaces') + + interfaces = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_interfaces', box_id='')}}) + + channels = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_channels', box_id='')}}) diff --git a/vendors/KeyMile/changeDirectoryProcessor.py b/nesi/keymile/api/schemas/keymile_channel_schemas.py similarity index 66% rename from vendors/KeyMile/changeDirectoryProcessor.py rename to nesi/keymile/api/schemas/keymile_channel_schemas.py index 19abce5..5d1e101 100644 --- a/vendors/KeyMile/changeDirectoryProcessor.py +++ b/nesi/keymile/api/schemas/keymile_channel_schemas.py @@ -10,11 +10,10 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -import re -from nesi import exceptions +from nesi.softbox.api.schemas.channel_schemas import * -class ChangeDirectoryProcessor: - - def do_cd(self, command, *args, context=None): - pass \ No newline at end of file +class KeyMileChannelSchema(ChannelSchema): + class Meta: + model = Channel + fields = ChannelSchema.Meta.fields + ('vccs', 'interfaces') \ No newline at end of file diff --git a/nesi/keymile/api/schemas/keymile_port_schemas.py b/nesi/keymile/api/schemas/keymile_port_schemas.py new file mode 100644 index 0000000..667b9c6 --- /dev/null +++ b/nesi/keymile/api/schemas/keymile_port_schemas.py @@ -0,0 +1,21 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.port_schemas import * + + +class KeyMilePortSchema(PortSchema): + class Meta: + model = Port + fields = PortSchema.Meta.fields + ('channels',) + + channels = ma.Nested(CpesSchema.CpeSchema, many=True) \ No newline at end of file diff --git a/nesi/keymile/keymile_resources/__init__.py b/nesi/keymile/keymile_resources/__init__.py index a9a2c5b..e6be87c 100644 --- a/nesi/keymile/keymile_resources/__init__.py +++ b/nesi/keymile/keymile_resources/__init__.py @@ -1 +1 @@ -__all__ = [] +__all__ = ["keymile_card", "keymile_port", "keymile_subrack", "keymile_channel", "keymile_interface"] diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 295f363..87586b3 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -10,9 +10,11 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.keymile.keymile_resources import keymile_card -from nesi.softbox.base_resources import credentials -from nesi.softbox.base_resources.box import * +from nesi.keymile.keymile_resources import * + + +from nesi.softbox.base_resources import credentials, base +from nesi.softbox.base_resources.box import BoxCollection, Box, logging LOG = logging.getLogger(__name__) @@ -25,6 +27,18 @@ class KeyMileBox(Box): """ # Define Keymile Properties + @property + def channels(self): + """Return `CpePortCollection` object.""" + return keymile_channel.KeyMileChannelCollection( + self._conn, base.get_sub_resource_path_by(self, 'channels')) + + @property + def interfaces(self): + """Return `CpePortCollection` object.""" + return keymile_interface.KeyMileInterfaceCollection( + self._conn, base.get_sub_resource_path_by(self, 'interfaces')) + @property def credentials(self): """Return `CredentialsCollection` object.""" @@ -39,6 +53,53 @@ def cards(self): self._conn, base.get_sub_resource_path_by( self, 'cards')) + def get_card(self, field, value): + """Get specific card object.""" + return keymile_card.KeyMileCardCollection( + self._conn, base.get_sub_resource_path_by(self, 'cards'), + params={field: value}).find_by_field_value(field, value) + + def get_cards(self, field, value): + """Get all cards.""" + return keymile_card.KeyMileCardCollection( + self._conn, base.get_sub_resource_path_by(self, 'cards'), + params={field: value}) + + def get_port(self, field, value): + """Get specific port object.""" + return keymile_port.KeyMilePortCollection( + self._conn, base.get_sub_resource_path_by(self, 'ports'), + params={field: value}).find_by_field_value(field, value) + + def get_ports(self, field, value): + """Get specific port object.""" + return keymile_port.KeyMilePortCollection( + self._conn, base.get_sub_resource_path_by(self, 'ports'), + params={field: value}) + + def get_chan(self, field, value): + """Get specific channel object.""" + return keymile_channel.KeyMileChannelCollection( + self._conn, base.get_sub_resource_path_by(self, 'channels'), + params={field: value}).find_by_field_value(field, value) + + def get_chans(self, field, value): + return keymile_channel.KeyMileChannelCollection( + self._conn, base.get_sub_resource_path_by(self, 'channels'), + params={field: value}) + + def get_interface(self, field, value): + """Get specific interface object.""" + return keymile_interface.KeyMileInterfaceCollection( + self._conn, base.get_sub_resource_path_by(self, 'interfaces'), + params={field: value}).find_by_field_value(field, value) + + def get_interfaces(self, field, value): + """Get specific interface object.""" + return keymile_interface.KeyMileInterfaceCollection( + self._conn, base.get_sub_resource_path_by(self, 'interfaces'), + params={field: value}) + class KeyMileBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/keymile/keymile_resources/keymile_channel.py b/nesi/keymile/keymile_resources/keymile_channel.py new file mode 100644 index 0000000..18e4a80 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_channel.py @@ -0,0 +1,34 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import logging + +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class KeyMileChannel(base.Resource): + """Represent logical channel resource.""" + + id = base.Field('id') + port_id = base.Field('port_id') + name = base.Field('name') + description = base.Field('description') + + +class KeyMileChannelCollection(base.ResourceCollection): + """Represent a collection of channels.""" + + @property + def _resource_type(self): + return KeyMileChannel diff --git a/nesi/keymile/keymile_resources/keymile_interface.py b/nesi/keymile/keymile_resources/keymile_interface.py new file mode 100644 index 0000000..24c8b82 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_interface.py @@ -0,0 +1,34 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import logging + +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class KeyMileInterface(base.Resource): + """Represent logical interface resource.""" + + id = base.Field('id') + port_id = base.Field('port_id') + name = base.Field('name') + description = base.Field('description') + + +class KeyMileInterfaceCollection(base.ResourceCollection): + """Represent a collection of interfaces.""" + + @property + def _resource_type(self): + return KeyMileInterface diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py new file mode 100644 index 0000000..c84be0b --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -0,0 +1,27 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.port import PortCollection, Port, logging, base + +LOG = logging.getLogger(__name__) + + +class KeyMilePort(Port): + """Represent physical port resource.""" + + +class KeyMilePortCollection(PortCollection): + """Represent a collection of ports.""" + + @property + def _resource_type(self): + return KeyMilePort \ No newline at end of file diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index dcb31d3..f4f7002 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -27,6 +27,7 @@ from .route_models import Route from .emu_models import Emu from .user_models import User +from .channel_models import Channel class Box(db.Model): @@ -56,6 +57,8 @@ class Box(db.Model): subrack_details = db.relationship('Subrack', backref='subracks', lazy='dynamic') cards = db.relationship('Card', backref='Box', lazy='dynamic') ports = db.relationship('Port', backref='Box', lazy='dynamic') + channels = db.relationship('Channel', backref='Box', lazy='dynamic') + interfaces = db.relationship('Interface', backref='Box', lazy='dynamic') cpes = db.relationship('Cpe', backref='Box', lazy='dynamic') cpe_ports = db.relationship('CpePort', backref='Box', lazy='dynamic') onts = db.relationship('Ont', backref='Box', lazy='dynamic') diff --git a/nesi/softbox/api/models/channel_models.py b/nesi/softbox/api/models/channel_models.py new file mode 100644 index 0000000..4837c8f --- /dev/null +++ b/nesi/softbox/api/models/channel_models.py @@ -0,0 +1,23 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import db +from ..models.interface_models import Interface + + +class Channel(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + description = db.Column(db.String()) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + port_id = db.Column(db.Integer, db.ForeignKey('port.id')) + interfaces = db.relationship('Interface', backref='Channel', lazy='dynamic') diff --git a/nesi/softbox/api/models/interface_models.py b/nesi/softbox/api/models/interface_models.py new file mode 100644 index 0000000..38dc722 --- /dev/null +++ b/nesi/softbox/api/models/interface_models.py @@ -0,0 +1,22 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import db + + +class Interface(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + description = db.Column(db.String()) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + chan_id = db.Column(db.Integer, db.ForeignKey('channel.id')) + port_id = db.Column(db.Integer, db.ForeignKey('port.id')) diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index f6d5ab1..17c9bbe 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -14,6 +14,8 @@ from nesi.softbox.api import db from .ont_models import Ont from .cpe_models import Cpe +from .channel_models import Channel +from .interface_models import Interface class Port(db.Model): @@ -305,3 +307,7 @@ class Port(db.Model): vectoring_group = db.Column(db.Integer(), default=None) vectoring_profile_id = db.Column(db.Integer(), default=None) template_name = db.Column(db.String(), default=None) + + # KeyMile + channels = db.relationship('Channel', backref='Port', lazy='dynamic') + interfaces = db.relationship('Interface', backref='Port', lazy='dynamic') diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index af4a27b..fb7d67d 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -30,10 +30,10 @@ class BoxSchema(ma.ModelSchema): class Meta: model = Box fields = ('id', 'vendor', 'model', 'version', 'software_version', 'network_protocol', 'network_address', - 'network_port', 'uuid', 'description', + 'network_port', 'uuid', 'description', 'interfaces', 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', - 'subracks', 'subrack_details', 'cards', 'ports', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', + 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') @@ -61,6 +61,14 @@ class Meta: {'_links': { 'self': ma.URLFor('show_ports', box_id='')}}) + channels = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_channels', box_id='')}}) + + interfaces = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_interfaces', box_id='')}}) + service_ports = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_service_ports', box_id='')}}) diff --git a/nesi/softbox/api/schemas/channel_schemas.py b/nesi/softbox/api/schemas/channel_schemas.py new file mode 100644 index 0000000..d496e3a --- /dev/null +++ b/nesi/softbox/api/schemas/channel_schemas.py @@ -0,0 +1,52 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.channel_models import Channel +from ..schemas.interface_schemas import InterfacesSchema + + +class ChannelSchema(ma.ModelSchema): + class Meta: + model = Channel + fields = ('id', 'box_id', 'box', 'port_id', 'interfaces', + 'name', 'description', '_links') + + interfaces = ma.Nested(InterfacesSchema.InterfaceSchema, many=True) + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_channel', box_id='', id='')}) + + +class ChannelsSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class ChannelSchema(ma.ModelSchema): + class Meta: + model = Channel + fields = ('id', 'name', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_channel', box_id='', id='')}) + + members = ma.Nested(ChannelSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_channels', box_id='')}) + + diff --git a/nesi/softbox/api/schemas/interface_schemas.py b/nesi/softbox/api/schemas/interface_schemas.py new file mode 100644 index 0000000..a98b4a5 --- /dev/null +++ b/nesi/softbox/api/schemas/interface_schemas.py @@ -0,0 +1,49 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.interface_models import Interface + + +class InterfaceSchema(ma.ModelSchema): + class Meta: + model = Interface + fields = ('id', 'box_id', 'box', 'chan_id', 'port_id', + 'name', 'description', '_links') + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_interface', box_id='', id='')}) + + +class InterfacesSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class InterfaceSchema(ma.ModelSchema): + class Meta: + model = Interface + fields = ('id', 'name', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_interface', box_id='', id='')}) + + members = ma.Nested(InterfaceSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_interfaces', box_id='')}) + + diff --git a/nesi/softbox/api/schemas/port_schemas.py b/nesi/softbox/api/schemas/port_schemas.py index b2cced5..83679f3 100644 --- a/nesi/softbox/api/schemas/port_schemas.py +++ b/nesi/softbox/api/schemas/port_schemas.py @@ -14,18 +14,24 @@ from ..models.port_models import Port from ..schemas.cpe_schemas import CpesSchema from ..schemas.ont_schemas import OntsSchema +from ..schemas.channel_schemas import ChannelsSchema +from ..schemas.interface_schemas import InterfacesSchema class PortSchema(ma.ModelSchema): class Meta: model = Port - fields = ('id', 'box_id', 'box', 'card_id', 'cpes', 'onts', 'loopback', 'name', + fields = ('id', 'box_id', 'box', 'card_id', 'cpes', 'onts', 'channels', 'loopback', 'name', 'interfaces', 'description', 'admin_state', 'operational_state', '_links') cpes = ma.Nested(CpesSchema.CpeSchema, many=True) onts = ma.Nested(OntsSchema.OntSchema, many=True) + channels = ma.Nested(ChannelsSchema.ChannelSchema, many=True) + + interfaces = ma.Nested(InterfacesSchema.InterfaceSchema, many=True) + box = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_box', id='')}}) diff --git a/nesi/softbox/api/views/__init__.py b/nesi/softbox/api/views/__init__.py index c37245d..cf9f0df 100644 --- a/nesi/softbox/api/views/__init__.py +++ b/nesi/softbox/api/views/__init__.py @@ -1,4 +1,4 @@ __all__ = ["box_views", "credential_views", "route_views", "subrack_views", "card_views", "port_views", "ont_views", "ontport_views", "cpe_views", "cpeport_views", "vlan_views", "portprofile_views", "emu_views", "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", - "qos_interface_views", "vlan_interface_views", "user_views"] + "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views"] diff --git a/nesi/softbox/api/views/channel_views.py b/nesi/softbox/api/views/channel_views.py new file mode 100644 index 0000000..ca37c4d --- /dev/null +++ b/nesi/softbox/api/views/channel_views.py @@ -0,0 +1,59 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from ..models.port_models import Port +from ..schemas.channel_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//channels', methods=['GET']) +def show_channels(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(ChannelsSchema(), Channel, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//channels/', methods=['GET']) +def show_channel(box_id, id): + response = show_component(Channel, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//channels', methods=['POST']) +def new_channel(box_id): + req = flask.request.json + + if 'name' not in req or req['name'] == "": + if 'port_id' in req: + port = json.loads(show_component(Port, box_id, req['port_id']).data.decode('utf-8')) + req['name'] = port['name'] + "/" + str(len(port['channels']) + 1) + response = new_component(ChannelSchema(), Channel, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//channels/', methods=['PUT']) +def update_channel(box_id, id): + req = flask.request.json + update_component(Channel, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//channels/', methods=['DELETE']) +def del_channel(box_id, id): + del_component(Channel, box_id, id) + return flask.Response(status=204) diff --git a/nesi/softbox/api/views/interface_views.py b/nesi/softbox/api/views/interface_views.py new file mode 100644 index 0000000..9987f5a --- /dev/null +++ b/nesi/softbox/api/views/interface_views.py @@ -0,0 +1,65 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from ..models.port_models import Port +from ..models.channel_models import Channel +from ..schemas.interface_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//interfaces', methods=['GET']) +def show_interfaces(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(InterfacesSchema(), Interface, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//interfaces/', methods=['GET']) +def show_interface(box_id, id): + response = show_component(Interface, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//interfaces', methods=['POST']) +def new_interface(box_id): + req = flask.request.json + + if 'name' not in req or req['name'] == "": + if 'port_id' in req: + port = json.loads(show_component(Port, box_id, req['port_id']).data.decode('utf-8')) + req['name'] = port['name'] + "/" + str(len(port['interfaces']) + 1) + elif 'chan_id' in req: + channel = json.loads(show_component(Channel, box_id, req['chan_id']).data.decode('utf-8')) + req['name'] = channel['name'] + "/" + str(len(channel['interfaces']) + 1) + else: + raise exceptions.Forbidden('can not have port and channel as parent') + response = new_component(InterfaceSchema(), Interface, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//interfaces/', methods=['PUT']) +def update_interface(box_id, id): + req = flask.request.json + update_component(Interface, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//interfaces/', methods=['DELETE']) +def del_interface(box_id, id): + del_component(Interface, box_id, id) + return flask.Response(status=204) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index f1a1f42..0efe85a 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -350,9 +350,9 @@ def loop(self, context=None, return_to=None, command=None): try: self.process_command(line, context) - except exceptions.CommandSyntaxError as exc: - self.line_buffer = [] # manually clear buffer in case of exception - self.on_error(dict(context, command=exc.command)) + except (exceptions.CommandExecutionError, exceptions.CommandSyntaxError) as exc: + self.line_buffer = [] + self.write_error_message(context, exc.template, *exc.template_scopes) except exceptions.TerminalExitError as exc: self.line_buffer = [] # manually clear buffer in case of exception @@ -364,12 +364,19 @@ def loop(self, context=None, return_to=None, command=None): # set prompt_len anew in case of prompt_len change in command-processor beneath self.set_prompt_end_pos(context) + if exc.command is not None: + command = exc.command + continue + # This is the first instance of the desired # CommandProcessor to unwind to, continuing self.on_cycle(context) self.on_exit(context) + def _terminate(self, command=None): + del self + def get_prompt_len(self): text = self._render('on_cycle', context=dict(), ignore_errors=True) @@ -411,6 +418,13 @@ def on_error(self, context): if text is not None: self._write(text) + def write_error_message(self, context, template, *scopes): + if template is None: + template = 'on_error' + text = self._render(template, context=context, *scopes, ignore_errors=True) + if text is not None: + self._write(text) + @property def comment(self): return '!' diff --git a/templates/KeyMile/login/base/execution_errors/invalid_address_error.j2 b/templates/KeyMile/login/base/execution_errors/invalid_address_error.j2 new file mode 100644 index 0000000..e9423d2 --- /dev/null +++ b/templates/KeyMile/login/base/execution_errors/invalid_address_error.j2 @@ -0,0 +1,2 @@ +error: invalid address + diff --git a/templates/KeyMile/login/mainloop/on_error.j2 b/templates/KeyMile/login/base/execution_errors/invalid_management_function_error.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/on_error.j2 rename to templates/KeyMile/login/base/execution_errors/invalid_management_function_error.j2 diff --git a/templates/KeyMile/login/mainloop/help.j2 b/templates/KeyMile/login/base/help/help.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help.j2 rename to templates/KeyMile/login/base/help/help.j2 diff --git a/templates/KeyMile/login/mainloop/help_cd.j2 b/templates/KeyMile/login/base/help/help_cd.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_cd.j2 rename to templates/KeyMile/login/base/help/help_cd.j2 diff --git a/templates/KeyMile/login/mainloop/help_download.j2 b/templates/KeyMile/login/base/help/help_download.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_download.j2 rename to templates/KeyMile/login/base/help/help_download.j2 diff --git a/templates/KeyMile/login/mainloop/help_exit.j2 b/templates/KeyMile/login/base/help/help_exit.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_exit.j2 rename to templates/KeyMile/login/base/help/help_exit.j2 diff --git a/templates/KeyMile/login/mainloop/help_ftpserver.j2 b/templates/KeyMile/login/base/help/help_ftpserver.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_ftpserver.j2 rename to templates/KeyMile/login/base/help/help_ftpserver.j2 diff --git a/templates/KeyMile/login/mainloop/help_get.j2 b/templates/KeyMile/login/base/help/help_get.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_get.j2 rename to templates/KeyMile/login/base/help/help_get.j2 diff --git a/templates/KeyMile/login/mainloop/help_help.j2 b/templates/KeyMile/login/base/help/help_help.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_help.j2 rename to templates/KeyMile/login/base/help/help_help.j2 diff --git a/templates/KeyMile/login/mainloop/help_ls.j2 b/templates/KeyMile/login/base/help/help_ls.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_ls.j2 rename to templates/KeyMile/login/base/help/help_ls.j2 diff --git a/templates/KeyMile/login/mainloop/help_mode.j2 b/templates/KeyMile/login/base/help/help_mode.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_mode.j2 rename to templates/KeyMile/login/base/help/help_mode.j2 diff --git a/templates/KeyMile/login/mainloop/help_profile.j2 b/templates/KeyMile/login/base/help/help_profile.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_profile.j2 rename to templates/KeyMile/login/base/help/help_profile.j2 diff --git a/templates/KeyMile/login/mainloop/help_pwd.j2 b/templates/KeyMile/login/base/help/help_pwd.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_pwd.j2 rename to templates/KeyMile/login/base/help/help_pwd.j2 diff --git a/templates/KeyMile/login/mainloop/help_set.j2 b/templates/KeyMile/login/base/help/help_set.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_set.j2 rename to templates/KeyMile/login/base/help/help_set.j2 diff --git a/templates/KeyMile/login/mainloop/help_show.j2 b/templates/KeyMile/login/base/help/help_show.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_show.j2 rename to templates/KeyMile/login/base/help/help_show.j2 diff --git a/templates/KeyMile/login/mainloop/help_upload.j2 b/templates/KeyMile/login/base/help/help_upload.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/help_upload.j2 rename to templates/KeyMile/login/base/help/help_upload.j2 diff --git a/templates/KeyMile/login/mainloop/on_enter.j2 b/templates/KeyMile/login/base/login_message.j2 similarity index 100% rename from templates/KeyMile/login/mainloop/on_enter.j2 rename to templates/KeyMile/login/base/login_message.j2 diff --git a/templates/KeyMile/login/base/ls/ls_ap_list.j2 b/templates/KeyMile/login/base/ls/ls_ap_list.j2 new file mode 100644 index 0000000..c514d30 --- /dev/null +++ b/templates/KeyMile/login/base/ls/ls_ap_list.j2 @@ -0,0 +1,3 @@ + +AP List: + diff --git a/templates/KeyMile/login/mainloop/ls_header.j2 b/templates/KeyMile/login/base/ls/ls_header.j2 similarity index 70% rename from templates/KeyMile/login/mainloop/ls_header.j2 rename to templates/KeyMile/login/base/ls/ls_header.j2 index 6080a9f..e0a8150 100644 --- a/templates/KeyMile/login/mainloop/ls_header.j2 +++ b/templates/KeyMile/login/base/ls/ls_header.j2 @@ -1,4 +1,4 @@ -Infos of AP: / +Infos of AP: {{ context.path }} Name : MileGate 2200 Main Mode : Equipment State : Ok @@ -8,16 +8,3 @@ Infos of AP: / Service Label : Description : -MF List: - main - cfgm - fm - status - -AP List: - eoam - fan - multicast - services - tdmConnections - diff --git a/templates/KeyMile/login/base/ls/ls_list_body.j2 b/templates/KeyMile/login/base/ls/ls_list_body.j2 new file mode 100644 index 0000000..325772f --- /dev/null +++ b/templates/KeyMile/login/base/ls/ls_list_body.j2 @@ -0,0 +1,2 @@ + {{ context.list_entry }} + diff --git a/templates/KeyMile/login/base/ls/ls_mf_body.j2 b/templates/KeyMile/login/base/ls/ls_mf_body.j2 new file mode 100644 index 0000000..4cbc7f7 --- /dev/null +++ b/templates/KeyMile/login/base/ls/ls_mf_body.j2 @@ -0,0 +1,2 @@ +{{ context.prop_type }}: {{ context.prop_name }} {{ context.prop_rw_rights }} + diff --git a/templates/KeyMile/login/base/ls/ls_mf_header.j2 b/templates/KeyMile/login/base/ls/ls_mf_header.j2 new file mode 100644 index 0000000..f245922 --- /dev/null +++ b/templates/KeyMile/login/base/ls/ls_mf_header.j2 @@ -0,0 +1,2 @@ +{{ context.mf_layer }} + diff --git a/templates/KeyMile/login/base/ls/ls_mf_list.j2 b/templates/KeyMile/login/base/ls/ls_mf_list.j2 new file mode 100644 index 0000000..e7c6651 --- /dev/null +++ b/templates/KeyMile/login/base/ls/ls_mf_list.j2 @@ -0,0 +1,3 @@ + +MF List: + diff --git a/templates/KeyMile/login/base/on_cycle.j2 b/templates/KeyMile/login/base/on_cycle.j2 new file mode 100644 index 0000000..aa3921f --- /dev/null +++ b/templates/KeyMile/login/base/on_cycle.j2 @@ -0,0 +1 @@ +{{ context.path }}> diff --git a/templates/KeyMile/login/base/on_error.j2 b/templates/KeyMile/login/base/on_error.j2 new file mode 100644 index 0000000..c36472c --- /dev/null +++ b/templates/KeyMile/login/base/on_error.j2 @@ -0,0 +1,2 @@ +error: invalid management function + diff --git a/templates/KeyMile/login/base/pwd.j2 b/templates/KeyMile/login/base/pwd.j2 new file mode 100644 index 0000000..b598ab2 --- /dev/null +++ b/templates/KeyMile/login/base/pwd.j2 @@ -0,0 +1,2 @@ +{{ context.path }}{{ context.spacer }}\ # current directory + diff --git a/templates/KeyMile/login/base/syntax_errors/syntax_error.j2 b/templates/KeyMile/login/base/syntax_errors/syntax_error.j2 new file mode 100644 index 0000000..314c72f --- /dev/null +++ b/templates/KeyMile/login/base/syntax_errors/syntax_error.j2 @@ -0,0 +1,2 @@ +error: syntax error + diff --git a/templates/KeyMile/login/mainloop/ls_body.j2 b/templates/KeyMile/login/mainloop/ls_body.j2 deleted file mode 100644 index 75c88ef..0000000 --- a/templates/KeyMile/login/mainloop/ls_body.j2 +++ /dev/null @@ -1,2 +0,0 @@ - unit-{{ context.card.name }} - diff --git a/templates/KeyMile/login/mainloop/on_cycle.j2 b/templates/KeyMile/login/mainloop/on_cycle.j2 deleted file mode 100644 index 050587e..0000000 --- a/templates/KeyMile/login/mainloop/on_cycle.j2 +++ /dev/null @@ -1 +0,0 @@ -/> diff --git a/templates/KeyMile/login/on_exit.j2 b/templates/KeyMile/login/on_exit.j2 deleted file mode 100644 index e69de29..0000000 diff --git a/templates/KeyMile/on_enter.j2 b/templates/KeyMile/on_enter.j2 deleted file mode 100644 index e69de29..0000000 diff --git a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py new file mode 100644 index 0000000..e7cb30f --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py @@ -0,0 +1,29 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class EoamCommandProcessor(BaseCommandProcessor): + __name__ = 'eoam' + management_functions = ('main', 'cfgm', 'status') + access_points = () + + main = {} + + cfgm = {} + + status = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py new file mode 100644 index 0000000..08cd8e3 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py @@ -0,0 +1,29 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class FanAlarmCommandProcessor(BaseCommandProcessor): + __name__ = 'fanAlarm' + management_functions = ('main', 'cfgm', 'fm') + access_points = () + + main = {} + + cfgm = {} + + fm = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py new file mode 100644 index 0000000..240ecdc --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py @@ -0,0 +1,29 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class FanCommandProcessor(BaseCommandProcessor): + __name__ = 'fan' + management_functions = ('main', 'cfgm', 'fm') + access_points = () + + main = {} + + cfgm = {} + + fm = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py new file mode 100644 index 0000000..c88ccd2 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py @@ -0,0 +1,33 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class MulticastCommandProcessor(BaseCommandProcessor): + __name__ = 'multicast' + management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') + access_points = () + + main = {} + + cfgm = {} + + fm = {} + + pm = {} + + status = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py new file mode 100644 index 0000000..838df63 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -0,0 +1,80 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class RootCommandProcessor(BaseCommandProcessor): + __name__ = 'root' + management_functions = {'main', 'cfgm', 'fm', 'status'} + access_points = ('eoam', 'fan', 'multicast', 'services', 'tdmConnections') + + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + }, + 'Logbooks': { + 'Cmd': ( + 'GetAllLogbooks', + 'GetAlarmLogbook', + 'GetEventLogbook', + 'GetConfigLogbook', + 'GetEquipmentLogbook', + 'GetSessionLogbook' + ) + }, + 'NESoftwareDownload': { + 'Cmd': ( + 'StartEsw', + ) + } + } + + cfgm = {} + + fm = {} + + status = { + 'DateAndTime': { + 'Time': { + 'Cmd': ( + 'SetDateAndTime', + ), + 'Prop': { + 'Summary': 'r-' + } + }, + 'SNTPClient': { + 'Prop': { + 'PrimaryServerState': 'r-' + } + } + } + } + + def _init_access_points(self, context=None): + for card in self._model.cards: + if 'unit-' + card.name in self.access_points: + continue + self.access_points += ('unit-' + card.name,) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py new file mode 100644 index 0000000..b758126 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -0,0 +1,29 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class ServicesCommandProcessor(BaseCommandProcessor): + __name__ = 'services' + management_functions = ('main', 'fm', 'status') + access_points = () + + main = {} + + fm = {} + + status = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py new file mode 100644 index 0000000..2d84a49 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py @@ -0,0 +1,31 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class ServicesMacAccessCtrlCommandProcessor(BaseCommandProcessor): + __name__ = 'servicesMacAccessCtrl' + management_functions = ('main', 'cfgm', 'fm', 'status') + access_points = () + + main = {} + + cfgm = {} + + fm = {} + + status = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py new file mode 100644 index 0000000..af77c82 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py @@ -0,0 +1,25 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class ServicesPacketCommandProcessor(BaseCommandProcessor): + __name__ = 'servicesPacket' + management_functions = ('main',) + access_points = ('1to1DoubleTag', '1to1SingeTag', 'mcast', 'nto1', 'pls', 'tls') + + main = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py new file mode 100644 index 0000000..7992aa8 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py @@ -0,0 +1,27 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class TdmConnectionsCommandProcessor(BaseCommandProcessor): + __name__ = 'tdmConnections' + management_functions = ('main', 'cfgm') + access_points = () + + main = {} + + cfgm = {} + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py new file mode 100644 index 0000000..9e891c3 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -0,0 +1,47 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class ChanCommandProcessor(BaseCommandProcessor): + __name__ = 'chan' + management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') + access_points = () + + main = {} + + cfgm = {} + + fm = {} + + pm = {} + + status = {} + + def _init_access_points(self, context=None): + chan = self._model.get_chan('name', context['unit'] + '/' + context['port'] + '/' + context['chan']) + card = self._model.get_card('name', context['unit']) + + for interface in self._model.get_interfaces('chan_id', chan.id): + if card.product != 'adsl': + ap_name = 'interface-' + else: + ap_name = 'vcc-' + identifier = ap_name + interface.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py new file mode 100644 index 0000000..17666ca --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py @@ -0,0 +1,23 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class VccCommandProcessor(BaseCommandProcessor): + __name__ = 'port' + management_functions = ('main', 'cfgm', 'pm', 'status') + access_points = () + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py new file mode 100644 index 0000000..0d3ad9d --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -0,0 +1,34 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class InterfaceCommandProcessor(BaseCommandProcessor): + __name__ = 'interface' + management_functions = ('main', 'cfgm', 'pm', 'status') + access_points = () + + main = {} + + cfgm = {} + + pm = {} + + status = {} + + def _init_access_points(self, context=None): + pass + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py new file mode 100644 index 0000000..d267ae8 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -0,0 +1,42 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class PortCommandProcessor(BaseCommandProcessor): + __name__ = 'port' + management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') + access_points = () + + main = {} + + cfgm = {} + + fm = {} + + pm = {} + + status = {} + + def _init_access_points(self, context=None): + port = self._model.get_port('name', context['unit'] + '/' + context['port']) + + for chan in self._model.get_chans('port_id', port.id): + identifier = 'chan-' + chan.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py new file mode 100644 index 0000000..5c2dfd7 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -0,0 +1,44 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class UnitCommandProcessor(BaseCommandProcessor): + __name__ = 'unit' + management_functions = ('main', 'cfgm', 'fm', 'status') + access_points = () #'internalPorts', only on certain cards + + main = {} + + cfgm = {} + + fm = {} + + status = {} + + def _init_access_points(self, context=None): + card = self._model.get_card('name', context['unit']) + + #if card.type == ?: + # self.access_points += ('internalPorts',) + # + + for port in self._model.get_ports('card_id', card.id): + identifier = 'port-' + port.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 6edfcdd..7e51d77 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -12,7 +12,271 @@ from nesi import exceptions from nesi.softbox.cli import base +import re class BaseCommandProcessor(base.CommandProcessor): """Create CLI REPR loop for example switch.""" + + management_functions = () + access_points = () + + def create_spacers(self, positions, args): + spacers = [] + previous_pos = 0 + i = 0 + for position in positions: + spacer = position - (previous_pos + len(str(args[i]))) + spacers.append(spacer) + previous_pos = position + i += 1 + + return spacers + + def do_help(self, command, *args, context=None): + help_scopes = ('login', 'base', 'help') + if self._validate(args, str): + help_arg, = self._dissect(args, str) + + if help_arg == 'cd': + self._write(self._render('help_cd', *help_scopes, context=context)) + elif help_arg == 'pwd': + self._write(self._render('help_pwd', *help_scopes, context=context)) + elif help_arg == 'ls': + self._write(self._render('help_ls', *help_scopes, context=context)) + elif help_arg == 'show': + self._write(self._render('help_show', *help_scopes, context=context)) + elif help_arg == 'mode': + self._write(self._render('help_mode', *help_scopes, context=context)) + elif help_arg == 'ftpserver': + self._write(self._render('help_ftpserver', *help_scopes, context=context)) + elif help_arg == 'upload': + self._write(self._render('help_upload', *help_scopes, context=context)) + elif help_arg == 'download': + self._write(self._render('help_download', *help_scopes, context=context)) + elif help_arg == 'get': + self._write(self._render('help_get', *help_scopes, context=context)) + elif help_arg == 'set': + self._write(self._render('help_set', *help_scopes, context=context)) + elif help_arg == 'profile': + self._write(self._render('help_profile', *help_scopes, context=context)) + elif help_arg == 'help': + self._write(self._render('help_help', *help_scopes, context=context)) + elif help_arg == 'exit': + self._write(self._render('help_exit', *help_scopes, context=context)) + else: + raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args,): + self._write(self._render('help', *help_scopes, context=context)) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_pwd(self, command, *args, context=None): + context['spacer'] = self.create_spacers((67,), (context['path'],))[0] * ' ' + self._write(self._render('pwd', 'login', 'base', context=context)) + + def do_cd(self, command, *args, context=None): + if args[0] == '/': + context['path'] = '/' + from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor + exc = exceptions.TerminalExitError + exc.return_to = RootCommandProcessor + + raise exc + + components = [x for x in args[0].split('/') if x] + + if not re.search( + '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', + components[0]): + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + + if args[0] == '.': + return # dot does nothing + + if args[0].startswith('./'): + if args[0] == './': + return + + self.do_cd(command, args[0][2:], context=context) + return + + if re.search('\.\./(?:[^.]+/)+\.\.', args[0]): + if args[0].endswith('..'): + raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + else: + raise exceptions.CommandExecutionError(template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + + if args[0].startswith('..'): + splitted_path = [x for x in context['path'].split('/') if x] + exit_component = None + if len(splitted_path) != 0: + exit_component = splitted_path.pop() + context['path'] = '/' + '/'.join(splitted_path) + + if exit_component in ('main', 'cfgm', 'fm', 'pm', 'status'): + self.set_prompt_end_pos(context=context) + if args[0] != '..': + self.do_cd('cd', args[0][3:], context=context) + return + + if args[0] == '..': + raise exceptions.TerminalExitError() + + exc = exceptions.TerminalExitError() + exc.command = 'cd ' + args[0][3:] + raise exc + + if args[0].startswith('/'): + if 'unit-' not in components[0] and components[0] not in ('eoam', 'fan', 'multicast', 'services', 'tdmConnection', 'main', 'cfgm', 'fm', 'pm', 'status'): + raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + + context['path'] = '/' + + if self.__name__ != 'root': + exc = exceptions.TerminalExitError() + from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor + exc.return_to = RootCommandProcessor + exc.command = 'cd ' + args[0].lstrip('/') + raise exc + + self.do_cd('cd', args[0].lstrip('/'), context=context) + else: + remaining_args = '/'.join(components[1:]) + + component_type = None + component_number = None + if '-' in components[0]: + component_type = components[0].split('-')[0] + component_number = components[0].split('-')[1] + command_processor = component_type.capitalize() + 'CommandProcessor' + else: + command_processor = self.__name__.capitalize() + components[0].capitalize() + 'CommandProcessor' + + if component_type == 'unit': + if self.__name__ != 'root': + raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + + context['unit'] = component_number + elif component_type == 'port': + if self.__name__ != 'unit': + raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + + context['port'] = component_number + elif component_type == 'chan': + if self.__name__ != 'port': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + context['chan'] = component_number + elif component_type == 'interface': + if self.__name__ != 'port' and self.__name__ != 'chan': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + context['chan'] = component_number + + if components[0] in ('main', 'cfgm', 'fm', 'pm', 'status'): + if re.search('(main|cfgm|fm|pm|status)', context['path']): + return + if context['path'] == '/': + new_path = components[0] + else: + new_path = '/' + components[0] + context['path'] += new_path + self.set_prompt_end_pos(context=context) + return + + from vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor import UnitCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.chan.chanCommandProcessor import ChanCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor import InterfaceCommandProcessor + subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') + + if len(remaining_args) > 0: + command = 'cd ' + remaining_args + else: + command = None + + if context['path'] == '/': + new_path = components[0] + else: + new_path = '/' + components[0] + + context['path'] += new_path + subprocessor.loop(context=context, return_to=self.__class__, command=command) + + def do_exit(self, command, *args, context=None): + exc = exceptions.TerminalExitError() + exc.return_to = 'sysexit' + raise exc + + def do_ls(self, command, *args, context=None): + if self._validate(args,): + scopes = ('login', 'base', 'ls') + if re.search('(pm|fm|status|main|cfgm)', context['path']): + mf_type = context['path'].split('/')[-1] + + mf_layers = None + if mf_type == 'status': + mf_layers = self.status + elif mf_type == 'cfgm': + mf_layers = self.cfgm + elif mf_type == 'fm': + mf_layers = self.fm + elif mf_type == 'pm': + mf_layers = self.pm + elif mf_type == 'main': + mf_layers = self.main + + def generate_ls_text(layers, depth): + text = '' + for layer in layers: + if layer not in ('Cmd', 'Prop', 'File'): + context['mf_layer'] = depth * ' ' + layer + text += self._render('ls_mf_header', *scopes, context=context) + depth += 1 + text += generate_ls_text(layers[layer], depth) + depth -= 1 + else: + if layer == 'Cmd': + prop_type = layer + ' ' + else: + prop_type = layer + + context['prop_type'] = depth * ' ' + prop_type + + for property in layers[layer]: + context['prop_name'] = property + + if prop_type in ('File', 'Prop'): + context['prop_rw_rights'] = layers[layer].get(property, '') + else: + context['prop_rw_rights'] = '' + text += self._render('ls_mf_body', *scopes, context=context) + return text + + text = generate_ls_text(mf_layers, 0) + self._write(text) + + else: + text = self._render('ls_header', *scopes, context=context) + + text += self._render('ls_mf_list', *scopes, context=context) + for management_function in self.management_functions: + context['list_entry'] = management_function + text += self._render('ls_list_body', *scopes, context=context) + + text += self._render('ls_ap_list', *scopes, context=context) + + self._init_access_points(context=context) + + for access_point in self.access_points: + context['list_entry'] = access_point + text += self._render('ls_list_body', *scopes, context=context) + + self._write(text) + else: + raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=command) + + def _init_access_points(self, context=None): + raise exceptions.SoftboxenError(message='Abstract method not implemented.') diff --git a/vendors/KeyMile/main.py b/vendors/KeyMile/main.py index b3dcf3f..21561dc 100644 --- a/vendors/KeyMile/main.py +++ b/vendors/KeyMile/main.py @@ -11,19 +11,11 @@ # License: https://github.com/inexio/NESi/LICENSE.rst from nesi.softbox.cli import base +from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor from nesi import exceptions -from vendors.KeyMile.rootCommandProcessor import RootCommandProcessor -class ReadInputCommandProcessor(base.CommandProcessor): - """Create CLI REPR loop for example switch.""" - - VENDOR = 'KeyMile' - MODEL = 'MG2200' - VERSION = '1' - - -class PreLoginCommandProcessor(ReadInputCommandProcessor): +class PreLoginCommandProcessor(base.CommandProcessor): def on_unknown_command(self, command, *args, context=None): subprocessor = self._create_subprocessor( @@ -43,7 +35,7 @@ def on_unknown_command(self, command, *args, context=None): raise exc -class LoginCommandProcessor(ReadInputCommandProcessor): +class LoginCommandProcessor(base.CommandProcessor): def on_unknown_command(self, command, *args, context=None): username = context.pop('username') @@ -59,8 +51,12 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.TerminalExitError() subprocessor = self._create_subprocessor( - RootCommandProcessor, 'login', 'mainloop') + RootCommandProcessor, 'login', 'base') + + context['path'] = '/' + + self._write(self._render('login_message', 'login', 'base', context=context)) - subprocessor.loop(context=context) + subprocessor.loop(context=context, return_to=RootCommandProcessor) self.on_exit(context) diff --git a/vendors/KeyMile/rootCommandProcessor.py b/vendors/KeyMile/rootCommandProcessor.py deleted file mode 100644 index 71c0edf..0000000 --- a/vendors/KeyMile/rootCommandProcessor.py +++ /dev/null @@ -1,74 +0,0 @@ -# This file is part of the NESi software. -# -# Copyright (c) 2020 -# Original Software Design by Ilya Etingof . -# -# Software adapted by inexio . -# - Janis Groß -# - Philip Konrath -# - Alexander Dincher -# -# License: https://github.com/inexio/NESi/LICENSE.rst - -from nesi import exceptions -from .baseCommandProcessor import BaseCommandProcessor -from .changeDirectoryProcessor import ChangeDirectoryProcessor - - -class RootCommandProcessor(BaseCommandProcessor, ChangeDirectoryProcessor): - - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - - def do_help(self, command, *args, context=None): - if self._validate(args, str): - help_arg, = self._dissect(args, str) - - if help_arg == 'cd': - self._write(self._render('help_cd', context=context)) - elif help_arg == 'pwd': - self._write(self._render('help_pwd', context=context)) - elif help_arg == 'ls': - self._write(self._render('help_ls', context=context)) - elif help_arg == 'show': - self._write(self._render('help_show', context=context)) - elif help_arg == 'mode': - self._write(self._render('help_mode', context=context)) - elif help_arg == 'ftpserver': - self._write(self._render('help_ftpserver', context=context)) - elif help_arg == 'upload': - self._write(self._render('help_upload', context=context)) - elif help_arg == 'download': - self._write(self._render('help_download', context=context)) - elif help_arg == 'get': - self._write(self._render('help_get', context=context)) - elif help_arg == 'set': - self._write(self._render('help_set', context=context)) - elif help_arg == 'profile': - self._write(self._render('help_profile', context=context)) - elif help_arg == 'help': - self._write(self._render('help_help', context=context)) - elif help_arg == 'exit': - self._write(self._render('help_exit', context=context)) - else: - raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args,): - self._write(self._render('help', context=context)) - else: - raise exceptions.CommandSyntaxError(command=command) - - def do_exit(self, command, *args, context=None): - exc = exceptions.TerminalExitError() - exc.return_to = 'sysexit' - raise exc - - def do_ls(self, command, *args, context=None): - if self._validate(args,): - text = self._render('ls_header', context=context) - - for card in self._model.cards: - text += self._render('ls_body', context=dict(context, card=card)) - - self._write(text) - else: - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file From ca66afda5a1f2ce535b8c0512418086576007b5b Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 2 Oct 2020 09:38:37 +0200 Subject: [PATCH 198/318] Added management function jsons --- .../accessPoints/root/eoamCommandProcessor.py | 53 ++- .../root/fan/fanAlarmCommandProcessor.py | 33 +- .../root/fan/fanCommandProcessor.py | 43 ++- .../root/multicastCommandProcessor.py | 162 ++++++++- .../root/services/servicesCommandProcessor.py | 31 +- .../servicesMacAccessCtrlCommandProcessor.py | 62 +++- .../servicesPacketCommandProcessor.py | 9 +- .../root/tdmConnectionsCommandProcessor.py | 34 +- .../unit/port/chan/chanCommandProcessor.py | 101 +++++- .../unit/port/chan/vcc/vccCommandProcessor.py | 105 ++++++ .../interface/interfaceCommandProcessor.py | 105 +++++- .../root/unit/port/portCommandProcessor.py | 335 +++++++++++++++++- 12 files changed, 1035 insertions(+), 38 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py index e7cb30f..0f9d2f1 100644 --- a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py @@ -19,11 +19,58 @@ class EoamCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'status') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'DefaultMdLevel': { + 'Prop': { + 'DefaultMdSettings': 'rw' + } + }, + 'ContextMap': { + 'Prop': { + 'Mapping': 'rw' + } + }, + 'Aggregation': { + 'Prop': { + 'Role': 'rw', + 'Address': 'rw' + } + }, + 'Md': { + 'Cmd': ( + 'CreateMd', + 'DeleteMd' + ) + } + } - status = {} + status = { + 'DefaultMdMips': { + 'Prop': { + 'Mips': 'r-' + } + }, + 'ConfigurationErrors': { + 'Prop': { + 'InterfacesInError': 'r-' + } + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py index 08cd8e3..78cb692 100644 --- a/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py @@ -19,11 +19,38 @@ class FanAlarmCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'General': { + 'Prop': { + 'Polarity': 'rw' + } + } + } - fm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py index 240ecdc..3e10c68 100644 --- a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py @@ -19,11 +19,48 @@ class FanCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'Equipment': { + 'Prop': { + 'CurrentStatus': 'r-' + } + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'General': { + 'Prop': { + 'Option': 'rw' + } + } + } - fm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py index c88ccd2..8ec0162 100644 --- a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py @@ -19,15 +19,167 @@ class MulticastCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'Multicast': { + 'General': { + 'Prop': { + 'SnoopingMode': 'rw', + 'LocalIPAddressForIGMPGeneration': 'rw', + 'IPSourceAddressOfQueries': 'rw', + 'portGroupInactivityTimeout': 'rw' + }, + 'Cmd': ( + 'CreateVlan', + 'DeleteVlan' + ) + }, + 'PreJoin': { + 'Prop': { + 'preJoinIntervalPeriod': 'rw' + } + }, + 'PostLeave': { + 'Prop': { + 'postLeaveDelayPeriod': 'rw' + } + }, + 'Preview': { + 'Prop': { + 'previewSettings': 'rw' + } + }, + 'Bandwidth': { + 'Prop': { + 'defaultBandwidthPerStream': 'rw' + } + }, + 'Alarms': { + 'Prop': { + 'configuredMulticastStreamsThreshold': 'rw' + } - fm = {} + } + } + } - pm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } - status = {} + pm = { + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + }, + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + } + } + + status = { + 'multicast': { + 'activeStreams': { + 'Dynamic': { + 'Prop': { + 'activeMulticastStreams': 'r-', + 'NumberOfActiveStreams': 'r-' + }, + 'Cmd': ( + 'clearAllStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticMulticastStreams': 'r-', + 'NumberOfStaticStreams': 'r-' + } + }, + }, + + 'unitConfiguration': { + 'Prop': { + 'multicastUnitConfigurationStatus': 'r-' + } + }, + 'portSummary': { + 'Prop': { + 'CoreUnitFrontPorts': 'r-', + 'CapableServiceUnits': 'r-' + } + }, + 'Router': { + 'Prop': { + 'learnedIpRouterSourceAddress': 'r-' + } + + } + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py index b758126..dcede08 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -19,11 +19,36 @@ class ServicesCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'fm', 'status') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } - fm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } - status = {} + status = { + 'Prop': { + 'conflictList': 'r-' + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py index 2d84a49..aea38f2 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py @@ -19,13 +19,67 @@ class ServicesMacAccessCtrlCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'status') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'General': { + 'Prop': { + 'Blacklist': 'rw' + } + } + } - fm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + }, + 'DuplicatedMac': { + 'Prop': { + 'DuplicatedMacAccessList': 'r-' + }, + 'Cmd': ( + 'FlushMacAccessDuplicatedList', + ) + } + } - status = {} + status = { + 'DynamicList': { + 'Prop': { + 'DynamicList': 'r-' + }, + 'Cmd': ( + 'FlushMacAccessDynamicList', + 'DeleteMacAccessDynamicListEntry' + ) + }, + 'UNIBlacklist': { + 'Prop': { + 'Blacklist': 'r-', + 'BNGlist': 'r-' + }, + 'Cmd': ( + 'DeleteMacAccessBNGlistEntry', + ) + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py index af77c82..e2bf785 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py @@ -19,7 +19,14 @@ class ServicesPacketCommandProcessor(BaseCommandProcessor): management_functions = ('main',) access_points = ('1to1DoubleTag', '1to1SingeTag', 'mcast', 'nto1', 'pls', 'tls') - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py index 7992aa8..905a06a 100644 --- a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py @@ -19,9 +19,39 @@ class TdmConnectionsCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'Connections': { + 'Cmd': ( + 'CreateConnection', + 'CreateBulkConnection', + 'CreateAdvancedConnection', + 'DeleteConnection', + 'DeleteMultipleConnections', + 'ShowConnections', + 'SetLabel1', + 'SetLabel2' + ) + }, + 'Ctps': { + 'Cmd': ( + 'ShowCtps', + ) + }, + 'Pbus': { + 'Prop': { + 'PbusUsage': 'r-' + } + } + } def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 9e891c3..e0d8ea3 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -19,15 +19,106 @@ class ChanCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'Profile': { + 'Prop': { + 'ChanProfile': 'rw' + } + }, + 'subinterface': { + 'Cmd': ( + 'CreateInterface', + 'DeleteInterface' + ) + } + } - fm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } - pm = {} + pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } + } - status = {} + status = { + 'General': { + 'Prop': { + 'Status': 'r-' + } + } + } def _init_access_points(self, context=None): chan = self._model.get_chan('name', context['unit'] + '/' + context['port'] + '/' + context['chan']) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py index 17666ca..8873005 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py @@ -19,5 +19,110 @@ class VccCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'pm', 'status') access_points = () + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } + + cfgm = { + 'Traceability': { + 'Prop': { + 'AutomaticAgentCircuitId': 'rw', + 'AgentCircuitId': 'rw' + } + }, + 'Filter': { + 'Prop': { + 'MACSourceFilteringMode': 'rw', + 'MacAccessWhitelist': 'rw', + 'NumberOfMacForFloodingPrev': 'rw', + 'L2CPFilter': 'rw', + 'DestMacBlacklistProfile': 'rw', + 'SrcMacBlacklist': 'rw' + } + }, + 'IfRateLimiter': { + 'Prop': { + 'IfRateLimiting': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'configuredProfiles': 'rw' + } + } + } + + pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } + } + + status = { + 'ServiceInfo': { + 'Prop': { + 'ServiceStatus': 'r-' + } + }, + 'UserConnection': { + 'Prop': { + 'CurrentPppConnectionState': 'r-' + } + } + } + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index 0d3ad9d..1e53469 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -19,13 +19,110 @@ class InterfaceCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'pm', 'status') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'Traceability': { + 'Prop': { + 'AutomaticAgentCircuitId': 'rw', + 'AgentCircuitId': 'rw' + } + }, + 'Filter': { + 'Prop': { + 'MACSourceFilteringMode': 'rw', + 'MacAccessWhitelist': 'rw', + 'NumberOfMacForFloodingPrev': 'rw', + 'L2CPFilter': 'rw', + 'DestMacBlacklistProfile': 'rw', + 'SrcMacBlacklist': 'rw' + } + }, + 'IfRateLimiter': { + 'Prop': { + 'IfRateLimiting': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'configuredProfiles': 'rw' + } + } + } - pm = {} + pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } + } - status = {} + status = { + 'ServiceInfo': { + 'Prop': { + 'ServiceStatus': 'r-' + } + }, + 'UserConnection': { + 'Prop': { + 'CurrentPppConnectionState': 'r-' + } + } + } def _init_access_points(self, context=None): pass diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index d267ae8..54ee05d 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -19,15 +19,340 @@ class PortCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') access_points = () - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + } + } - cfgm = {} + cfgm = { + 'Multicast': { + 'Prop': { + 'MaxNumberOfMulticastStreams': 'rw', + 'EnableIgmpClassifier': 'rw', + 'AllowStaticStreams': 'rw', + 'EnableFastLeave': 'rw', + 'GroupManagement': 'rw', + 'Bandwidth': 'rw' + }, + 'Cmd': ( + 'GetGroupList', + ) + }, + 'Traceability': { + 'Prop': { + 'AgentRemoteId': 'rw' + } + }, + 'Security': { + 'Prop': { + 'ServiceOptions': 'rw', + 'MaxNumberOfMac': 'rw' + } + }, + 'AccessControl': { + 'Prop': { + 'ClassificationKey': 'rw', + 'MAT': 'rw' + } + }, + 'RateLimiter': { + 'Prop': { + 'RateLimiting': 'rw', + 'RateLimitingCoS': 'rw' + } + }, + 'Qos': { + 'Prop': { + 'WfqProfile': 'rw' + } + }, + 'Wire': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'PortProfiles': 'rw' + } + }, + 'Misc': { + 'Prop': { + 'SpecificDPBO': 'rw', + 'SpecificUPBO': 'rw' + } + } + } - fm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } - pm = {} + pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } + } - status = {} + status = { + 'General': { + 'Prop': { + 'Standard': 'r-', + 'PowerMgmStatus': 'r-', + 'Vdsl2Parameters': 'r-', + 'EstUPBOElectricalLength': 'r-', + 'LineRate': 'r-', + 'LineSnrMargin': 'r-', + 'AttainableNetDataRate': 'r-', + 'AttainableRate': 'r-', + 'OutputPower': 'r-', + 'BandStatus': 'r-' + } + }, + 'statistics': { + 'Prop': { + 'counters': 'r-', + 'PolicingCounters': 'r-' + }, + 'Cmd': ( + 'ResetPortCounters', + ) + }, + 'Nto1MacAccessDynamicList': { + 'Prop': { + 'UnicastList': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters', + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + }, + }, + 'TLSMacForwardingList': { + 'Prop': { + 'MacForwardingList': 'r-' + }, + 'Cmd': ( + 'FlushMacForwardingList', + ) + }, + '1to1MacForwardingList': { + 'Prop': { + 'One2OneMacForwardingList': 'r-' + } + }, + 'Qos': { + 'Prop': { + 'wfqueues': 'r-' + } + }, + 'Multicast': { + 'stream': { + 'Dynamic': { + 'Prop': { + 'ActiveStreams': 'r-' + }, + 'Cmd': ( + 'ClearActiveStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticStreams': 'r-' + } + }, + }, + + 'Vlan': { + 'Prop': { + 'AttachedVlans': 'r-' + } + }, + 'Preview': { + 'Cmd': ( + 'ResetPreviewSettings', + ) + }, + 'Bandwidth': { + 'Prop': { + 'bandwidthStatus': 'r-' + } + }, + }, + 'LineTest': { + 'MELT': { + 'Prop': { + 'MeltResults': 'r-' + }, + 'Cmd': ( + 'StartMeltMeasurement', + ) + }, + 'Delt': { + 'Prop': { + 'DeltMeasurementStatus': 'r-', + 'RecordedDeltMeasurements': 'r-' + }, + 'Cmd': ( + 'StartDeltMeasurement', + ) + }, + 'Selt': { + 'Prop': { + 'SeltMeasurementStatus': 'r-', + 'RecordedSeltMeasurements': 'r-', + 'CableType': 'rw', + 'BandplanProfile': 'rw', + 'TargetSnrm': 'rw' + }, + 'Cmd': ( + 'StartSeltMeasurement', + ) + }, + }, + 'Defects': { + 'Prop': { + 'Defects': 'r-' + } + }, + 'LineInventory': { + 'Prop': { + 'VendorId': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'DslOperationStatus': 'r-' + } + }, + 'Subcarrier': { + 'Cmd': ( + 'ShowBitAllocation', + ) + }, + 'RfiBands': { + 'Prop': { + 'NotchStatus': 'r-' + } + } + } def _init_access_points(self, context=None): port = self._model.get_port('name', context['unit'] + '/' + context['port']) From 35a9cabb6866bb32aa2951b6e01af01f832aa55a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp-Noah=20Gro=C3=9F?= Date: Fri, 2 Oct 2020 10:09:15 +0200 Subject: [PATCH 199/318] Implemented Mgmt_Cards and Mgmt_Ports. --- nesi/softbox/api/models/card_models.py | 1 + nesi/softbox/api/models/mgmt_card_models.py | 27 +++++++ nesi/softbox/api/models/mgmt_port_models.py | 23 ++++++ nesi/softbox/api/models/subrack_models.py | 2 + nesi/softbox/api/schemas/mgmt_card_schemas.py | 51 ++++++++++++ nesi/softbox/api/schemas/mgmt_port_schemas.py | 49 ++++++++++++ nesi/softbox/api/schemas/subrack_schemas.py | 4 +- nesi/softbox/api/views/__init__.py | 2 +- nesi/softbox/api/views/base_views.py | 1 + nesi/softbox/api/views/card_views.py | 1 + nesi/softbox/api/views/mgmt_card_views.py | 78 +++++++++++++++++++ nesi/softbox/api/views/mgmt_port_views.py | 66 ++++++++++++++++ nesi/softbox/base_resources/card.py | 1 + nesi/softbox/base_resources/mgmt_card.py | 35 +++++++++ nesi/softbox/base_resources/mgmt_port.py | 55 +++++++++++++ 15 files changed, 394 insertions(+), 2 deletions(-) create mode 100644 nesi/softbox/api/models/mgmt_card_models.py create mode 100644 nesi/softbox/api/models/mgmt_port_models.py create mode 100644 nesi/softbox/api/schemas/mgmt_card_schemas.py create mode 100644 nesi/softbox/api/schemas/mgmt_port_schemas.py create mode 100644 nesi/softbox/api/views/mgmt_card_views.py create mode 100644 nesi/softbox/api/views/mgmt_port_views.py create mode 100644 nesi/softbox/base_resources/mgmt_card.py create mode 100644 nesi/softbox/base_resources/mgmt_port.py diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index c132fb4..f190760 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst import uuid diff --git a/nesi/softbox/api/models/mgmt_card_models.py b/nesi/softbox/api/models/mgmt_card_models.py new file mode 100644 index 0000000..80cd845 --- /dev/null +++ b/nesi/softbox/api/models/mgmt_card_models.py @@ -0,0 +1,27 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst +import uuid + +from nesi.softbox.api import db +from .mgmt_port_models import MgmtPort + + +class MgmtCard(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + description = db.Column(db.String(), default='None') + subrack_id = db.Column(db.Integer, db.ForeignKey('subrack.id')) + admin_state = db.Column(db.Enum('0', '1'), default='0') + operational_state = db.Column(db.Enum('0', '1'), default='0') + mgmt_ports = db.relationship('MgmtPort', backref='MgmtCard', lazy='dynamic') diff --git a/nesi/softbox/api/models/mgmt_port_models.py b/nesi/softbox/api/models/mgmt_port_models.py new file mode 100644 index 0000000..5fa2437 --- /dev/null +++ b/nesi/softbox/api/models/mgmt_port_models.py @@ -0,0 +1,23 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst +from nesi.softbox.api import db + +class MgmtPort(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + mgmt_card_id = db.Column(db.Integer, db.ForeignKey('mgmt_card.id')) + admin_state = db.Column(db.Enum('0', '1'), default='0') + operational_state = db.Column(db.Enum('0', '1'), default='0') + + description = db.Column(db.String(64)) diff --git a/nesi/softbox/api/models/subrack_models.py b/nesi/softbox/api/models/subrack_models.py index a4cfa6e..46f207b 100644 --- a/nesi/softbox/api/models/subrack_models.py +++ b/nesi/softbox/api/models/subrack_models.py @@ -13,6 +13,7 @@ from nesi.softbox.api import db from .card_models import Card +from .mgmt_card_models import MgmtCard class Subrack(db.Model): @@ -20,6 +21,7 @@ class Subrack(db.Model): name = db.Column(db.String(64), default='test') box_id = db.Column(db.Integer, db.ForeignKey('box.id')) cards = db.relationship('Card', backref='Subrack', lazy='dynamic') + mgmt_cards = db.relationship('MgmtCard', backref='Subrack', lazy='dynamic') # data description = db.Column(db.String(), default='') planned_type = db.Column(db.Enum('rvxs-a', 'not-planned', 'planned', 'nfxs-f'), default='not-planned') diff --git a/nesi/softbox/api/schemas/mgmt_card_schemas.py b/nesi/softbox/api/schemas/mgmt_card_schemas.py new file mode 100644 index 0000000..5d7e4f0 --- /dev/null +++ b/nesi/softbox/api/schemas/mgmt_card_schemas.py @@ -0,0 +1,51 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.mgmt_card_models import MgmtCard +from ..schemas.mgmt_port_schemas import MgmtPortsSchema + + +class MgmtCardSchema(ma.ModelSchema): + class Meta: + model = MgmtCard + fields = ('id', 'box_id', 'box', 'name', 'subrack_id', 'admin_state', 'operational_state', 'description', 'mgmt_ports') + + mgmt_ports = ma.Nested(MgmtPortsSchema.MgmtPortSchema, many=True) + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_mgmt_card', box_id='', id=''), + 'collection': ma.URLFor('show_mgmt_cards', box_id='')}) + + +class MgmtCardsSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class MgmtCardSchema(ma.ModelSchema): + class Meta: + model = MgmtCard + fields = ('id', 'name', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_mgmt_card', box_id='', id='')}) + + members = ma.Nested(MgmtCardSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_mgmt_cards', box_id='')}) diff --git a/nesi/softbox/api/schemas/mgmt_port_schemas.py b/nesi/softbox/api/schemas/mgmt_port_schemas.py new file mode 100644 index 0000000..0cdbae4 --- /dev/null +++ b/nesi/softbox/api/schemas/mgmt_port_schemas.py @@ -0,0 +1,49 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.mgmt_port_models import MgmtPort + + +class MgmtPortSchema(ma.ModelSchema): + class Meta: + model = MgmtPort + fields = ('id', 'box_id', 'box', 'mgmt_card_id', 'name', + 'description', 'admin_state', 'operational_state', '_links') + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_mgmt_port', box_id='', id=''), + 'collection': ma.URLFor('show_mgmt_ports', box_id='')}) + + +class MgmtPortsSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class MgmtPortSchema(ma.ModelSchema): + class Meta: + model = MgmtPort + fields = ('id', 'name', 'operational_state', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_mgmt_port', box_id='', id='')}) + + members = ma.Nested(MgmtPortSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_mgmt_ports', box_id='')}) diff --git a/nesi/softbox/api/schemas/subrack_schemas.py b/nesi/softbox/api/schemas/subrack_schemas.py index dc42f7d..7a6c773 100644 --- a/nesi/softbox/api/schemas/subrack_schemas.py +++ b/nesi/softbox/api/schemas/subrack_schemas.py @@ -13,15 +13,17 @@ from nesi.softbox.api import ma from ..models.subrack_models import Subrack from ..schemas.card_schemas import CardsSchema +from ..schemas.mgmt_card_schemas import MgmtCardsSchema class SubrackSchema(ma.ModelSchema): class Meta: model = Subrack - fields = ('id', 'box_id', 'box', 'cards', + fields = ('id', 'box_id', 'box', 'cards', 'mgmt_cards', 'name', 'description', '_links') cards = ma.Nested(CardsSchema.CardSchema, many=True) + mgmt_cards = ma.Nested(MgmtCardsSchema.MgmtCardSchema, many=True) box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/views/__init__.py b/nesi/softbox/api/views/__init__.py index cf9f0df..e6e1f95 100644 --- a/nesi/softbox/api/views/__init__.py +++ b/nesi/softbox/api/views/__init__.py @@ -1,4 +1,4 @@ __all__ = ["box_views", "credential_views", "route_views", "subrack_views", "card_views", "port_views", "ont_views", "ontport_views", "cpe_views", "cpeport_views", "vlan_views", "portprofile_views", "emu_views", "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", - "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views"] + "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views", "mgmt_card_views", "mgmt_port_views"] diff --git a/nesi/softbox/api/views/base_views.py b/nesi/softbox/api/views/base_views.py index aef71de..ac46d02 100644 --- a/nesi/softbox/api/views/base_views.py +++ b/nesi/softbox/api/views/base_views.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst diff --git a/nesi/softbox/api/views/card_views.py b/nesi/softbox/api/views/card_views.py index c063e89..5374f92 100644 --- a/nesi/softbox/api/views/card_views.py +++ b/nesi/softbox/api/views/card_views.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst diff --git a/nesi/softbox/api/views/mgmt_card_views.py b/nesi/softbox/api/views/mgmt_card_views.py new file mode 100644 index 0000000..9167f9a --- /dev/null +++ b/nesi/softbox/api/views/mgmt_card_views.py @@ -0,0 +1,78 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import re + +from .base_views import * +from .box_views import show_box +from ..models.mgmt_card_models import MgmtCard +from ..models.subrack_models import Subrack +from ..schemas.mgmt_card_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//mgmt_cards', methods=['GET']) +def show_mgmt_cards(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(MgmtCardsSchema(), MgmtCard, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//mgmt_cards/', methods=['GET']) +def show_mgmt_card(box_id, id): + response = show_component(MgmtCard, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//mgmt_cards', methods=['POST']) +def new_mgmt_card(box_id): + req = flask.request.json + + box = json.loads(show_box(box_id)[0].data.decode('utf-8')) + subrack = json.loads(show_component(Subrack, box_id, req['subrack_id']).data.decode('utf-8')) + if 'name' not in req or req['name'] == '' or req['name'] not in ('11', '13'): + if box['vendor'] == 'KeyMile': + card11_exists = False + card13_exists = False + for card in subrack['mgmt_cards']: + if card['name'] == '11': + card11_exists = True + elif card['name'] == '13': + card13_exists = True + if not card11_exists: + req['name'] = '11' + elif not card13_exists: + req['name'] = '13' + else: + return flask.Response(status=500) + + response = new_component(MgmtCardSchema(), MgmtCard, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//mgmt_cards/', methods=['PUT']) +def update_mgmt_card(box_id, id): + req = flask.request.json + update_component(MgmtCard, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//mgmt_cards/', methods=['DELETE']) +def del_mgmt_card(box_id, id): + del_component(MgmtCard, box_id, id) + return flask.Response(status=204) diff --git a/nesi/softbox/api/views/mgmt_port_views.py b/nesi/softbox/api/views/mgmt_port_views.py new file mode 100644 index 0000000..b7ec236 --- /dev/null +++ b/nesi/softbox/api/views/mgmt_port_views.py @@ -0,0 +1,66 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from .box_views import show_box +from ..models.mgmt_card_models import MgmtCard +from ..schemas.mgmt_port_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//mgmt_ports', methods=['GET']) +def show_mgmt_ports(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(MgmtPortsSchema(), MgmtPort, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//mgmt_ports/', methods=['GET']) +def show_mgmt_port(box_id, id): + response = show_component(MgmtPort, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//mgmt_ports', methods=['POST']) +def new_mgmt_port(box_id): + req = flask.request.json + + mgmt_card = json.loads(show_component(MgmtCard, box_id, req['mgmt_card_id']).data.decode('utf-8')) + box = json.loads(show_box(box_id)[0].data.decode('utf-8')) + + if 'name' not in req or req['name'] == "": #TODO evtl. noch zu bearbeiten + if box['vendor'] == 'Huawei': + req['name'] = mgmt_card['name'] + "/" + str(len(mgmt_card['mgmt_ports'])) + else: + req['name'] = mgmt_card['name'] + "/" + str(len(mgmt_card['mgmt_ports']) + 1) + + response = new_component(MgmtPortSchema(), MgmtPort, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//mgmt_ports/', methods=['PUT']) +def update_mgmt_port(box_id, id): + req = flask.request.json + update_component(MgmtPort, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//mgmt_ports/', methods=['DELETE']) +def del_mgmt_port(box_id, id): + del_component(MgmtPort, box_id, id) + return flask.Response(status=204) diff --git a/nesi/softbox/base_resources/card.py b/nesi/softbox/base_resources/card.py index 2de330b..93df665 100644 --- a/nesi/softbox/base_resources/card.py +++ b/nesi/softbox/base_resources/card.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst diff --git a/nesi/softbox/base_resources/mgmt_card.py b/nesi/softbox/base_resources/mgmt_card.py new file mode 100644 index 0000000..feef2d0 --- /dev/null +++ b/nesi/softbox/base_resources/mgmt_card.py @@ -0,0 +1,35 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import logging + +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class MgmtCard(base.Resource): + """Represent physical shelf resource.""" + id = base.Field('id') + name = base.Field('name') + box_id = base.Field('box_id') + description = base.Field('description') + subrack_id = base.Field('subrack_id') + + +class MgmtCardCollection(base.ResourceCollection): + """Represent a collection of cards.""" + + @property + def _resource_type(self): + return MgmtCard diff --git a/nesi/softbox/base_resources/mgmt_port.py b/nesi/softbox/base_resources/mgmt_port.py new file mode 100644 index 0000000..176e161 --- /dev/null +++ b/nesi/softbox/base_resources/mgmt_port.py @@ -0,0 +1,55 @@ + +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import logging + +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class MgmtPort(base.Resource): + """Represent physical port resource.""" + + id = base.Field('id') + name = base.Field('name') + box_id = base.Field('box_id') + card_id = base.Field('card_id') + description = base.Field('description') + admin_state = base.Field('admin_state') + operational_state = base.Field('operational_state') + + def admin_up(self): + """Set the admin port state to up""" + self.update(admin_state='1') + + def admin_down(self): + """Set the admin port state to down""" + self.update(admin_state='0') + + def down(self): + """Set the port state to down""" + self.update(operational_state='0') + + def up(self): + """Set the port state to up""" + self.update(operational_state='1') + + +class MgmtPortCollection(base.ResourceCollection): + """Represent a collection of management ports.""" + + @property + def _resource_type(self): + return MgmtPort From b7266122592ffab5a5e56e87a0f51d8004ff8048 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 2 Oct 2020 10:45:58 +0200 Subject: [PATCH 200/318] Implemented get commands for first few properties --- .../base/execution_errors/invalid_property.j2 | 2 + .../login/base/get/administrative_status.j2 | 3 + .../KeyMile/login/base/get/attainable_rate.j2 | 4 + .../KeyMile/login/base/get/chan_profile.j2 | 3 + .../login/base/get/operational_status.j2 | 3 + ...dProcessor.py => alarmCommandProcessor.py} | 4 +- .../root/fan/fanCommandProcessor.py | 9 +- .../accessPoints/root/rootCommandProcessor.py | 297 +++++++++++++++++- .../unit/port/chan/vcc/vccCommandProcessor.py | 2 +- .../interface/interfaceCommandProcessor.py | 3 - .../root/unit/port/portCommandProcessor.py | 19 ++ .../root/unit/unitCommandProcessor.py | 195 +++++++++++- vendors/KeyMile/baseCommandProcessor.py | 59 +++- 13 files changed, 570 insertions(+), 33 deletions(-) create mode 100644 templates/KeyMile/login/base/execution_errors/invalid_property.j2 create mode 100644 templates/KeyMile/login/base/get/administrative_status.j2 create mode 100644 templates/KeyMile/login/base/get/attainable_rate.j2 create mode 100644 templates/KeyMile/login/base/get/chan_profile.j2 create mode 100644 templates/KeyMile/login/base/get/operational_status.j2 rename vendors/KeyMile/accessPoints/root/fan/{fanAlarmCommandProcessor.py => alarmCommandProcessor.py} (94%) diff --git a/templates/KeyMile/login/base/execution_errors/invalid_property.j2 b/templates/KeyMile/login/base/execution_errors/invalid_property.j2 new file mode 100644 index 0000000..af8470b --- /dev/null +++ b/templates/KeyMile/login/base/execution_errors/invalid_property.j2 @@ -0,0 +1,2 @@ +error: invalid property + diff --git a/templates/KeyMile/login/base/get/administrative_status.j2 b/templates/KeyMile/login/base/get/administrative_status.j2 new file mode 100644 index 0000000..62715fa --- /dev/null +++ b/templates/KeyMile/login/base/get/administrative_status.j2 @@ -0,0 +1,3 @@ + \ # AdministrativeStatus +{{ context.port.admin_state }}{{ context.spacer }}\ # State + diff --git a/templates/KeyMile/login/base/get/attainable_rate.j2 b/templates/KeyMile/login/base/get/attainable_rate.j2 new file mode 100644 index 0000000..dc5e135 --- /dev/null +++ b/templates/KeyMile/login/base/get/attainable_rate.j2 @@ -0,0 +1,4 @@ + \ # AttainableRate +{{ context.port.downstream_max }}{{ context.spacer1 }}\ # Downstream +{{ context.port.upstream_max }}{{ context.spacer2 }}\ # Upstream + diff --git a/templates/KeyMile/login/base/get/chan_profile.j2 b/templates/KeyMile/login/base/get/chan_profile.j2 new file mode 100644 index 0000000..7691f6d --- /dev/null +++ b/templates/KeyMile/login/base/get/chan_profile.j2 @@ -0,0 +1,3 @@ + \ # ChannelProfile +{{ context.port_profile.name }}{{ context.spacer }}\ # Name + diff --git a/templates/KeyMile/login/base/get/operational_status.j2 b/templates/KeyMile/login/base/get/operational_status.j2 new file mode 100644 index 0000000..ea79363 --- /dev/null +++ b/templates/KeyMile/login/base/get/operational_status.j2 @@ -0,0 +1,3 @@ + \ # OperationalStatus +{{ context.port.operational_state }}{{ context.spacer }}\ # State + diff --git a/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py similarity index 94% rename from vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py rename to vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py index 78cb692..e2f83a8 100644 --- a/vendors/KeyMile/accessPoints/root/fan/fanAlarmCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py @@ -14,8 +14,8 @@ from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor -class FanAlarmCommandProcessor(BaseCommandProcessor): - __name__ = 'fanAlarm' +class AlarmCommandProcessor(BaseCommandProcessor): + __name__ = 'alarm' management_functions = ('main', 'cfgm', 'fm') access_points = () diff --git a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py index 3e10c68..efb61a5 100644 --- a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py @@ -62,5 +62,12 @@ class FanCommandProcessor(BaseCommandProcessor): } } + def _init_access_points(self, context=None): + for i in range(1, 12): + identifier = 'alarm-' + str(i) + if identifier in self.access_points: + continue + self.access_points += (identifier,) + def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 838df63..4dd4cf4 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -48,25 +48,308 @@ class RootCommandProcessor(BaseCommandProcessor): } } - cfgm = {} + cfgm = { + 'ConfigurationManagement': { + 'Prop': { + 'ConfigurationStatus': 'r-', + 'BackupDescription': 'r-' + }, + 'Cmd': ( + 'Load', + 'Save', + 'Initialize', + 'ChangeDescription' + ), + 'File': { + 'Configuration': 'rw' + } + }, + 'ManagementInterface': { + 'Prop': { + 'IP_Address': 'rw', + 'VlanId': 'rw', + 'ManagementVlanCoS': 'rw' + } + }, + 'Packet': { + 'Prop': { + 'Bridge': 'rw', + 'MACMovement': 'rw', + 'Traceability': 'rw', + 'PPPoA': 'rw' + } + }, + 'SessionManagement': { + 'Prop': { + 'TelnetEnabled': 'r-', + 'SshEnabled': 'r-', + 'UsbEnabled': 'r-', + 'RetryTime': 'r-', + 'SessionmanagerTime': 'r-', + 'AuthenticationManagementInterfaces': 'r-', + 'LocalAuthenticationFallback': 'r-', + 'RadiusDefaultUserclass': 'r-' + } + }, + 'RadiusClient': { + 'Prop': { + 'CommonRadius': 'r-', + 'PrimaryRadiusServer': 'r-', + 'AlternateRadiusServer': 'r-' + } + }, + 'DateAndTime': { + 'SNTPClient': { + 'Prop': { + 'OperationMode': 'rw', + 'PrimaryServer': 'rw', + 'SecondaryServer': 'rw', + 'PollingInterval': 'rw', + 'BroadcastDelay': 'rw' + } + }, + 'TimeZone': { + 'Prop': { + 'TimeZone': 'rw', + 'DaylightSaving': 'r-' + } + }, + }, + 'ProfileManagement': { + 'Prop': { + 'ProfileCpsTable': 'r-' + }, + 'Cmd': ( + 'Check', + 'Delete' + ), + 'File': { + 'Profile': 'rw', + 'Cps': 'rw' + } + }, + 'QoS': { + 'Prop': { + 'PriorityMapping': 'rw', + 'QueueMode': 'rw' + } + }, + 'SNMP': { + 'General': { + 'Prop': { + 'SNMPSupport': 'rw', + 'SNMPParameters': 'r-' + }, + 'Cmd': ( + 'SetDefaultSNMPConfigurationTables' + ) + }, + 'USM': { + 'Prop': { + 'LocalUserTable': 'rw', + 'RemoteUserTable': 'rw' + } + }, + }, + 'SyslogDestinations': { + 'Destination1': { + 'Prop': { + 'SyslogDestination1': 'rw' + } + }, + 'Destination2': { + 'Prop': { + 'SyslogDestination2': 'rw' + } + }, + 'Destination3': { + 'Prop': { + 'SyslogDestination3': 'rw' + } + }, + 'Destination4': { + 'Prop': { + 'SyslogDestination4': 'rw' + } + }, + 'Destination5': { + 'Prop': { + 'SyslogDestination5': 'rw' + } + }, + 'Destination6': { + 'Prop': { + 'SyslogDestination6': 'rw' + } + }, + 'Destination7': { + 'Prop': { + 'SyslogDestination7': 'rw' + } + }, + 'Destination8': { + 'Prop': { + 'SyslogDestination8': 'rw' + } + }, + 'Destination9': { + 'Prop': { + 'SyslogDestination9': 'rw' + } + }, + 'Destination10': { + 'Prop': { + 'SyslogDestination10': 'rw' + } + }, + }, + 'SyslogSources': { + 'Prop': { + 'SyslogSourceConfiguration': 'rw' + } + }, + 'BatteryPowerSaving': { + 'Prop': { + 'PowerSavingEnabled': 'rw', + 'PowerSavingAlarm': 'rw', + 'PowerSavingThresholds': 'rw', + 'PowerSavingUnits': 'r-' + }, + 'Cmd': ( + 'PowerSavingAddUnit', + 'PowerSavingRemoveUnit' + ) + }, + 'Ipsec': { + 'Prop': { + 'Ipsec': 'rw' + } + }, + 'TemeratureLimits': { + 'Prop': { + 'ThresholdExceed': 'rw', + 'ThresholdWarning': 'rw' + } + }, + 'ESO': { + 'Prop': { + 'Eso1ClockSources': 'rw', + 'Eso2ClockSource': 'rw' + } + }, + 'PETS': { + 'Prop': { + 'ClockSources': 'rw', + 'PetsClockPriority': 'rw' + } + } + } - fm = {} + fm = { + 'ActiveFailures': { + 'Prop': { + 'ActiveFailureTable': 'r-' + } + }, + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge' + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } status = { 'DateAndTime': { 'Time': { - 'Cmd': ( - 'SetDateAndTime', - ), 'Prop': { 'Summary': 'r-' - } + }, + 'Cmd': ( + 'SetDateAndTime' + ) }, 'SNTPClient': { 'Prop': { - 'PrimaryServerState': 'r-' + 'PrimaryServerState': 'r-', + 'SecondaryServerState': 'r-', + 'LastResponseTime': 'r-', + 'LastJumpTime': 'r-', + 'LastAdjustmentTime': 'r-' } + }, + }, + 'ManagementInterface': { + 'Prop': { + 'SshFingerprint': 'r-' + }, + 'Cmd': ( + 'Ping' + ) + }, + 'SessionManagement': { + 'Cmd': ( + 'ShowSessions' + ) + }, + 'RadiusClient': { + 'Prop': { + 'PrimaryRadiusServerStatus': 'r-', + 'AlternateRadiusServerStatus': 'r-' } + }, + 'Ipsec': { + 'Prop': { + 'IpsecSAStatus': 'r-' + }, + 'Cmd': ( + 'GetIpsecLogbook' + ) + }, + 'Redundancy': { + 'Prop': { + 'NeConfigurationStatus': 'r-', + 'RedundancyRoles': 'r-', + 'RedundancyStatus': 'r-' + }, + 'Cmd': ( + 'ManualSwitchOver', + 'ForcedSwitchOver', + 'IsolateUnits', + 'JoinUnits' + ) + }, + 'Temperature': { + 'Prop': { + 'CurrTemperature': 'r-', + 'MaxTemperature': 'r-', + 'MinTemperature': 'r-' + }, + 'Cmd': ( + 'ResetMinMax' + ) + }, + 'ESO': { + 'Prop': { + 'ClockOutputEso1': 'r-', + 'ClockOutputEso2': 'r-' + } + }, + 'PETS': { + 'Prop': { + 'PetsClockSources': 'r-', + 'PetsOperationStatus': 'r-' + }, + 'Cmd': ( + 'PetsClockOperation' + ) } } diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py index 8873005..21d96b0 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py @@ -15,7 +15,7 @@ class VccCommandProcessor(BaseCommandProcessor): - __name__ = 'port' + __name__ = 'vcc' management_functions = ('main', 'cfgm', 'pm', 'status') access_points = () diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index 1e53469..d8638a1 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -124,8 +124,5 @@ class InterfaceCommandProcessor(BaseCommandProcessor): } } - def _init_access_points(self, context=None): - pass - def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 54ee05d..beadf56 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -354,6 +354,25 @@ class PortCommandProcessor(BaseCommandProcessor): } } + def do_get(self, command, *args, context=None): + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + if self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': + text = self._render('attainable_rate', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': + text = self._render('administrative_status', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': + text = self._render('operational_status', *scopes, context=context) + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + def _init_access_points(self, context=None): port = self._model.get_port('name', context['unit'] + '/' + context['port']) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 5c2dfd7..9c218de 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -19,13 +19,200 @@ class UnitCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'status') access_points = () #'internalPorts', only on certain cards - main = {} + main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'Equipment': { + 'Prop': { + 'AssignmentStatus': 'r-', + 'CurrentStatus': 'r-' + }, + 'Cmd': ( + 'Assign', + 'Unassign', + 'Restart', + 'StopInBoot' + ) + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + }, + 'Logbooks': { + 'Cmd': ( + 'GetAlarmLogbook', + 'GetEventLogbook', + 'GetEquipmentLogbook' + ) + }, + 'Software': { + 'Prop': { + 'DiskSpace': 'r-', + 'SoftwareOnUnit': 'r-', + 'HardwareAndSoftware': 'r-', + 'Status': 'r-', + 'Configuration': 'rw' + }, + 'Cmd': ( + 'DeleteSoftware', + 'StartSoftware' + ), + 'File': { + 'Software': 'rw' + } + } + } - cfgm = {} + cfgm = { + 'Vlan': { + 'Prop': { + 'VlanCosTable': 'r-' + } + }, + 'Security': { + 'Prop': { + 'filtering': 'rw', + 'EoamMode': 'rw' + } + }, + 'Logon': { + 'Prop': { + 'LogonOptions': 'rw', + 'OneToOneOptions': 'rw' + } + }, + 'Mac': { + 'Prop': { + 'MacServiceBased': 'rw' + } + }, + 'HostPort': { + 'Prop': { + 'PolicerProfile': 'rw', + 'TrunkPolicerProfile': 'rw', + 'ProtRateLimiter': 'rw' + } + }, + 'QoS': { + 'Prop': { + 'ColorMarking': 'rw' + } + }, + 'Wire': { + 'General': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Thresholds': { + 'Prop': { + 'MeltAlarmThresholds': 'rw' + } + } + } + } - fm = {} + fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge' + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } + } - status = {} + status = { + 'MacAllocationTable': { + 'Prop': { + 'MacAllocationTableEntries': 'r-' + } + }, + 'SwitchPort': { + 'Prop': { + 'Mac': 'r-', + 'MacStatus': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters' + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters' + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters' + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters' + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters' + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters' + ) + }, + }, + }, + 'BufferManagement': { + 'Prop': { + 'BufferMgmtStatus': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'MeltLineTestStatus': 'r-', + 'SearchTone': 'rw' + }, + 'Cmd': ( + 'StartMeltAll', + 'StopMeltAll' + ) + } + } def _init_access_points(self, context=None): card = self._model.get_card('name', context['unit']) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 7e51d77..185e14a 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -21,17 +21,30 @@ class BaseCommandProcessor(base.CommandProcessor): management_functions = () access_points = () - def create_spacers(self, positions, args): - spacers = [] - previous_pos = 0 - i = 0 - for position in positions: - spacer = position - (previous_pos + len(str(args[i]))) - spacers.append(spacer) - previous_pos = position - i += 1 - - return spacers + main = {} + + cfgm = {} + + fm = {} + + pm = {} + + status = {} + + def map_states(self, object, type): + if object.admin_state == '0': + if type == 'port': + object.admin_state = 'Down' + elif object.admin_state == '1': + if type == 'port': + object.admin_state = 'Down' + + if object.operational_state == '0': + if type == 'port': + object.operational_state = 'Down' + elif object.operational_state == '1': + if type == 'port': + object.operational_state = 'Down' def do_help(self, command, *args, context=None): help_scopes = ('login', 'base', 'help') @@ -76,10 +89,16 @@ def do_pwd(self, command, *args, context=None): self._write(self._render('pwd', 'login', 'base', context=context)) def do_cd(self, command, *args, context=None): + if len(args) == 0: + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + if args[0] == '/': context['path'] = '/' from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor - exc = exceptions.TerminalExitError + exc = exceptions.TerminalExitError() exc.return_to = RootCommandProcessor raise exc @@ -87,7 +106,7 @@ def do_cd(self, command, *args, context=None): components = [x for x in args[0].split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', components[0]): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty @@ -152,7 +171,7 @@ def do_cd(self, command, *args, context=None): component_number = components[0].split('-')[1] command_processor = component_type.capitalize() + 'CommandProcessor' else: - command_processor = self.__name__.capitalize() + components[0].capitalize() + 'CommandProcessor' + command_processor = components[0].capitalize() + 'CommandProcessor' if component_type == 'unit': if self.__name__ != 'root': @@ -175,6 +194,10 @@ def do_cd(self, command, *args, context=None): template_scopes=()) # TODO: fix exception to not require all fields as empty context['chan'] = component_number + if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): + if self.__name__ != 'root': + raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + if components[0] in ('main', 'cfgm', 'fm', 'pm', 'status'): if re.search('(main|cfgm|fm|pm|status)', context['path']): return @@ -190,6 +213,12 @@ def do_cd(self, command, *args, context=None): from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor from vendors.KeyMile.accessPoints.root.unit.port.chan.chanCommandProcessor import ChanCommandProcessor from vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor import InterfaceCommandProcessor + from vendors.KeyMile.accessPoints.root.fan.fanCommandProcessor import FanCommandProcessor + from vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor import AlarmCommandProcessor + from vendors.KeyMile.accessPoints.root.eoamCommandProcessor import EoamCommandProcessor + from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor + from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor + from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if len(remaining_args) > 0: @@ -279,4 +308,4 @@ def generate_ls_text(layers, depth): raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=command) def _init_access_points(self, context=None): - raise exceptions.SoftboxenError(message='Abstract method not implemented.') + pass # Abstract method not implemented From 61d69dee9c65bae2e641303a63d3437fad30d1c8 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 2 Oct 2020 13:00:22 +0200 Subject: [PATCH 201/318] Extracted management function dicts into external files for every command processor --- .../accessPoints/root/eoamCommandProcessor.py | 55 +-- .../root/eoamManagementFunctions.py | 52 +++ .../root/fan/alarmCommandProcessor.py | 35 +- .../root/fan/alarmManagementFunctions.py | 32 ++ .../root/fan/fanCommandProcessor.py | 45 +-- .../root/fan/fanManagementFunctions.py | 42 +++ .../root/multicastCommandProcessor.py | 166 +-------- .../root/multicastManagementFunctions.py | 161 +++++++++ .../accessPoints/root/rootCommandProcessor.py | 337 +---------------- .../root/rootManagementFunctions.py | 333 +++++++++++++++++ .../services/macAccessCtrlCommandProcessor.py | 28 ++ .../macAccessCtrlManagementFunctions.py | 61 ++++ ...Processor.py => packetCommandProcessor.py} | 13 +- .../services/packetManagementFunctions.py | 8 + .../root/services/servicesCommandProcessor.py | 33 +- .../servicesMacAccessCtrlCommandProcessor.py | 85 ----- .../services/servicesManagementFunctions.py | 30 ++ .../root/tdmConnectionsCommandProcessor.py | 35 +- .../root/tdmConnectionsManagementFunctions.py | 33 ++ .../unit/port/chan/chanCommandProcessor.py | 105 +----- .../unit/port/chan/chanManagementFunctions.py | 100 ++++++ .../unit/port/chan/vcc/vccCommandProcessor.py | 108 +----- .../port/chan/vcc/vccManagementFunctions.py | 104 ++++++ .../interface/interfaceCommandProcessor.py | 108 +----- .../interface/interfaceManagementFunctions.py | 104 ++++++ .../root/unit/port/portCommandProcessor.py | 339 +----------------- .../root/unit/port/portManagementFunctions.py | 334 +++++++++++++++++ .../root/unit/unitCommandProcessor.py | 198 +--------- .../root/unit/unitManagementFunctions.py | 194 ++++++++++ 29 files changed, 1664 insertions(+), 1614 deletions(-) create mode 100644 vendors/KeyMile/accessPoints/root/eoamManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/fan/alarmManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/fan/fanManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/multicastManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/rootManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/services/macAccessCtrlManagementFunctions.py rename vendors/KeyMile/accessPoints/root/services/{servicesPacketCommandProcessor.py => packetCommandProcessor.py} (75%) create mode 100644 vendors/KeyMile/accessPoints/root/services/packetManagementFunctions.py delete mode 100644 vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/services/servicesManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/tdmConnectionsManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/chan/chanManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/port/portManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/unitManagementFunctions.py diff --git a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py index 0f9d2f1..d6888f5 100644 --- a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py @@ -19,58 +19,9 @@ class EoamCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'status') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'AdminAndOperStatus': { - 'Prop': { - 'AdministrativeStatus': 'rw', - 'OperationalStatus': 'r-' - } - } - } - - cfgm = { - 'DefaultMdLevel': { - 'Prop': { - 'DefaultMdSettings': 'rw' - } - }, - 'ContextMap': { - 'Prop': { - 'Mapping': 'rw' - } - }, - 'Aggregation': { - 'Prop': { - 'Role': 'rw', - 'Address': 'rw' - } - }, - 'Md': { - 'Cmd': ( - 'CreateMd', - 'DeleteMd' - ) - } - } - - status = { - 'DefaultMdMips': { - 'Prop': { - 'Mips': 'r-' - } - }, - 'ConfigurationErrors': { - 'Prop': { - 'InterfacesInError': 'r-' - } - } - } + from .eoamManagementFunctions import main + from .eoamManagementFunctions import cfgm + from .eoamManagementFunctions import status def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/eoamManagementFunctions.py b/vendors/KeyMile/accessPoints/root/eoamManagementFunctions.py new file mode 100644 index 0000000..c669d81 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/eoamManagementFunctions.py @@ -0,0 +1,52 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + } +} + +cfgm = { + 'DefaultMdLevel': { + 'Prop': { + 'DefaultMdSettings': 'rw' + } + }, + 'ContextMap': { + 'Prop': { + 'Mapping': 'rw' + } + }, + 'Aggregation': { + 'Prop': { + 'Role': 'rw', + 'Address': 'rw' + } + }, + 'Md': { + 'Cmd': ( + 'CreateMd', + 'DeleteMd' + ) + } +} + +status = { + 'DefaultMdMips': { + 'Prop': { + 'Mips': 'r-' + } + }, + 'ConfigurationErrors': { + 'Prop': { + 'InterfacesInError': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py index e2f83a8..a88d5ef 100644 --- a/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py @@ -19,38 +19,9 @@ class AlarmCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - cfgm = { - 'General': { - 'Prop': { - 'Polarity': 'rw' - } - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } + from .alarmManagementFunctions import main + from .alarmManagementFunctions import cfgm + from .alarmManagementFunctions import fm def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/fan/alarmManagementFunctions.py b/vendors/KeyMile/accessPoints/root/fan/alarmManagementFunctions.py new file mode 100644 index 0000000..7ecdd32 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/fan/alarmManagementFunctions.py @@ -0,0 +1,32 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'General': { + 'Prop': { + 'Polarity': 'rw' + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py index efb61a5..cd8dff8 100644 --- a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py @@ -19,48 +19,9 @@ class FanCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'Equipment': { - 'Prop': { - 'CurrentStatus': 'r-' - } - }, - 'Inventory': { - 'Prop': { - 'EquipmentInventory': 'r-' - } - } - } - - cfgm = { - 'General': { - 'Prop': { - 'Option': 'rw' - } - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } + from .fanManagementFunctions import main + from .fanManagementFunctions import cfgm + from .fanManagementFunctions import fm def _init_access_points(self, context=None): for i in range(1, 12): diff --git a/vendors/KeyMile/accessPoints/root/fan/fanManagementFunctions.py b/vendors/KeyMile/accessPoints/root/fan/fanManagementFunctions.py new file mode 100644 index 0000000..3a7049a --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/fan/fanManagementFunctions.py @@ -0,0 +1,42 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'Equipment': { + 'Prop': { + 'CurrentStatus': 'r-' + } + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + } +} + +cfgm = { + 'General': { + 'Prop': { + 'Option': 'rw' + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py index 8ec0162..43b31cf 100644 --- a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py @@ -19,167 +19,11 @@ class MulticastCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - cfgm = { - 'Multicast': { - 'General': { - 'Prop': { - 'SnoopingMode': 'rw', - 'LocalIPAddressForIGMPGeneration': 'rw', - 'IPSourceAddressOfQueries': 'rw', - 'portGroupInactivityTimeout': 'rw' - }, - 'Cmd': ( - 'CreateVlan', - 'DeleteVlan' - ) - }, - 'PreJoin': { - 'Prop': { - 'preJoinIntervalPeriod': 'rw' - } - }, - 'PostLeave': { - 'Prop': { - 'postLeaveDelayPeriod': 'rw' - } - }, - 'Preview': { - 'Prop': { - 'previewSettings': 'rw' - } - }, - 'Bandwidth': { - 'Prop': { - 'defaultBandwidthPerStream': 'rw' - } - }, - 'Alarms': { - 'Prop': { - 'configuredMulticastStreamsThreshold': 'rw' - } - - } - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } - - pm = { - 'UserCounter': { - 'Prop': { - 'UserCounterDisplayMode': 'rw', - 'UserCounterTable': 'r-' - }, - 'Cmd': ( - 'UserCounterReset', - ) - }, - 'History15min': { - 'Prop': { - 'History15minDisplayMode': 'rw', - 'History15minTable': 'r-' - } - }, - 'History24h': { - 'Prop': { - 'History24hDisplayMode': 'rw', - 'History24hTable': 'r-' - } - }, - 'Alarm15min': { - 'Prop': { - 'Alarm15minDisplayMode': 'rw', - 'Alarm15minTable': 'r-' - }, - 'Cmd': ( - 'Alarm15minReset', - ) - }, - 'Alarm24h': { - 'Prop': { - 'Alarm24hDisplayMode': 'rw', - 'Alarm24hTable': 'r-' - }, - 'Cmd': ( - 'Alarm24hReset', - ) - }, - 'PerformanceMonitoring': { - 'Cmd': ( - 'UserCounter', - 'GetHistory15min', - 'GetHistory24h', - 'GetAlarm15min', - 'GetAlarm24hRecursive', - 'ResetUserCounter', - 'ResetAlarm15min', - 'ResetAlarm24h' - ) - } - } - - status = { - 'multicast': { - 'activeStreams': { - 'Dynamic': { - 'Prop': { - 'activeMulticastStreams': 'r-', - 'NumberOfActiveStreams': 'r-' - }, - 'Cmd': ( - 'clearAllStreams', - ) - }, - 'Static': { - 'Prop': { - 'StaticMulticastStreams': 'r-', - 'NumberOfStaticStreams': 'r-' - } - }, - }, - - 'unitConfiguration': { - 'Prop': { - 'multicastUnitConfigurationStatus': 'r-' - } - }, - 'portSummary': { - 'Prop': { - 'CoreUnitFrontPorts': 'r-', - 'CapableServiceUnits': 'r-' - } - }, - 'Router': { - 'Prop': { - 'learnedIpRouterSourceAddress': 'r-' - } - - } - } - } + from .multicastManagementFunctions import main + from .multicastManagementFunctions import cfgm + from .multicastManagementFunctions import fm + from .multicastManagementFunctions import pm + from .multicastManagementFunctions import status def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/multicastManagementFunctions.py b/vendors/KeyMile/accessPoints/root/multicastManagementFunctions.py new file mode 100644 index 0000000..0b5c804 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/multicastManagementFunctions.py @@ -0,0 +1,161 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'Multicast': { + 'General': { + 'Prop': { + 'SnoopingMode': 'rw', + 'LocalIPAddressForIGMPGeneration': 'rw', + 'IPSourceAddressOfQueries': 'rw', + 'portGroupInactivityTimeout': 'rw' + }, + 'Cmd': ( + 'CreateVlan', + 'DeleteVlan' + ) + }, + 'PreJoin': { + 'Prop': { + 'preJoinIntervalPeriod': 'rw' + } + }, + 'PostLeave': { + 'Prop': { + 'postLeaveDelayPeriod': 'rw' + } + }, + 'Preview': { + 'Prop': { + 'previewSettings': 'rw' + } + }, + 'Bandwidth': { + 'Prop': { + 'defaultBandwidthPerStream': 'rw' + } + }, + 'Alarms': { + 'Prop': { + 'configuredMulticastStreamsThreshold': 'rw' + } + + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +pm = { + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + }, + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + } +} + +status = { + 'multicast': { + 'activeStreams': { + 'Dynamic': { + 'Prop': { + 'activeMulticastStreams': 'r-', + 'NumberOfActiveStreams': 'r-' + }, + 'Cmd': ( + 'clearAllStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticMulticastStreams': 'r-', + 'NumberOfStaticStreams': 'r-' + } + }, + }, + + 'unitConfiguration': { + 'Prop': { + 'multicastUnitConfigurationStatus': 'r-' + } + }, + 'portSummary': { + 'Prop': { + 'CoreUnitFrontPorts': 'r-', + 'CapableServiceUnits': 'r-' + } + }, + 'Router': { + 'Prop': { + 'learnedIpRouterSourceAddress': 'r-' + } + + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 4dd4cf4..81725fc 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -19,339 +19,10 @@ class RootCommandProcessor(BaseCommandProcessor): management_functions = {'main', 'cfgm', 'fm', 'status'} access_points = ('eoam', 'fan', 'multicast', 'services', 'tdmConnections') - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'Inventory': { - 'Prop': { - 'EquipmentInventory': 'r-' - } - }, - 'Logbooks': { - 'Cmd': ( - 'GetAllLogbooks', - 'GetAlarmLogbook', - 'GetEventLogbook', - 'GetConfigLogbook', - 'GetEquipmentLogbook', - 'GetSessionLogbook' - ) - }, - 'NESoftwareDownload': { - 'Cmd': ( - 'StartEsw', - ) - } - } - - cfgm = { - 'ConfigurationManagement': { - 'Prop': { - 'ConfigurationStatus': 'r-', - 'BackupDescription': 'r-' - }, - 'Cmd': ( - 'Load', - 'Save', - 'Initialize', - 'ChangeDescription' - ), - 'File': { - 'Configuration': 'rw' - } - }, - 'ManagementInterface': { - 'Prop': { - 'IP_Address': 'rw', - 'VlanId': 'rw', - 'ManagementVlanCoS': 'rw' - } - }, - 'Packet': { - 'Prop': { - 'Bridge': 'rw', - 'MACMovement': 'rw', - 'Traceability': 'rw', - 'PPPoA': 'rw' - } - }, - 'SessionManagement': { - 'Prop': { - 'TelnetEnabled': 'r-', - 'SshEnabled': 'r-', - 'UsbEnabled': 'r-', - 'RetryTime': 'r-', - 'SessionmanagerTime': 'r-', - 'AuthenticationManagementInterfaces': 'r-', - 'LocalAuthenticationFallback': 'r-', - 'RadiusDefaultUserclass': 'r-' - } - }, - 'RadiusClient': { - 'Prop': { - 'CommonRadius': 'r-', - 'PrimaryRadiusServer': 'r-', - 'AlternateRadiusServer': 'r-' - } - }, - 'DateAndTime': { - 'SNTPClient': { - 'Prop': { - 'OperationMode': 'rw', - 'PrimaryServer': 'rw', - 'SecondaryServer': 'rw', - 'PollingInterval': 'rw', - 'BroadcastDelay': 'rw' - } - }, - 'TimeZone': { - 'Prop': { - 'TimeZone': 'rw', - 'DaylightSaving': 'r-' - } - }, - }, - 'ProfileManagement': { - 'Prop': { - 'ProfileCpsTable': 'r-' - }, - 'Cmd': ( - 'Check', - 'Delete' - ), - 'File': { - 'Profile': 'rw', - 'Cps': 'rw' - } - }, - 'QoS': { - 'Prop': { - 'PriorityMapping': 'rw', - 'QueueMode': 'rw' - } - }, - 'SNMP': { - 'General': { - 'Prop': { - 'SNMPSupport': 'rw', - 'SNMPParameters': 'r-' - }, - 'Cmd': ( - 'SetDefaultSNMPConfigurationTables' - ) - }, - 'USM': { - 'Prop': { - 'LocalUserTable': 'rw', - 'RemoteUserTable': 'rw' - } - }, - }, - 'SyslogDestinations': { - 'Destination1': { - 'Prop': { - 'SyslogDestination1': 'rw' - } - }, - 'Destination2': { - 'Prop': { - 'SyslogDestination2': 'rw' - } - }, - 'Destination3': { - 'Prop': { - 'SyslogDestination3': 'rw' - } - }, - 'Destination4': { - 'Prop': { - 'SyslogDestination4': 'rw' - } - }, - 'Destination5': { - 'Prop': { - 'SyslogDestination5': 'rw' - } - }, - 'Destination6': { - 'Prop': { - 'SyslogDestination6': 'rw' - } - }, - 'Destination7': { - 'Prop': { - 'SyslogDestination7': 'rw' - } - }, - 'Destination8': { - 'Prop': { - 'SyslogDestination8': 'rw' - } - }, - 'Destination9': { - 'Prop': { - 'SyslogDestination9': 'rw' - } - }, - 'Destination10': { - 'Prop': { - 'SyslogDestination10': 'rw' - } - }, - }, - 'SyslogSources': { - 'Prop': { - 'SyslogSourceConfiguration': 'rw' - } - }, - 'BatteryPowerSaving': { - 'Prop': { - 'PowerSavingEnabled': 'rw', - 'PowerSavingAlarm': 'rw', - 'PowerSavingThresholds': 'rw', - 'PowerSavingUnits': 'r-' - }, - 'Cmd': ( - 'PowerSavingAddUnit', - 'PowerSavingRemoveUnit' - ) - }, - 'Ipsec': { - 'Prop': { - 'Ipsec': 'rw' - } - }, - 'TemeratureLimits': { - 'Prop': { - 'ThresholdExceed': 'rw', - 'ThresholdWarning': 'rw' - } - }, - 'ESO': { - 'Prop': { - 'Eso1ClockSources': 'rw', - 'Eso2ClockSource': 'rw' - } - }, - 'PETS': { - 'Prop': { - 'ClockSources': 'rw', - 'PetsClockPriority': 'rw' - } - } - } - - fm = { - 'ActiveFailures': { - 'Prop': { - 'ActiveFailureTable': 'r-' - } - }, - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge' - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } - - status = { - 'DateAndTime': { - 'Time': { - 'Prop': { - 'Summary': 'r-' - }, - 'Cmd': ( - 'SetDateAndTime' - ) - }, - 'SNTPClient': { - 'Prop': { - 'PrimaryServerState': 'r-', - 'SecondaryServerState': 'r-', - 'LastResponseTime': 'r-', - 'LastJumpTime': 'r-', - 'LastAdjustmentTime': 'r-' - } - }, - }, - 'ManagementInterface': { - 'Prop': { - 'SshFingerprint': 'r-' - }, - 'Cmd': ( - 'Ping' - ) - }, - 'SessionManagement': { - 'Cmd': ( - 'ShowSessions' - ) - }, - 'RadiusClient': { - 'Prop': { - 'PrimaryRadiusServerStatus': 'r-', - 'AlternateRadiusServerStatus': 'r-' - } - }, - 'Ipsec': { - 'Prop': { - 'IpsecSAStatus': 'r-' - }, - 'Cmd': ( - 'GetIpsecLogbook' - ) - }, - 'Redundancy': { - 'Prop': { - 'NeConfigurationStatus': 'r-', - 'RedundancyRoles': 'r-', - 'RedundancyStatus': 'r-' - }, - 'Cmd': ( - 'ManualSwitchOver', - 'ForcedSwitchOver', - 'IsolateUnits', - 'JoinUnits' - ) - }, - 'Temperature': { - 'Prop': { - 'CurrTemperature': 'r-', - 'MaxTemperature': 'r-', - 'MinTemperature': 'r-' - }, - 'Cmd': ( - 'ResetMinMax' - ) - }, - 'ESO': { - 'Prop': { - 'ClockOutputEso1': 'r-', - 'ClockOutputEso2': 'r-' - } - }, - 'PETS': { - 'Prop': { - 'PetsClockSources': 'r-', - 'PetsOperationStatus': 'r-' - }, - 'Cmd': ( - 'PetsClockOperation' - ) - } - } + from .rootManagementFunctions import main + from .rootManagementFunctions import cfgm + from .rootManagementFunctions import fm + from .rootManagementFunctions import status def _init_access_points(self, context=None): for card in self._model.cards: diff --git a/vendors/KeyMile/accessPoints/root/rootManagementFunctions.py b/vendors/KeyMile/accessPoints/root/rootManagementFunctions.py new file mode 100644 index 0000000..479c920 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/rootManagementFunctions.py @@ -0,0 +1,333 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + }, + 'Logbooks': { + 'Cmd': ( + 'GetAllLogbooks', + 'GetAlarmLogbook', + 'GetEventLogbook', + 'GetConfigLogbook', + 'GetEquipmentLogbook', + 'GetSessionLogbook' + ) + }, + 'NESoftwareDownload': { + 'Cmd': ( + 'StartEsw', + ) + } +} + +cfgm = { + 'ConfigurationManagement': { + 'Prop': { + 'ConfigurationStatus': 'r-', + 'BackupDescription': 'r-' + }, + 'Cmd': ( + 'Load', + 'Save', + 'Initialize', + 'ChangeDescription' + ), + 'File': { + 'Configuration': 'rw' + } + }, + 'ManagementInterface': { + 'Prop': { + 'IP_Address': 'rw', + 'VlanId': 'rw', + 'ManagementVlanCoS': 'rw' + } + }, + 'Packet': { + 'Prop': { + 'Bridge': 'rw', + 'MACMovement': 'rw', + 'Traceability': 'rw', + 'PPPoA': 'rw' + } + }, + 'SessionManagement': { + 'Prop': { + 'TelnetEnabled': 'r-', + 'SshEnabled': 'r-', + 'UsbEnabled': 'r-', + 'RetryTime': 'r-', + 'SessionmanagerTime': 'r-', + 'AuthenticationManagementInterfaces': 'r-', + 'LocalAuthenticationFallback': 'r-', + 'RadiusDefaultUserclass': 'r-' + } + }, + 'RadiusClient': { + 'Prop': { + 'CommonRadius': 'r-', + 'PrimaryRadiusServer': 'r-', + 'AlternateRadiusServer': 'r-' + } + }, + 'DateAndTime': { + 'SNTPClient': { + 'Prop': { + 'OperationMode': 'rw', + 'PrimaryServer': 'rw', + 'SecondaryServer': 'rw', + 'PollingInterval': 'rw', + 'BroadcastDelay': 'rw' + } + }, + 'TimeZone': { + 'Prop': { + 'TimeZone': 'rw', + 'DaylightSaving': 'r-' + } + }, + }, + 'ProfileManagement': { + 'Prop': { + 'ProfileCpsTable': 'r-' + }, + 'Cmd': ( + 'Check', + 'Delete' + ), + 'File': { + 'Profile': 'rw', + 'Cps': 'rw' + } + }, + 'QoS': { + 'Prop': { + 'PriorityMapping': 'rw', + 'QueueMode': 'rw' + } + }, + 'SNMP': { + 'General': { + 'Prop': { + 'SNMPSupport': 'rw', + 'SNMPParameters': 'r-' + }, + 'Cmd': ( + 'SetDefaultSNMPConfigurationTables', + ) + }, + 'USM': { + 'Prop': { + 'LocalUserTable': 'rw', + 'RemoteUserTable': 'rw' + } + }, + }, + 'SyslogDestinations': { + 'Destination1': { + 'Prop': { + 'SyslogDestination1': 'rw' + } + }, + 'Destination2': { + 'Prop': { + 'SyslogDestination2': 'rw' + } + }, + 'Destination3': { + 'Prop': { + 'SyslogDestination3': 'rw' + } + }, + 'Destination4': { + 'Prop': { + 'SyslogDestination4': 'rw' + } + }, + 'Destination5': { + 'Prop': { + 'SyslogDestination5': 'rw' + } + }, + 'Destination6': { + 'Prop': { + 'SyslogDestination6': 'rw' + } + }, + 'Destination7': { + 'Prop': { + 'SyslogDestination7': 'rw' + } + }, + 'Destination8': { + 'Prop': { + 'SyslogDestination8': 'rw' + } + }, + 'Destination9': { + 'Prop': { + 'SyslogDestination9': 'rw' + } + }, + 'Destination10': { + 'Prop': { + 'SyslogDestination10': 'rw' + } + }, + }, + 'SyslogSources': { + 'Prop': { + 'SyslogSourceConfiguration': 'rw' + } + }, + 'BatteryPowerSaving': { + 'Prop': { + 'PowerSavingEnabled': 'rw', + 'PowerSavingAlarm': 'rw', + 'PowerSavingThresholds': 'rw', + 'PowerSavingUnits': 'r-' + }, + 'Cmd': ( + 'PowerSavingAddUnit', + 'PowerSavingRemoveUnit' + ) + }, + 'Ipsec': { + 'Prop': { + 'Ipsec': 'rw' + } + }, + 'TemeratureLimits': { + 'Prop': { + 'ThresholdExceed': 'rw', + 'ThresholdWarning': 'rw' + } + }, + 'ESO': { + 'Prop': { + 'Eso1ClockSources': 'rw', + 'Eso2ClockSource': 'rw' + } + }, + 'PETS': { + 'Prop': { + 'ClockSources': 'rw', + 'PetsClockPriority': 'rw' + } + } +} + +fm = { + 'ActiveFailures': { + 'Prop': { + 'ActiveFailureTable': 'r-' + } + }, + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +status = { + 'DateAndTime': { + 'Time': { + 'Prop': { + 'Summary': 'r-' + }, + 'Cmd': ( + 'SetDateAndTime', + ) + }, + 'SNTPClient': { + 'Prop': { + 'PrimaryServerState': 'r-', + 'SecondaryServerState': 'r-', + 'LastResponseTime': 'r-', + 'LastJumpTime': 'r-', + 'LastAdjustmentTime': 'r-' + } + }, + }, + 'ManagementInterface': { + 'Prop': { + 'SshFingerprint': 'r-' + }, + 'Cmd': ( + 'Ping', + ) + }, + 'SessionManagement': { + 'Cmd': ( + 'ShowSessions', + ) + }, + 'RadiusClient': { + 'Prop': { + 'PrimaryRadiusServerStatus': 'r-', + 'AlternateRadiusServerStatus': 'r-' + } + }, + 'Ipsec': { + 'Prop': { + 'IpsecSAStatus': 'r-' + }, + 'Cmd': ( + 'GetIpsecLogbook', + ) + }, + 'Redundancy': { + 'Prop': { + 'NeConfigurationStatus': 'r-', + 'RedundancyRoles': 'r-', + 'RedundancyStatus': 'r-' + }, + 'Cmd': ( + 'ManualSwitchOver', + 'ForcedSwitchOver', + 'IsolateUnits', + 'JoinUnits' + ) + }, + 'Temperature': { + 'Prop': { + 'CurrTemperature': 'r-', + 'MaxTemperature': 'r-', + 'MinTemperature': 'r-' + }, + 'Cmd': ( + 'ResetMinMax', + ) + }, + 'ESO': { + 'Prop': { + 'ClockOutputEso1': 'r-', + 'ClockOutputEso2': 'r-' + } + }, + 'PETS': { + 'Prop': { + 'PetsClockSources': 'r-', + 'PetsOperationStatus': 'r-' + }, + 'Cmd': ( + 'PetsClockOperation', + ) + } +} diff --git a/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py new file mode 100644 index 0000000..d93320a --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py @@ -0,0 +1,28 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class MacAccessCtrlCommandProcessor(BaseCommandProcessor): + __name__ = 'macAccessCtrl' + management_functions = ('main', 'cfgm', 'fm', 'status') + access_points = () + + from .macAccessCtrlManagementFunctions import main + from .macAccessCtrlManagementFunctions import cfgm + from .macAccessCtrlManagementFunctions import fm + from .macAccessCtrlManagementFunctions import status + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/macAccessCtrlManagementFunctions.py b/vendors/KeyMile/accessPoints/root/services/macAccessCtrlManagementFunctions.py new file mode 100644 index 0000000..4ec41f2 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/macAccessCtrlManagementFunctions.py @@ -0,0 +1,61 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'General': { + 'Prop': { + 'Blacklist': 'rw' + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + }, + 'DuplicatedMac': { + 'Prop': { + 'DuplicatedMacAccessList': 'r-' + }, + 'Cmd': ( + 'FlushMacAccessDuplicatedList', + ) + } +} + +status = { + 'DynamicList': { + 'Prop': { + 'DynamicList': 'r-' + }, + 'Cmd': ( + 'FlushMacAccessDynamicList', + 'DeleteMacAccessDynamicListEntry' + ) + }, + 'UNIBlacklist': { + 'Prop': { + 'Blacklist': 'r-', + 'BNGlist': 'r-' + }, + 'Cmd': ( + 'DeleteMacAccessBNGlistEntry', + ) + } +} diff --git a/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py similarity index 75% rename from vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py rename to vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py index e2bf785..96d4113 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesPacketCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py @@ -14,19 +14,12 @@ from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor -class ServicesPacketCommandProcessor(BaseCommandProcessor): - __name__ = 'servicesPacket' +class PacketCommandProcessor(BaseCommandProcessor): + __name__ = 'packet' management_functions = ('main',) access_points = ('1to1DoubleTag', '1to1SingeTag', 'mcast', 'nto1', 'pls', 'tls') - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } + from .packetManagementFunctions import main def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/packetManagementFunctions.py b/vendors/KeyMile/accessPoints/root/services/packetManagementFunctions.py new file mode 100644 index 0000000..ebb0f2f --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/packetManagementFunctions.py @@ -0,0 +1,8 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py index dcede08..253a74f 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -19,36 +19,9 @@ class ServicesCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'fm', 'status') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } - - status = { - 'Prop': { - 'conflictList': 'r-' - } - } + from .servicesManagementFunctions import main + from .servicesManagementFunctions import fm + from .servicesManagementFunctions import status def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py deleted file mode 100644 index aea38f2..0000000 --- a/vendors/KeyMile/accessPoints/root/services/servicesMacAccessCtrlCommandProcessor.py +++ /dev/null @@ -1,85 +0,0 @@ -# This file is part of the NESi software. -# -# Copyright (c) 2020 -# Original Software Design by Ilya Etingof . -# -# Software adapted by inexio . -# - Janis Groß -# - Philip Konrath -# - Alexander Dincher -# -# License: https://github.com/inexio/NESi/LICENSE.rst - -from nesi import exceptions -from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor - - -class ServicesMacAccessCtrlCommandProcessor(BaseCommandProcessor): - __name__ = 'servicesMacAccessCtrl' - management_functions = ('main', 'cfgm', 'fm', 'status') - access_points = () - - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - cfgm = { - 'General': { - 'Prop': { - 'Blacklist': 'rw' - } - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - }, - 'DuplicatedMac': { - 'Prop': { - 'DuplicatedMacAccessList': 'r-' - }, - 'Cmd': ( - 'FlushMacAccessDuplicatedList', - ) - } - } - - status = { - 'DynamicList': { - 'Prop': { - 'DynamicList': 'r-' - }, - 'Cmd': ( - 'FlushMacAccessDynamicList', - 'DeleteMacAccessDynamicListEntry' - ) - }, - 'UNIBlacklist': { - 'Prop': { - 'Blacklist': 'r-', - 'BNGlist': 'r-' - }, - 'Cmd': ( - 'DeleteMacAccessBNGlistEntry', - ) - } - } - - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/services/servicesManagementFunctions.py b/vendors/KeyMile/accessPoints/root/services/servicesManagementFunctions.py new file mode 100644 index 0000000..b1bccfc --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/servicesManagementFunctions.py @@ -0,0 +1,30 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +status = { + 'Prop': { + 'conflictList': 'r-' + } +} diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py index 905a06a..12b4d77 100644 --- a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py @@ -19,39 +19,8 @@ class TdmConnectionsCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - cfgm = { - 'Connections': { - 'Cmd': ( - 'CreateConnection', - 'CreateBulkConnection', - 'CreateAdvancedConnection', - 'DeleteConnection', - 'DeleteMultipleConnections', - 'ShowConnections', - 'SetLabel1', - 'SetLabel2' - ) - }, - 'Ctps': { - 'Cmd': ( - 'ShowCtps', - ) - }, - 'Pbus': { - 'Prop': { - 'PbusUsage': 'r-' - } - } - } + from .tdmConnectionsManagementFunctions import main + from .tdmConnectionsManagementFunctions import cfgm def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsManagementFunctions.py b/vendors/KeyMile/accessPoints/root/tdmConnectionsManagementFunctions.py new file mode 100644 index 0000000..894d3f3 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/tdmConnectionsManagementFunctions.py @@ -0,0 +1,33 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'Connections': { + 'Cmd': ( + 'CreateConnection', + 'CreateBulkConnection', + 'CreateAdvancedConnection', + 'DeleteConnection', + 'DeleteMultipleConnections', + 'ShowConnections', + 'SetLabel1', + 'SetLabel2' + ) + }, + 'Ctps': { + 'Cmd': ( + 'ShowCtps', + ) + }, + 'Pbus': { + 'Prop': { + 'PbusUsage': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index e0d8ea3..2f4b9b9 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -19,106 +19,11 @@ class ChanCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - cfgm = { - 'Profile': { - 'Prop': { - 'ChanProfile': 'rw' - } - }, - 'subinterface': { - 'Cmd': ( - 'CreateInterface', - 'DeleteInterface' - ) - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } - - pm = { - 'PerformanceMonitoring': { - 'Cmd': ( - 'UserCounter', - 'GetHistory15min', - 'GetHistory24h', - 'GetAlarm15min', - 'GetAlarm24hRecursive', - 'ResetUserCounter', - 'ResetAlarm15min', - 'ResetAlarm24h' - ) - }, - 'UserCounter': { - 'Prop': { - 'UserCounterDisplayMode': 'rw', - 'UserCounterTable': 'r-' - }, - 'Cmd': ( - 'UserCounterReset', - ) - }, - 'History15min': { - 'Prop': { - 'History15minDisplayMode': 'rw', - 'History15minTable': 'r-' - } - }, - 'History24h': { - 'Prop': { - 'History24hDisplayMode': 'rw', - 'History24hTable': 'r-' - } - }, - 'Alarm15min': { - 'Prop': { - 'Alarm15minDisplayMode': 'rw', - 'Alarm15minTable': 'r-' - }, - 'Cmd': ( - 'Alarm15minReset', - ) - }, - 'Alarm24h': { - 'Prop': { - 'Alarm24hDisplayMode': 'rw', - 'Alarm24hTable': 'r-' - }, - 'Cmd': ( - 'Alarm24hReset', - ) - } - } - - status = { - 'General': { - 'Prop': { - 'Status': 'r-' - } - } - } + from .chanManagementFunctions import main + from .chanManagementFunctions import cfgm + from .chanManagementFunctions import fm + from .chanManagementFunctions import pm + from .chanManagementFunctions import status def _init_access_points(self, context=None): chan = self._model.get_chan('name', context['unit'] + '/' + context['port'] + '/' + context['chan']) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanManagementFunctions.py new file mode 100644 index 0000000..ab83570 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanManagementFunctions.py @@ -0,0 +1,100 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'Profile': { + 'Prop': { + 'ChanProfile': 'rw' + } + }, + 'subinterface': { + 'Cmd': ( + 'CreateInterface', + 'DeleteInterface' + ) + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } +} + +status = { + 'General': { + 'Prop': { + 'Status': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py index 21d96b0..40d569a 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py @@ -19,110 +19,10 @@ class VccCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'pm', 'status') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - cfgm = { - 'Traceability': { - 'Prop': { - 'AutomaticAgentCircuitId': 'rw', - 'AgentCircuitId': 'rw' - } - }, - 'Filter': { - 'Prop': { - 'MACSourceFilteringMode': 'rw', - 'MacAccessWhitelist': 'rw', - 'NumberOfMacForFloodingPrev': 'rw', - 'L2CPFilter': 'rw', - 'DestMacBlacklistProfile': 'rw', - 'SrcMacBlacklist': 'rw' - } - }, - 'IfRateLimiter': { - 'Prop': { - 'IfRateLimiting': 'rw' - } - }, - 'Profiles': { - 'Prop': { - 'configuredProfiles': 'rw' - } - } - } - - pm = { - 'PerformanceMonitoring': { - 'Cmd': ( - 'UserCounter', - 'GetHistory15min', - 'GetHistory24h', - 'GetAlarm15min', - 'GetAlarm24hRecursive', - 'ResetUserCounter', - 'ResetAlarm15min', - 'ResetAlarm24h' - ) - }, - 'UserCounter': { - 'Prop': { - 'UserCounterDisplayMode': 'rw', - 'UserCounterTable': 'r-' - }, - 'Cmd': ( - 'UserCounterReset', - ) - }, - 'History15min': { - 'Prop': { - 'History15minDisplayMode': 'rw', - 'History15minTable': 'r-' - } - }, - 'History24h': { - 'Prop': { - 'History24hDisplayMode': 'rw', - 'History24hTable': 'r-' - } - }, - 'Alarm15min': { - 'Prop': { - 'Alarm15minDisplayMode': 'rw', - 'Alarm15minTable': 'r-' - }, - 'Cmd': ( - 'Alarm15minReset', - ) - }, - 'Alarm24h': { - 'Prop': { - 'Alarm24hDisplayMode': 'rw', - 'Alarm24hTable': 'r-' - }, - 'Cmd': ( - 'Alarm24hReset', - ) - } - } - - status = { - 'ServiceInfo': { - 'Prop': { - 'ServiceStatus': 'r-' - } - }, - 'UserConnection': { - 'Prop': { - 'CurrentPppConnectionState': 'r-' - } - } - } + from .vccManagementFunctions import main + from .vccManagementFunctions import cfgm + from .vccManagementFunctions import pm + from .vccManagementFunctions import status def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py new file mode 100644 index 0000000..9278f33 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py @@ -0,0 +1,104 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'Traceability': { + 'Prop': { + 'AutomaticAgentCircuitId': 'rw', + 'AgentCircuitId': 'rw' + } + }, + 'Filter': { + 'Prop': { + 'MACSourceFilteringMode': 'rw', + 'MacAccessWhitelist': 'rw', + 'NumberOfMacForFloodingPrev': 'rw', + 'L2CPFilter': 'rw', + 'DestMacBlacklistProfile': 'rw', + 'SrcMacBlacklist': 'rw' + } + }, + 'IfRateLimiter': { + 'Prop': { + 'IfRateLimiting': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'configuredProfiles': 'rw' + } + } +} + +pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } +} + +status = { + 'ServiceInfo': { + 'Prop': { + 'ServiceStatus': 'r-' + } + }, + 'UserConnection': { + 'Prop': { + 'CurrentPppConnectionState': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index d8638a1..5bbae5d 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -19,110 +19,10 @@ class InterfaceCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'pm', 'status') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } - } - - cfgm = { - 'Traceability': { - 'Prop': { - 'AutomaticAgentCircuitId': 'rw', - 'AgentCircuitId': 'rw' - } - }, - 'Filter': { - 'Prop': { - 'MACSourceFilteringMode': 'rw', - 'MacAccessWhitelist': 'rw', - 'NumberOfMacForFloodingPrev': 'rw', - 'L2CPFilter': 'rw', - 'DestMacBlacklistProfile': 'rw', - 'SrcMacBlacklist': 'rw' - } - }, - 'IfRateLimiter': { - 'Prop': { - 'IfRateLimiting': 'rw' - } - }, - 'Profiles': { - 'Prop': { - 'configuredProfiles': 'rw' - } - } - } - - pm = { - 'PerformanceMonitoring': { - 'Cmd': ( - 'UserCounter', - 'GetHistory15min', - 'GetHistory24h', - 'GetAlarm15min', - 'GetAlarm24hRecursive', - 'ResetUserCounter', - 'ResetAlarm15min', - 'ResetAlarm24h' - ) - }, - 'UserCounter': { - 'Prop': { - 'UserCounterDisplayMode': 'rw', - 'UserCounterTable': 'r-' - }, - 'Cmd': ( - 'UserCounterReset', - ) - }, - 'History15min': { - 'Prop': { - 'History15minDisplayMode': 'rw', - 'History15minTable': 'r-' - } - }, - 'History24h': { - 'Prop': { - 'History24hDisplayMode': 'rw', - 'History24hTable': 'r-' - } - }, - 'Alarm15min': { - 'Prop': { - 'Alarm15minDisplayMode': 'rw', - 'Alarm15minTable': 'r-' - }, - 'Cmd': ( - 'Alarm15minReset', - ) - }, - 'Alarm24h': { - 'Prop': { - 'Alarm24hDisplayMode': 'rw', - 'Alarm24hTable': 'r-' - }, - 'Cmd': ( - 'Alarm24hReset', - ) - } - } - - status = { - 'ServiceInfo': { - 'Prop': { - 'ServiceStatus': 'r-' - } - }, - 'UserConnection': { - 'Prop': { - 'CurrentPppConnectionState': 'r-' - } - } - } + from .interfaceManagementFunctions import main + from .interfaceManagementFunctions import cfgm + from .interfaceManagementFunctions import pm + from .interfaceManagementFunctions import status def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceManagementFunctions.py new file mode 100644 index 0000000..9278f33 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceManagementFunctions.py @@ -0,0 +1,104 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'Traceability': { + 'Prop': { + 'AutomaticAgentCircuitId': 'rw', + 'AgentCircuitId': 'rw' + } + }, + 'Filter': { + 'Prop': { + 'MACSourceFilteringMode': 'rw', + 'MacAccessWhitelist': 'rw', + 'NumberOfMacForFloodingPrev': 'rw', + 'L2CPFilter': 'rw', + 'DestMacBlacklistProfile': 'rw', + 'SrcMacBlacklist': 'rw' + } + }, + 'IfRateLimiter': { + 'Prop': { + 'IfRateLimiting': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'configuredProfiles': 'rw' + } + } +} + +pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } +} + +status = { + 'ServiceInfo': { + 'Prop': { + 'ServiceStatus': 'r-' + } + }, + 'UserConnection': { + 'Prop': { + 'CurrentPppConnectionState': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index beadf56..e9b392e 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -19,340 +19,11 @@ class PortCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') access_points = () - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'AdminAndOperStatus': { - 'Prop': { - 'AdministrativeStatus': 'rw', - 'OperationalStatus': 'r-' - } - } - } - - cfgm = { - 'Multicast': { - 'Prop': { - 'MaxNumberOfMulticastStreams': 'rw', - 'EnableIgmpClassifier': 'rw', - 'AllowStaticStreams': 'rw', - 'EnableFastLeave': 'rw', - 'GroupManagement': 'rw', - 'Bandwidth': 'rw' - }, - 'Cmd': ( - 'GetGroupList', - ) - }, - 'Traceability': { - 'Prop': { - 'AgentRemoteId': 'rw' - } - }, - 'Security': { - 'Prop': { - 'ServiceOptions': 'rw', - 'MaxNumberOfMac': 'rw' - } - }, - 'AccessControl': { - 'Prop': { - 'ClassificationKey': 'rw', - 'MAT': 'rw' - } - }, - 'RateLimiter': { - 'Prop': { - 'RateLimiting': 'rw', - 'RateLimitingCoS': 'rw' - } - }, - 'Qos': { - 'Prop': { - 'WfqProfile': 'rw' - } - }, - 'Wire': { - 'Prop': { - 'MeltConfiguration': 'rw' - } - }, - 'Profiles': { - 'Prop': { - 'PortProfiles': 'rw' - } - }, - 'Misc': { - 'Prop': { - 'SpecificDPBO': 'rw', - 'SpecificUPBO': 'rw' - } - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } - - pm = { - 'PerformanceMonitoring': { - 'Cmd': ( - 'UserCounter', - 'GetHistory15min', - 'GetHistory24h', - 'GetAlarm15min', - 'GetAlarm24hRecursive', - 'ResetUserCounter', - 'ResetAlarm15min', - 'ResetAlarm24h' - ) - }, - 'UserCounter': { - 'Prop': { - 'UserCounterDisplayMode': 'rw', - 'UserCounterTable': 'r-' - }, - 'Cmd': ( - 'UserCounterReset', - ) - }, - 'History15min': { - 'Prop': { - 'History15minDisplayMode': 'rw', - 'History15minTable': 'r-' - } - }, - 'History24h': { - 'Prop': { - 'History24hDisplayMode': 'rw', - 'History24hTable': 'r-' - } - }, - 'Alarm15min': { - 'Prop': { - 'Alarm15minDisplayMode': 'rw', - 'Alarm15minTable': 'r-' - }, - 'Cmd': ( - 'Alarm15minReset', - ) - }, - 'Alarm24h': { - 'Prop': { - 'Alarm24hDisplayMode': 'rw', - 'Alarm24hTable': 'r-' - }, - 'Cmd': ( - 'Alarm24hReset', - ) - } - } - - status = { - 'General': { - 'Prop': { - 'Standard': 'r-', - 'PowerMgmStatus': 'r-', - 'Vdsl2Parameters': 'r-', - 'EstUPBOElectricalLength': 'r-', - 'LineRate': 'r-', - 'LineSnrMargin': 'r-', - 'AttainableNetDataRate': 'r-', - 'AttainableRate': 'r-', - 'OutputPower': 'r-', - 'BandStatus': 'r-' - } - }, - 'statistics': { - 'Prop': { - 'counters': 'r-', - 'PolicingCounters': 'r-' - }, - 'Cmd': ( - 'ResetPortCounters', - ) - }, - 'Nto1MacAccessDynamicList': { - 'Prop': { - 'UnicastList': 'r-' - } - }, - 'HostPortStatistics': { - 'GeneralCounters': { - 'Prop': { - 'GeneralList': 'r-' - }, - 'Cmd': ( - 'ResetGeneralCounters', - ) - }, - 'ProtocolCounters': { - 'IgmpCounters': { - 'Prop': { - 'IgmpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetIgmpCounters', - ) - }, - 'DhcpCounters': { - 'Prop': { - 'DhcpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetDhcpCounters', - ) - }, - 'ArpCounters': { - 'Prop': { - 'ArpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetArpCounters', - ) - }, - 'PPPoECounters': { - 'Prop': { - 'PPPoEProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetPPPoECounters', - ) - }, - 'UnknownSourceMACCounters': { - 'Prop': { - 'UnknownSrcMACProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetUnknownSrcMACCounters', - ) - }, - }, - }, - 'TLSMacForwardingList': { - 'Prop': { - 'MacForwardingList': 'r-' - }, - 'Cmd': ( - 'FlushMacForwardingList', - ) - }, - '1to1MacForwardingList': { - 'Prop': { - 'One2OneMacForwardingList': 'r-' - } - }, - 'Qos': { - 'Prop': { - 'wfqueues': 'r-' - } - }, - 'Multicast': { - 'stream': { - 'Dynamic': { - 'Prop': { - 'ActiveStreams': 'r-' - }, - 'Cmd': ( - 'ClearActiveStreams', - ) - }, - 'Static': { - 'Prop': { - 'StaticStreams': 'r-' - } - }, - }, - - 'Vlan': { - 'Prop': { - 'AttachedVlans': 'r-' - } - }, - 'Preview': { - 'Cmd': ( - 'ResetPreviewSettings', - ) - }, - 'Bandwidth': { - 'Prop': { - 'bandwidthStatus': 'r-' - } - }, - }, - 'LineTest': { - 'MELT': { - 'Prop': { - 'MeltResults': 'r-' - }, - 'Cmd': ( - 'StartMeltMeasurement', - ) - }, - 'Delt': { - 'Prop': { - 'DeltMeasurementStatus': 'r-', - 'RecordedDeltMeasurements': 'r-' - }, - 'Cmd': ( - 'StartDeltMeasurement', - ) - }, - 'Selt': { - 'Prop': { - 'SeltMeasurementStatus': 'r-', - 'RecordedSeltMeasurements': 'r-', - 'CableType': 'rw', - 'BandplanProfile': 'rw', - 'TargetSnrm': 'rw' - }, - 'Cmd': ( - 'StartSeltMeasurement', - ) - }, - }, - 'Defects': { - 'Prop': { - 'Defects': 'r-' - } - }, - 'LineInventory': { - 'Prop': { - 'VendorId': 'r-' - } - }, - 'Maintenance': { - 'Prop': { - 'DslOperationStatus': 'r-' - } - }, - 'Subcarrier': { - 'Cmd': ( - 'ShowBitAllocation', - ) - }, - 'RfiBands': { - 'Prop': { - 'NotchStatus': 'r-' - } - } - } + from .portManagementFunctions import main + from .portManagementFunctions import cfgm + from .portManagementFunctions import fm + from .portManagementFunctions import pm + from .portManagementFunctions import status def do_get(self, command, *args, context=None): scopes = ('login', 'base', 'get') diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/port/portManagementFunctions.py new file mode 100644 index 0000000..9529dba --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/port/portManagementFunctions.py @@ -0,0 +1,334 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + } +} + +cfgm = { + 'Multicast': { + 'Prop': { + 'MaxNumberOfMulticastStreams': 'rw', + 'EnableIgmpClassifier': 'rw', + 'AllowStaticStreams': 'rw', + 'EnableFastLeave': 'rw', + 'GroupManagement': 'rw', + 'Bandwidth': 'rw' + }, + 'Cmd': ( + 'GetGroupList', + ) + }, + 'Traceability': { + 'Prop': { + 'AgentRemoteId': 'rw' + } + }, + 'Security': { + 'Prop': { + 'ServiceOptions': 'rw', + 'MaxNumberOfMac': 'rw' + } + }, + 'AccessControl': { + 'Prop': { + 'ClassificationKey': 'rw', + 'MAT': 'rw' + } + }, + 'RateLimiter': { + 'Prop': { + 'RateLimiting': 'rw', + 'RateLimitingCoS': 'rw' + } + }, + 'Qos': { + 'Prop': { + 'WfqProfile': 'rw' + } + }, + 'Wire': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'PortProfiles': 'rw' + } + }, + 'Misc': { + 'Prop': { + 'SpecificDPBO': 'rw', + 'SpecificUPBO': 'rw' + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } +} + +status = { + 'General': { + 'Prop': { + 'Standard': 'r-', + 'PowerMgmStatus': 'r-', + 'Vdsl2Parameters': 'r-', + 'EstUPBOElectricalLength': 'r-', + 'LineRate': 'r-', + 'LineSnrMargin': 'r-', + 'AttainableNetDataRate': 'r-', + 'AttainableRate': 'r-', + 'OutputPower': 'r-', + 'BandStatus': 'r-' + } + }, + 'statistics': { + 'Prop': { + 'counters': 'r-', + 'PolicingCounters': 'r-' + }, + 'Cmd': ( + 'ResetPortCounters', + ) + }, + 'Nto1MacAccessDynamicList': { + 'Prop': { + 'UnicastList': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters', + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + }, + }, + 'TLSMacForwardingList': { + 'Prop': { + 'MacForwardingList': 'r-' + }, + 'Cmd': ( + 'FlushMacForwardingList', + ) + }, + '1to1MacForwardingList': { + 'Prop': { + 'One2OneMacForwardingList': 'r-' + } + }, + 'Qos': { + 'Prop': { + 'wfqueues': 'r-' + } + }, + 'Multicast': { + 'stream': { + 'Dynamic': { + 'Prop': { + 'ActiveStreams': 'r-' + }, + 'Cmd': ( + 'ClearActiveStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticStreams': 'r-' + } + }, + }, + + 'Vlan': { + 'Prop': { + 'AttachedVlans': 'r-' + } + }, + 'Preview': { + 'Cmd': ( + 'ResetPreviewSettings', + ) + }, + 'Bandwidth': { + 'Prop': { + 'bandwidthStatus': 'r-' + } + }, + }, + 'LineTest': { + 'MELT': { + 'Prop': { + 'MeltResults': 'r-' + }, + 'Cmd': ( + 'StartMeltMeasurement', + ) + }, + 'Delt': { + 'Prop': { + 'DeltMeasurementStatus': 'r-', + 'RecordedDeltMeasurements': 'r-' + }, + 'Cmd': ( + 'StartDeltMeasurement', + ) + }, + 'Selt': { + 'Prop': { + 'SeltMeasurementStatus': 'r-', + 'RecordedSeltMeasurements': 'r-', + 'CableType': 'rw', + 'BandplanProfile': 'rw', + 'TargetSnrm': 'rw' + }, + 'Cmd': ( + 'StartSeltMeasurement', + ) + }, + }, + 'Defects': { + 'Prop': { + 'Defects': 'r-' + } + }, + 'LineInventory': { + 'Prop': { + 'VendorId': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'DslOperationStatus': 'r-' + } + }, + 'Subcarrier': { + 'Cmd': ( + 'ShowBitAllocation', + ) + }, + 'RfiBands': { + 'Prop': { + 'NotchStatus': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 9c218de..368a108 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -19,200 +19,10 @@ class UnitCommandProcessor(BaseCommandProcessor): management_functions = ('main', 'cfgm', 'fm', 'status') access_points = () #'internalPorts', only on certain cards - main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'Equipment': { - 'Prop': { - 'AssignmentStatus': 'r-', - 'CurrentStatus': 'r-' - }, - 'Cmd': ( - 'Assign', - 'Unassign', - 'Restart', - 'StopInBoot' - ) - }, - 'Inventory': { - 'Prop': { - 'EquipmentInventory': 'r-' - } - }, - 'Logbooks': { - 'Cmd': ( - 'GetAlarmLogbook', - 'GetEventLogbook', - 'GetEquipmentLogbook' - ) - }, - 'Software': { - 'Prop': { - 'DiskSpace': 'r-', - 'SoftwareOnUnit': 'r-', - 'HardwareAndSoftware': 'r-', - 'Status': 'r-', - 'Configuration': 'rw' - }, - 'Cmd': ( - 'DeleteSoftware', - 'StartSoftware' - ), - 'File': { - 'Software': 'rw' - } - } - } - - cfgm = { - 'Vlan': { - 'Prop': { - 'VlanCosTable': 'r-' - } - }, - 'Security': { - 'Prop': { - 'filtering': 'rw', - 'EoamMode': 'rw' - } - }, - 'Logon': { - 'Prop': { - 'LogonOptions': 'rw', - 'OneToOneOptions': 'rw' - } - }, - 'Mac': { - 'Prop': { - 'MacServiceBased': 'rw' - } - }, - 'HostPort': { - 'Prop': { - 'PolicerProfile': 'rw', - 'TrunkPolicerProfile': 'rw', - 'ProtRateLimiter': 'rw' - } - }, - 'QoS': { - 'Prop': { - 'ColorMarking': 'rw' - } - }, - 'Wire': { - 'General': { - 'Prop': { - 'MeltConfiguration': 'rw' - } - }, - 'Thresholds': { - 'Prop': { - 'MeltAlarmThresholds': 'rw' - } - } - } - } - - fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' - }, - 'Cmd': ( - 'Acknowledge' - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' - } - } - } - - status = { - 'MacAllocationTable': { - 'Prop': { - 'MacAllocationTableEntries': 'r-' - } - }, - 'SwitchPort': { - 'Prop': { - 'Mac': 'r-', - 'MacStatus': 'r-' - } - }, - 'HostPortStatistics': { - 'GeneralCounters': { - 'Prop': { - 'GeneralList': 'r-' - }, - 'Cmd': ( - 'ResetGeneralCounters' - ) - }, - 'ProtocolCounters': { - 'IgmpCounters': { - 'Prop': { - 'IgmpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetIgmpCounters' - ) - }, - 'DhcpCounters': { - 'Prop': { - 'DhcpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetDhcpCounters' - ) - }, - 'ArpCounters': { - 'Prop': { - 'ArpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetArpCounters' - ) - }, - 'PPPoECounters': { - 'Prop': { - 'PPPoEProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetPPPoECounters' - ) - }, - 'UnknownSourceMACCounters': { - 'Prop': { - 'UnknownSrcMACProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetUnknownSrcMACCounters' - ) - }, - }, - }, - 'BufferManagement': { - 'Prop': { - 'BufferMgmtStatus': 'r-' - } - }, - 'Maintenance': { - 'Prop': { - 'MeltLineTestStatus': 'r-', - 'SearchTone': 'rw' - }, - 'Cmd': ( - 'StartMeltAll', - 'StopMeltAll' - ) - } - } + from .unitManagementFunctions import main + from .unitManagementFunctions import cfgm + from .unitManagementFunctions import fm + from .unitManagementFunctions import status def _init_access_points(self, context=None): card = self._model.get_card('name', context['unit']) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/unitManagementFunctions.py new file mode 100644 index 0000000..0a5adbd --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/unitManagementFunctions.py @@ -0,0 +1,194 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'Equipment': { + 'Prop': { + 'AssignmentStatus': 'r-', + 'CurrentStatus': 'r-' + }, + 'Cmd': ( + 'Assign', + 'Unassign', + 'Restart', + 'StopInBoot' + ) + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + }, + 'Logbooks': { + 'Cmd': ( + 'GetAlarmLogbook', + 'GetEventLogbook', + 'GetEquipmentLogbook' + ) + }, + 'Software': { + 'Prop': { + 'DiskSpace': 'r-', + 'SoftwareOnUnit': 'r-', + 'HardwareAndSoftware': 'r-', + 'Status': 'r-', + 'Configuration': 'rw' + }, + 'Cmd': ( + 'DeleteSoftware', + 'StartSoftware' + ), + 'File': { + 'Software': 'rw' + } + } +} + +cfgm = { + 'Vlan': { + 'Prop': { + 'VlanCosTable': 'r-' + } + }, + 'Security': { + 'Prop': { + 'filtering': 'rw', + 'EoamMode': 'rw' + } + }, + 'Logon': { + 'Prop': { + 'LogonOptions': 'rw', + 'OneToOneOptions': 'rw' + } + }, + 'Mac': { + 'Prop': { + 'MacServiceBased': 'rw' + } + }, + 'HostPort': { + 'Prop': { + 'PolicerProfile': 'rw', + 'TrunkPolicerProfile': 'rw', + 'ProtRateLimiter': 'rw' + } + }, + 'QoS': { + 'Prop': { + 'ColorMarking': 'rw' + } + }, + 'Wire': { + 'General': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Thresholds': { + 'Prop': { + 'MeltAlarmThresholds': 'rw' + } + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +status = { + 'MacAllocationTable': { + 'Prop': { + 'MacAllocationTableEntries': 'r-' + } + }, + 'SwitchPort': { + 'Prop': { + 'Mac': 'r-', + 'MacStatus': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters', + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + }, + }, + 'BufferManagement': { + 'Prop': { + 'BufferMgmtStatus': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'MeltLineTestStatus': 'r-', + 'SearchTone': 'rw' + }, + 'Cmd': ( + 'StartMeltAll', + 'StopMeltAll' + ) + } +} From 96f3b85d056c0dbfbc89d652a5be9273d9c8033f Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 2 Oct 2020 14:29:32 +0200 Subject: [PATCH 202/318] Added create_spacers function again --- vendors/KeyMile/baseCommandProcessor.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 185e14a..d6463c9 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -46,6 +46,18 @@ def map_states(self, object, type): if type == 'port': object.operational_state = 'Down' + def create_spacers(self, positions, args): + spacers = [] + previous_pos = 0 + i = 0 + for position in positions: + spacer = position - (previous_pos + len(str(args[i]))) + spacers.append(spacer) + previous_pos = position + i += 1 + + return spacers + def do_help(self, command, *args, context=None): help_scopes = ('login', 'base', 'help') if self._validate(args, str): @@ -88,6 +100,9 @@ def do_pwd(self, command, *args, context=None): context['spacer'] = self.create_spacers((67,), (context['path'],))[0] * ' ' self._write(self._render('pwd', 'login', 'base', context=context)) + def exec_in_path(self, path, command, *args, context=None): + pass + def do_cd(self, command, *args, context=None): if len(args) == 0: exc = exceptions.CommandSyntaxError(command=command) @@ -304,6 +319,12 @@ def generate_ls_text(layers, depth): text += self._render('ls_list_body', *scopes, context=context) self._write(text) + elif self._validate(args, '-e'): + pass + elif self._validate([args[0]], str): + path = args[0] + + self.do_cd('cd', path, context=context) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=command) From f5fb2cbbaabaa4b420c524b30cf46c4a42b52c32 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 5 Oct 2020 12:29:31 +0200 Subject: [PATCH 203/318] Fixed base_views to handle new keymile schemas --- nesi/keymile/api/schemas/__init__.py | 17 +++++++++++++++++ nesi/softbox/api/views/base_views.py | 1 + 2 files changed, 18 insertions(+) diff --git a/nesi/keymile/api/schemas/__init__.py b/nesi/keymile/api/schemas/__init__.py index e69de29..04e408d 100644 --- a/nesi/keymile/api/schemas/__init__.py +++ b/nesi/keymile/api/schemas/__init__.py @@ -0,0 +1,17 @@ +from inspect import isclass +from pkgutil import iter_modules +from pathlib import Path +from importlib import import_module + +# iterate through the modules in the current package +package_dir = Path(__file__).resolve().parent +for (_, module_name, _) in iter_modules([package_dir]): + + # import the module and iterate through its attributes + module = import_module(f"{__name__}.{module_name}") + for attribute_name in dir(module): + attribute = getattr(module, attribute_name) + + if isclass(attribute): + # Add the class to this package's variables + globals()[attribute_name] = attribute \ No newline at end of file diff --git a/nesi/softbox/api/views/base_views.py b/nesi/softbox/api/views/base_views.py index ac46d02..4259e94 100644 --- a/nesi/softbox/api/views/base_views.py +++ b/nesi/softbox/api/views/base_views.py @@ -20,6 +20,7 @@ from nesi.softbox.api.schemas import * from nesi.alcatel.api.schemas import * from nesi.huawei.api.schemas import * +from nesi.keymile.api.schemas import * # important for other view classes from nesi.softbox.api import db From ec3c20f65d0abc7af9c8fcdfba99469c625e35b3 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 6 Oct 2020 09:45:34 +0200 Subject: [PATCH 204/318] Initialize Keymile testsetup --- .../integration_tests/keymile/backup.txt | 3 ++ .../integration_tests/keymile/getDslam4.txt | 3 ++ .../keymile/getInventory2.txt | 3 ++ .../integration_tests/keymile/getIpsx7.txt | 3 ++ .../keymile/getMonitoring3.txt | 3 ++ .../integration_tests/keymile/getState1.txt | 3 ++ .../keymile/getSubscriber6.txt | 3 ++ .../integration_tests/keymile/getVoice5.txt | 3 ++ .../keymile/setChannelProfile14.txt | 3 ++ .../keymile/setDslProfile8.txt | 3 ++ .../keymile/setInterface16.txt | 3 ++ .../integration_tests/keymile/setIpAddr6.txt | 3 ++ .../keymile/setPortProfile13.txt | 3 ++ .../integration_tests/keymile/setProfile7.txt | 3 ++ .../keymile/setSIPDomain12.txt | 3 ++ .../integration_tests/keymile/setTraffic1.txt | 3 ++ .../integration_tests/keymile/setVCC15.txt | 3 ++ .../integration_tests/keymile/setconfDsl2.txt | 3 ++ .../keymile/setconfVoice9.txt | 3 ++ .../keymile/setdeconfVoicePort11.txt | 3 ++ .../keymile/setdeconfVoicePort17.txt | 3 ++ .../keymile/setportaktiv4.txt | 3 ++ .../keymile/setportdeactiv5.txt | 3 ++ .../keymile/setunconfDsl3.txt | 3 ++ .../keymile/setunconfVoice10.txt | 3 ++ .../keymile/test Loopback3.txt | 3 ++ .../keymile/testVoicePort2.txt | 3 ++ .../integration_tests/keymile/testmelt1.txt | 3 ++ .../keymile/testmelting4.txt | 3 ++ test_cases/unit_tests/keymile/test_keymile.py | 41 ++++++++++++------- 30 files changed, 113 insertions(+), 15 deletions(-) create mode 100644 test_cases/integration_tests/keymile/backup.txt create mode 100644 test_cases/integration_tests/keymile/getDslam4.txt create mode 100644 test_cases/integration_tests/keymile/getInventory2.txt create mode 100644 test_cases/integration_tests/keymile/getIpsx7.txt create mode 100644 test_cases/integration_tests/keymile/getMonitoring3.txt create mode 100644 test_cases/integration_tests/keymile/getState1.txt create mode 100644 test_cases/integration_tests/keymile/getSubscriber6.txt create mode 100644 test_cases/integration_tests/keymile/getVoice5.txt create mode 100644 test_cases/integration_tests/keymile/setChannelProfile14.txt create mode 100644 test_cases/integration_tests/keymile/setDslProfile8.txt create mode 100644 test_cases/integration_tests/keymile/setInterface16.txt create mode 100644 test_cases/integration_tests/keymile/setIpAddr6.txt create mode 100644 test_cases/integration_tests/keymile/setPortProfile13.txt create mode 100644 test_cases/integration_tests/keymile/setProfile7.txt create mode 100644 test_cases/integration_tests/keymile/setSIPDomain12.txt create mode 100644 test_cases/integration_tests/keymile/setTraffic1.txt create mode 100644 test_cases/integration_tests/keymile/setVCC15.txt create mode 100644 test_cases/integration_tests/keymile/setconfDsl2.txt create mode 100644 test_cases/integration_tests/keymile/setconfVoice9.txt create mode 100644 test_cases/integration_tests/keymile/setdeconfVoicePort11.txt create mode 100644 test_cases/integration_tests/keymile/setdeconfVoicePort17.txt create mode 100644 test_cases/integration_tests/keymile/setportaktiv4.txt create mode 100644 test_cases/integration_tests/keymile/setportdeactiv5.txt create mode 100644 test_cases/integration_tests/keymile/setunconfDsl3.txt create mode 100644 test_cases/integration_tests/keymile/setunconfVoice10.txt create mode 100644 test_cases/integration_tests/keymile/test Loopback3.txt create mode 100644 test_cases/integration_tests/keymile/testVoicePort2.txt create mode 100644 test_cases/integration_tests/keymile/testmelt1.txt create mode 100644 test_cases/integration_tests/keymile/testmelting4.txt diff --git a/test_cases/integration_tests/keymile/backup.txt b/test_cases/integration_tests/keymile/backup.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/backup.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getDslam4.txt b/test_cases/integration_tests/keymile/getDslam4.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/getDslam4.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getInventory2.txt b/test_cases/integration_tests/keymile/getInventory2.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/getInventory2.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getIpsx7.txt b/test_cases/integration_tests/keymile/getIpsx7.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/getIpsx7.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getMonitoring3.txt b/test_cases/integration_tests/keymile/getMonitoring3.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/getMonitoring3.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getState1.txt b/test_cases/integration_tests/keymile/getState1.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/getState1.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getSubscriber6.txt b/test_cases/integration_tests/keymile/getSubscriber6.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/getSubscriber6.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getVoice5.txt b/test_cases/integration_tests/keymile/getVoice5.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/getVoice5.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setChannelProfile14.txt b/test_cases/integration_tests/keymile/setChannelProfile14.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setChannelProfile14.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setDslProfile8.txt b/test_cases/integration_tests/keymile/setDslProfile8.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setDslProfile8.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setInterface16.txt b/test_cases/integration_tests/keymile/setInterface16.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setInterface16.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setIpAddr6.txt b/test_cases/integration_tests/keymile/setIpAddr6.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setIpAddr6.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setPortProfile13.txt b/test_cases/integration_tests/keymile/setPortProfile13.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setPortProfile13.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setProfile7.txt b/test_cases/integration_tests/keymile/setProfile7.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setProfile7.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setSIPDomain12.txt b/test_cases/integration_tests/keymile/setSIPDomain12.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setSIPDomain12.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setTraffic1.txt b/test_cases/integration_tests/keymile/setTraffic1.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setTraffic1.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setVCC15.txt b/test_cases/integration_tests/keymile/setVCC15.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setVCC15.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfDsl2.txt b/test_cases/integration_tests/keymile/setconfDsl2.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setconfDsl2.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfVoice9.txt b/test_cases/integration_tests/keymile/setconfVoice9.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setconfVoice9.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setportaktiv4.txt b/test_cases/integration_tests/keymile/setportaktiv4.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setportaktiv4.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setportdeactiv5.txt b/test_cases/integration_tests/keymile/setportdeactiv5.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setportdeactiv5.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setunconfDsl3.txt b/test_cases/integration_tests/keymile/setunconfDsl3.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setunconfDsl3.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setunconfVoice10.txt b/test_cases/integration_tests/keymile/setunconfVoice10.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/setunconfVoice10.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/test Loopback3.txt b/test_cases/integration_tests/keymile/test Loopback3.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/test Loopback3.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/testVoicePort2.txt b/test_cases/integration_tests/keymile/testVoicePort2.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/testVoicePort2.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/testmelt1.txt b/test_cases/integration_tests/keymile/testmelt1.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/testmelt1.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/testmelting4.txt b/test_cases/integration_tests/keymile/testmelting4.txt new file mode 100644 index 0000000..6f999b9 --- /dev/null +++ b/test_cases/integration_tests/keymile/testmelting4.txt @@ -0,0 +1,3 @@ +admin +secret +exit \ No newline at end of file diff --git a/test_cases/unit_tests/keymile/test_keymile.py b/test_cases/unit_tests/keymile/test_keymile.py index db82172..e5a171a 100644 --- a/test_cases/unit_tests/keymile/test_keymile.py +++ b/test_cases/unit_tests/keymile/test_keymile.py @@ -11,23 +11,34 @@ # License: https://github.com/inexio/NESi/LICENSE.rst from test_cases.unit_tests.test_core import TestCore +import pytest +from os import listdir +from os.path import isfile, join class TestKeymile(TestCore): + PATH = 'test_cases/integration_tests/keymile/' + DATA = [f for f in listdir('test_cases/integration_tests/keymile/') if + isfile(join('test_cases/integration_tests/keymile/', f)) and f != 'output.txt'] - def test_portup_portdown(self): - port = self.model.get_port("name", '1/1/1/1') - assert(self.model.get_port("name", '1/1/1/1').admin_state == '0') - port.admin_up() - assert(self.model.get_port("name", '1/1/1/1').admin_state == '1') - port.admin_down() - assert(self.model.get_port("name", '1/1/1/1').admin_state == '0') - - def test_ontportup_portdown(self): - port = self.model.get_ont_port("name", '1/1/4/1/1/1/1') - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '0') - port.admin_up() - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '1') - port.admin_down() - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '0') + def test_box(self): + assert True + def test_card(self): + assert True + + def test_channel(self): + assert True + + def test_interface(self): + assert True + + def test_port(self): + assert True + + def test_subrack(self): + assert True + + @pytest.mark.parametrize("path", DATA) + def test_integration(self, path): + self.run(self.PATH + path, self.PATH + 'output.txt') From 43d2554d9f93926610d1ad63b4c6fcb9204af70b Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 6 Oct 2020 09:47:39 +0200 Subject: [PATCH 205/318] Updated gitignore --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c38ccac..00d2735 100644 --- a/.gitignore +++ b/.gitignore @@ -134,4 +134,8 @@ dmypy.json # Tests /test_cases/integration_tests/alcatel/output.txt -/test_cases/integration_tests/huawei/output.txt \ No newline at end of file +/test_cases/integration_tests/huawei/output.txt +/test_cases/integration_tests/keymile/output.txt +/test_cases/integration_tests/edgecore/output.txt +/test_cases/integration_tests/pbn/output.txt +/test_cases/integration_tests/zhone/output.txt \ No newline at end of file From 53cf78363a5f592e63453c0988caa3f2e970a446 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 6 Oct 2020 15:25:02 +0200 Subject: [PATCH 206/318] Added case sensitivity for command processors --- nesi/softbox/cli/base.py | 19 +++++++++++++++++-- vendors/KeyMile/main.py | 2 ++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 0efe85a..04cbce4 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -45,11 +45,12 @@ class CommandProcessor: """ def __init__(self, model, input_stream, output_stream, history, - template_root=None, scopes=(), daemon=False): + template_root=None, scopes=(), daemon=False, parent=None, case_sensitive=True): self._model = model self._input = input_stream self._output = output_stream self._scopes = scopes + self._parent = parent self._template_root = template_root self._template_dir = os.path.join( template_root, *scopes) @@ -61,6 +62,7 @@ def __init__(self, model, input_stream, output_stream, history, self.daemon = daemon # CLI specific attributes + self.case_sensitive = case_sensitive self.line_buffer = [] self.history_enabled = True self.hide_input = False @@ -279,6 +281,9 @@ def _get_command_func(self, line): command = args[0] args = args[1:] + if self.case_sensitive is False: + command = command.lower() + if command == self.negation: command += "_" + args.pop(0) @@ -318,7 +323,7 @@ def _create_subprocessor(self, subprocessor, *scopes): return subprocessor( self._model, self._input, self._output, self.history, template_root=self._template_root, - scopes=scopes, daemon=self.daemon) + scopes=scopes, daemon=self.daemon, parent=self, case_sensitive=self.case_sensitive) def process_command(self, line, context): self._parse_and_execute_command(line, context) @@ -443,6 +448,11 @@ def _dissect(self, args, *tokens): except IndexError: raise exceptions.CommandSyntaxError(command=' '.join(args)) + if self.case_sensitive is False: + arg = arg.lower() + if not isinstance(token, type): + token = token.lower() + if type(token) == type: values.append(arg) @@ -461,6 +471,11 @@ def _validate(self, args, *tokens): except IndexError: return False + if self.case_sensitive is False: + arg = arg.lower() + if not isinstance(token, type): + token = token.lower() + if arg != token and type(token) != type: return False diff --git a/vendors/KeyMile/main.py b/vendors/KeyMile/main.py index 21561dc..ff9abd4 100644 --- a/vendors/KeyMile/main.py +++ b/vendors/KeyMile/main.py @@ -50,6 +50,8 @@ def on_unknown_command(self, command, *args, context=None): self._write(text) raise exceptions.TerminalExitError() + self.case_sensitive = False + subprocessor = self._create_subprocessor( RootCommandProcessor, 'login', 'base') From 88e39c4d42274610ce5448869dbf41e393067ca5 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 7 Oct 2020 10:04:39 +0200 Subject: [PATCH 207/318] Added subscriber classes and portgroupCommandProcessor --- .../conf/bootstraps/create-keymile-MG2200.sh | 20 +- nesi/keymile/keymile_resources/__init__.py | 3 +- nesi/keymile/keymile_resources/keymile_box.py | 18 ++ .../keymile_resources/keymile_subscriber.py | 36 +++ nesi/softbox/api/models/box_models.py | 2 + nesi/softbox/api/models/card_models.py | 2 +- nesi/softbox/api/models/subscriber_models.py | 13 + nesi/softbox/api/schemas/box_schemas.py | 6 +- .../softbox/api/schemas/subscriber_schemas.py | 47 ++++ nesi/softbox/api/views/__init__.py | 3 +- nesi/softbox/api/views/subscriber_views.py | 53 ++++ templates/KeyMile/login/base/get/ip.j2 | 5 + templates/KeyMile/login/base/get/sip.j2 | 17 ++ .../login/base/get/subscriberList_bottom.j2 | 2 + .../login/base/get/subscriberList_item.j2 | 7 + .../login/base/get/subscriberList_item2.j2 | 6 + .../login/base/get/subscriberList_top.j2 | 3 + .../root/unit/port/portCommandProcessor.py | 2 +- .../port/portgroupportCommandProcessor.py | 66 +++++ .../port/portgroupportManagementFunctions.py | 264 ++++++++++++++++++ .../portgroup/portgroupCommandProcessor.py | 37 +++ .../portgroup/portgroupManagementFunctions.py | 17 ++ .../root/unit/unitCommandProcessor.py | 40 ++- 23 files changed, 662 insertions(+), 7 deletions(-) create mode 100644 nesi/keymile/keymile_resources/keymile_subscriber.py create mode 100644 nesi/softbox/api/models/subscriber_models.py create mode 100644 nesi/softbox/api/schemas/subscriber_schemas.py create mode 100644 nesi/softbox/api/views/subscriber_views.py create mode 100644 templates/KeyMile/login/base/get/ip.j2 create mode 100644 templates/KeyMile/login/base/get/sip.j2 create mode 100644 templates/KeyMile/login/base/get/subscriberList_bottom.j2 create mode 100644 templates/KeyMile/login/base/get/subscriberList_item.j2 create mode 100644 templates/KeyMile/login/base/get/subscriberList_item2.j2 create mode 100644 templates/KeyMile/login/base/get/subscriberList_top.j2 create mode 100644 vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupManagementFunctions.py diff --git a/bootup/conf/bootstraps/create-keymile-MG2200.sh b/bootup/conf/bootstraps/create-keymile-MG2200.sh index 7bd564b..0b64ca8 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2200.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2200.sh @@ -44,6 +44,24 @@ req='{ root_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) +# test subscriber +req='{ + "name": "tester", + "number": 9023, + "type": "unit" +}' + +subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) + +# test subscriber +req='{ + "name": "tester2", + "number": 90223, + "type": "unit" +}' + +subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) + ### Subrack 0 ### # Create a physical subrack at the network device (admin operation) @@ -59,7 +77,7 @@ subrack_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "xdsl" + "product": "analog" }' unit_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) diff --git a/nesi/keymile/keymile_resources/__init__.py b/nesi/keymile/keymile_resources/__init__.py index e6be87c..17f26e0 100644 --- a/nesi/keymile/keymile_resources/__init__.py +++ b/nesi/keymile/keymile_resources/__init__.py @@ -1 +1,2 @@ -__all__ = ["keymile_card", "keymile_port", "keymile_subrack", "keymile_channel", "keymile_interface"] +__all__ = ["keymile_card", "keymile_port", "keymile_subrack", "keymile_channel", "keymile_interface", + "keymile_subscriber"] diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 87586b3..178a817 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -53,6 +53,12 @@ def cards(self): self._conn, base.get_sub_resource_path_by( self, 'cards')) + @property + def subscribers(self): + """Return `SubscriberCollection` object.""" + return keymile_subscriber.KeymileSubscriberCollection( + self._conn, base.get_sub_resource_path_by(self, 'subscribers')) + def get_card(self, field, value): """Get specific card object.""" return keymile_card.KeyMileCardCollection( @@ -100,6 +106,18 @@ def get_interfaces(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'interfaces'), params={field: value}) + def get_subscriber(self, field, value): + """Get specific subscriber object.""" + return keymile_subscriber.KeymileSubscriberCollection( + self._conn, base.get_sub_resource_path_by(self, 'subscribers'), + params={field: value}).find_by_field_value(field, value) + + def get_subscribers(self, field, value): + """Get specific subscribers object.""" + return keymile_subscriber.KeymileSubscriberCollection( + self._conn, base.get_sub_resource_path_by(self, 'subscribers'), + params={field: value}) + class KeyMileBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/keymile/keymile_resources/keymile_subscriber.py b/nesi/keymile/keymile_resources/keymile_subscriber.py new file mode 100644 index 0000000..5dc324d --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_subscriber.py @@ -0,0 +1,36 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.service_port import logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class KeymileSubscriber(base.Resource): + """Represent logical subscriber resource.""" + + # fields + id = base.Field('id') + number = base.Field('number') + name = base.Field('name') + type = base.Field('type') + address = base.Field('address') + registration_state = base.Field('registration_state') + + +class KeymileSubscriberCollection(base.ResourceCollection): + """Represent a collection of logical subscribers.""" + + @property + def _resource_type(self): + return KeymileSubscriber diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index f4f7002..3540487 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -28,6 +28,7 @@ from .emu_models import Emu from .user_models import User from .channel_models import Channel +from .subscriber_models import Subscriber class Box(db.Model): @@ -70,6 +71,7 @@ class Box(db.Model): vlan_interfaces = db.relationship('VlanInterface', backref='Box', lazy='dynamic') routes = db.relationship('Route', backref='Box', lazy='dynamic') emus = db.relationship('Emu', backref='Box', lazy='dynamic') + subscribers = db.relationship('Subscriber', backref='Box', lazy='dynamic') board_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_instl_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_init_reporting_logging = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index f190760..7433116 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -23,7 +23,7 @@ class Card(db.Model): subrack_id = db.Column(db.Integer, db.ForeignKey('subrack.id')) ports = db.relationship('Port', backref='Card', lazy='dynamic') ppc = db.Column(db.Enum('8', '16', '32', '48', '64'), default='32') - product = db.Column(db.Enum('xdsl', 'vdsl', 'adsl', 'sdsl', 'ftth-pon', 'ftth', 'mgnt'), + product = db.Column(db.Enum('xdsl', 'vdsl', 'adsl', 'sdsl', 'ftth-pon', 'ftth', 'mgnt', 'analog', 'isdn'), nullable=False, default='vdsl') # Alcatel specific data diff --git a/nesi/softbox/api/models/subscriber_models.py b/nesi/softbox/api/models/subscriber_models.py new file mode 100644 index 0000000..1dc9cd1 --- /dev/null +++ b/nesi/softbox/api/models/subscriber_models.py @@ -0,0 +1,13 @@ +from nesi.softbox.api import db + + +class Subscriber(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + + number = db.Column(db.Integer(), nullable=False, unique=True) + type = db.Column(db.Enum('unit', 'port'), default='port') + address = db.Column(db.String(), default='') + registration_state = db.Column(db.Enum('registered'), default='registered') + diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index fb7d67d..b28a8e1 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -32,7 +32,7 @@ class Meta: fields = ('id', 'vendor', 'model', 'version', 'software_version', 'network_protocol', 'network_address', 'network_port', 'uuid', 'description', 'interfaces', 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', - 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', + 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') @@ -77,6 +77,10 @@ class Meta: {'_links': { 'self': ma.URLFor('show_emus', box_id='')}}) + subscribers = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_subscribers', box_id='')}}) + onts = ma.Hyperlinks({'_links': { 'self': ma.URLFor('show_onts', box_id='')}}) diff --git a/nesi/softbox/api/schemas/subscriber_schemas.py b/nesi/softbox/api/schemas/subscriber_schemas.py new file mode 100644 index 0000000..d788063 --- /dev/null +++ b/nesi/softbox/api/schemas/subscriber_schemas.py @@ -0,0 +1,47 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.subscriber_models import Subscriber + + +class SubscriberSchema(ma.ModelSchema): + class Meta: + model = Subscriber + fields = ('id', 'name', 'box', 'number', 'type', 'address', 'registration_state', '_links') + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_subscriber', box_id='', id=''), + 'collection': ma.URLFor('show_subscribers', box_id='')}) + + +class SubscribersSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class EmuSchema(ma.ModelSchema): + class Meta: + model = Subscriber + fields = ('id', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_subscriber', box_id='', id='')}) + + members = ma.Nested(SubscriberSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_subscribers', box_id='')}) diff --git a/nesi/softbox/api/views/__init__.py b/nesi/softbox/api/views/__init__.py index e6e1f95..edde876 100644 --- a/nesi/softbox/api/views/__init__.py +++ b/nesi/softbox/api/views/__init__.py @@ -1,4 +1,5 @@ __all__ = ["box_views", "credential_views", "route_views", "subrack_views", "card_views", "port_views", "ont_views", "ontport_views", "cpe_views", "cpeport_views", "vlan_views", "portprofile_views", "emu_views", "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", - "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views", "mgmt_card_views", "mgmt_port_views"] + "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views", + "mgmt_card_views", "mgmt_port_views", "subscriber_views"] diff --git a/nesi/softbox/api/views/subscriber_views.py b/nesi/softbox/api/views/subscriber_views.py new file mode 100644 index 0000000..4b46e43 --- /dev/null +++ b/nesi/softbox/api/views/subscriber_views.py @@ -0,0 +1,53 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from ..schemas.subscriber_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//subscribers', methods=['GET']) +def show_subscribers(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(SubscribersSchema(), Subscriber, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//subscribers/', methods=['GET']) +def show_subscriber(box_id, id): + response = show_component(Subscriber, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//subscribers/', methods=['PUT']) +def update_subscriber(box_id, id): + req = flask.request.json + update_component(Subscriber, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//subscribers', methods=['POST']) +def new_subscriber(box_id): + req = flask.request.json + response = new_component(SubscriberSchema(), Subscriber, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//subscribers/', methods=['DELETE']) +def del_subscriber(box_id, id): + del_component(Subscriber, box_id, id) + return flask.Response(status=204) diff --git a/templates/KeyMile/login/base/get/ip.j2 b/templates/KeyMile/login/base/get/ip.j2 new file mode 100644 index 0000000..c5d5e83 --- /dev/null +++ b/templates/KeyMile/login/base/get/ip.j2 @@ -0,0 +1,5 @@ + \ # Ip +10.16.12.14 \ # GatewayIpAddress +255.255.255.0 \ # SubnetMask +10.16.12.1 \ # DefaultGateway + diff --git a/templates/KeyMile/login/base/get/sip.j2 b/templates/KeyMile/login/base/get/sip.j2 new file mode 100644 index 0000000..fa1eed3 --- /dev/null +++ b/templates/KeyMile/login/base/get/sip.j2 @@ -0,0 +1,17 @@ + \ # sip +"Name" \ # GatewayName +"hab.dich.loieb.net" \ # HomeDomain +500 \ # SipPortNumber +"+49" \ # CountryCode +"6567" \ # AreaCode +500 \ # RetransmissionTimerT1 +4 \ # MaxRetransmissionIntervalT2 +false \ # SipExtension100relRequired +None \ # assertedIdentityMode +true \ # OverlapSignalling +30 \ # OverlapT10timer + \ # SessionTimer +false \ # UacRequestSessionTimer +false \ # UasRequestSessionTimer +1800 \ # SessionExpiration + diff --git a/templates/KeyMile/login/base/get/subscriberList_bottom.j2 b/templates/KeyMile/login/base/get/subscriberList_bottom.j2 new file mode 100644 index 0000000..7d2b463 --- /dev/null +++ b/templates/KeyMile/login/base/get/subscriberList_bottom.j2 @@ -0,0 +1,2 @@ +} \ + diff --git a/templates/KeyMile/login/base/get/subscriberList_item.j2 b/templates/KeyMile/login/base/get/subscriberList_item.j2 new file mode 100644 index 0000000..189f50a --- /dev/null +++ b/templates/KeyMile/login/base/get/subscriberList_item.j2 @@ -0,0 +1,7 @@ + \ # [{{ context.i }}] # + \ # Subscriber + "{{ context.subscriber.number }}"{{ context.spacer1 }}\ # SubscriberNumber + "{{ context.subscriber.registration_state }}"{{ context.spacer2 }}\ # RegistrationStatus + "{{ context.subscriber.address }}"{{ context.spacer3 }}\ # Address +; \ + diff --git a/templates/KeyMile/login/base/get/subscriberList_item2.j2 b/templates/KeyMile/login/base/get/subscriberList_item2.j2 new file mode 100644 index 0000000..733e082 --- /dev/null +++ b/templates/KeyMile/login/base/get/subscriberList_item2.j2 @@ -0,0 +1,6 @@ + \ # [{{ context.i }}] # + \ # Subscriber + "{{ context.subscriber.number }}"{{ context.spacer1 }}\ # SubscriberNumber + "{{ context.subscriber.registration_state }}"{{ context.spacer2 }}\ # RegistrationStatus +; \ + diff --git a/templates/KeyMile/login/base/get/subscriberList_top.j2 b/templates/KeyMile/login/base/get/subscriberList_top.j2 new file mode 100644 index 0000000..2e483ea --- /dev/null +++ b/templates/KeyMile/login/base/get/subscriberList_top.j2 @@ -0,0 +1,3 @@ + \ # Registration +{ \ # UnregisteredSubscriberList + diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index e9b392e..b4ad848 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -32,7 +32,7 @@ def do_get(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - if self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': + elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py new file mode 100644 index 0000000..dcbb3be --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -0,0 +1,66 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor + + +class PortgroupPortCommandProcessor(PortCommandProcessor): + __name__ = 'portgroupport' + management_functions = ('main', 'cfgm', 'status') + access_points = () + + from .portgroupportManagementFunctions import main + from .portgroupportManagementFunctions import cfgm + from .portgroupportManagementFunctions import fm + from .portgroupportManagementFunctions import pm + from .portgroupportManagementFunctions import status + + def do_get(self, command, *args, context=None): + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': + text = self._render('attainable_rate', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ + self._model.get_card('name', context['unit']).product == 'isdn': + text = self._render('subscriberList_top', *scopes, context=context) + i = 0 + for subscriber in self._model.subscribers: + if subscriber.type == 'port': # TODO: show only subscriber of this port + + context['i'] = i + context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' + context['spacer2'] = self.create_spacers((63,), (subscriber.registration_state,))[0] * ' ' + i += 1 + text += self._render('subscriberList_item2', *scopes, context=dict(context, subscriber=subscriber)) + text += self._render('subscriberList_bottom', *scopes, context=context) + + self._write(text) + elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': + text = self._render('administrative_status', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': + text = self._render('operational_status', *scopes, context=context) + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + + def _init_access_points(self, context=None): + port = self._model.get_port('name', context['unit'] + '/' + context['portgroup'] + '/' + context['port']) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportManagementFunctions.py new file mode 100644 index 0000000..5add929 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportManagementFunctions.py @@ -0,0 +1,264 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + } +} + +cfgm = { + 'Multicast': { + 'Prop': { + 'MaxNumberOfMulticastStreams': 'rw', + 'EnableIgmpClassifier': 'rw', + 'AllowStaticStreams': 'rw', + 'EnableFastLeave': 'rw', + 'GroupManagement': 'rw', + 'Bandwidth': 'rw' + }, + 'Cmd': ( + 'GetGroupList', + ) + }, + 'Traceability': { + 'Prop': { + 'AgentRemoteId': 'rw' + } + }, + 'Security': { + 'Prop': { + 'ServiceOptions': 'rw', + 'MaxNumberOfMac': 'rw' + } + }, + 'AccessControl': { + 'Prop': { + 'ClassificationKey': 'rw', + 'MAT': 'rw' + } + }, + 'RateLimiter': { + 'Prop': { + 'RateLimiting': 'rw', + 'RateLimitingCoS': 'rw' + } + }, + 'Qos': { + 'Prop': { + 'WfqProfile': 'rw' + } + }, + 'Wire': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'PortProfiles': 'rw' + } + }, + 'Misc': { + 'Prop': { + 'SpecificDPBO': 'rw', + 'SpecificUPBO': 'rw' + } + } +} + +status = { + 'General': { + 'Prop': { + 'Standard': 'r-', + 'PowerMgmStatus': 'r-', + 'Vdsl2Parameters': 'r-', + 'EstUPBOElectricalLength': 'r-', + 'LineRate': 'r-', + 'LineSnrMargin': 'r-', + 'AttainableNetDataRate': 'r-', + 'AttainableRate': 'r-', + 'OutputPower': 'r-', + 'BandStatus': 'r-' + } + }, + 'statistics': { + 'Prop': { + 'counters': 'r-', + 'PolicingCounters': 'r-' + }, + 'Cmd': ( + 'ResetPortCounters', + ) + }, + 'Nto1MacAccessDynamicList': { + 'Prop': { + 'UnicastList': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters', + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + }, + }, + 'TLSMacForwardingList': { + 'Prop': { + 'MacForwardingList': 'r-' + }, + 'Cmd': ( + 'FlushMacForwardingList', + ) + }, + '1to1MacForwardingList': { + 'Prop': { + 'One2OneMacForwardingList': 'r-' + } + }, + 'Qos': { + 'Prop': { + 'wfqueues': 'r-' + } + }, + 'Multicast': { + 'stream': { + 'Dynamic': { + 'Prop': { + 'ActiveStreams': 'r-' + }, + 'Cmd': ( + 'ClearActiveStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticStreams': 'r-' + } + }, + }, + + 'Vlan': { + 'Prop': { + 'AttachedVlans': 'r-' + } + }, + 'Preview': { + 'Cmd': ( + 'ResetPreviewSettings', + ) + }, + 'Bandwidth': { + 'Prop': { + 'bandwidthStatus': 'r-' + } + }, + }, + 'LineTest': { + 'MELT': { + 'Prop': { + 'MeltResults': 'r-' + }, + 'Cmd': ( + 'StartMeltMeasurement', + ) + }, + 'Delt': { + 'Prop': { + 'DeltMeasurementStatus': 'r-', + 'RecordedDeltMeasurements': 'r-' + }, + 'Cmd': ( + 'StartDeltMeasurement', + ) + }, + 'Selt': { + 'Prop': { + 'SeltMeasurementStatus': 'r-', + 'RecordedSeltMeasurements': 'r-', + 'CableType': 'rw', + 'BandplanProfile': 'rw', + 'TargetSnrm': 'rw' + }, + 'Cmd': ( + 'StartSeltMeasurement', + ) + }, + }, + 'Defects': { + 'Prop': { + 'Defects': 'r-' + } + }, + 'LineInventory': { + 'Prop': { + 'VendorId': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'DslOperationStatus': 'r-' + } + }, + 'Subcarrier': { + 'Cmd': ( + 'ShowBitAllocation', + ) + }, + 'RfiBands': { + 'Prop': { + 'NotchStatus': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py new file mode 100644 index 0000000..47cf9f2 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -0,0 +1,37 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class PortgroupCommandProcessor(BaseCommandProcessor): + __name__ = 'portgroup' + management_functions = ('main', 'cfgm') + access_points = () + + from .portgroupManagementFunctions import main + from .portgroupManagementFunctions import cfgm + + def _init_access_points(self, context=None): # work in progress + card = self._model.get_card('name', context['unit']) + portgroup = context['portgroup'] + + for port in self._model.get_ports('card_id', card.id): + if port.name.count('/') == 2 and port.name.strip('/')[1] == 'portgroup-' + portgroup: + identifier = 'port-' + port.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupManagementFunctions.py new file mode 100644 index 0000000..d281df9 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupManagementFunctions.py @@ -0,0 +1,17 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'General': { + 'Cmd': { + 'CreatePort', + 'DeletePort' + } + } +} \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 368a108..1a5dc5a 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -37,5 +37,43 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) + # todo: add portgroup to access_points + + def do_get(self, command, *args, context=None): + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ + (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', context['unit']).product == 'analog'): + text = self._render('subscriberList_top', *scopes, context=context) + i = 0 + for subscriber in self._model.subscribers: + if subscriber.type == 'unit': + context['i'] = i + context['spacer1'] = self.create_spacers((63,), (subscriber.number, ))[0] * ' ' + context['spacer2'] = self.create_spacers((63,), (subscriber.registration_state, ))[0] * ' ' + context['spacer3'] = self.create_spacers((63,), (subscriber.address, ))[0] * ' ' + + i += 1 + text += self._render('subscriberList_item', *scopes, context=dict(context, subscriber=subscriber)) + text += self._render('subscriberList_bottom', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'SIP') and context['path'].split('/')[-1] == 'cfgm' and \ + (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', context['unit']).product == 'analog'): + # TODO: dynamic fields + text = self._render('sip', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'IP') and context['path'].split('/')[-1] == 'cfgm' and \ + (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', context['unit']).product == 'analog'): + # TODO: dynamic fields + text = self._render('ip', *scopes, context=context) + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) From 8526f5fe0e7f89141605fbccdf85bddbba691c04 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Wed, 7 Oct 2020 10:48:56 +0200 Subject: [PATCH 208/318] Added new card fields --- .../conf/bootstraps/create-keymile-MG2200.sh | 177 +++++++++++++++++- nesi/huawei/huawei_resources/huawei_card.py | 1 - .../api/schemas/keymile_card_schemas.py | 23 +++ .../keymile/keymile_resources/keymile_card.py | 25 ++- nesi/softbox/api/models/card_models.py | 21 +++ .../KeyMile/login/base/get/current_status.j2 | 8 + .../login/base/get/equipment_inventory.j2 | 16 ++ .../login/base/get/hardware_and_software.j2 | 9 + .../root/services/packetCommandProcessor.py | 4 +- .../root/services/servicesCommandProcessor.py | 4 +- .../root/unit/unitCommandProcessor.py | 118 +++++++++++- vendors/KeyMile/baseCommandProcessor.py | 4 +- 12 files changed, 385 insertions(+), 25 deletions(-) create mode 100644 nesi/keymile/api/schemas/keymile_card_schemas.py create mode 100644 templates/KeyMile/login/base/get/current_status.j2 create mode 100644 templates/KeyMile/login/base/get/equipment_inventory.j2 create mode 100644 templates/KeyMile/login/base/get/hardware_and_software.j2 diff --git a/bootup/conf/bootstraps/create-keymile-MG2200.sh b/bootup/conf/bootstraps/create-keymile-MG2200.sh index 0b64ca8..abc2883 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2200.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2200.sh @@ -77,7 +77,24 @@ subrack_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "analog" + "product": "adsl", + "board_name": "SUAD2", + "supplier_build_state": "R3D", + "board_id": "305", + "hardware_key": 102, + "software": "suad2_r5c01.esw", + "software_name": "SUAD2", + "software_revision": "R5C01", + "state": "Ok", + "serial_number": "4363507882", + "manufacturer_name": "KEYMILE", + "model_name": "37900030", + "short_text": "MG SUSE1 SHDSL EFM 32-port", + "manufacturer_id": "100989", + "manufacturer_part_number": "09862706", + "manufacturer_build_state": "02", + "boot_loader": "BLSU1_R1G01/CT23337", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -117,7 +134,24 @@ interface_1_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "xdsl" + "product": "sdsl", + "board_name": "SUSE1", + "supplier_build_state": "R1A", + "board_id": "330", + "hardware_key": 1, + "software": "suse1_r4d02_t01.esw", + "software_name": "SUSE1", + "software_revision": "R4D02_T01", + "state": "Ok", + "serial_number": "6973180458", + "manufacturer_name": "KEYMILE", + "model_name": "37900196", + "short_text": "MG SUAD2 ADSL2+ AnnexB 32-port", + "manufacturer_id": "100989", + "manufacturer_part_number": "09860762", + "manufacturer_build_state": "05", + "boot_loader": "BLSU1_R1F01/CT18388", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -149,7 +183,24 @@ port_2_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "xdsl" + "product": "sdsl", + "board_name": "SUSE1", + "supplier_build_state": "R1A", + "board_id": "330", + "hardware_key": 3, + "software": "suse1_r4d02_t01.esw", + "software_name": "SUSE1", + "software_revision": "R4D02_T01", + "state": "Ok", + "serial_number": "3383369557", + "manufacturer_name": "KEYMILE", + "model_name": "37900196", + "short_text": "MG SUSE1 SHDSL EFM 32-port", + "manufacturer_id": "100989", + "manufacturer_part_number": "09862706", + "manufacturer_build_state": "02", + "boot_loader": "BLSU1_R1G01/CT23337", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_3=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -179,7 +230,24 @@ interface_3_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "xdsl" + "product": "adsl", + "board_name": "SUAD2", + "supplier_build_state": "R3D", + "board_id": "305", + "hardware_key": 104, + "software": "suad2_r5c01.esw", + "software_name": "SUAD2", + "software_revision": "R5C01", + "state": "Ok", + "serial_number": "4810312946", + "manufacturer_name": "KEYMILE", + "model_name": "37900030", + "short_text": "MG SUAD2 ADSL2+ AnnexB 32-port", + "manufacturer_id": "100989", + "manufacturer_part_number": "09860762", + "manufacturer_build_state": "05", + "boot_loader": "BLSU1_R1F01/CT18388", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -189,7 +257,24 @@ unit_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "vdsl" + "product": "vdsl", + "board_name": "SUVM4", + "supplier_build_state": "R1G", + "board_id": "345", + "hardware_key": 1, + "software": "suvm4_r3c02_01.esw", + "software_name": "SUVM4", + "software_revision": "R3C02_01", + "state": "Ok", + "serial_number": "6702369850", + "manufacturer_name": "KEYMILE", + "model_name": "37900293", + "short_text": "MG SUVM4 VDSL2 ISDN 32-port", + "manufacturer_id": "100989", + "manufacturer_part_number": "09866094", + "manufacturer_build_state": "01", + "boot_loader": "BPSUVM4_R1B03/CT0", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_5=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -199,7 +284,24 @@ unit_5=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "vdsl" + "product": "vdsl", + "board_name": "SUVM6", + "supplier_build_state": "R1K", + "board_id": "377", + "hardware_key": 25, + "software": "suvm6_r3e10_01.esw", + "software_name": "SUVM6", + "software_revision": "R3E10_01", + "state": "Ok", + "serial_number": "1283288279", + "manufacturer_name": "KEYMILE", + "model_name": "37900528", + "short_text": "MG SUVM6 VDSL2/17MHz ISDN 48pt", + "manufacturer_id": "100989", + "manufacturer_part_number": "09869778", + "manufacturer_build_state": "20", + "boot_loader": "BPSUVM6_R1B02/CT0", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_6=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -209,7 +311,24 @@ unit_6=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "vdsl" + "product": "vdsl", + "board_name": "SUVM6", + "supplier_build_state": "R1K", + "board_id": "377", + "hardware_key": 14, + "software": "suvm6_r3e10_01.esw", + "software_name": "SUVM6", + "software_revision": "R3E10_01", + "state": "Ok", + "serial_number": "6135149854", + "manufacturer_name": "KEYMILE", + "model_name": "37900528", + "short_text": "MG SUVM6 VDSL2/17MHz ISDN 48pt", + "manufacturer_id": "100989", + "manufacturer_part_number": "09869778", + "manufacturer_build_state": "20", + "boot_loader": "BPSUVM6_R1B02/CT0", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_7=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -219,7 +338,47 @@ unit_7=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "vdsl" + "product": "vdsl", + "board_name": "SUVM6", + "supplier_build_state": "R1K", + "board_id": "377", + "hardware_key": 104, + "software": "suvm6_r3e10_01.esw", + "software_name": "SUVM6", + "software_revision": "R3E10_01", + "state": "Ok", + "serial_number": "8781619728", + "manufacturer_name": "KEYMILE", + "model_name": "37900528", + "short_text": "MG SUVM6 VDSL2/17MHz ISDN 48pt", + "manufacturer_id": "100989", + "manufacturer_part_number": "09869778", + "manufacturer_build_state": "20", + "boot_loader": "BPSUVM6_R1B02/CT0", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' -unit_8=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) \ No newline at end of file +unit_8=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Unit-19 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "product": "isdn", + "name": "19" +}' + +unit_19=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_19', + "admin_state": "1", + "operational_state": "1", + "name": "19/1/1" +}' + +port_19_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) \ No newline at end of file diff --git a/nesi/huawei/huawei_resources/huawei_card.py b/nesi/huawei/huawei_resources/huawei_card.py index 30c1ffa..6670ea2 100644 --- a/nesi/huawei/huawei_resources/huawei_card.py +++ b/nesi/huawei/huawei_resources/huawei_card.py @@ -35,4 +35,3 @@ class HuaweiCardCollection(CardCollection): @property def _resource_type(self): return HuaweiCard - diff --git a/nesi/keymile/api/schemas/keymile_card_schemas.py b/nesi/keymile/api/schemas/keymile_card_schemas.py new file mode 100644 index 0000000..eb4344d --- /dev/null +++ b/nesi/keymile/api/schemas/keymile_card_schemas.py @@ -0,0 +1,23 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.card_schemas import * + + +class KeyMileCardSchema(CardSchema): + class Meta: + model = Card + fields = CardSchema.Meta.fields + ('board_name', 'supplier_build_state', 'board_id', 'hardware_key', 'software', + 'software_name', 'software_revision', 'state', 'serial_number', + 'manufacturer_name', 'model_name', 'short_text', 'manufacturer_id', + 'manufacturer_part_number', 'manufacturer_build_state', 'customer_id', + 'customer_product_id', 'boot_loader', 'processor') diff --git a/nesi/keymile/keymile_resources/keymile_card.py b/nesi/keymile/keymile_resources/keymile_card.py index 3870bc6..8370b93 100644 --- a/nesi/keymile/keymile_resources/keymile_card.py +++ b/nesi/keymile/keymile_resources/keymile_card.py @@ -10,7 +10,8 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.softbox.base_resources.card import CardCollection, Card, logging, base +from nesi.softbox.base_resources.card import CardCollection, Card, logging +from nesi.softbox.base_resources import base LOG = logging.getLogger(__name__) @@ -18,10 +19,30 @@ class KeyMileCard(Card): """Represent physical shelf resource.""" + board_name = base.Field('board_name') + supplier_build_state = base.Field('supplier_build_state') + board_id = base.Field('board_id') + hardware_key = base.Field('hardware_key') + software = base.Field('software') + software_name = base.Field('software_name') + software_revision = base.Field('software_revision') + state = base.Field('state') + serial_number = base.Field('serial_number') + manufacturer_name = base.Field('manufacturer_name') + model_name = base.Field('model_name') + short_text = base.Field('short_text') + manufacturer_id = base.Field('manufacturer_id') + manufacturer_part_number = base.Field('manufacturer_part_number') + manufacturer_build_state = base.Field('manufacturer_build_state') + customer_id = base.Field('customer_id') + customer_product_id = base.Field('customer_product_id') + boot_loader = base.Field('boot_loader') + processor = base.Field('processor') + class KeyMileCardCollection(CardCollection): """Represent a collection of cards.""" @property def _resource_type(self): - return KeyMileCard \ No newline at end of file + return KeyMileCard diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index 7433116..2d0a4d7 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -80,3 +80,24 @@ class Card(db.Model): power_off_cause = db.Column(db.String(), default='-') power_off_time = db.Column(db.String(), default='-') temperature = db.Column(db.String(), default='68C') + + # Keymile specific data + supplier_build_state = db.Column(db.Enum('R1G', 'R1D', 'R2B', 'R2A', 'R1K', 'R1H', 'R2B', 'R1E', 'R3D', 'R1C', + 'R1A', ''), default='') + board_id = db.Column(db.Enum('345', '332', '303', '308', '377', '356', '305', '307', '330', '0'), default='0') + hardware_key = db.Column(db.Integer(), default=0) + software = db.Column(db.String(), default='') + software_name = db.Column(db.String(), default='') + software_revision = db.Column(db.String(), default='') + state = db.Column(db.Enum('Ok', 'Empty'), default='Empty') + serial_number = db.Column(db.String(), default='') + manufacturer_name = db.Column(db.String(), default='') + model_name = db.Column(db.String(), default='') + short_text = db.Column(db.String(), default='') + manufacturer_id = db.Column(db.String(), default='') + manufacturer_part_number = db.Column(db.String(), default='') + manufacturer_build_state = db.Column(db.String(), default='') + customer_id = db.Column(db.String(), default='') + customer_product_id = db.Column(db.String(), default='') + boot_loader = db.Column(db.String(), default='') + processor = db.Column(db.String(), default='') diff --git a/templates/KeyMile/login/base/get/current_status.j2 b/templates/KeyMile/login/base/get/current_status.j2 new file mode 100644 index 0000000..2ea3cef --- /dev/null +++ b/templates/KeyMile/login/base/get/current_status.j2 @@ -0,0 +1,8 @@ + \ # EquipmentStatus +{{ context.unit_state }}{{ context.spacer_1 }}\ # State +{{ context.unit_hardware | safe }}{{ context.spacer_2 }}\ # Hardware +{{ context.unit_software | safe }}{{ context.spacer_3 }}\ # Software +{{ context.unit_serial_number | safe }}{{ context.spacer_4 }}\ # SerialNumber +{{ context.unit_manufacturer_name | safe }}{{ context.spacer_5 }}\ # ManufacturerName +{{ context.unit_model_name | safe }}{{ context.spacer_6 }}\ # ModelName + diff --git a/templates/KeyMile/login/base/get/equipment_inventory.j2 b/templates/KeyMile/login/base/get/equipment_inventory.j2 new file mode 100644 index 0000000..6780cd1 --- /dev/null +++ b/templates/KeyMile/login/base/get/equipment_inventory.j2 @@ -0,0 +1,16 @@ + \ # EquipmentInventory +{{ context.unit_symbol | safe }}{{ context.spacer_1 }}\ # Symbol +{{ context.unit_short_text | safe }}{{ context.spacer_2 }}\ # ShortText +{{ context.unit_board_id }}{{ context.spacer_3 }}\ # BoardId +{{ context.unit_hardware_key }}{{ context.spacer_4 }}\ # HardwareKey +{{ context.unit_manufacturer_id | safe }}{{ context.spacer_5 }}\ # ManufacturerId +{{ context.unit_serial_number | safe }}{{ context.spacer_6 }}\ # ManufacturerSerialNumber +{{ context.unit_manufacturer_part_number | safe }}{{ context.spacer_7 }}\ # ManufacturerPartNumber +{{ context.unit_manufacturer_build_state | safe }}{{ context.spacer_8 }}\ # ManufacturerBuildState +{{ context.unit_supplier_part_number | safe }}{{ context.spacer_9 }}\ # SupplierPartNumber +{{ context.unit_supplier_build_state | safe }}{{ context.spacer_10 }}\ # SupplierBuildState +{{ context.unit_customer_id | safe }}{{ context.spacer_11 }}\ # CustomerId +{{ context.unit_customer_product_id | safe }}{{ context.spacer_12 }}\ # CustomerProductId +{{ context.unit_boot_loader | safe }}{{ context.spacer_13 }}\ # Bootloader +{{ context.unit_processor | safe }}{{ context.spacer_14 }}\ # Processor + diff --git a/templates/KeyMile/login/base/get/hardware_and_software.j2 b/templates/KeyMile/login/base/get/hardware_and_software.j2 new file mode 100644 index 0000000..0ac56c1 --- /dev/null +++ b/templates/KeyMile/login/base/get/hardware_and_software.j2 @@ -0,0 +1,9 @@ + \ # HardwareAndSoftware +{{ context.unit_hardware | safe }}{{ context.spacer_1 }}\ # Hardware +{{ context.unit_supplier_build_state | safe }}{{ context.spacer_2 }}\ # SupplierBuildState +{{ context.unit_board_id | safe }}{{ context.spacer_3 }}\ # BoardId +{{ context.unit_hardware_key | safe }}{{ context.spacer_4 }}\ # HardwareKey +{{ context.unit_software | safe }}{{ context.spacer_5 }}\ # Software +{{ context.unit_software_name | safe }}{{ context.spacer_6 }}\ # SoftwareName +{{ context.unit_software_revision | safe }}{{ context.spacer_7 }}\ # SoftwareRevision + diff --git a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py index 96d4113..1413d30 100644 --- a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py @@ -17,9 +17,9 @@ class PacketCommandProcessor(BaseCommandProcessor): __name__ = 'packet' management_functions = ('main',) - access_points = ('1to1DoubleTag', '1to1SingeTag', 'mcast', 'nto1', 'pls', 'tls') + access_points = ('1to1DoubleTag', '1to1SingleTag', 'mcast', 'nto1', 'pls', 'tls') from .packetManagementFunctions import main def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py index 253a74f..98da567 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -17,11 +17,11 @@ class ServicesCommandProcessor(BaseCommandProcessor): __name__ = 'services' management_functions = ('main', 'fm', 'status') - access_points = () + access_points = ('packet', 'macAccessCtrl') from .servicesManagementFunctions import main from .servicesManagementFunctions import fm from .servicesManagementFunctions import status def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 1a5dc5a..2e6bb75 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -17,7 +17,7 @@ class UnitCommandProcessor(BaseCommandProcessor): __name__ = 'unit' management_functions = ('main', 'cfgm', 'fm', 'status') - access_points = () #'internalPorts', only on certain cards + access_points = () # 'internalPorts', only on certain cards from .unitManagementFunctions import main from .unitManagementFunctions import cfgm @@ -27,7 +27,7 @@ class UnitCommandProcessor(BaseCommandProcessor): def _init_access_points(self, context=None): card = self._model.get_card('name', context['unit']) - #if card.type == ?: + # if card.type == ?: # self.access_points += ('internalPorts',) # @@ -40,37 +40,139 @@ def _init_access_points(self, context=None): # todo: add portgroup to access_points def do_get(self, command, *args, context=None): + card = self._model.get_card('name', context['unit']) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ - (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', context['unit']).product == 'analog'): + (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', + context[ + 'unit']).product == 'analog'): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: if subscriber.type == 'unit': context['i'] = i - context['spacer1'] = self.create_spacers((63,), (subscriber.number, ))[0] * ' ' - context['spacer2'] = self.create_spacers((63,), (subscriber.registration_state, ))[0] * ' ' - context['spacer3'] = self.create_spacers((63,), (subscriber.address, ))[0] * ' ' + context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' + context['spacer2'] = self.create_spacers((63,), (subscriber.registration_state,))[0] * ' ' + context['spacer3'] = self.create_spacers((63,), (subscriber.address,))[0] * ' ' i += 1 text += self._render('subscriberList_item', *scopes, context=dict(context, subscriber=subscriber)) text += self._render('subscriberList_bottom', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'SIP') and context['path'].split('/')[-1] == 'cfgm' and \ - (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', context['unit']).product == 'analog'): + (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', + context[ + 'unit']).product == 'analog'): # TODO: dynamic fields text = self._render('sip', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'IP') and context['path'].split('/')[-1] == 'cfgm' and \ - (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', context['unit']).product == 'analog'): + (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', + context[ + 'unit']).product == 'analog'): # TODO: dynamic fields text = self._render('ip', *scopes, context=context) self._write(text) + + elif self._validate((args[0],), 'HardwareAndSoftware'): + unit_hardware = '"' + card.board_name + '"' + context['unit_hardware'] = unit_hardware + context['spacer_1'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' + unit_supplier_build_state = '"' + card.supplier_build_state + '"' + context['unit_supplier_build_state'] = unit_supplier_build_state + context['spacer_2'] = self.create_spacers((67,), (unit_supplier_build_state,))[0] * ' ' + unit_board_id = card.board_id + context['unit_board_id'] = unit_board_id + context['spacer_3'] = self.create_spacers((67,), (unit_board_id,))[0] * ' ' + unit_hardware_key = card.hardware_key + context['unit_hardware_key'] = unit_hardware_key + context['spacer_4'] = self.create_spacers((67,), (unit_hardware_key,))[0] * ' ' + unit_software = '"' + card.software + '"' + context['unit_software'] = unit_software + context['spacer_5'] = self.create_spacers((67,), (unit_software,))[0] * ' ' + unit_software_name = '"' + card.software_name + '"' + context['unit_software_name'] = unit_software_name + context['spacer_6'] = self.create_spacers((67,), (unit_software_name,))[0] * ' ' + unit_software_revision = '"' + card.software_revision + '"' + context['unit_software_revision'] = unit_software_revision + context['spacer_7'] = self.create_spacers((67,), (unit_software_revision,))[0] * ' ' + text = self._render('hardware_and_software', *scopes, context=context) + self._write(text) + + elif self._validate((args[0],), 'CurrentStatus'): + unit_state = card.state + context['unit_state'] = unit_state + context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' + unit_hardware = '"' + card.board_name + ' ' + card.supplier_build_state + '"' + context['unit_hardware'] = unit_hardware + context['spacer_2'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' + unit_software = '"' + card.software[:-4] + '"' + context['unit_software'] = unit_software + context['spacer_3'] = self.create_spacers((67,), (unit_software,))[0] * ' ' + unit_serial_number = '"' + card.serial_number + '"' + context['unit_serial_number'] = unit_serial_number + context['spacer_4'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' + unit_manufacturer_name = '"' + card.manufacturer_name + '"' + context['unit_manufacturer_name'] = unit_manufacturer_name + context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_name,))[0] * ' ' + unit_model_name = '"' + card.model_name + '"' + context['unit_model_name'] = unit_model_name + context['spacer_6'] = self.create_spacers((67,), (unit_model_name,))[0] * ' ' + text = self._render('current_status', *scopes, context=context) + self._write(text) + + elif self._validate((args[0],), 'EquipmentInventory'): + unit_symbol = '"' + card.board_name + '"' + context['unit_symbol'] = unit_symbol + context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' + unit_short_text = '"' + card.short_text + '"' + context['unit_short_text'] = unit_short_text + context['spacer_2'] = self.create_spacers((67,), (unit_short_text,))[0] * ' ' + unit_board_id = card.board_id + context['unit_board_id'] = unit_board_id + context['spacer_3'] = self.create_spacers((67,), (unit_board_id,))[0] * ' ' + unit_hardware_key = card.hardware_key + context['unit_hardware_key'] = unit_hardware_key + context['spacer_4'] = self.create_spacers((67,), (unit_hardware_key,))[0] * ' ' + unit_manufacturer_id = '"' + card.manufacturer_id + '"' + context['unit_manufacturer_id'] = unit_manufacturer_id + context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_id,))[0] * ' ' + unit_serial_number = '"' + card.serial_number + '"' + context['unit_serial_number'] = unit_serial_number + context['spacer_6'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' + unit_manufacturer_part_number = '"' + card.manufacturer_part_number + '"' + context['unit_manufacturer_part_number'] = unit_manufacturer_part_number + context['spacer_7'] = self.create_spacers((67,), (unit_manufacturer_part_number,))[0] * ' ' + unit_manufacturer_build_state = '"' + card.manufacturer_build_state + '"' + context['unit_manufacturer_build_state'] = unit_manufacturer_build_state + context['spacer_8'] = self.create_spacers((67,), (unit_manufacturer_build_state,))[0] * ' ' + unit_supplier_part_number = '"' + card.model_name + '"' + context['unit_supplier_part_number'] = unit_supplier_part_number + context['spacer_9'] = self.create_spacers((67,), (unit_supplier_part_number,))[0] * ' ' + unit_supplier_build_state = '"' + card.supplier_build_state + '"' + context['unit_supplier_build_state'] = unit_supplier_build_state + context['spacer_10'] = self.create_spacers((67,), (unit_supplier_build_state,))[0] * ' ' + unit_customer_id = '"' + card.customer_id + '"' + context['unit_customer_id'] = unit_customer_id + context['spacer_11'] = self.create_spacers((67,), (unit_customer_id,))[0] * ' ' + unit_customer_product_id = '"' + card.customer_product_id + '"' + context['unit_customer_product_id'] = unit_customer_product_id + context['spacer_12'] = self.create_spacers((67,), (unit_customer_product_id,))[0] * ' ' + unit_boot_loader = '"' + card.boot_loader + '"' + context['unit_boot_loader'] = unit_boot_loader + context['spacer_13'] = self.create_spacers((67,), (unit_boot_loader,))[0] * ' ' + unit_processor = '"' + card.processor + '"' + context['unit_processor'] = unit_processor + context['spacer_14'] = self.create_spacers((67,), (unit_processor,))[0] * ' ' + text = self._render('equipment_inventory', *scopes, context=context) + self._write(text) + else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index d6463c9..afce2fd 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -121,7 +121,7 @@ def do_cd(self, command, *args, context=None): components = [x for x in args[0].split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|packet|macAccessCtrl|\.|\.\.)$', components[0]): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty @@ -234,6 +234,8 @@ def do_cd(self, command, *args, context=None): from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor + from vendors.KeyMile.accessPoints.root.services.packetCommandProcessor import PacketCommandProcessor + from vendors.KeyMile.accessPoints.root.services.macAccessCtrlCommandProcessor import MacAccessCtrlCommandProcessor as MacaccessctrlCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if len(remaining_args) > 0: From a902c2eb04a10683d9a4089dea7bf629d7a3b9ae Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 7 Oct 2020 11:10:25 +0200 Subject: [PATCH 209/318] added context to get Integration tests --- .../integration_tests/keymile/getDslam4.txt | 1 + .../keymile/getInventory2.txt | 15 +++ .../integration_tests/keymile/getIpsx7.txt | 5 + .../keymile/getMonitoring3.txt | 18 ++++ .../integration_tests/keymile/getState1.txt | 101 ++++++++++++++++++ .../keymile/getSubscriber6.txt | 2 + .../integration_tests/keymile/getVoice5.txt | 6 ++ 7 files changed, 148 insertions(+) diff --git a/test_cases/integration_tests/keymile/getDslam4.txt b/test_cases/integration_tests/keymile/getDslam4.txt index 6f999b9..a36c092 100644 --- a/test_cases/integration_tests/keymile/getDslam4.txt +++ b/test_cases/integration_tests/keymile/getDslam4.txt @@ -1,3 +1,4 @@ admin secret +ls exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getInventory2.txt b/test_cases/integration_tests/keymile/getInventory2.txt index 6f999b9..c45e0e0 100644 --- a/test_cases/integration_tests/keymile/getInventory2.txt +++ b/test_cases/integration_tests/keymile/getInventory2.txt @@ -1,3 +1,18 @@ admin secret +ls +cd /services/packet/nto1/ +ls +cd /services/packet/nto1/srvc-{$match}/cfgm +get Service +cd /unit-{$slot} +ls +cd /unit-{$slot}/mai +get HardwareAndSoftware +get CurrentStatus +get EquipmentInventory +cd /unit-{$slot}/port-{$port} +ls +cd /unit-{$slot}/port-{$port}/main +get OperationalStatus exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getIpsx7.txt b/test_cases/integration_tests/keymile/getIpsx7.txt index 6f999b9..dead751 100644 --- a/test_cases/integration_tests/keymile/getIpsx7.txt +++ b/test_cases/integration_tests/keymile/getIpsx7.txt @@ -1,3 +1,8 @@ admin secret +cd /unit-19/status +get SubscriberList +cd /unit-19/cfgm +get SIP +get IP exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getMonitoring3.txt b/test_cases/integration_tests/keymile/getMonitoring3.txt index 6f999b9..6338665 100644 --- a/test_cases/integration_tests/keymile/getMonitoring3.txt +++ b/test_cases/integration_tests/keymile/getMonitoring3.txt @@ -1,3 +1,21 @@ admin secret +ls +cd status +get CurrTemperature +cd .. +cd fan +ls +cd .. +cd unit-1 +ls +cd .. + + + + + + + + exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getState1.txt b/test_cases/integration_tests/keymile/getState1.txt index 6f999b9..cdfab20 100644 --- a/test_cases/integration_tests/keymile/getState1.txt +++ b/test_cases/integration_tests/keymile/getState1.txt @@ -1,3 +1,104 @@ admin secret +#adsl SUAD2 +cd /unit-{$card}/port-{$port}/status +get AttainableRate +cd /unit-{$card}/port-{$port}/main +get AdministrativeStatus +get OperationalStatus +cd /unit-{$card}/port-{$port}/chan-1/cfgm +get ProfileName +get ChanProfile +cd /unit-{$card}/port-{$port}/chan-1/status +get status +cd /unit-{$card}/port-{$port}/chan-1/vcc-1/cfgm +get configuredProfiles +cd /unit-{$card}/port-{$port}/chan-1/vcc-1/status +get ServiceStatus +cd /unit-11 +ls +cd /unit-{$slotIpss} +ls +#vdsl SUVD2 +cd /unit-{$card}/port-{$port}/status +get AttainableRate +cd /unit-{$card}/port-{$port}/main +get AdministrativeStatus +get OperationalStatus +cd /unit-{$card}/port-{$port}/chan-1/cfgm +get ChanProfile +cd /unit-{$card}/port-{$port}/chan-1/status +get status +cd /unit-{$card}/port-{$port}/chan-1/interface-1/cfgm +get configuredProfiles +get vlanProfile +cd /unit-{$card}/port-{$port}/chan-1/interface-1/status +get ServiceStatus +cd /unit-11 +ls +cd /unit-{$card}/port-{$port} +get status/VendorId +cd /unit-{$slotIpss} +ls +#xdsl +cd /unit-{$card}/port-{$port}/status +get AttainableRate +get UnicastList +cd /unit-{$card}/port-{$port}/main +get AdministrativeStatus +get OperationalStatus +cd /unit-{$card}/port-{$port} +ls +cd /unit-{$card}/port-{$port}/chan-1/cfgm +get ChanProfile +cd /unit-{$card}/port-{$port}/chan-1/status +get status +cd /unit-{$card}/port-{$port}/chan-1/interface-1/cfgm +get configuredProfiles +cd /unit-{$card}/port-{$port}/chan-1/interface-1/status +get ServiceStatus +cd /unit-{$card} +ls +cd /unit-11 +ls +cd /unit-{$card}/port-{$port} +get status/VendorId +#ftth +cd /unit-{$card}/port-{$port}/main +get AdministrativeStatus +get OperationalStatus +cd /unit-{$card}/port-{$port} +ls +cd /unit-{$card}/port-{$port}/status +get PortMacStatus +get PortGeneralStatus +cd /unit-{$card}/port-{$port}/interface-1/cfgm +get configuredProfiles +get vlanProfile +get IfRateLimiting +cd /unit-{$card}/port-{$port}/interface-1/status +get ServiceStatus +cd /unit-{$card}/port-{$port}/status +get DDMStatus +#sdsl +cd /unit-{$card}/port-{$port}/main +ls +cd /unit-{$card}/port-{$port}/status +ls +get LineActualState +get LineOperationState +cd /unit-{$card}/logports/logport-{$port}/status +get ActualStatus +get OperationalWireState +cd /unit-{$card}/logports/logport-{$port}/main +get AdministrativeStatus +get OperationalStatus +cd /unit-{$card}/logports/logport-{$port}/cfgm +get SpanProfiles +cd /unit-{$card}/logports/logport-{$port}/interface-1/cfgm +get configuredProfiles +get vlanProfile +cd /unit-{$card}/logports/logport-{$port}/interface-1/status +get ServiceStatus +ls exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getSubscriber6.txt b/test_cases/integration_tests/keymile/getSubscriber6.txt index 6f999b9..1a0f1b4 100644 --- a/test_cases/integration_tests/keymile/getSubscriber6.txt +++ b/test_cases/integration_tests/keymile/getSubscriber6.txt @@ -1,3 +1,5 @@ admin secret +cd /unit-19/portgroup-1/port-1/status +get SubscriberList exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getVoice5.txt b/test_cases/integration_tests/keymile/getVoice5.txt index 6f999b9..e3318fa 100644 --- a/test_cases/integration_tests/keymile/getVoice5.txt +++ b/test_cases/integration_tests/keymile/getVoice5.txt @@ -1,3 +1,9 @@ admin secret +#analog +cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm +get pstnport +#isdn +cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm +get isdnport exit \ No newline at end of file From 9c381724691a1e1778c6fffc68f36da3efdf8ff4 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 7 Oct 2020 13:38:55 +0200 Subject: [PATCH 210/318] added context to set Integration tests --- .../keymile/setChannelProfile14.txt | 8 +++++++ .../keymile/setInterface16.txt | 12 ++++++++++ .../integration_tests/keymile/setIpAddr6.txt | 14 +++++++++++ .../keymile/setPortProfile13.txt | 7 ++++++ .../integration_tests/keymile/setProfile7.txt | 3 --- .../keymile/setSIPDomain12.txt | 9 ++++++++ .../integration_tests/keymile/setTraffic1.txt | 13 +++++++++++ .../integration_tests/keymile/setVCC15.txt | 3 +++ .../integration_tests/keymile/setconfDsl2.txt | 23 +++++++++++++++++++ .../keymile/setconfVoice9.txt | 16 +++++++++++++ .../keymile/setdeconfVoicePort11.txt | 4 ++++ .../keymile/setdeconfVoicePort17.txt | 23 +++++++++++++++++++ .../keymile/setportaktiv4.txt | 15 ++++++++++++ .../keymile/setportdeactiv5.txt | 15 ++++++++++++ .../keymile/setunconfDsl3.txt | 23 +++++++++++++++++++ .../keymile/setunconfVoice10.txt | 3 --- 16 files changed, 185 insertions(+), 6 deletions(-) delete mode 100644 test_cases/integration_tests/keymile/setProfile7.txt delete mode 100644 test_cases/integration_tests/keymile/setunconfVoice10.txt diff --git a/test_cases/integration_tests/keymile/setChannelProfile14.txt b/test_cases/integration_tests/keymile/setChannelProfile14.txt index 6f999b9..3ad57dd 100644 --- a/test_cases/integration_tests/keymile/setChannelProfile14.txt +++ b/test_cases/integration_tests/keymile/setChannelProfile14.txt @@ -1,3 +1,11 @@ admin secret +cd /unit-$card/port-$port/chan-1/cfgm +#SUVM6/4 +set chanprofile $profile +set chanprofile default +#else +cd /unit-$card/port-$port/chan-1/cfgm +set ProfileName $profile +set ProfileName default exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setInterface16.txt b/test_cases/integration_tests/keymile/setInterface16.txt index 6f999b9..16a5569 100644 --- a/test_cases/integration_tests/keymile/setInterface16.txt +++ b/test_cases/integration_tests/keymile/setInterface16.txt @@ -1,3 +1,15 @@ admin secret +#SUSE1 +cd /unit-$card/logports/logport-$port/cfgm +#SUEN4 +cd /unit-$card/port-$port/cfgm +#SUE16 +cd /unit-$card/port-$port/cfgm +#ftth +cd /unit-$card/port-$port/cfgm +#else +cd /unit-$card/port-$port/chan-1/cfgm +CreateInterface default VCC_1_32_10100 +DeleteInterface all exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setIpAddr6.txt b/test_cases/integration_tests/keymile/setIpAddr6.txt index 6f999b9..e4e5a91 100644 --- a/test_cases/integration_tests/keymile/setIpAddr6.txt +++ b/test_cases/integration_tests/keymile/setIpAddr6.txt @@ -1,3 +1,17 @@ admin secret +cd /services/packet/1to1SingleTag/srvc-1/cfgm +set Service /unit-{$managementSlot}/control {$input->vlan_voice_new} CoS0 Add +cd /services/packet/1to1SingleTag/srvc-2/cfgm +set Service /unit-{$managementSlot}/media {$input->vlan_voice_new} CoS0 Add +cd /unit-{$managementSlot}/cfgm +set Ip {$input->ip_voice} 255.255.255.0 {$input->gateway_voice} +cd /cfgm +save +cd /unit-{$managementSlot}/main +restart +set /cfgm/IP_Address {$input->ip_new} 255.255.255.0 {$input->gateway} +/cfgm/Save +/unit-11/main/restart +set /cfgm/VlanId {$input->vlan_new} exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setPortProfile13.txt b/test_cases/integration_tests/keymile/setPortProfile13.txt index 6f999b9..ed42302 100644 --- a/test_cases/integration_tests/keymile/setPortProfile13.txt +++ b/test_cases/integration_tests/keymile/setPortProfile13.txt @@ -1,3 +1,10 @@ admin secret + +cd /unit-$card/port-$port/cfgm +#SUVM6 posibilities +set portprofiles true $vdslProfile 0 false default 0 false default 0 false default Priority +set portprofiles true " . $vdslProfile . " 0 false default 0 false default 0 false default Priority +set portprofiles false default 0 false default 0 false default 0 true " . $adslProfile . " Priority +set portprofiles true default 0 false default 0 false default 0 true default Priority exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setProfile7.txt b/test_cases/integration_tests/keymile/setProfile7.txt deleted file mode 100644 index 6f999b9..0000000 --- a/test_cases/integration_tests/keymile/setProfile7.txt +++ /dev/null @@ -1,3 +0,0 @@ -admin -secret -exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setSIPDomain12.txt b/test_cases/integration_tests/keymile/setSIPDomain12.txt index 6f999b9..d465075 100644 --- a/test_cases/integration_tests/keymile/setSIPDomain12.txt +++ b/test_cases/integration_tests/keymile/setSIPDomain12.txt @@ -1,3 +1,12 @@ admin secret +#analog or isdn +cd /unit-{$slotIpss}/cfgm +get Sip +set Proxy PrimaryOnly $domain 5060 "" 0 true Options 10 "" 0 true Options 10 +set Registrar $domain 5060 OneByOneRegistration 1 +set Sip $name $domain 5060 +49 $area 500 4 false None true 30 false false 1800 +set digitmap {sip "xxx" $domain 0 ""; sip "*xx*x.#" $domain 0 ""; sip "*xx*" $domain 0 ""; sip "*xx#" $domain 0 ""; sip "#xx#" $domain 0 ""; } +cd /cfgm +save exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setTraffic1.txt b/test_cases/integration_tests/keymile/setTraffic1.txt index 6f999b9..a9cc539 100644 --- a/test_cases/integration_tests/keymile/setTraffic1.txt +++ b/test_cases/integration_tests/keymile/setTraffic1.txt @@ -1,3 +1,16 @@ admin secret +#ftth +cd /unit-$card +ls +#SUEN4 +cd /unit-$card/port-$port/cfgm +Set Mode "Speed1000 Autoneg On" +Set FlowControl false +CreateInterface VLAN_$trafficVlan +#else +cd /unit-$card/port-$port/cfgm +Set Mode "1000MbitsFullDuplex" +Set FlowControl false +CreateInterface VLAN_$trafficVlan exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setVCC15.txt b/test_cases/integration_tests/keymile/setVCC15.txt index 6f999b9..cd9305b 100644 --- a/test_cases/integration_tests/keymile/setVCC15.txt +++ b/test_cases/integration_tests/keymile/setVCC15.txt @@ -1,3 +1,6 @@ admin secret +cd /unit-$card/port-$port/chan-1/cfgm +CreateVcc $profile default +DeleteVcc all exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfDsl2.txt b/test_cases/integration_tests/keymile/setconfDsl2.txt index 6f999b9..c2e2afc 100644 --- a/test_cases/integration_tests/keymile/setconfDsl2.txt +++ b/test_cases/integration_tests/keymile/setconfDsl2.txt @@ -1,3 +1,26 @@ admin secret +#adsl +cd /unit-$card/port-$port/main +Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" +set AdministrativeStatus up +#vdsl +cd /unit-$card/port-$port/main +Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" +set AdministrativeStatus up +#xdsl +cd /unit-$card/port-$port/main +Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" +set AdministrativeStatus up +#ftth +cd /unit-$card/port-$port/main +Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" +set AdministrativeStatus up +#sdsl +cd /unit-$card/logports/cfgm +create $bonding_port $profile +cd /unit-$card/logports/logport-$port/cfgm +CreateInterface name $servicetype +cd /unit-$card/logports/logport-$port/main +set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfVoice9.txt b/test_cases/integration_tests/keymile/setconfVoice9.txt index 6f999b9..60f70f6 100644 --- a/test_cases/integration_tests/keymile/setconfVoice9.txt +++ b/test_cases/integration_tests/keymile/setconfVoice9.txt @@ -1,3 +1,19 @@ admin secret +#analog +cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm +set pstnport true {$numbers} true false none none none none none +cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/main +Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" +cd /unit-$voiceCard/port-$voicePort/main +set AdministrativeStatus up +Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" +#isdn +cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm +set isdnport true {$numbers} true false none none none none none +cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/main +Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" +cd /unit-$voiceCard/port-$voicePort/main +set AdministrativeStatus up +Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt index 6f999b9..6704e55 100644 --- a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt @@ -1,3 +1,7 @@ admin secret +#isdn or analog +cd /unit-$ipsxSlot/portgroup-$card/port-$port/cfgm +get pstnport +cd / exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt index 6f999b9..d82cfe2 100644 --- a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt @@ -1,3 +1,26 @@ admin secret +#analog +cd /unit-$card/port-$port/main +set AdministrativeStatus down +Set Labels "" "" "" +cd /unit-$ipsxSlot/portgroup-$card/port-$port/cfgm +Set pstnport false {} true false none none none none none +cd /unit-$ipsxSlot/portgroup-$card/port-$port/main +Set Labels "" "" "" +#isdn +cd /unit-$card/port-$port/main +set AdministrativeStatus down +Set Labels "" "" "" +cd /unit-$ipsxSlot/portgroup-$card/port-$port/cfgm +Set isdnport false {} true false false none none none none +cd /unit-$ipsxSlot/portgroup-$card/port-$port/main +Set Labels "" "" "" + + + + + + + exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setportaktiv4.txt b/test_cases/integration_tests/keymile/setportaktiv4.txt index 6f999b9..c917fa5 100644 --- a/test_cases/integration_tests/keymile/setportaktiv4.txt +++ b/test_cases/integration_tests/keymile/setportaktiv4.txt @@ -1,3 +1,18 @@ admin secret +#adsl +cd /unit-$card/port-$port/main +set AdministrativeStatus up +#vdsl +cd /unit-$card/port-$port/main +set AdministrativeStatus up +#xdsl +cd /unit-$card/port-$port/main +set AdministrativeStatus up +#ftth +cd /unit-$card/port-$port/main +set AdministrativeStatus up +#sdsl +cd /unit-$card/logports/logport-$port/main +set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setportdeactiv5.txt b/test_cases/integration_tests/keymile/setportdeactiv5.txt index 6f999b9..041cd8d 100644 --- a/test_cases/integration_tests/keymile/setportdeactiv5.txt +++ b/test_cases/integration_tests/keymile/setportdeactiv5.txt @@ -1,3 +1,18 @@ admin secret +#adsl +cd /unit-$card/port-$port/main +set AdministrativeStatus down +#vdsl +cd /unit-$card/port-$port/main +set AdministrativeStatus down +#xdsl +cd /unit-$card/port-$port/main +set AdministrativeStatus down +#ftth +cd /unit-$card/port-$port/main +set AdministrativeStatus down +#sdsl +cd /unit-$card/logports/logport-$port/main +set AdministrativeStatus down exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setunconfDsl3.txt b/test_cases/integration_tests/keymile/setunconfDsl3.txt index 6f999b9..7213e54 100644 --- a/test_cases/integration_tests/keymile/setunconfDsl3.txt +++ b/test_cases/integration_tests/keymile/setunconfDsl3.txt @@ -1,3 +1,26 @@ admin secret +#adsl +cd /unit-$card/port-$port/main +set AdministrativeStatus down +Set Labels "" "" "" +#vdsl +cd /unit-$card/port-$port/main +set AdministrativeStatus down +Set Labels "" "" "" +#xdsl +cd /unit-$card/port-$port/main +set AdministrativeStatus down +Set Labels "" "" "" +#ftth +cd /unit-$card/port-$port/main +set AdministrativeStatus down +Set Labels "" "" "" +#sdsl +cd /unit-$card/logports/logport-$port/main +set AdministrativeStatus down +Set Labels "" "" "" +cd /unit-$card/logports/logport-$port/main +cd /unit-$card/logports/cfgm +Delete logport-$port exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setunconfVoice10.txt b/test_cases/integration_tests/keymile/setunconfVoice10.txt deleted file mode 100644 index 6f999b9..0000000 --- a/test_cases/integration_tests/keymile/setunconfVoice10.txt +++ /dev/null @@ -1,3 +0,0 @@ -admin -secret -exit \ No newline at end of file From 243df5dba71c56e88edf63e1d1bfd7e3a22ca2b9 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 7 Oct 2020 13:53:09 +0200 Subject: [PATCH 211/318] added logportCommandProcessor and refactored do_get functionality --- .../unit/logport/logportsCommandProcessor.py | 37 +++ .../logport/logportsManagementFunctions.py | 17 ++ .../logport/port/logportCommandProcessor.py | 43 +++ .../port/logportManagementFunctions.py | 264 ++++++++++++++++++ .../port/portgroupportCommandProcessor.py | 56 ++-- 5 files changed, 384 insertions(+), 33 deletions(-) create mode 100644 vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py new file mode 100644 index 0000000..1f28568 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -0,0 +1,37 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class LogPortsCommandProcessor(BaseCommandProcessor): + __name__ = 'logports' + management_functions = ('main', 'cfgm') + access_points = () + + from .logportsManagementFunctions import main + from .logportsManagementFunctions import cfgm + + def _init_access_points(self, context=None): # work in progress + card = self._model.get_card('name', context['unit']) + logports = context['logports'] + + for port in self._model.get_ports('card_id', card.id): + if port.name.count('/') == 2 and port.name.strip('/')[1] == 'logports-' + logports: + identifier = 'port-' + port.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py new file mode 100644 index 0000000..d281df9 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py @@ -0,0 +1,17 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } +} + +cfgm = { + 'General': { + 'Cmd': { + 'CreatePort', + 'DeletePort' + } + } +} \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py new file mode 100644 index 0000000..1df5208 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -0,0 +1,43 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor + + +class LogPortCommandProcessor(PortCommandProcessor): + __name__ = 'logport' + management_functions = ('main', 'cfgm', 'status') + access_points = () + + from .logportManagementFunctions import main + from .logportManagementFunctions import cfgm + from .logportManagementFunctions import status + + def do_get(self, command, *args, context=None): + scopes = ('login', 'base', 'get') + try: + super().do_get(command, *args, context=None) + except exceptions.CommandExecutionError: + #TODO: example + if self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': + text = self._render('attainable_rate', *scopes, context=context) + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + + def _init_access_points(self, context=None): + port = self._model.get_port('name', context['unit'] + '/' + context['portgroup'] + '/' + context['port']) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py new file mode 100644 index 0000000..5add929 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py @@ -0,0 +1,264 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + } +} + +cfgm = { + 'Multicast': { + 'Prop': { + 'MaxNumberOfMulticastStreams': 'rw', + 'EnableIgmpClassifier': 'rw', + 'AllowStaticStreams': 'rw', + 'EnableFastLeave': 'rw', + 'GroupManagement': 'rw', + 'Bandwidth': 'rw' + }, + 'Cmd': ( + 'GetGroupList', + ) + }, + 'Traceability': { + 'Prop': { + 'AgentRemoteId': 'rw' + } + }, + 'Security': { + 'Prop': { + 'ServiceOptions': 'rw', + 'MaxNumberOfMac': 'rw' + } + }, + 'AccessControl': { + 'Prop': { + 'ClassificationKey': 'rw', + 'MAT': 'rw' + } + }, + 'RateLimiter': { + 'Prop': { + 'RateLimiting': 'rw', + 'RateLimitingCoS': 'rw' + } + }, + 'Qos': { + 'Prop': { + 'WfqProfile': 'rw' + } + }, + 'Wire': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'PortProfiles': 'rw' + } + }, + 'Misc': { + 'Prop': { + 'SpecificDPBO': 'rw', + 'SpecificUPBO': 'rw' + } + } +} + +status = { + 'General': { + 'Prop': { + 'Standard': 'r-', + 'PowerMgmStatus': 'r-', + 'Vdsl2Parameters': 'r-', + 'EstUPBOElectricalLength': 'r-', + 'LineRate': 'r-', + 'LineSnrMargin': 'r-', + 'AttainableNetDataRate': 'r-', + 'AttainableRate': 'r-', + 'OutputPower': 'r-', + 'BandStatus': 'r-' + } + }, + 'statistics': { + 'Prop': { + 'counters': 'r-', + 'PolicingCounters': 'r-' + }, + 'Cmd': ( + 'ResetPortCounters', + ) + }, + 'Nto1MacAccessDynamicList': { + 'Prop': { + 'UnicastList': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters', + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + }, + }, + 'TLSMacForwardingList': { + 'Prop': { + 'MacForwardingList': 'r-' + }, + 'Cmd': ( + 'FlushMacForwardingList', + ) + }, + '1to1MacForwardingList': { + 'Prop': { + 'One2OneMacForwardingList': 'r-' + } + }, + 'Qos': { + 'Prop': { + 'wfqueues': 'r-' + } + }, + 'Multicast': { + 'stream': { + 'Dynamic': { + 'Prop': { + 'ActiveStreams': 'r-' + }, + 'Cmd': ( + 'ClearActiveStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticStreams': 'r-' + } + }, + }, + + 'Vlan': { + 'Prop': { + 'AttachedVlans': 'r-' + } + }, + 'Preview': { + 'Cmd': ( + 'ResetPreviewSettings', + ) + }, + 'Bandwidth': { + 'Prop': { + 'bandwidthStatus': 'r-' + } + }, + }, + 'LineTest': { + 'MELT': { + 'Prop': { + 'MeltResults': 'r-' + }, + 'Cmd': ( + 'StartMeltMeasurement', + ) + }, + 'Delt': { + 'Prop': { + 'DeltMeasurementStatus': 'r-', + 'RecordedDeltMeasurements': 'r-' + }, + 'Cmd': ( + 'StartDeltMeasurement', + ) + }, + 'Selt': { + 'Prop': { + 'SeltMeasurementStatus': 'r-', + 'RecordedSeltMeasurements': 'r-', + 'CableType': 'rw', + 'BandplanProfile': 'rw', + 'TargetSnrm': 'rw' + }, + 'Cmd': ( + 'StartSeltMeasurement', + ) + }, + }, + 'Defects': { + 'Prop': { + 'Defects': 'r-' + } + }, + 'LineInventory': { + 'Prop': { + 'VendorId': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'DslOperationStatus': 'r-' + } + }, + 'Subcarrier': { + 'Cmd': ( + 'ShowBitAllocation', + ) + }, + 'RfiBands': { + 'Prop': { + 'NotchStatus': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index dcbb3be..0c4258f 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -21,43 +21,33 @@ class PortgroupPortCommandProcessor(PortCommandProcessor): from .portgroupportManagementFunctions import main from .portgroupportManagementFunctions import cfgm - from .portgroupportManagementFunctions import fm - from .portgroupportManagementFunctions import pm from .portgroupportManagementFunctions import status def do_get(self, command, *args, context=None): scopes = ('login', 'base', 'get') - if self._validate(args, *()): - exc = exceptions.CommandSyntaxError(command=command) - exc.template = 'syntax_error' - exc.template_scopes = ('login', 'base', 'syntax_errors') - raise exc - elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': - text = self._render('attainable_rate', *scopes, context=context) - self._write(text) - elif self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ - self._model.get_card('name', context['unit']).product == 'isdn': - text = self._render('subscriberList_top', *scopes, context=context) - i = 0 - for subscriber in self._model.subscribers: - if subscriber.type == 'port': # TODO: show only subscriber of this port - - context['i'] = i - context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' - context['spacer2'] = self.create_spacers((63,), (subscriber.registration_state,))[0] * ' ' - i += 1 - text += self._render('subscriberList_item2', *scopes, context=dict(context, subscriber=subscriber)) - text += self._render('subscriberList_bottom', *scopes, context=context) - - self._write(text) - elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': - text = self._render('administrative_status', *scopes, context=context) - self._write(text) - elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': - text = self._render('operational_status', *scopes, context=context) - self._write(text) - else: - raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + try: + super().do_get(command, *args, context=None) + except exceptions.CommandExecutionError: + # TODO: example + if self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ + self._model.get_card('name', context['unit']).product == 'isdn': + text = self._render('subscriberList_top', *scopes, context=context) + i = 0 + for subscriber in self._model.subscribers: + if subscriber.type == 'port': # TODO: show only subscriber of this port + + context['i'] = i + context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' + context['spacer2'] = self.create_spacers((63,), (subscriber.registration_state,))[0] * ' ' + i += 1 + text += self._render('subscriberList_item2', *scopes, + context=dict(context, subscriber=subscriber)) + text += self._render('subscriberList_bottom', *scopes, context=context) + + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) def _init_access_points(self, context=None): port = self._model.get_port('name', context['unit'] + '/' + context['portgroup'] + '/' + context['port']) From a67ed2eb280da4c8aae1f35709bd66ef5b2a2729 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 7 Oct 2020 13:53:54 +0200 Subject: [PATCH 212/318] deleted obsolete TODOS --- .../root/unit/logport/port/logportCommandProcessor.py | 1 - .../root/unit/portgroup/port/portgroupportCommandProcessor.py | 1 - 2 files changed, 2 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 1df5208..200467b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -28,7 +28,6 @@ def do_get(self, command, *args, context=None): try: super().do_get(command, *args, context=None) except exceptions.CommandExecutionError: - #TODO: example if self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 0c4258f..4c86300 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -28,7 +28,6 @@ def do_get(self, command, *args, context=None): try: super().do_get(command, *args, context=None) except exceptions.CommandExecutionError: - # TODO: example if self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ self._model.get_card('name', context['unit']).product == 'isdn': text = self._render('subscriberList_top', *scopes, context=context) From 36e145b585a462383c8f7d437e9253a9edf0089e Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Wed, 7 Oct 2020 14:39:02 +0200 Subject: [PATCH 213/318] Small fixes for units, ports, and some schemas + filled 3 testfiles --- nesi/softbox/api/schemas/credential_schemas.py | 2 +- nesi/softbox/api/schemas/emu_schemas.py | 2 +- nesi/softbox/api/schemas/mgmt_card_schemas.py | 3 ++- nesi/softbox/api/schemas/qos_interface_schemas.py | 2 +- nesi/softbox/api/schemas/route_schemas.py | 2 +- nesi/softbox/api/schemas/service_port_schemas.py | 2 +- nesi/softbox/api/schemas/service_vlan_schemas.py | 2 +- nesi/softbox/api/schemas/subscriber_schemas.py | 2 +- nesi/softbox/api/schemas/user_schemas.py | 2 +- nesi/softbox/api/schemas/vlan_interface_schemas.py | 2 +- nesi/softbox/api/schemas/vlan_schemas.py | 2 +- templates/KeyMile/login/base/get/operational_status.j2 | 2 +- .../integration_tests/keymile/test Loopback3.txt | 6 ++++++ .../integration_tests/keymile/testVoicePort2.txt | 7 +++++++ test_cases/integration_tests/keymile/testmelt1.txt | 3 --- test_cases/integration_tests/keymile/testmelting4.txt | 10 ++++++++++ .../root/unit/port/portCommandProcessor.py | 6 ++++++ .../accessPoints/root/unit/unitCommandProcessor.py | 6 +++--- vendors/KeyMile/baseCommandProcessor.py | 4 ++-- 19 files changed, 47 insertions(+), 20 deletions(-) delete mode 100644 test_cases/integration_tests/keymile/testmelt1.txt diff --git a/nesi/softbox/api/schemas/credential_schemas.py b/nesi/softbox/api/schemas/credential_schemas.py index c60f477..7259d53 100644 --- a/nesi/softbox/api/schemas/credential_schemas.py +++ b/nesi/softbox/api/schemas/credential_schemas.py @@ -18,7 +18,7 @@ class CredentialSchema(ma.ModelSchema): class Meta: model = Credential fields = ('id', 'protocol', 'credential', 'username', 'password', - 'box', '_links') + 'box', 'box_id', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/emu_schemas.py b/nesi/softbox/api/schemas/emu_schemas.py index aad1347..7d4fb13 100644 --- a/nesi/softbox/api/schemas/emu_schemas.py +++ b/nesi/softbox/api/schemas/emu_schemas.py @@ -17,7 +17,7 @@ class EmuSchema(ma.ModelSchema): class Meta: model = Emu - fields = ('id', 'name', 'box', '_links') + fields = ('id', 'name', 'box', 'box_id', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/mgmt_card_schemas.py b/nesi/softbox/api/schemas/mgmt_card_schemas.py index 5d7e4f0..c03f1c5 100644 --- a/nesi/softbox/api/schemas/mgmt_card_schemas.py +++ b/nesi/softbox/api/schemas/mgmt_card_schemas.py @@ -19,7 +19,8 @@ class MgmtCardSchema(ma.ModelSchema): class Meta: model = MgmtCard - fields = ('id', 'box_id', 'box', 'name', 'subrack_id', 'admin_state', 'operational_state', 'description', 'mgmt_ports') + fields = ('id', 'box_id', 'box', 'name', 'subrack_id', 'admin_state', 'operational_state', 'description', + 'mgmt_ports') mgmt_ports = ma.Nested(MgmtPortsSchema.MgmtPortSchema, many=True) diff --git a/nesi/softbox/api/schemas/qos_interface_schemas.py b/nesi/softbox/api/schemas/qos_interface_schemas.py index 0743d85..02dd33f 100644 --- a/nesi/softbox/api/schemas/qos_interface_schemas.py +++ b/nesi/softbox/api/schemas/qos_interface_schemas.py @@ -17,7 +17,7 @@ class QosInterfaceSchema(ma.ModelSchema): class Meta: model = QosInterface - fields = ('id', 'name', 'description', 'box', + fields = ('id', 'name', 'description', 'box', 'box_id', '_links') _links = ma.Hyperlinks({ diff --git a/nesi/softbox/api/schemas/route_schemas.py b/nesi/softbox/api/schemas/route_schemas.py index da0b85e..41db76f 100644 --- a/nesi/softbox/api/schemas/route_schemas.py +++ b/nesi/softbox/api/schemas/route_schemas.py @@ -17,7 +17,7 @@ class RouteSchema(ma.ModelSchema): class Meta: model = Route - fields = ('id', 'dst', 'gw', 'metric', 'box', '_links') + fields = ('id', 'dst', 'gw', 'metric', 'box', 'box_id', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/service_port_schemas.py b/nesi/softbox/api/schemas/service_port_schemas.py index ae33609..251d7ef 100644 --- a/nesi/softbox/api/schemas/service_port_schemas.py +++ b/nesi/softbox/api/schemas/service_port_schemas.py @@ -17,7 +17,7 @@ class ServicePortSchema(ma.ModelSchema): class Meta: model = ServicePort - fields = ('id', 'name', 'box', 'connected_id', 'connected_type', 'admin_state', 'operational_state', + fields = ('id', 'name', 'box', 'box_id', 'connected_id', 'connected_type', 'admin_state', 'operational_state', '_links') box = ma.Hyperlinks( diff --git a/nesi/softbox/api/schemas/service_vlan_schemas.py b/nesi/softbox/api/schemas/service_vlan_schemas.py index d9c0e2a..1354f95 100644 --- a/nesi/softbox/api/schemas/service_vlan_schemas.py +++ b/nesi/softbox/api/schemas/service_vlan_schemas.py @@ -17,7 +17,7 @@ class ServiceVlanSchema(ma.ModelSchema): class Meta: model = ServiceVlan - fields = ('id', 'name', 'service_port_id', 'vlan_id', 'box', 'card_id', '_links') + fields = ('id', 'name', 'service_port_id', 'vlan_id', 'box', 'box_id', 'card_id', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/subscriber_schemas.py b/nesi/softbox/api/schemas/subscriber_schemas.py index d788063..25b65d6 100644 --- a/nesi/softbox/api/schemas/subscriber_schemas.py +++ b/nesi/softbox/api/schemas/subscriber_schemas.py @@ -17,7 +17,7 @@ class SubscriberSchema(ma.ModelSchema): class Meta: model = Subscriber - fields = ('id', 'name', 'box', 'number', 'type', 'address', 'registration_state', '_links') + fields = ('id', 'name', 'box', 'box_id', 'number', 'type', 'address', 'registration_state', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/user_schemas.py b/nesi/softbox/api/schemas/user_schemas.py index f2f93e5..6341cd0 100644 --- a/nesi/softbox/api/schemas/user_schemas.py +++ b/nesi/softbox/api/schemas/user_schemas.py @@ -17,7 +17,7 @@ class UserSchema(ma.ModelSchema): class Meta: model = User - fields = ('id', 'box', 'credentials_id', 'name', '_links') + fields = ('id', 'box', 'box_id', 'credentials_id', 'name', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/vlan_interface_schemas.py b/nesi/softbox/api/schemas/vlan_interface_schemas.py index ff335dc..aa67183 100644 --- a/nesi/softbox/api/schemas/vlan_interface_schemas.py +++ b/nesi/softbox/api/schemas/vlan_interface_schemas.py @@ -17,7 +17,7 @@ class VlanInterfaceSchema(ma.ModelSchema): class Meta: model = VlanInterface - fields = ('id', 'name', 'box', 'vlan_id', '_links') + fields = ('id', 'name', 'box', 'box_id', 'vlan_id', '_links') _links = ma.Hyperlinks({ 'self': ma.URLFor( diff --git a/nesi/softbox/api/schemas/vlan_schemas.py b/nesi/softbox/api/schemas/vlan_schemas.py index 96d608a..49ca8d7 100644 --- a/nesi/softbox/api/schemas/vlan_schemas.py +++ b/nesi/softbox/api/schemas/vlan_schemas.py @@ -17,7 +17,7 @@ class VlanSchema(ma.ModelSchema): class Meta: model = Vlan - fields = ('id', 'box_id', 'number', 'mtu', + fields = ('id', 'box_id', 'number', 'mtu', 'box' '_links') box = ma.Hyperlinks( diff --git a/templates/KeyMile/login/base/get/operational_status.j2 b/templates/KeyMile/login/base/get/operational_status.j2 index ea79363..167d462 100644 --- a/templates/KeyMile/login/base/get/operational_status.j2 +++ b/templates/KeyMile/login/base/get/operational_status.j2 @@ -1,3 +1,3 @@ \ # OperationalStatus -{{ context.port.operational_state }}{{ context.spacer }}\ # State +{{ context.port_operational_state }}{{ context.spacer }}\ # State diff --git a/test_cases/integration_tests/keymile/test Loopback3.txt b/test_cases/integration_tests/keymile/test Loopback3.txt index 6f999b9..a4c19e2 100644 --- a/test_cases/integration_tests/keymile/test Loopback3.txt +++ b/test_cases/integration_tests/keymile/test Loopback3.txt @@ -1,3 +1,9 @@ admin secret +#isdn +cd /unit-$voiceCard/port-$voicePort/status +Lock +StartQuickLoopbackTest +get QuickLoopbackTest +Unlock exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/testVoicePort2.txt b/test_cases/integration_tests/keymile/testVoicePort2.txt index 6f999b9..0602971 100644 --- a/test_cases/integration_tests/keymile/testVoicePort2.txt +++ b/test_cases/integration_tests/keymile/testVoicePort2.txt @@ -1,3 +1,10 @@ admin secret +cd /unit-{$voice_card}/main +get HardwareAndSoftware +/unit-$voice_card/port-$voice_port/status/StartLineTest +get /unit-$voice_card/port-$voice_port/status/LineTestResults +#SUVM6 +cd /unit-$card/port-$port/main +set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/testmelt1.txt b/test_cases/integration_tests/keymile/testmelt1.txt deleted file mode 100644 index 6f999b9..0000000 --- a/test_cases/integration_tests/keymile/testmelt1.txt +++ /dev/null @@ -1,3 +0,0 @@ -admin -secret -exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/testmelting4.txt b/test_cases/integration_tests/keymile/testmelting4.txt index 6f999b9..a526c37 100644 --- a/test_cases/integration_tests/keymile/testmelting4.txt +++ b/test_cases/integration_tests/keymile/testmelting4.txt @@ -1,3 +1,13 @@ admin secret +#voiceport +/unit-$voice_card/port-$voice_port/status/StartLineTest +get /unit-$voice_card/port-$voice_port/status/LineTestResults +#else +/unit-$card/port-$port/status/StartMeltMeasurement +get /unit-$card/port-$port/status/MeltResults + +#SUVM6 +cd /unit-$card/port-$port/main +set AdministrativeStatus up exit \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index b4ad848..69ba6b0 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -26,6 +26,8 @@ class PortCommandProcessor(BaseCommandProcessor): from .portManagementFunctions import status def do_get(self, command, *args, context=None): + port_name = context['unit'] + '/' + context['port'] + port = self._model.get_port('name', port_name) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -39,6 +41,10 @@ def do_get(self, command, *args, context=None): text = self._render('administrative_status', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': + self.map_states(port, 'port') + port_operational_state = port.operational_state + context['port_operational_state'] = port_operational_state + context['spacer'] = self.create_spacers((67,), (port_operational_state,))[0] * ' ' text = self._render('operational_status', *scopes, context=context) self._write(text) else: diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 2e6bb75..0deccb2 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -80,7 +80,7 @@ def do_get(self, command, *args, context=None): text = self._render('ip', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'HardwareAndSoftware'): + elif self._validate((args[0],), 'HardwareAndSoftware') and context['path'].split('/')[-1] == 'main': unit_hardware = '"' + card.board_name + '"' context['unit_hardware'] = unit_hardware context['spacer_1'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' @@ -105,7 +105,7 @@ def do_get(self, command, *args, context=None): text = self._render('hardware_and_software', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'CurrentStatus'): + elif self._validate((args[0],), 'CurrentStatus') and context['path'].split('/')[-1] == 'main': unit_state = card.state context['unit_state'] = unit_state context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' @@ -127,7 +127,7 @@ def do_get(self, command, *args, context=None): text = self._render('current_status', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'EquipmentInventory'): + elif self._validate((args[0],), 'EquipmentInventory') and context['path'].split('/')[-1] == 'main': unit_symbol = '"' + card.board_name + '"' context['unit_symbol'] = unit_symbol context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index afce2fd..21d6af9 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -37,14 +37,14 @@ def map_states(self, object, type): object.admin_state = 'Down' elif object.admin_state == '1': if type == 'port': - object.admin_state = 'Down' + object.admin_state = 'Up' if object.operational_state == '0': if type == 'port': object.operational_state = 'Down' elif object.operational_state == '1': if type == 'port': - object.operational_state = 'Down' + object.operational_state = 'Up' def create_spacers(self, positions, args): spacers = [] From 2142fcd1d59df65db1f45e75b2150a6783c2e950 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 7 Oct 2020 16:02:22 +0200 Subject: [PATCH 214/318] offer parent and child relation in baseCommandProcessor --- vendors/KeyMile/baseCommandProcessor.py | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 21d6af9..4c4ed07 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -103,6 +103,44 @@ def do_pwd(self, command, *args, context=None): def exec_in_path(self, path, command, *args, context=None): pass + ''' + search := string keyword like "unit" or "port" + node := contains the dict tree or + None for default tree structure + parent := None or contains parent dict (should be None / important for rekursive call) + return := Tuple of ParentList, ChildList + ''' + def get_parent_and_child_relation(self, search, node=None, parent=None): + if node is None: + node = { + "root": { + "unit": { + "control": {}, + "media": {}, + "port": { + "chanel": { + "interfaces": {} + }, + "interfaces": {} + }, + "portgroups": {"portgroupports": {}}, + "logports": {"logport": {}}, + "vectoringports": {"vectorport": {}}, + "internalports": {"internalport": {}} + }, + "eoam": {}, + "tdmConnections": {}, + "services": {}, + "multicast": {} + }} + for x, y in node.items(): + if y.get(search) is not None: + pp = list(parent.keys()) + pc = list(y[search].keys()) + return (pp, pc) + else: + return self.get_parent_and_child_relation(search=search, node=y, parent=node) + def do_cd(self, command, *args, context=None): if len(args) == 0: exc = exceptions.CommandSyntaxError(command=command) From 7519fc7b429b594f8331f6ca9fb92a2da8982710 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 7 Oct 2020 16:43:35 +0200 Subject: [PATCH 215/318] First set structure --- .../accessPoints/root/eoamCommandProcessor.py | 11 ++++++++++- .../root/multicastCommandProcessor.py | 11 ++++++++++- .../accessPoints/root/rootCommandProcessor.py | 10 ++++++++++ .../root/tdmConnectionsCommandProcessor.py | 11 ++++++++++- .../unit/logport/logportsCommandProcessor.py | 11 ++++++++++- .../unit/logport/port/logportCommandProcessor.py | 16 +++++++++++++++- .../root/unit/port/chan/chanCommandProcessor.py | 11 ++++++++++- .../unit/port/chan/vcc/vccCommandProcessor.py | 11 ++++++++++- .../port/interface/interfaceCommandProcessor.py | 9 +++++++++ .../root/unit/port/portCommandProcessor.py | 12 +++++++++++- .../port/portgroupportCommandProcessor.py | 16 +++++++++++++++- .../unit/portgroup/portgroupCommandProcessor.py | 11 ++++++++++- .../root/unit/unitCommandProcessor.py | 9 +++++++++ vendors/KeyMile/baseCommandProcessor.py | 8 ++++++++ 14 files changed, 147 insertions(+), 10 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py index d6888f5..cf866dc 100644 --- a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py @@ -24,4 +24,13 @@ class EoamCommandProcessor(BaseCommandProcessor): from .eoamManagementFunctions import status def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py index 43b31cf..5cad2b8 100644 --- a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py @@ -26,4 +26,13 @@ class MulticastCommandProcessor(BaseCommandProcessor): from .multicastManagementFunctions import status def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 81725fc..1fd5799 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -30,5 +30,15 @@ def _init_access_points(self, context=None): continue self.access_points += ('unit-' + card.name,) + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py index 12b4d77..b230d5c 100644 --- a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py @@ -23,4 +23,13 @@ class TdmConnectionsCommandProcessor(BaseCommandProcessor): from .tdmConnectionsManagementFunctions import cfgm def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 1f28568..cee387f 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -34,4 +34,13 @@ def _init_access_points(self, context=None): # work in progress self.access_points += (identifier,) def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 200467b..382a1e0 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -39,4 +39,18 @@ def _init_access_points(self, context=None): port = self._model.get_port('name', context['unit'] + '/' + context['portgroup'] + '/' + context['port']) def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + try: + super().set(command, *args, context=None) + except exceptions.CommandExecutionError: + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 2f4b9b9..1029469 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -40,4 +40,13 @@ def _init_access_points(self, context=None): self.access_points += (identifier,) def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py index 40d569a..c0e0842 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py @@ -25,4 +25,13 @@ class VccCommandProcessor(BaseCommandProcessor): from .vccManagementFunctions import status def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index 5bbae5d..4deae4d 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -26,3 +26,12 @@ class InterfaceCommandProcessor(BaseCommandProcessor): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 69ba6b0..79bfeb5 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -60,4 +60,14 @@ def _init_access_points(self, context=None): self.access_points += (identifier,) def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 4c86300..f603a08 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -52,4 +52,18 @@ def _init_access_points(self, context=None): port = self._model.get_port('name', context['unit'] + '/' + context['portgroup'] + '/' + context['port']) def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + try: + super().set(command, *args, context=None) + except exceptions.CommandExecutionError: + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index 47cf9f2..f2fa5dc 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -34,4 +34,13 @@ def _init_access_points(self, context=None): # work in progress self.access_points += (identifier,) def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 0deccb2..f4ff360 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -179,3 +179,12 @@ def do_get(self, command, *args, context=None): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 4c4ed07..3eca771 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -141,6 +141,14 @@ def get_parent_and_child_relation(self, search, node=None, parent=None): else: return self.get_parent_and_child_relation(search=search, node=y, parent=node) + def do_set(self, command, *args, context=None): + self.set(command, args, context) + return + + def set(self, command, *args, context=None): + #interface method + return + def do_cd(self, command, *args, context=None): if len(args) == 0: exc = exceptions.CommandSyntaxError(command=command) From 44a4d5ff1dfda65434aabe303199c7dc76f1c4f6 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 8 Oct 2020 09:52:58 +0200 Subject: [PATCH 216/318] Refactored do_cd and added generic function to switch between directories --- ...ile-MG2200.sh => create-keymile-MG2500.sh} | 84 +++- bootup/restapi.sh | 2 +- templates/KeyMile/login/base/ls/ls_header.j2 | 2 +- .../unit/port/chan/chanCommandProcessor.py | 4 +- .../root/unit/port/portCommandProcessor.py | 2 +- .../portgroup/portgroupCommandProcessor.py | 5 +- .../root/unit/unitCommandProcessor.py | 2 +- vendors/KeyMile/baseCommandProcessor.py | 448 ++++++++++-------- vendors/KeyMile/main.py | 1 + 9 files changed, 345 insertions(+), 205 deletions(-) rename bootup/conf/bootstraps/{create-keymile-MG2200.sh => create-keymile-MG2500.sh} (83%) diff --git a/bootup/conf/bootstraps/create-keymile-MG2200.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh similarity index 83% rename from bootup/conf/bootstraps/create-keymile-MG2200.sh rename to bootup/conf/bootstraps/create-keymile-MG2500.sh index abc2883..6a0d3e4 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2200.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -22,12 +22,12 @@ path="`dirname \"$0\"`" # Create a network device (admin operation) req='{ "vendor": "KeyMile", - "model": "MG2200", + "model": "MG2500", "version": "1", "description": "Example Switch", - "hostname": "KeyMileMG2200", + "hostname": "KeyMileMG2500", "mgmt_address": "10.0.0.12", - "software_version": "MG2200V800R016C00", + "software_version": "MG2500V800R016C00", "network_protocol": "telnet", "network_address": "127.0.0.1", "network_port": 9023, @@ -36,13 +36,85 @@ req='{ box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 -# Admin credentials +# Sessionmanager credentials req='{ - "username": "admin", + "username": "sessionmanager", "password": "secret" }' -root_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) +sessionmanager_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# Sessionmanager user +req='{ + "name": "sessionmanager", + "credentials_id": '$sessionmanager_credential_id', + "level": "Super", + "profile": "root", + "append_info": "Sessionmanager", + "lock_status": "Unlocked" +}' + +sessionmanager_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) + +# Manager credentials +req='{ + "username": "manager", + "password": "secret" +}' + +manager_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# Manager user +req='{ + "name": "manager", + "credentials_id": '$manager_credential_id', + "level": "Admin", + "profile": "admin", + "append_info": "Manager", + "lock_status": "Unlocked" +}' + +manager_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) + +# Maintenance credentials +req='{ + "username": "maintenance", + "password": "secret" +}' + +maintenance_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# Manager user +req='{ + "name": "maintenance", + "credentials_id": '$maintenance_credential_id', + "level": "Operator", + "profile": "operator", + "append_info": "Maintenance", + "lock_status": "Unlocked" +}' + +maintenance_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) + +# Information credentials +req='{ + "username": "information", + "password": "secret" +}' + +information_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# Manager user +req='{ + "name": "information", + "credentials_id": '$information_credential_id', + "level": "User", + "profile": "commonuser", + "append_info": "Information", + "lock_status": "Unlocked" +}' + +information_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) # test subscriber req='{ diff --git a/bootup/restapi.sh b/bootup/restapi.sh index d14d657..7071288 100755 --- a/bootup/restapi.sh +++ b/bootup/restapi.sh @@ -181,7 +181,7 @@ if [ $recreate_db = "yes" ]; then #bash bootup/conf/bootstraps/create-box-port-vlan.sh #bash bootup/conf/bootstraps/create-alcatel-7360.sh #bash bootup/conf/bootstraps/create-huawei-5623.sh - bash bootup/conf/bootstraps/create-keymile-MG2200.sh + bash bootup/conf/bootstraps/create-keymile-MG2500.sh fi if [ $alcatel_api = "yes" ]; then diff --git a/templates/KeyMile/login/base/ls/ls_header.j2 b/templates/KeyMile/login/base/ls/ls_header.j2 index e0a8150..2f31160 100644 --- a/templates/KeyMile/login/base/ls/ls_header.j2 +++ b/templates/KeyMile/login/base/ls/ls_header.j2 @@ -1,4 +1,4 @@ -Infos of AP: {{ context.path }} +Infos of AP: {{ context.ls_path }} Name : MileGate 2200 Main Mode : Equipment State : Ok diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 1029469..c3f3e2b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -26,8 +26,8 @@ class ChanCommandProcessor(BaseCommandProcessor): from .chanManagementFunctions import status def _init_access_points(self, context=None): - chan = self._model.get_chan('name', context['unit'] + '/' + context['port'] + '/' + context['chan']) - card = self._model.get_card('name', context['unit']) + chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + card = self._model.get_card('name', self._parent._parent.component_id) for interface in self._model.get_interfaces('chan_id', chan.id): if card.product != 'adsl': diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 79bfeb5..585ac74 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -51,7 +51,7 @@ def do_get(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) def _init_access_points(self, context=None): - port = self._model.get_port('name', context['unit'] + '/' + context['port']) + port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) for chan in self._model.get_chans('port_id', port.id): identifier = 'chan-' + chan.name.split('/')[-1] diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index f2fa5dc..b9dfef6 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -23,11 +23,10 @@ class PortgroupCommandProcessor(BaseCommandProcessor): from .portgroupManagementFunctions import cfgm def _init_access_points(self, context=None): # work in progress - card = self._model.get_card('name', context['unit']) - portgroup = context['portgroup'] + card = self._model.get_card('name', self._parent.component_id) for port in self._model.get_ports('card_id', card.id): - if port.name.count('/') == 2 and port.name.strip('/')[1] == 'portgroup-' + portgroup: + if port.name.count('/') == 2 and port.name.strip('/')[1] == 'portgroup-' + self.component_id: identifier = 'port-' + port.name.split('/')[-1] if identifier in self.access_points: continue diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index f4ff360..1fe5609 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -25,7 +25,7 @@ class UnitCommandProcessor(BaseCommandProcessor): from .unitManagementFunctions import status def _init_access_points(self, context=None): - card = self._model.get_card('name', context['unit']) + card = self._model.get_card('name', self.component_id) # if card.type == ?: # self.access_points += ('internalPorts',) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 3eca771..5b588d3 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -21,6 +21,11 @@ class BaseCommandProcessor(base.CommandProcessor): management_functions = () access_points = () + component_id = None + + def set_component_id(self, id): + self.component_id = id + main = {} cfgm = {} @@ -100,281 +105,344 @@ def do_pwd(self, command, *args, context=None): context['spacer'] = self.create_spacers((67,), (context['path'],))[0] * ' ' self._write(self._render('pwd', 'login', 'base', context=context)) - def exec_in_path(self, path, command, *args, context=None): - pass + def ls(self, context=None, path_type='path'): + scopes = ('login', 'base', 'ls') + context['ls_path'] = context[path_type] + if re.search('(pm|fm|status|main|cfgm)', context['ls_path']): + mf_type = context['ls_path'].split('/')[-1] + + mf_layers = None + if mf_type == 'status': + mf_layers = self.status + elif mf_type == 'cfgm': + mf_layers = self.cfgm + elif mf_type == 'fm': + mf_layers = self.fm + elif mf_type == 'pm': + mf_layers = self.pm + elif mf_type == 'main': + mf_layers = self.main + + def generate_ls_text(layers, depth): + text = '' + for layer in layers: + if layer not in ('Cmd', 'Prop', 'File'): + context['mf_layer'] = depth * ' ' + layer + text += self._render('ls_mf_header', *scopes, context=context) + depth += 1 + text += generate_ls_text(layers[layer], depth) + depth -= 1 + else: + if layer == 'Cmd': + prop_type = layer + ' ' + else: + prop_type = layer - ''' - search := string keyword like "unit" or "port" - node := contains the dict tree or - None for default tree structure - parent := None or contains parent dict (should be None / important for rekursive call) - return := Tuple of ParentList, ChildList - ''' - def get_parent_and_child_relation(self, search, node=None, parent=None): - if node is None: - node = { - "root": { - "unit": { - "control": {}, - "media": {}, - "port": { - "chanel": { - "interfaces": {} - }, - "interfaces": {} - }, - "portgroups": {"portgroupports": {}}, - "logports": {"logport": {}}, - "vectoringports": {"vectorport": {}}, - "internalports": {"internalport": {}} - }, - "eoam": {}, - "tdmConnections": {}, - "services": {}, - "multicast": {} - }} - for x, y in node.items(): - if y.get(search) is not None: - pp = list(parent.keys()) - pc = list(y[search].keys()) - return (pp, pc) - else: - return self.get_parent_and_child_relation(search=search, node=y, parent=node) + context['prop_type'] = depth * ' ' + prop_type - def do_set(self, command, *args, context=None): - self.set(command, args, context) - return + for property in layers[layer]: + context['prop_name'] = property - def set(self, command, *args, context=None): - #interface method - return + if prop_type in ('File', 'Prop'): + context['prop_rw_rights'] = layers[layer].get(property, '') + else: + context['prop_rw_rights'] = '' + text += self._render('ls_mf_body', *scopes, context=context) + return text - def do_cd(self, command, *args, context=None): - if len(args) == 0: - exc = exceptions.CommandSyntaxError(command=command) - exc.template = 'syntax_error' - exc.template_scopes = ('login', 'base', 'syntax_errors') - raise exc + text = generate_ls_text(mf_layers, 0) + self._write(text) - if args[0] == '/': - context['path'] = '/' - from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor - exc = exceptions.TerminalExitError() - exc.return_to = RootCommandProcessor + else: + text = self._render('ls_header', *scopes, context=context) + + text += self._render('ls_mf_list', *scopes, context=context) + for management_function in self.management_functions: + context['list_entry'] = management_function + text += self._render('ls_list_body', *scopes, context=context) + + text += self._render('ls_ap_list', *scopes, context=context) + + self._init_access_points(context=context) + + for access_point in self.access_points: + context['list_entry'] = access_point + text += self._render('ls_list_body', *scopes, context=context) - raise exc + self._write(text) - components = [x for x in args[0].split('/') if x] + def do_ls(self, command, *args, context=None): + if self._validate(args, ): + self.ls(context=context) + elif self._validate(args, '-e'): + pass + elif self._validate(args, str): + path = args[0] + + try: + tmp_cmdproc = self.change_directory(path, context=context) + tmp_cmdproc.ls(context=context, path_type='component_path') + except exceptions.CommandExecutionError: + raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + context['component_path'] = context['path'] + else: + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=command) + + def change_directory(self, path, context=None): + path = path.lower() + if path == '/': + if self.__name__ != 'root': + self._parent.change_directory(path, context=context) + else: + context['component_path'] = '/' + return self + + components = [x for x in path.split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|packet|macAccessCtrl|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', components[0]): - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty + raise exceptions.SoftboxenError() - if args[0] == '.': - return # dot does nothing + if path == '.': + return self - if args[0].startswith('./'): - if args[0] == './': - return + if path.startswith('./'): + if path == './': + return self - self.do_cd(command, args[0][2:], context=context) - return + return self.change_directory(path[2:], context=context) - if re.search('\.\./(?:[^.]+/)+\.\.', args[0]): - if args[0].endswith('..'): + if re.search('\.\./(?:[^.]+/)+\.\.', path): + if path.endswith('..'): raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) else: raise exceptions.CommandExecutionError(template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors'), command=None) - if args[0].startswith('..'): - splitted_path = [x for x in context['path'].split('/') if x] + if path.startswith('..'): + splitted_path = [x for x in context['component_path'].split('/') if x] exit_component = None if len(splitted_path) != 0: exit_component = splitted_path.pop() - context['path'] = '/' + '/'.join(splitted_path) + context['component_path'] = '/' + '/'.join(splitted_path) if exit_component in ('main', 'cfgm', 'fm', 'pm', 'status'): self.set_prompt_end_pos(context=context) - if args[0] != '..': - self.do_cd('cd', args[0][3:], context=context) - return + if path != '..': + return self._parent.change_directory(path[3:], context=context) + return self - if args[0] == '..': - raise exceptions.TerminalExitError() + if path == '..': + return self._parent - exc = exceptions.TerminalExitError() - exc.command = 'cd ' + args[0][3:] - raise exc - - if args[0].startswith('/'): + return self._parent.change_directory(path[3:], context=context) + if path.startswith('/'): if 'unit-' not in components[0] and components[0] not in ('eoam', 'fan', 'multicast', 'services', 'tdmConnection', 'main', 'cfgm', 'fm', 'pm', 'status'): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - context['path'] = '/' - if self.__name__ != 'root': - exc = exceptions.TerminalExitError() - from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor - exc.return_to = RootCommandProcessor - exc.command = 'cd ' + args[0].lstrip('/') - raise exc - - self.do_cd('cd', args[0].lstrip('/'), context=context) + subprocessor = self._parent.change_directory(path, context=context) + else: + context['component_path'] = '/' + subprocessor = self.change_directory(path.lstrip('/'), context=context) else: remaining_args = '/'.join(components[1:]) component_type = None - component_number = None + component_id = None if '-' in components[0]: component_type = components[0].split('-')[0] - component_number = components[0].split('-')[1] + component_id = components[0].split('-')[1] command_processor = component_type.capitalize() + 'CommandProcessor' else: command_processor = components[0].capitalize() + 'CommandProcessor' if component_type == 'unit': if self.__name__ != 'root': - raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - - context['unit'] = component_number - elif component_type == 'port': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'portgroup' or component_type == 'logports' or component_type == 'huntgroup': if self.__name__ != 'unit': - raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - - context['port'] = component_number + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'port': + if self.__name__ != 'unit' and self.__name__ != 'portgroup': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'chan': if self.__name__ != 'port': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - context['chan'] = component_number elif component_type == 'interface': if self.__name__ != 'port' and self.__name__ != 'chan': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - context['chan'] = component_number - if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): if self.__name__ != 'root': - raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty if components[0] in ('main', 'cfgm', 'fm', 'pm', 'status'): if re.search('(main|cfgm|fm|pm|status)', context['path']): - return - if context['path'] == '/': + return self + if context['component_path'] == '/': new_path = components[0] else: new_path = '/' + components[0] - context['path'] += new_path - self.set_prompt_end_pos(context=context) - return + context['component_path'] += new_path + return self from vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor import UnitCommandProcessor from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor from vendors.KeyMile.accessPoints.root.unit.port.chan.chanCommandProcessor import ChanCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor import InterfaceCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor import \ + InterfaceCommandProcessor from vendors.KeyMile.accessPoints.root.fan.fanCommandProcessor import FanCommandProcessor from vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor import AlarmCommandProcessor from vendors.KeyMile.accessPoints.root.eoamCommandProcessor import EoamCommandProcessor from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor - from vendors.KeyMile.accessPoints.root.services.packetCommandProcessor import PacketCommandProcessor - from vendors.KeyMile.accessPoints.root.services.macAccessCtrlCommandProcessor import MacAccessCtrlCommandProcessor as MacaccessctrlCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import PortgroupCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import PortgroupPortCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') - if len(remaining_args) > 0: - command = 'cd ' + remaining_args - else: - command = None + if component_id is not None: + subprocessor.set_component_id(component_id) - if context['path'] == '/': + if context['component_path'] == '/': new_path = components[0] else: new_path = '/' + components[0] + context['component_path'] += new_path - context['path'] += new_path - subprocessor.loop(context=context, return_to=self.__class__, command=command) - - def do_exit(self, command, *args, context=None): - exc = exceptions.TerminalExitError() - exc.return_to = 'sysexit' - raise exc - - def do_ls(self, command, *args, context=None): - if self._validate(args,): - scopes = ('login', 'base', 'ls') - if re.search('(pm|fm|status|main|cfgm)', context['path']): - mf_type = context['path'].split('/')[-1] - - mf_layers = None - if mf_type == 'status': - mf_layers = self.status - elif mf_type == 'cfgm': - mf_layers = self.cfgm - elif mf_type == 'fm': - mf_layers = self.fm - elif mf_type == 'pm': - mf_layers = self.pm - elif mf_type == 'main': - mf_layers = self.main - - def generate_ls_text(layers, depth): - text = '' - for layer in layers: - if layer not in ('Cmd', 'Prop', 'File'): - context['mf_layer'] = depth * ' ' + layer - text += self._render('ls_mf_header', *scopes, context=context) - depth += 1 - text += generate_ls_text(layers[layer], depth) - depth -= 1 - else: - if layer == 'Cmd': - prop_type = layer + ' ' - else: - prop_type = layer - - context['prop_type'] = depth * ' ' + prop_type - - for property in layers[layer]: - context['prop_name'] = property - - if prop_type in ('File', 'Prop'): - context['prop_rw_rights'] = layers[layer].get(property, '') - else: - context['prop_rw_rights'] = '' - text += self._render('ls_mf_body', *scopes, context=context) - return text + if len(remaining_args) > 0: + subprocessor = subprocessor.change_directory(remaining_args, context=context) - text = generate_ls_text(mf_layers, 0) - self._write(text) + return subprocessor + ''' + search := string keyword like "unit" or "port" + node := contains the dict tree or + None for default tree structure + parent := None or contains parent dict (should be None / important for rekursive call) + return := Tuple of ParentList, ChildList + ''' + def get_parent_and_child_relation(self, search, node=None, parent=None): + if node is None: + node = { + "root": { + "unit": { + "control": {}, + "media": {}, + "port": { + "chanel": { + "interfaces": {} + }, + "interfaces": {} + }, + "portgroups": {"portgroupports": {}}, + "logports": {"logport": {}}, + "vectoringports": {"vectorport": {}}, + "internalports": {"internalport": {}} + }, + "eoam": {}, + "tdmConnections": {}, + "services": {}, + "multicast": {} + }} + for x, y in node.items(): + if y.get(search) is not None: + pp = list(parent.keys()) + pc = list(y[search].keys()) + return (pp, pc) else: - text = self._render('ls_header', *scopes, context=context) - - text += self._render('ls_mf_list', *scopes, context=context) - for management_function in self.management_functions: - context['list_entry'] = management_function - text += self._render('ls_list_body', *scopes, context=context) - - text += self._render('ls_ap_list', *scopes, context=context) + return self.get_parent_and_child_relation(search=search, node=y, parent=node) - self._init_access_points(context=context) + def do_set(self, command, *args, context=None): + self.set(command, args, context) + return - for access_point in self.access_points: - context['list_entry'] = access_point - text += self._render('ls_list_body', *scopes, context=context) + def set(self, command, *args, context=None): + #interface method + return - self._write(text) - elif self._validate(args, '-e'): - pass - elif self._validate([args[0]], str): + def do_cd(self, command, *args, context=None): + if self._validate(args, ): + raise exceptions.CommandSyntaxError() + elif self._validate(args, str): path = args[0] - self.do_cd('cd', path, context=context) + try: + subprocessor = self.change_directory(path, context=context) + return_to = self.get_command_processor(subprocessor) + except: + context['component_path'] = context['path'] + raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + context['path'] = context['component_path'] + subprocessor.loop(context=context, return_to=return_to) else: - raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=command) + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=command) + + def get_command_processor(self, current_processor, component_type=None): + from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor import UnitCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.chan.chanCommandProcessor import ChanCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor import \ + InterfaceCommandProcessor + from vendors.KeyMile.accessPoints.root.fan.fanCommandProcessor import FanCommandProcessor + from vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor import AlarmCommandProcessor + from vendors.KeyMile.accessPoints.root.eoamCommandProcessor import EoamCommandProcessor + from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor + from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor + from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor + if current_processor.__class__ == RootCommandProcessor: + return_to = RootCommandProcessor + if component_type not in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services', 'unit') and component_type is not None: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif current_processor.__class__ == UnitCommandProcessor: + return_to = RootCommandProcessor + if component_type != 'port' and component_type is not None: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif current_processor.__class__ == PortCommandProcessor: + return_to = UnitCommandProcessor + if component_type != 'chan' and component_type is not None: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif current_processor.__class__ == ChanCommandProcessor: + return_to = PortCommandProcessor + if component_type != 'interface' and component_type is not None: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif current_processor.__class__ == InterfaceCommandProcessor: + return_to = ChanCommandProcessor + return_to = PortCommandProcessor + elif current_processor.__class__ == FanCommandProcessor: + return_to = RootCommandProcessor + elif current_processor.__class__ == AlarmCommandProcessor: + return_to = FanCommandProcessor + elif current_processor.__class__ == EoamCommandProcessor: + return_to = RootCommandProcessor + elif current_processor.__class__ == MulticastCommandProcessor: + return_to = RootCommandProcessor + elif current_processor.__class__ == TdmConnectionsCommandProcessor: + return_to = RootCommandProcessor + elif current_processor.__class__ == ServicesCommandProcessor: + return_to = RootCommandProcessor + + return return_to + + def do_exit(self, command, *args, context=None): + exc = exceptions.TerminalExitError() + exc.return_to = 'sysexit' + raise exc def _init_access_points(self, context=None): pass # Abstract method not implemented diff --git a/vendors/KeyMile/main.py b/vendors/KeyMile/main.py index ff9abd4..95e03f6 100644 --- a/vendors/KeyMile/main.py +++ b/vendors/KeyMile/main.py @@ -56,6 +56,7 @@ def on_unknown_command(self, command, *args, context=None): RootCommandProcessor, 'login', 'base') context['path'] = '/' + context['component_path'] = '/' self._write(self._render('login_message', 'login', 'base', context=context)) From 8683b0330382422a2dcfd9d1f7de4427f2df1c51 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 8 Oct 2020 10:51:03 +0200 Subject: [PATCH 217/318] refactored parent child function --- vendors/KeyMile/baseCommandProcessor.py | 70 ++++++++++++++++--------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 5b588d3..aa52ce2 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -325,44 +325,62 @@ def change_directory(self, path, context=None): ''' search := string keyword like "unit" or "port" + parent := string keyword to describe the parent of search like "root" node := contains the dict tree or None for default tree structure - parent := None or contains parent dict (should be None / important for rekursive call) - return := Tuple of ParentList, ChildList + parent_keys := should be None / important for rekursive call + return := Tuple of (ParentList, ChildList) or ([],[]) ''' - def get_parent_and_child_relation(self, search, node=None, parent=None): + + def get_parent_and_child_relation(self, search, parent=None, node=None, parent_keys=None): + if parent == "": + return ([], []) if node is None: node = { - "root": { - "unit": { - "control": {}, - "media": {}, - "port": { - "chanel": { - "interfaces": {} + "root": { + "unit": { + "control": {}, + "media": {}, + "port": { + "chanel": { + "interfaces": { + "hell": {} + } + }, + "interfaces": { + "hell2": {} + } }, - "interfaces": {} + "portgroups": {"portgroupports": {}}, + "logports": {"logport": {}}, + "vectoringports": {"vectorport": {}}, + "internalports": {"internalport": {}} }, - "portgroups": {"portgroupports": {}}, - "logports": {"logport": {}}, - "vectoringports": {"vectorport": {}}, - "internalports": {"internalport": {}} - }, - "eoam": {}, - "tdmConnections": {}, - "services": {}, - "multicast": {} - }} + "eoam": {}, + "tdmConnections": {}, + "services": {}, + "multicast": {} + }} for x, y in node.items(): - if y.get(search) is not None: - pp = list(parent.keys()) - pc = list(y[search].keys()) + if x == search and (parent is None or parent_keys.__contains__(parent)): + if parent is not None: + pp = [parent] + elif parent_keys is None: + pp = [] + else: + pp = [parent_keys] + pc = list(y.keys()) return (pp, pc) else: - return self.get_parent_and_child_relation(search=search, node=y, parent=node) + (pp, pc) = self.get_parent_and_child_relation(search=search, parent=parent, node=y, parent_keys=x) + if pp == [] and pc == []: + pass + else: + return (pp, pc) + else: + return ([], []) def do_set(self, command, *args, context=None): - self.set(command, args, context) return def set(self, command, *args, context=None): From f1d394338c28be50c770a108f4727616d1d67a14 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 8 Oct 2020 11:25:36 +0200 Subject: [PATCH 218/318] Added restrictions for card names if keymile version is a certain one --- .../conf/bootstraps/create-keymile-MG2500.sh | 4 +-- nesi/softbox/api/views/card_views.py | 14 ++++++++++- .../root/unit/unitCommandProcessor.py | 25 ++++++++++--------- vendors/KeyMile/baseCommandProcessor.py | 9 ++++--- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 6a0d3e4..06f1a66 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -22,8 +22,8 @@ path="`dirname \"$0\"`" # Create a network device (admin operation) req='{ "vendor": "KeyMile", - "model": "MG2500", - "version": "1", + "model": "MileGate", + "version": "2500", "description": "Example Switch", "hostname": "KeyMileMG2500", "mgmt_address": "10.0.0.12", diff --git a/nesi/softbox/api/views/card_views.py b/nesi/softbox/api/views/card_views.py index 5374f92..9852947 100644 --- a/nesi/softbox/api/views/card_views.py +++ b/nesi/softbox/api/views/card_views.py @@ -58,11 +58,16 @@ def new_card(box_id): else: p = re.compile('^([0-9]+)?/?([0-9]+)?/?([0-9]+)?$') match_groups = p.match(last_card['name']).groups() - filtered_match_groups = [x for x in match_groups if x is not None] # filter out None values + filtered_match_groups = [x for x in match_groups if x is not None] # filter out None values last_card_index = filtered_match_groups[len(filtered_match_groups) - 1] if subrack['name'] != "": req['name'] = subrack['name'] + "/" + str(int(last_card_index) + 1) else: + if vendor == 'KeyMile': + if int(last_card_index) + 1 in (11, 13): + return flask.Response(status=500) # MgmtCard slots are reserved + if (box['version'] == '2500' and int(last_card_index) + 1 > 21) or (box['version'] == '2300' and int(last_card_index) + 1 > 14) or (box['version'] == '2200' and int(last_card_index) + 1 > 12): + return flask.Response(status=500) req['name'] = str(int(last_card_index) + 1) else: if subrack['name'] != "": @@ -73,6 +78,13 @@ def new_card(box_id): else: if vendor == 'Huawei': req['name'] = "0" + if vendor == 'KeyMile': + if box['version'] == '2500': + req['name'] = "1" + elif box['version'] == '2300': + req['name'] = "7" + elif box['version'] == '2200': + req['name'] = "9" else: req['name'] = "1" diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 1fe5609..ecf05a1 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -16,7 +16,7 @@ class UnitCommandProcessor(BaseCommandProcessor): __name__ = 'unit' - management_functions = ('main', 'cfgm', 'fm', 'status') + management_functions = ('main', 'fm') access_points = () # 'internalPorts', only on certain cards from .unitManagementFunctions import main @@ -25,17 +25,18 @@ class UnitCommandProcessor(BaseCommandProcessor): from .unitManagementFunctions import status def _init_access_points(self, context=None): - card = self._model.get_card('name', self.component_id) - - # if card.type == ?: - # self.access_points += ('internalPorts',) - # - - for port in self._model.get_ports('card_id', card.id): - identifier = 'port-' + port.name.split('/')[-1] - if identifier in self.access_points: - continue - self.access_points += (identifier,) + try: + card = self._model.get_card('name', self.component_id) + + self.management_functions = ('main', 'cfgm', 'fm', 'status') + + for port in self._model.get_ports('card_id', card.id): + identifier = 'port-' + port.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + except exceptions.InvalidInputError: + pass # todo: add portgroup to access_points diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index aa52ce2..33041c3 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -156,6 +156,8 @@ def generate_ls_text(layers, depth): else: text = self._render('ls_header', *scopes, context=context) + self._init_access_points(context=context) + text += self._render('ls_mf_list', *scopes, context=context) for management_function in self.management_functions: context['list_entry'] = management_function @@ -163,8 +165,6 @@ def generate_ls_text(layers, depth): text += self._render('ls_ap_list', *scopes, context=context) - self._init_access_points(context=context) - for access_point in self.access_points: context['list_entry'] = access_point text += self._render('ls_list_body', *scopes, context=context) @@ -194,7 +194,7 @@ def change_directory(self, path, context=None): path = path.lower() if path == '/': if self.__name__ != 'root': - self._parent.change_directory(path, context=context) + return self._parent.change_directory(path, context=context) else: context['component_path'] = '/' return self @@ -260,6 +260,9 @@ def change_directory(self, path, context=None): command_processor = components[0].capitalize() + 'CommandProcessor' if component_type == 'unit': + if (self._model.version == '2200' and not 9 <= int(component_id) <= 12) or (self._model.version == '2300' and not 7 <= int(component_id) <= 14) or (self._model.version == '2500' and not 1 <= int(component_id) <= 21): + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty# if self.__name__ != 'root': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty From 38f70d2dc20985800c8fc5bc72d0a7e6b3bb0281 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 8 Oct 2020 11:35:54 +0200 Subject: [PATCH 219/318] updated set function --- .../accessPoints/root/eoamCommandProcessor.py | 4 ++++ .../root/multicastCommandProcessor.py | 4 ++++ .../accessPoints/root/rootCommandProcessor.py | 4 ++++ .../services/macAccessCtrlCommandProcessor.py | 20 ++++++++++++++++++- .../root/services/packetCommandProcessor.py | 18 +++++++++++++++++ .../root/services/servicesCommandProcessor.py | 18 +++++++++++++++++ .../root/tdmConnectionsCommandProcessor.py | 4 ++++ .../unit/logport/logportsCommandProcessor.py | 4 ++++ .../logport/port/logportCommandProcessor.py | 4 ++++ .../unit/port/chan/chanCommandProcessor.py | 4 ++++ .../interface/interfaceCommandProcessor.py | 4 ++++ .../root/unit/port/portCommandProcessor.py | 4 ++++ .../port/portgroupportCommandProcessor.py | 4 ++++ .../portgroup/portgroupCommandProcessor.py | 4 ++++ .../root/unit/unitCommandProcessor.py | 4 ++++ vendors/KeyMile/baseCommandProcessor.py | 10 ++++++++++ 16 files changed, 113 insertions(+), 1 deletion(-) diff --git a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py index cf866dc..ea461fb 100644 --- a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py @@ -32,5 +32,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py index 5cad2b8..c724daf 100644 --- a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py @@ -34,5 +34,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 1fd5799..3b245f4 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -36,6 +36,10 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py index d93320a..42dbfba 100644 --- a/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py @@ -25,4 +25,22 @@ class MacAccessCtrlCommandProcessor(BaseCommandProcessor): from .macAccessCtrlManagementFunctions import status def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + try: + super().set(command, *args, context=None) + except exceptions.CommandExecutionError: + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + # TODO test case + return + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py index 1413d30..a8dffac 100644 --- a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py @@ -23,3 +23,21 @@ class PacketCommandProcessor(BaseCommandProcessor): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + try: + super().set(command, *args, context=None) + except exceptions.CommandExecutionError: + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + # TODO test case + return + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py index 98da567..47ca719 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -25,3 +25,21 @@ class ServicesCommandProcessor(BaseCommandProcessor): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + + def set(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + try: + super().set(command, *args, context=None) + except exceptions.CommandExecutionError: + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + # TODO test case + return + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py index b230d5c..15fe3fd 100644 --- a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py @@ -31,5 +31,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index cee387f..9e76d86 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -42,5 +42,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 382a1e0..193cfe5 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -51,6 +51,10 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + # TODO test case + return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index c3f3e2b..288e2db 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -48,5 +48,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index 4deae4d..1073477 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -33,5 +33,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 585ac74..e620c73 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -69,5 +69,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index f603a08..eee4a76 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -64,6 +64,10 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + # TODO test case + return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index b9dfef6..a129baa 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -41,5 +41,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index ecf05a1..f798367 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -187,5 +187,9 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'test', str): + ip, = self._dissect(args, 'test', str) + #TODO test case + return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 33041c3..4777e1d 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -384,6 +384,16 @@ def get_parent_and_child_relation(self, search, parent=None, node=None, parent_k return ([], []) def do_set(self, command, *args, context=None): + if len(args) == 0: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + elif args[0].count('/') > 0 or args[0].count('.') > 0: + proc = self.change_directory(args[0], context=context) + # ToDO: is set ../properties true possible?? + proc.set(command, *args[1:], context=context) + elif args[0].count('/') == 0: + self.set(command, *args, context=context) + return def set(self, command, *args, context=None): From 544459b32639902123aa64c3f7d8b1d0b87bd783 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 8 Oct 2020 13:42:35 +0200 Subject: [PATCH 220/318] Empty cards now get displayed when ls'ing on root layer, if no port is underneath a card there is no longer the option to cd into a non existing port --- .../accessPoints/root/rootCommandProcessor.py | 21 +++++++++++++++++++ vendors/KeyMile/baseCommandProcessor.py | 7 +++++++ 2 files changed, 28 insertions(+) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 3b245f4..9ecee4d 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -30,6 +30,27 @@ def _init_access_points(self, context=None): continue self.access_points += ('unit-' + card.name,) + first_unit = 0 + unit_count = 0 + if self._model.version == '2500': + first_unit = 1 + unit_count = 21 + elif self._model.version == '2300': + first_unit = 7 + unit_count = 8 + elif self._model.version == '2200': + first_unit = 9 + unit_count = 4 + + for i in range(first_unit, first_unit + unit_count): + if 'unit-' + str(i) in self.access_points: + continue + + if 'unit-' + str(i - 1) not in self.access_points: + self.access_points += (i,) + else: + self.access_points = self.access_points[:self.access_points.index('unit-' + str(i - 1)) + 1] + ('unit-' + str(i),) + self.access_points[self.access_points.index('unit-' + str(i - 1)) + 1:] + def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 4777e1d..07b96a5 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -183,6 +183,7 @@ def do_ls(self, command, *args, context=None): tmp_cmdproc = self.change_directory(path, context=context) tmp_cmdproc.ls(context=context, path_type='component_path') except exceptions.CommandExecutionError: + context['component_path'] = context['path'] raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) context['component_path'] = context['path'] else: @@ -271,6 +272,12 @@ def change_directory(self, path, context=None): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'port': + try: + self._model.get_port('name', self.component_id + '/' + component_id) + except exceptions.InvalidInputError: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if self.__name__ != 'unit' and self.__name__ != 'portgroup': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty From 6b0bdcd5c7726af78300af31d1e6e3bee4790e26 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 8 Oct 2020 14:18:05 +0200 Subject: [PATCH 221/318] added first set functionality for up down --- .../root/unit/port/portCommandProcessor.py | 28 ++++++++++++++----- .../root/unit/unitCommandProcessor.py | 18 ++++-------- vendors/KeyMile/baseCommandProcessor.py | 14 +++++++--- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index e620c73..1f3aa64 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -26,8 +26,7 @@ class PortCommandProcessor(BaseCommandProcessor): from .portManagementFunctions import status def do_get(self, command, *args, context=None): - port_name = context['unit'] + '/' + context['port'] - port = self._model.get_port('name', port_name) + port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -38,7 +37,9 @@ def do_get(self, command, *args, context=None): text = self._render('attainable_rate', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': - text = self._render('administrative_status', *scopes, context=context) + self.map_states(port, 'port') + context['spacer'] = self.create_spacers((67,), (port.admin_state,))[0] * ' ' + text = self._render('administrative_status', *scopes, context=dict(context, port=port)) self._write(text) elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': self.map_states(port, 'port') @@ -62,16 +63,29 @@ def _init_access_points(self, context=None): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + def get_port_component(self): + return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') + print(context['path']) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return + elif self._validate(args, 'AdministrativeStatus', str) and context['path'].split('/')[-1] == 'main': + state, = self._dissect(args, 'AdministrativeStatus', str) + try: + port = self.get_port_component() + if state == 'up': + port.admin_up() + elif state == 'down': + port.admin_down() + else: + raise exceptions.SoftboxenError() + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index f798367..6e3cf72 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -41,7 +41,7 @@ def _init_access_points(self, context=None): # todo: add portgroup to access_points def do_get(self, command, *args, context=None): - card = self._model.get_card('name', context['unit']) + card = self._model.get_card('name', self.component_id) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -50,9 +50,7 @@ def do_get(self, command, *args, context=None): raise exc elif self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ - (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', - context[ - 'unit']).product == 'analog'): + (card.product == 'isdn' or card.product == 'analog'): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: @@ -67,16 +65,12 @@ def do_get(self, command, *args, context=None): text += self._render('subscriberList_bottom', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'SIP') and context['path'].split('/')[-1] == 'cfgm' and \ - (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', - context[ - 'unit']).product == 'analog'): + (card.product == 'isdn' or card.product == 'analog'): # TODO: dynamic fields text = self._render('sip', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'IP') and context['path'].split('/')[-1] == 'cfgm' and \ - (self._model.get_card('name', context['unit']).product == 'isdn' or self._model.get_card('name', - context[ - 'unit']).product == 'analog'): + (card.product == 'isdn' or card.product == 'analog'): # TODO: dynamic fields text = self._render('ip', *scopes, context=context) self._write(text) @@ -187,8 +181,8 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) + elif self._validate(args, 'CurrentStatus', 'test', str): + ip, = self._dissect(args, 'CurrentStatus', 'test', str) #TODO test case return else: diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 07b96a5..fdda854 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -319,6 +319,9 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import PortgroupPortCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') + if component_id is not None and self.component_id is not None: + subprocessor.set_component_id(self.component_id + '/' + component_id) + if component_id is not None: subprocessor.set_component_id(component_id) @@ -394,10 +397,13 @@ def do_set(self, command, *args, context=None): if len(args) == 0: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif args[0].count('/') > 0 or args[0].count('.') > 0: - proc = self.change_directory(args[0], context=context) - # ToDO: is set ../properties true possible?? - proc.set(command, *args[1:], context=context) + elif args[0].count('/') > 0: + path = '' + for el in args[0].split('/')[:-1]: + path += el + '/' + proc = self.change_directory(str(path[:-1]), context=context) + res =(args[0].split('/')[-1],) + args[1:] + proc.set(command, *res, context=context) elif args[0].count('/') == 0: self.set(command, *args, context=context) From b8f2de39c4e4ddaac3c24899b8783db42fac0203 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Thu, 8 Oct 2020 15:49:54 +0200 Subject: [PATCH 222/318] Sneakily removing some prints out of Huawei command processors --- vendors/Huawei/configCommandProcessor.py | 1 - vendors/Huawei/vlanSrvprofCommandProcessor.py | 1 - 2 files changed, 2 deletions(-) diff --git a/vendors/Huawei/configCommandProcessor.py b/vendors/Huawei/configCommandProcessor.py index 2427165..2b8821f 100644 --- a/vendors/Huawei/configCommandProcessor.py +++ b/vendors/Huawei/configCommandProcessor.py @@ -1029,7 +1029,6 @@ def do_port(self, command, *args, context=None): def do_xdsl(self, command, *args, context=None): if self._validate(args, 'vectoring-group', 'link', 'add', str, str): profile_idx, port_idx = self._dissect(args, 'vectoring-group', 'link', 'add', str, str) - print(port_idx) portname = port_idx[0:3] + '/' + port_idx[4] try: diff --git a/vendors/Huawei/vlanSrvprofCommandProcessor.py b/vendors/Huawei/vlanSrvprofCommandProcessor.py index 0677d3d..0a46789 100644 --- a/vendors/Huawei/vlanSrvprofCommandProcessor.py +++ b/vendors/Huawei/vlanSrvprofCommandProcessor.py @@ -100,7 +100,6 @@ def do_igmp(self, command, *args, context=None): def do_pitp(self, command, *args, context=None): if self._validate(args, 'enable'): self._model.set_pitp('enable') - print(context['srvprof'].vlan_mac) text = self._render('please_wait_commit', context=context) self._write(text) From 711f1e31d02f43bb7a678b05d617ea56358dc235 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Thu, 8 Oct 2020 15:50:34 +0200 Subject: [PATCH 223/318] Added global get function --- .../accessPoints/root/rootCommandProcessor.py | 6 +- .../root/unit/port/portCommandProcessor.py | 17 +++-- .../root/unit/unitCommandProcessor.py | 26 +++++--- vendors/KeyMile/baseCommandProcessor.py | 66 +++++++++++++++---- 4 files changed, 84 insertions(+), 31 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 9ecee4d..0e465c6 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -66,4 +66,8 @@ def set(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors')) def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file + raise exceptions.CommandSyntaxError(command=command) + + def get_property(self, command, *args, context=None): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 1f3aa64..3fa69b0 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -25,23 +25,27 @@ class PortCommandProcessor(BaseCommandProcessor): from .portManagementFunctions import pm from .portManagementFunctions import status - def do_get(self, command, *args, context=None): - port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + def get_property(self, command, *args, context=None): + port_name = self._parent.component_id + '/' + self.component_id + port = self._model.get_port('name', port_name) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': + elif self._validate(args, 'AttainableRate') and (context['path'].split('/')[-1] == 'status' + or context['component_path'].split('/')[-1] == 'status'): text = self._render('attainable_rate', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': + elif self._validate(args, 'AdministrativeStatus') and (context['path'].split('/')[-1] == 'main' + or context['component_path'].split('/')[-1] == 'main'): self.map_states(port, 'port') context['spacer'] = self.create_spacers((67,), (port.admin_state,))[0] * ' ' text = self._render('administrative_status', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': + elif self._validate(args, 'OperationalStatus') and (context['path'].split('/')[-1] == 'main' + or context['component_path'].split('/')[-1] == 'main'): self.map_states(port, 'port') port_operational_state = port.operational_state context['port_operational_state'] = port_operational_state @@ -49,7 +53,8 @@ def do_get(self, command, *args, context=None): text = self._render('operational_status', *scopes, context=context) self._write(text) else: - raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) def _init_access_points(self, context=None): port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 6e3cf72..21aa15c 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -40,7 +40,7 @@ def _init_access_points(self, context=None): # todo: add portgroup to access_points - def do_get(self, command, *args, context=None): + def get_property(self, command, *args, context=None): card = self._model.get_card('name', self.component_id) scopes = ('login', 'base', 'get') if self._validate(args, *()): @@ -49,8 +49,9 @@ def do_get(self, command, *args, context=None): exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ - (card.product == 'isdn' or card.product == 'analog'): + elif self._validate(args, 'SubscriberList') and (context['path'].split('/')[-1] == 'status' + or context['component_path'].split('/')[-1] == 'status') \ + and (card.product == 'isdn' or card.product == 'analog'): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: @@ -64,18 +65,21 @@ def do_get(self, command, *args, context=None): text += self._render('subscriberList_item', *scopes, context=dict(context, subscriber=subscriber)) text += self._render('subscriberList_bottom', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'SIP') and context['path'].split('/')[-1] == 'cfgm' and \ - (card.product == 'isdn' or card.product == 'analog'): + elif self._validate(args, 'SIP') and (context['path'].split('/')[-1] == 'cfgm' + or context['component_path'].split('/')[-1] == 'cfgm') \ + and (card.product == 'isdn' or card.product == 'analog'): # TODO: dynamic fields text = self._render('sip', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'IP') and context['path'].split('/')[-1] == 'cfgm' and \ - (card.product == 'isdn' or card.product == 'analog'): + elif self._validate(args, 'IP') and (context['path'].split('/')[-1] == 'cfgm' + or context['component_path'].split('/')[-1] == 'cfgm') \ + and (card.product == 'isdn' or card.product == 'analog'): # TODO: dynamic fields text = self._render('ip', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'HardwareAndSoftware') and context['path'].split('/')[-1] == 'main': + elif self._validate(args, 'HardwareAndSoftware') and (context['path'].split('/')[-1] == 'main' + or context['component_path'].split('/')[-1] == 'main'): unit_hardware = '"' + card.board_name + '"' context['unit_hardware'] = unit_hardware context['spacer_1'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' @@ -100,7 +104,8 @@ def do_get(self, command, *args, context=None): text = self._render('hardware_and_software', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'CurrentStatus') and context['path'].split('/')[-1] == 'main': + elif self._validate(args, 'CurrentStatus') and (context['path'].split('/')[-1] == 'main' + or context['component_path'].split('/')[-1] == 'main'): unit_state = card.state context['unit_state'] = unit_state context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' @@ -122,7 +127,8 @@ def do_get(self, command, *args, context=None): text = self._render('current_status', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'EquipmentInventory') and context['path'].split('/')[-1] == 'main': + elif self._validate(args, 'EquipmentInventory') and (context['path'].split('/')[-1] == 'main' + or context['component_path'].split('/')[-1] == 'main'): unit_symbol = '"' + card.board_name + '"' context['unit_symbol'] = unit_symbol context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index fdda854..d0d4078 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -96,7 +96,7 @@ def do_help(self, command, *args, context=None): self._write(self._render('help_exit', *help_scopes, context=context)) else: raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args,): + elif self._validate(args, ): self._write(self._render('help', *help_scopes, context=context)) else: raise exceptions.CommandSyntaxError(command=command) @@ -142,7 +142,6 @@ def generate_ls_text(layers, depth): for property in layers[layer]: context['prop_name'] = property - if prop_type in ('File', 'Prop'): context['prop_rw_rights'] = layers[layer].get(property, '') else: @@ -184,7 +183,10 @@ def do_ls(self, command, *args, context=None): tmp_cmdproc.ls(context=context, path_type='component_path') except exceptions.CommandExecutionError: context['component_path'] = context['path'] - raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + context['component_path'] = context['path'] else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', @@ -218,9 +220,13 @@ def change_directory(self, path, context=None): if re.search('\.\./(?:[^.]+/)+\.\.', path): if path.endswith('..'): - raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) else: - raise exceptions.CommandExecutionError(template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + raise exceptions.CommandExecutionError(template='invalid_address_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) if path.startswith('..'): splitted_path = [x for x in context['component_path'].split('/') if x] @@ -240,8 +246,10 @@ def change_directory(self, path, context=None): return self._parent.change_directory(path[3:], context=context) if path.startswith('/'): - if 'unit-' not in components[0] and components[0] not in ('eoam', 'fan', 'multicast', 'services', 'tdmConnection', 'main', 'cfgm', 'fm', 'pm', 'status'): - raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + if 'unit-' not in components[0] and components[0] not in ( + 'eoam', 'fan', 'multicast', 'services', 'tdmConnection', 'main', 'cfgm', 'fm', 'pm', 'status'): + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty if self.__name__ != 'root': subprocessor = self._parent.change_directory(path, context=context) @@ -315,8 +323,10 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import PortgroupCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import PortgroupPortCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import \ + PortgroupCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import \ + PortgroupPortCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if component_id is not None and self.component_id is not None: @@ -393,6 +403,31 @@ def get_parent_and_child_relation(self, search, parent=None, node=None, parent_k else: return ([], []) + def do_get(self, command, *args, context=None): + if len(args) >= 1: + if '/' in args[0]: + path = '' + for component in args[0].split('/')[:-1]: + path += component + '/' + prop = args[0].split('/')[-1] + try: + tmp_cmdproc = self.change_directory(path, context=context) + tmp_cmdproc.get_property(command, prop, context=context) + except exceptions.CommandExecutionError: + raise exceptions.CommandExecutionError(template='syntax_error', + template_scopes=('login', 'base', 'syntax_errors'), + command=None) + else: + self.get_property(command, args[0], context=context) + else: + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + + def get_property(self, command, *args, context=None): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + def do_set(self, command, *args, context=None): if len(args) == 0: raise exceptions.CommandExecutionError(command=command, template='invalid_property', @@ -402,7 +437,7 @@ def do_set(self, command, *args, context=None): for el in args[0].split('/')[:-1]: path += el + '/' proc = self.change_directory(str(path[:-1]), context=context) - res =(args[0].split('/')[-1],) + args[1:] + res = (args[0].split('/')[-1],) + args[1:] proc.set(command, *res, context=context) elif args[0].count('/') == 0: self.set(command, *args, context=context) @@ -410,7 +445,7 @@ def do_set(self, command, *args, context=None): return def set(self, command, *args, context=None): - #interface method + # interface method return def do_cd(self, command, *args, context=None): @@ -424,7 +459,9 @@ def do_cd(self, command, *args, context=None): return_to = self.get_command_processor(subprocessor) except: context['component_path'] = context['path'] - raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) context['path'] = context['component_path'] subprocessor.loop(context=context, return_to=return_to) else: @@ -447,7 +484,8 @@ def get_command_processor(self, current_processor, component_type=None): from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor if current_processor.__class__ == RootCommandProcessor: return_to = RootCommandProcessor - if component_type not in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services', 'unit') and component_type is not None: + if component_type not in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services', 'unit') \ + and component_type is not None: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif current_processor.__class__ == UnitCommandProcessor: @@ -489,4 +527,4 @@ def do_exit(self, command, *args, context=None): raise exc def _init_access_points(self, context=None): - pass # Abstract method not implemented + pass # Abstract method not implemented From 3f8edfd7d39830b30072c062386b15cf08bae599 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 8 Oct 2020 16:36:03 +0200 Subject: [PATCH 224/318] added set and get functionality for labels on ports and units --- .../api/schemas/keymile_card_schemas.py | 2 +- .../api/schemas/keymile_port_schemas.py | 4 +- .../keymile/keymile_resources/keymile_card.py | 7 ++++ .../keymile/keymile_resources/keymile_port.py | 7 ++++ nesi/softbox/api/models/card_models.py | 4 +- nesi/softbox/api/models/port_models.py | 4 +- templates/KeyMile/login/base/get/labels.j2 | 5 +++ .../root/unit/port/portCommandProcessor.py | 26 +++++++++---- .../port/portgroupportCommandProcessor.py | 6 +-- .../root/unit/unitCommandProcessor.py | 37 ++++++++++++------- 10 files changed, 73 insertions(+), 29 deletions(-) create mode 100644 templates/KeyMile/login/base/get/labels.j2 diff --git a/nesi/keymile/api/schemas/keymile_card_schemas.py b/nesi/keymile/api/schemas/keymile_card_schemas.py index eb4344d..7b658b8 100644 --- a/nesi/keymile/api/schemas/keymile_card_schemas.py +++ b/nesi/keymile/api/schemas/keymile_card_schemas.py @@ -20,4 +20,4 @@ class Meta: 'software_name', 'software_revision', 'state', 'serial_number', 'manufacturer_name', 'model_name', 'short_text', 'manufacturer_id', 'manufacturer_part_number', 'manufacturer_build_state', 'customer_id', - 'customer_product_id', 'boot_loader', 'processor') + 'customer_product_id', 'boot_loader', 'processor', 'label1', 'label2') diff --git a/nesi/keymile/api/schemas/keymile_port_schemas.py b/nesi/keymile/api/schemas/keymile_port_schemas.py index 667b9c6..c8a1f07 100644 --- a/nesi/keymile/api/schemas/keymile_port_schemas.py +++ b/nesi/keymile/api/schemas/keymile_port_schemas.py @@ -16,6 +16,6 @@ class KeyMilePortSchema(PortSchema): class Meta: model = Port - fields = PortSchema.Meta.fields + ('channels',) + fields = PortSchema.Meta.fields + ('channels', 'label1', 'label2') - channels = ma.Nested(CpesSchema.CpeSchema, many=True) \ No newline at end of file + channels = ma.Nested(CpesSchema.CpeSchema, many=True) diff --git a/nesi/keymile/keymile_resources/keymile_card.py b/nesi/keymile/keymile_resources/keymile_card.py index 8370b93..7680fbc 100644 --- a/nesi/keymile/keymile_resources/keymile_card.py +++ b/nesi/keymile/keymile_resources/keymile_card.py @@ -38,6 +38,13 @@ class KeyMileCard(Card): customer_product_id = base.Field('customer_product_id') boot_loader = base.Field('boot_loader') processor = base.Field('processor') + label1 = base.Field('label1') + label2 = base.Field('label2') + + def set_label(self, l1, l2, desc): + self.update(label1=l1) + self.update(label2=l2) + self.update(description=desc) class KeyMileCardCollection(CardCollection): diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py index c84be0b..ea36140 100644 --- a/nesi/keymile/keymile_resources/keymile_port.py +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -17,6 +17,13 @@ class KeyMilePort(Port): """Represent physical port resource.""" + label1 = base.Field('label1') + label2 = base.Field('label2') + + def set_label(self, l1, l2, desc): + self.update(label1=l1) + self.update(label2=l2) + self.update(description=desc) class KeyMilePortCollection(PortCollection): diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index 2d0a4d7..aa1855f 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -27,7 +27,7 @@ class Card(db.Model): nullable=False, default='vdsl') # Alcatel specific data - description = db.Column(db.String(), default='None') + description = db.Column(db.String(), default='""') position = db.Column(db.String()) entry_vlan_number = db.Column(db.Integer()) planned_type = db.Column(db.Enum('rdlt-c', 'rant-a', 'nant-a', 'nrnt-a', 'fant-f', 'relt-a', 'nelt-b', 'fglt-b', @@ -101,3 +101,5 @@ class Card(db.Model): customer_product_id = db.Column(db.String(), default='') boot_loader = db.Column(db.String(), default='') processor = db.Column(db.String(), default='') + label1 = db.Column(db.String(), default='""') + label2 = db.Column(db.String(), default='""') diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 17c9bbe..1705e0c 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -27,7 +27,7 @@ class Port(db.Model): cpes = db.relationship('Cpe', backref='Port', lazy='dynamic') # Alcatel data - description = db.Column(db.String()) + description = db.Column(db.String(), default='') type = db.Column(db.Enum('pon', 'ethernet-line'), default='pon') shutdown = db.Column(db.Boolean(), default=False) speed = db.Column(db.Enum('10M', '1G', '10G'), default='1G') @@ -311,3 +311,5 @@ class Port(db.Model): # KeyMile channels = db.relationship('Channel', backref='Port', lazy='dynamic') interfaces = db.relationship('Interface', backref='Port', lazy='dynamic') + label1 = db.Column(db.String(), default='""') + label2 = db.Column(db.String(), default='""') diff --git a/templates/KeyMile/login/base/get/labels.j2 b/templates/KeyMile/login/base/get/labels.j2 new file mode 100644 index 0000000..d8b257f --- /dev/null +++ b/templates/KeyMile/login/base/get/labels.j2 @@ -0,0 +1,5 @@ + \ # Labels +{{ context.port.label1 | safe }}{{ context.spacer1 }}\ # Label1 +{{ context.port.label2 | safe }}{{ context.spacer2 }}\ # Label2 +{{ context.port.description | safe }}{{ context.spacer3 }}\ # Description + diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 3fa69b0..0363cef 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -34,18 +34,21 @@ def get_property(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'AttainableRate') and (context['path'].split('/')[-1] == 'status' - or context['component_path'].split('/')[-1] == 'status'): + elif self._validate((args[0],), 'AttainableRate') and context['component_path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) - elif self._validate(args, 'AdministrativeStatus') and (context['path'].split('/')[-1] == 'main' - or context['component_path'].split('/')[-1] == 'main'): + elif self._validate((args[0],), 'AdministrativeStatus') and context['component_path'].split('/')[-1] == 'main': self.map_states(port, 'port') context['spacer'] = self.create_spacers((67,), (port.admin_state,))[0] * ' ' text = self._render('administrative_status', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate(args, 'OperationalStatus') and (context['path'].split('/')[-1] == 'main' - or context['component_path'].split('/')[-1] == 'main'): + elif self._validate(args, 'Labels') and context['component_path'].split('/')[-1] == 'main': + context['spacer1'] = self.create_spacers((67,), (port.label1,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (port.label2,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (port.description,))[0] * ' ' + text = self._render('labels', *scopes, context=dict(context, port=port)) + self._write(text) + elif self._validate((args[0],), 'OperationalStatus') and context['component_path'].split('/')[-1] == 'main': self.map_states(port, 'port') port_operational_state = port.operational_state context['port_operational_state'] = port_operational_state @@ -73,13 +76,12 @@ def get_port_component(self): def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') - print(context['path']) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'AdministrativeStatus', str) and context['path'].split('/')[-1] == 'main': + elif self._validate(args, 'AdministrativeStatus', str) and context['component_path'].split('/')[-1] == 'main': state, = self._dissect(args, 'AdministrativeStatus', str) try: port = self.get_port_component() @@ -92,5 +94,13 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'Labels', str, str, str) and context['component_path'].split('/')[-1] == 'main': + label1, label2, description = self._dissect(args, 'Labels', str, str, str) + try: + port = self.get_port_component() + port.set_label(label1, label2, description) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index eee4a76..d0a5072 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -28,8 +28,8 @@ def do_get(self, command, *args, context=None): try: super().do_get(command, *args, context=None) except exceptions.CommandExecutionError: - if self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ - self._model.get_card('name', context['unit']).product == 'isdn': + if self._validate((args[0],), 'SubscriberList') and context['component_path'].split('/')[-1] == 'status' and \ + self._model.get_card('name', self._parent._parent.component_id).product == 'isdn': text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: @@ -49,7 +49,7 @@ def do_get(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors')) def _init_access_points(self, context=None): - port = self._model.get_port('name', context['unit'] + '/' + context['portgroup'] + '/' + context['port']) + port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 21aa15c..1b1dbdb 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -49,9 +49,8 @@ def get_property(self, command, *args, context=None): exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'SubscriberList') and (context['path'].split('/')[-1] == 'status' - or context['component_path'].split('/')[-1] == 'status') \ - and (card.product == 'isdn' or card.product == 'analog'): + elif self._validate(args, 'SubscriberList') and context['component_path'].split('/')[-1] == 'status' and \ + (card.product == 'isdn' or card.product == 'analog'): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: @@ -65,19 +64,24 @@ def get_property(self, command, *args, context=None): text += self._render('subscriberList_item', *scopes, context=dict(context, subscriber=subscriber)) text += self._render('subscriberList_bottom', *scopes, context=context) self._write(text) - elif self._validate(args, 'SIP') and (context['path'].split('/')[-1] == 'cfgm' - or context['component_path'].split('/')[-1] == 'cfgm') \ - and (card.product == 'isdn' or card.product == 'analog'): + elif self._validate(args, 'SIP') and context['component_path'].split('/')[-1] == 'cfgm' and \ + (card.product == 'isdn' or card.product == 'analog'): # TODO: dynamic fields text = self._render('sip', *scopes, context=context) self._write(text) - elif self._validate(args, 'IP') and (context['path'].split('/')[-1] == 'cfgm' - or context['component_path'].split('/')[-1] == 'cfgm') \ - and (card.product == 'isdn' or card.product == 'analog'): + elif self._validate(args, 'IP') and context['component_path'].split('/')[-1] == 'cfgm' and \ + (card.product == 'isdn' or card.product == 'analog'): # TODO: dynamic fields text = self._render('ip', *scopes, context=context) self._write(text) + elif self._validate(args, 'Labels') and context['component_path'].split('/')[-1] == 'main': + context['spacer1'] = self.create_spacers((67,), (card.label1,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (card.label2,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (card.description,))[0] * ' ' + text = self._render('labels', *scopes, context=dict(context, port=card)) + self._write(text) + elif self._validate(args, 'HardwareAndSoftware') and (context['path'].split('/')[-1] == 'main' or context['component_path'].split('/')[-1] == 'main'): unit_hardware = '"' + card.board_name + '"' @@ -181,15 +185,22 @@ def get_property(self, command, *args, context=None): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + def get_component(self): + return self._model.get_card('name', self.component_id) + def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'CurrentStatus', 'test', str): - ip, = self._dissect(args, 'CurrentStatus', 'test', str) - #TODO test case - return + elif self._validate(args, 'Labels', str, str, str) and context['component_path'].split('/')[-1] == 'main': + label1, label2, description = self._dissect(args, 'Labels', str, str, str) + try: + component = self.get_component() + component.set_label(label1, label2, description) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) else: raise exceptions.CommandSyntaxError(command=command) From 0ecef0cf6af7dd81762638e35595b94619b6e73f Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 9 Oct 2020 10:36:21 +0200 Subject: [PATCH 225/318] Minor code adjustments --- .../accessPoints/root/unit/unitCommandProcessor.py | 9 +++------ vendors/KeyMile/baseCommandProcessor.py | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 1b1dbdb..ef7afcd 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -82,8 +82,7 @@ def get_property(self, command, *args, context=None): text = self._render('labels', *scopes, context=dict(context, port=card)) self._write(text) - elif self._validate(args, 'HardwareAndSoftware') and (context['path'].split('/')[-1] == 'main' - or context['component_path'].split('/')[-1] == 'main'): + elif self._validate(args, 'HardwareAndSoftware') and context['component_path'].split('/')[-1] == 'main': unit_hardware = '"' + card.board_name + '"' context['unit_hardware'] = unit_hardware context['spacer_1'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' @@ -108,8 +107,7 @@ def get_property(self, command, *args, context=None): text = self._render('hardware_and_software', *scopes, context=context) self._write(text) - elif self._validate(args, 'CurrentStatus') and (context['path'].split('/')[-1] == 'main' - or context['component_path'].split('/')[-1] == 'main'): + elif self._validate(args, 'CurrentStatus') and context['component_path'].split('/')[-1] == 'main': unit_state = card.state context['unit_state'] = unit_state context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' @@ -131,8 +129,7 @@ def get_property(self, command, *args, context=None): text = self._render('current_status', *scopes, context=context) self._write(text) - elif self._validate(args, 'EquipmentInventory') and (context['path'].split('/')[-1] == 'main' - or context['component_path'].split('/')[-1] == 'main'): + elif self._validate(args, 'EquipmentInventory') and context['component_path'].split('/')[-1] == 'main': unit_symbol = '"' + card.board_name + '"' context['unit_symbol'] = unit_symbol context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index d0d4078..9238279 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -351,7 +351,7 @@ def change_directory(self, path, context=None): parent := string keyword to describe the parent of search like "root" node := contains the dict tree or None for default tree structure - parent_keys := should be None / important for rekursive call + parent_keys := should be None / important for recursive call return := Tuple of (ParentList, ChildList) or ([],[]) ''' From 3c84cb28950e480ba7ebd1ef50af7c8cc008ad97 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 13 Oct 2020 10:54:35 +0200 Subject: [PATCH 226/318] create portgroupports --- .../conf/bootstraps/create-keymile-MG2500.sh | 15 +---- nesi/keymile/keymile_resources/__init__.py | 2 +- nesi/keymile/keymile_resources/keymile_box.py | 18 ++++++ .../keymile_portgroupport.py | 58 +++++++++++++++++++ nesi/softbox/api/models/box_models.py | 2 + .../api/models/portgroupport_models.py | 13 +++++ .../api/schemas/portgroupport_schemas.py | 48 +++++++++++++++ .../softbox/api/schemas/subscriber_schemas.py | 2 +- nesi/softbox/api/views/__init__.py | 2 +- nesi/softbox/api/views/portgroupport_views.py | 53 +++++++++++++++++ 10 files changed, 198 insertions(+), 15 deletions(-) create mode 100644 nesi/keymile/keymile_resources/keymile_portgroupport.py create mode 100644 nesi/softbox/api/models/portgroupport_models.py create mode 100644 nesi/softbox/api/schemas/portgroupport_schemas.py create mode 100644 nesi/softbox/api/views/portgroupport_views.py diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 06f1a66..8f992ab 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -125,15 +125,6 @@ req='{ subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) -# test subscriber -req='{ - "name": "tester2", - "number": 90223, - "type": "unit" -}' - -subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) - ### Subrack 0 ### # Create a physical subrack at the network device (admin operation) @@ -443,14 +434,14 @@ req='{ unit_19=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) -### Port-1 ### +### PortGroupPort-1 ### # Create a physical port at the network device (admin operation) req='{ "card_id": '$unit_19', "admin_state": "1", "operational_state": "1", - "name": "19/1/1" + "name": "19/G1/1" }' -port_19_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) \ No newline at end of file +port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) \ No newline at end of file diff --git a/nesi/keymile/keymile_resources/__init__.py b/nesi/keymile/keymile_resources/__init__.py index 17f26e0..fcea829 100644 --- a/nesi/keymile/keymile_resources/__init__.py +++ b/nesi/keymile/keymile_resources/__init__.py @@ -1,2 +1,2 @@ __all__ = ["keymile_card", "keymile_port", "keymile_subrack", "keymile_channel", "keymile_interface", - "keymile_subscriber"] + "keymile_subscriber", "keymile_portgroupport"] diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 178a817..d800261 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -59,6 +59,12 @@ def subscribers(self): return keymile_subscriber.KeymileSubscriberCollection( self._conn, base.get_sub_resource_path_by(self, 'subscribers')) + @property + def portgroupsports(self): + """Return `PortgrouportCollection` object.""" + return keymile_portgroupport.KeymilePortGroupPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'portgrouports')) + def get_card(self, field, value): """Get specific card object.""" return keymile_card.KeyMileCardCollection( @@ -118,6 +124,18 @@ def get_subscribers(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'subscribers'), params={field: value}) + def get_portgroupport(self, field, value): + """Get specific portgroupport object.""" + return keymile_portgroupport.KeymilePortGroupPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'portgroupports'), + params={field: value}).find_by_field_value(field, value) + + def get_portgroupports(self, field, value): + """Get specific portgroupports object.""" + return keymile_portgroupport.KeymilePortGroupPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'portgroupports'), + params={field: value}) + class KeyMileBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/keymile/keymile_resources/keymile_portgroupport.py b/nesi/keymile/keymile_resources/keymile_portgroupport.py new file mode 100644 index 0000000..fa976d3 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_portgroupport.py @@ -0,0 +1,58 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.service_port import logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class KeymilePortGroupPort(base.Resource): + """Represent logical subscriber resource.""" + + # fields + id = base.Field('id') + name = base.Field('name') + operational_state = base.Field('operational_state') + admin_state = base.Field('admin_state') + description = base.Field('description') + label1 = base.Field('label1') + label2 = base.Field('label2') + + def set_label(self, l1, l2, desc): + self.update(label1=l1) + self.update(label2=l2) + self.update(description=desc) + + def admin_up(self): + """Set the admin port state to up""" + self.update(admin_state='1') + + def admin_down(self): + """Set the admin port state to down""" + self.update(admin_state='0') + + def down(self): + """Set the port state to down""" + self.update(operational_state='0') + + def up(self): + """Set the port state to down""" + self.update(operational_state='1') + + +class KeymilePortGroupPortCollection(base.ResourceCollection): + """Represent a collection of logical subscribers.""" + + @property + def _resource_type(self): + return KeymilePortGroupPort diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 3540487..af447ad 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -29,6 +29,7 @@ from .user_models import User from .channel_models import Channel from .subscriber_models import Subscriber +from .portgroupport_models import PortGroupPort class Box(db.Model): @@ -72,6 +73,7 @@ class Box(db.Model): routes = db.relationship('Route', backref='Box', lazy='dynamic') emus = db.relationship('Emu', backref='Box', lazy='dynamic') subscribers = db.relationship('Subscriber', backref='Box', lazy='dynamic') + portgroupports = db.relationship('PortGroupPort', backref='Box', lazy='dynamic') board_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_instl_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_init_reporting_logging = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/models/portgroupport_models.py b/nesi/softbox/api/models/portgroupport_models.py new file mode 100644 index 0000000..24811ba --- /dev/null +++ b/nesi/softbox/api/models/portgroupport_models.py @@ -0,0 +1,13 @@ +from nesi.softbox.api import db + + +class PortGroupPort(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + operational_state = db.Column(db.Enum('1', '0'), default='0') # 0 => down, 1 => up + admin_state = db.Column(db.Enum('1', '0'), default='0') + description = db.Column(db.String(), default='') + label1 = db.Column(db.String(), default='""') + label2 = db.Column(db.String(), default='""') + card_id = db.Column(db.Integer, db.ForeignKey('card.id')) diff --git a/nesi/softbox/api/schemas/portgroupport_schemas.py b/nesi/softbox/api/schemas/portgroupport_schemas.py new file mode 100644 index 0000000..932f44b --- /dev/null +++ b/nesi/softbox/api/schemas/portgroupport_schemas.py @@ -0,0 +1,48 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.portgroupport_models import PortGroupPort + + +class PortGroupPortSchema(ma.ModelSchema): + class Meta: + model = PortGroupPort + fields = ('id', 'name', 'box_id', 'card_id', 'operational_state', 'admin_state', 'description', 'label1', + 'label2', '_links') + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_portgroupport', box_id='', id=''), + 'collection': ma.URLFor('show_portgroupports', box_id='')}) + + +class PortGroupPortsSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class PortGroupPortSchema(ma.ModelSchema): + class Meta: + model = PortGroupPort + fields = ('id', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_portgroupport', box_id='', id='')}) + + members = ma.Nested(PortGroupPortSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_portgroupports', box_id='')}) diff --git a/nesi/softbox/api/schemas/subscriber_schemas.py b/nesi/softbox/api/schemas/subscriber_schemas.py index 25b65d6..3efa31c 100644 --- a/nesi/softbox/api/schemas/subscriber_schemas.py +++ b/nesi/softbox/api/schemas/subscriber_schemas.py @@ -32,7 +32,7 @@ class SubscribersSchema(ma.ModelSchema): class Meta: fields = ('members', 'count', '_links') - class EmuSchema(ma.ModelSchema): + class SubscriberSchema(ma.ModelSchema): class Meta: model = Subscriber fields = ('id', '_links') diff --git a/nesi/softbox/api/views/__init__.py b/nesi/softbox/api/views/__init__.py index edde876..2bc77b7 100644 --- a/nesi/softbox/api/views/__init__.py +++ b/nesi/softbox/api/views/__init__.py @@ -2,4 +2,4 @@ "ontport_views", "cpe_views", "cpeport_views", "vlan_views", "portprofile_views", "emu_views", "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views", - "mgmt_card_views", "mgmt_port_views", "subscriber_views"] + "mgmt_card_views", "mgmt_port_views", "subscriber_views", "portgroupport_views"] diff --git a/nesi/softbox/api/views/portgroupport_views.py b/nesi/softbox/api/views/portgroupport_views.py new file mode 100644 index 0000000..3f452a3 --- /dev/null +++ b/nesi/softbox/api/views/portgroupport_views.py @@ -0,0 +1,53 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from ..schemas.portgroupport_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//portgroupports', methods=['GET']) +def show_portgroupports(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(PortGroupPortsSchema(), PortGroupPort, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//portgroupports/', methods=['GET']) +def show_portgroupport(box_id, id): + response = show_component(PortGroupPort, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//portgroupports/', methods=['PUT']) +def update_portgroupport(box_id, id): + req = flask.request.json + update_component(PortGroupPort, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//portgroupports', methods=['POST']) +def new_portgroupport(box_id): + req = flask.request.json + response = new_component(PortGroupPortSchema(), PortGroupPort, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//portgroupports/', methods=['DELETE']) +def del_portgroupport(box_id, id): + del_component(PortGroupPort, box_id, id) + return flask.Response(status=204) From 6e0c06983001bd7608379714be156d90944bad53 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 13 Oct 2020 13:48:17 +0200 Subject: [PATCH 227/318] Added portgroups and portgroupports to reachable CommandProcessors --- nesi/softbox/api/schemas/box_schemas.py | 6 +++++- .../port/portgroupportCommandProcessor.py | 4 ++-- .../unit/portgroup/portgroupCommandProcessor.py | 6 +++--- .../root/unit/unitCommandProcessor.py | 6 ++++++ vendors/KeyMile/baseCommandProcessor.py | 16 ++++++++++++++-- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index b28a8e1..87a9215 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -34,7 +34,7 @@ class Meta: 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', - 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', + 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') credentials = ma.Hyperlinks( @@ -81,6 +81,10 @@ class Meta: {'_links': { 'self': ma.URLFor('show_subscribers', box_id='')}}) + portgroupports = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_portgroupports', box_id='')}}) + onts = ma.Hyperlinks({'_links': { 'self': ma.URLFor('show_onts', box_id='')}}) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index d0a5072..706cf6c 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -14,7 +14,7 @@ from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor -class PortgroupPortCommandProcessor(PortCommandProcessor): +class PortgroupportCommandProcessor(PortCommandProcessor): __name__ = 'portgroupport' management_functions = ('main', 'cfgm', 'status') access_points = () @@ -49,7 +49,7 @@ def do_get(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors')) def _init_access_points(self, context=None): - port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + pass def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index a129baa..988535a 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -25,9 +25,9 @@ class PortgroupCommandProcessor(BaseCommandProcessor): def _init_access_points(self, context=None): # work in progress card = self._model.get_card('name', self._parent.component_id) - for port in self._model.get_ports('card_id', card.id): - if port.name.count('/') == 2 and port.name.strip('/')[1] == 'portgroup-' + self.component_id: - identifier = 'port-' + port.name.split('/')[-1] + for gport in self._model.get_portgroupports('card_id', card.id): + if gport.name.split('/')[1] == 'G' + self.component_id: + identifier = 'port-' + gport.name.split('/')[-1] if identifier in self.access_points: continue self.access_points += (identifier,) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index ef7afcd..4e8d4dd 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -35,6 +35,12 @@ def _init_access_points(self, context=None): if identifier in self.access_points: continue self.access_points += (identifier,) + + for gport in self._model.get_portgroupports('card_id', card.id): + identifier = 'portgroup-' + gport.name.split('/')[1][1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) except exceptions.InvalidInputError: pass diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 9238279..b3677f7 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -205,7 +205,7 @@ def change_directory(self, path, context=None): components = [x for x in path.split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', components[0]): raise exceptions.SoftboxenError() @@ -264,6 +264,10 @@ def change_directory(self, path, context=None): if '-' in components[0]: component_type = components[0].split('-')[0] component_id = components[0].split('-')[1] + if component_type == 'port': + if self.__name__ == 'portgroup': + component_type = 'portgroupport' + command_processor = component_type.capitalize() + 'CommandProcessor' else: command_processor = components[0].capitalize() + 'CommandProcessor' @@ -326,7 +330,7 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import \ PortgroupCommandProcessor from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import \ - PortgroupPortCommandProcessor + PortgroupportCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if component_id is not None and self.component_id is not None: @@ -482,6 +486,10 @@ def get_command_processor(self, current_processor, component_type=None): from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import \ + PortgroupCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import \ + PortgroupportCommandProcessor if current_processor.__class__ == RootCommandProcessor: return_to = RootCommandProcessor if component_type not in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services', 'unit') \ @@ -518,6 +526,10 @@ def get_command_processor(self, current_processor, component_type=None): return_to = RootCommandProcessor elif current_processor.__class__ == ServicesCommandProcessor: return_to = RootCommandProcessor + elif current_processor.__class__ == PortgroupportCommandProcessor: + return_to = PortgroupCommandProcessor + elif current_processor.__class__ == PortgroupCommandProcessor: + return_to = UnitCommandProcessor return return_to From b93786178c037633190aa8e3deac0a4690ed9418 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 13 Oct 2020 15:04:57 +0200 Subject: [PATCH 228/318] Fixed do_get from portgroupport CP --- .../accessPoints/root/unit/port/portCommandProcessor.py | 3 +-- .../unit/portgroup/port/portgroupportCommandProcessor.py | 7 +++++-- vendors/KeyMile/baseCommandProcessor.py | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 0363cef..30f0d40 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -26,8 +26,7 @@ class PortCommandProcessor(BaseCommandProcessor): from .portManagementFunctions import status def get_property(self, command, *args, context=None): - port_name = self._parent.component_id + '/' + self.component_id - port = self._model.get_port('name', port_name) + port = self.get_port_component() scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 706cf6c..81d95ee 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -23,10 +23,13 @@ class PortgroupportCommandProcessor(PortCommandProcessor): from .portgroupportManagementFunctions import cfgm from .portgroupportManagementFunctions import status - def do_get(self, command, *args, context=None): + def get_port_component(self): + return self._model.get_portgroupport('name', self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id) + + def get_property(self, command, *args, context=None): scopes = ('login', 'base', 'get') try: - super().do_get(command, *args, context=None) + super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: if self._validate((args[0],), 'SubscriberList') and context['component_path'].split('/')[-1] == 'status' and \ self._model.get_card('name', self._parent._parent.component_id).product == 'isdn': diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index b3677f7..3ed7fe9 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -416,7 +416,7 @@ def do_get(self, command, *args, context=None): prop = args[0].split('/')[-1] try: tmp_cmdproc = self.change_directory(path, context=context) - tmp_cmdproc.get_property(command, prop, context=context) + tmp_cmdproc.get_property(command, *prop, context=context) except exceptions.CommandExecutionError: raise exceptions.CommandExecutionError(template='syntax_error', template_scopes=('login', 'base', 'syntax_errors'), From 948c07e8139a1ae970fc57faea41efc0aa6626df Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 14 Oct 2020 08:48:27 +0200 Subject: [PATCH 229/318] added isdnport and pstnport get and set functionality --- .../conf/bootstraps/create-keymile-MG2500.sh | 16 ++++- .../keymile_portgroupport.py | 37 +++++++++++ .../api/models/portgroupport_models.py | 17 +++++ .../api/schemas/portgroupport_schemas.py | 5 +- .../KeyMile/login/base/get/isdnport_bottom.j2 | 9 +++ .../KeyMile/login/base/get/isdnport_middle.j2 | 9 +++ .../KeyMile/login/base/get/isdnport_top.j2 | 4 ++ .../KeyMile/login/base/get/pstnport_bottom.j2 | 9 +++ .../KeyMile/login/base/get/pstnport_middle.j2 | 9 +++ .../KeyMile/login/base/get/pstnport_top.j2 | 4 ++ .../port/portgroupportCommandProcessor.py | 66 +++++++++++++++++-- 11 files changed, 177 insertions(+), 8 deletions(-) create mode 100644 templates/KeyMile/login/base/get/isdnport_bottom.j2 create mode 100644 templates/KeyMile/login/base/get/isdnport_middle.j2 create mode 100644 templates/KeyMile/login/base/get/isdnport_top.j2 create mode 100644 templates/KeyMile/login/base/get/pstnport_bottom.j2 create mode 100644 templates/KeyMile/login/base/get/pstnport_middle.j2 create mode 100644 templates/KeyMile/login/base/get/pstnport_top.j2 diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 8f992ab..ecb035e 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -441,7 +441,21 @@ req='{ "card_id": '$unit_19', "admin_state": "1", "operational_state": "1", - "name": "19/G1/1" + "name": "19/G1/1", + "type": "PSTN" +}' + +port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) + +### PortGroupPort-2 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_19', + "admin_state": "1", + "operational_state": "1", + "name": "19/G2/1", + "type": "ISDN" }' port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) \ No newline at end of file diff --git a/nesi/keymile/keymile_resources/keymile_portgroupport.py b/nesi/keymile/keymile_resources/keymile_portgroupport.py index fa976d3..97619ec 100644 --- a/nesi/keymile/keymile_resources/keymile_portgroupport.py +++ b/nesi/keymile/keymile_resources/keymile_portgroupport.py @@ -27,6 +27,19 @@ class KeymilePortGroupPort(base.Resource): description = base.Field('description') label1 = base.Field('label1') label2 = base.Field('label2') + type = base.Field('type') + enable = base.Field('enable') + subsriber_identification = base.Field('subsriber_identification') + register_as_global = base.Field('register_as_global') + register_default_number_only = base.Field('register_default_number_only') + layer_1_permanently_activated = base.Field('layer_1_permanently_activated') + sip_profile = base.Field('sip_profile') + proxy_registrar_profile = base.Field('proxy_registrar_profile') + codec_sdp_profile = base.Field('codec_sdp_profile') + isdnba_profile = base.Field('isdnba_profile') + pay_phone = base.Field('pay_phone') + pstn_profile = base.Field('pstn_profile') + enterprise_profile = base.Field('enterprise_profile') def set_label(self, l1, l2, desc): self.update(label1=l1) @@ -49,6 +62,30 @@ def up(self): """Set the port state to down""" self.update(operational_state='1') + def set_pstnport(self, enable, subscriberident, registerglobal, phone, sip, proxy, codec, pstn, enterprise): + """Set the pstnport""" + self.update(enable=enable) + self.update(subsriber_identification=subscriberident) + self.update(register_as_global=registerglobal) + self.update(pay_phone=phone) + self.update(sip_profile=sip) + self.update(proxy_registrar_profile=proxy) + self.update(codec_sdp_profile=codec) + self.update(pstn_profile=pstn) + self.update(enterprise_profile=enterprise) + + def set_isdnport(self, enable, subscriberident, registerglobal, regdefault, layer1, sip, proxy, codec, isdn): + """Set the pstnport""" + self.update(enable=enable) + self.update(subsriber_identification=subscriberident) + self.update(register_as_global=registerglobal) + self.update(register_default_number_only=regdefault) + self.update(sip_profile=sip) + self.update(proxy_registrar_profile=proxy) + self.update(codec_sdp_profile=codec) + self.update(layer_1_permanently_activated=layer1) + self.update(isdnba_profile=isdn) + class KeymilePortGroupPortCollection(base.ResourceCollection): """Represent a collection of logical subscribers.""" diff --git a/nesi/softbox/api/models/portgroupport_models.py b/nesi/softbox/api/models/portgroupport_models.py index 24811ba..788bf0e 100644 --- a/nesi/softbox/api/models/portgroupport_models.py +++ b/nesi/softbox/api/models/portgroupport_models.py @@ -11,3 +11,20 @@ class PortGroupPort(db.Model): label1 = db.Column(db.String(), default='""') label2 = db.Column(db.String(), default='""') card_id = db.Column(db.Integer, db.ForeignKey('card.id')) + type = db.Column(db.Enum('ISDN', 'PSTN'), default='ISDN') + + #isdn + enable = db.Column(db.Boolean(), default=False) + subsriber_identification = db.Column(db.String(), default=None) + register_as_global = db.Column(db.Boolean, default=None) + register_default_number_only = db.Column(db.Boolean, default=None) + layer_1_permanently_activated = db.Column(db.Boolean, default=None) + sip_profile = db.Column(db.String(), default=None) + proxy_registrar_profile = db.Column(db.String(), default=None) + codec_sdp_profile = db.Column(db.String(), default=None) + isdnba_profile = db.Column(db.String(), default=None) + + #pstn + pay_phone = db.Column(db.Boolean(), default= None) + pstn_profile = db.Column(db.String(), default=None) + enterprise_profile = db.Column(db.String(), default=None) diff --git a/nesi/softbox/api/schemas/portgroupport_schemas.py b/nesi/softbox/api/schemas/portgroupport_schemas.py index 932f44b..82712dc 100644 --- a/nesi/softbox/api/schemas/portgroupport_schemas.py +++ b/nesi/softbox/api/schemas/portgroupport_schemas.py @@ -18,7 +18,10 @@ class PortGroupPortSchema(ma.ModelSchema): class Meta: model = PortGroupPort fields = ('id', 'name', 'box_id', 'card_id', 'operational_state', 'admin_state', 'description', 'label1', - 'label2', '_links') + 'label2', 'type', 'enable', 'subsriber_identification', 'register_as_global', + 'register_default_number_only', 'layer_1_permanently_activated', 'sip_profile', 'isdnba_profile', + 'proxy_registrar_profile', 'codec_sdp_profile', 'pay_phone', 'pstn_profile', 'enterprise_profile', + '_links') box = ma.Hyperlinks( {'_links': { diff --git a/templates/KeyMile/login/base/get/isdnport_bottom.j2 b/templates/KeyMile/login/base/get/isdnport_bottom.j2 new file mode 100644 index 0000000..97c6e19 --- /dev/null +++ b/templates/KeyMile/login/base/get/isdnport_bottom.j2 @@ -0,0 +1,9 @@ +} \ +{{ context.port.register_as_global }}{{ context.spacer2 }}\ # RegisterAsGlobal +{{ context.port.register_default_number_only }}{{ context.spacer3 }}\ # RegisterDefaultNumberOnly +{{ context.port.layer_1_permanently_activated }}{{ context.spacer8 }}\ # Layer1PermanentlyActivated +{{ context.port.sip_profile }}{{ context.spacer4 }}\ # SipProfile +{{ context.port.proxy_registrar_profile }}{{ context.spacer5 }}\ # ProxyRegistrarProfile +{{ context.port.codec_sdp_profile }}{{ context.spacer6 }}\ # CodecSdpProfile +{{ context.port.isdnba_profile }}{{ context.spacer7 }}\ # IsdnBaProfile + diff --git a/templates/KeyMile/login/base/get/isdnport_middle.j2 b/templates/KeyMile/login/base/get/isdnport_middle.j2 new file mode 100644 index 0000000..19f929b --- /dev/null +++ b/templates/KeyMile/login/base/get/isdnport_middle.j2 @@ -0,0 +1,9 @@ + \ # [0] # + \ # SubscriberId + "9108007" \ # SubscriberNumber + "4962329108007" \ # AuthorisationUserName + "5yhnxz7x" \ # AuthorisationPassword + "" \ # DisplayName + None \ # privacy +; \ + diff --git a/templates/KeyMile/login/base/get/isdnport_top.j2 b/templates/KeyMile/login/base/get/isdnport_top.j2 new file mode 100644 index 0000000..6f7ea38 --- /dev/null +++ b/templates/KeyMile/login/base/get/isdnport_top.j2 @@ -0,0 +1,4 @@ + \ # IsdnPort +{{ context.port.enable }}{{ context.spacer1 }}\ # Enable +{ \ # SubscriberIdentifications + diff --git a/templates/KeyMile/login/base/get/pstnport_bottom.j2 b/templates/KeyMile/login/base/get/pstnport_bottom.j2 new file mode 100644 index 0000000..88b7918 --- /dev/null +++ b/templates/KeyMile/login/base/get/pstnport_bottom.j2 @@ -0,0 +1,9 @@ +} \ +{{ context.port.register_as_global }}{{ context.spacer2 }}\ # RegisterAsGlobal +{{ context.port.pay_phone }}{{ context.spacer3 }}\ # PayPhone +{{ context.port.sip_profile }}{{ context.spacer4 }}\ # SipProfile +{{ context.port.proxy_registrar_profile }}{{ context.spacer5 }}\ # ProxyRegistrarProfile +{{ context.port.codec_sdp_profile }}{{ context.spacer6 }}\ # CodecSdpProfile +{{ context.port.pstn_profile }}{{ context.spacer7 }}\ # PstnProfile +{{ context.port.enterprise_profile }}{{ context.spacer8 }}\ # EnterpriseProfile + diff --git a/templates/KeyMile/login/base/get/pstnport_middle.j2 b/templates/KeyMile/login/base/get/pstnport_middle.j2 new file mode 100644 index 0000000..19f929b --- /dev/null +++ b/templates/KeyMile/login/base/get/pstnport_middle.j2 @@ -0,0 +1,9 @@ + \ # [0] # + \ # SubscriberId + "9108007" \ # SubscriberNumber + "4962329108007" \ # AuthorisationUserName + "5yhnxz7x" \ # AuthorisationPassword + "" \ # DisplayName + None \ # privacy +; \ + diff --git a/templates/KeyMile/login/base/get/pstnport_top.j2 b/templates/KeyMile/login/base/get/pstnport_top.j2 new file mode 100644 index 0000000..9aab7aa --- /dev/null +++ b/templates/KeyMile/login/base/get/pstnport_top.j2 @@ -0,0 +1,4 @@ + \ # PstnPort +{{ context.port.enable }}{{ context.spacer1 }}\ # Enable +{ \ # SubscriberIdentifications + diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 81d95ee..b88c025 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -27,6 +27,7 @@ def get_port_component(self): return self._model.get_portgroupport('name', self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id) def get_property(self, command, *args, context=None): + port = self.get_port_component() scopes = ('login', 'base', 'get') try: super().get_property(command, *args, context=context) @@ -46,6 +47,34 @@ def get_property(self, command, *args, context=None): context=dict(context, subscriber=subscriber)) text += self._render('subscriberList_bottom', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'Isdnport') and context['component_path'].split('/')[-1] == 'cfgm' and \ + port.type == 'ISDN': + context['spacer1'] = self.create_spacers((67,), (port.enable,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (port.register_as_global,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (port.register_default_number_only,))[0] * ' ' + context['spacer4'] = self.create_spacers((67,), (port.sip_profile,))[0] * ' ' + context['spacer5'] = self.create_spacers((67,), (port.proxy_registrar_profile,))[0] * ' ' + context['spacer6'] = self.create_spacers((67,), (port.codec_sdp_profile,))[0] * ' ' + context['spacer7'] = self.create_spacers((67,), (port.isdnba_profile,))[0] * ' ' + context['spacer8'] = self.create_spacers((67,), (port.layer_1_permanently_activated,))[0] * ' ' + text = self._render('isdnport_top', *scopes, context=dict(context, port=port)) + text += self._render('isdnport_middle', *scopes, context=dict(context, subscriber=port)) #TODO: subscriber dynamic + text += self._render('isdnport_bottom', *scopes, context=dict(context, port=port)) + self._write(text) + elif self._validate((args[0],), 'pstnport') and context['component_path'].split('/')[-1] == 'cfgm' and \ + port.type == 'PSTN': + context['spacer1'] = self.create_spacers((67,), (port.enable,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (port.register_as_global,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (port.pay_phone,))[0] * ' ' + context['spacer4'] = self.create_spacers((67,), (port.sip_profile,))[0] * ' ' + context['spacer5'] = self.create_spacers((67,), (port.proxy_registrar_profile,))[0] * ' ' + context['spacer6'] = self.create_spacers((67,), (port.codec_sdp_profile,))[0] * ' ' + context['spacer7'] = self.create_spacers((67,), (port.pstn_profile,))[0] * ' ' + context['spacer8'] = self.create_spacers((67,), (port.enterprise_profile,))[0] * ' ' + text = self._render('pstnport_top', *scopes, context=dict(context, port=port)) + text += self._render('pstnport_middle', *scopes, context=dict(context, subscriber=port)) #TODO: subscriber dynamic + text += self._render('pstnport_bottom', *scopes, context=dict(context, port=port)) self._write(text) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', @@ -60,17 +89,42 @@ def on_unknown_command(self, command, *args, context=None): def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') try: - super().set(command, *args, context=None) - except exceptions.CommandExecutionError: + super().set(command, *args, context=context) + except exceptions.CommandSyntaxError: if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - # TODO test case - return + elif self._validate(args, 'pstnport', str, str, str, str, str, str, str, str, str) and \ + context['component_path'].split('/')[-1] == 'cfgm': + enable, subident, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', + str, str, str, str, str, str, str, str, str) + try: + port = self.get_port_component() + #TODO: integrate subscriber instead of string + enable = True if enable.lower() == 'true' else False + register = True if register.lower() == 'true' else False + phone = True if phone.lower() == 'true' else False + port.set_pstnport(enable, subident, register, phone, sip, proxy, codec, pstn, enterprise) + except exceptions.SoftboxenError: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'isdnport', str, str, str, str, str, str, str, str, str) and \ + context['component_path'].split('/')[-1] == 'cfgm': + enable, subident, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', + str, str, str, str, str, str, str, str, str) + try: + port = self.get_port_component() + #TODO: integrate subscriber instead of string + enable = True if enable.lower() == 'true' else False + register = True if register.lower() == 'true' else False + regdefault = True if regdefault.lower() == 'true' else False + layer1 = True if layer1.lower() == 'true' else False + port.set_isdnport(enable, subident, register, regdefault, layer1, sip, proxy, codec, isdnba) + except exceptions.SoftboxenError: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) \ No newline at end of file From d62e7379c91572c9dc43e2b47f1a011853ed3a8b Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 14 Oct 2020 11:23:50 +0200 Subject: [PATCH 230/318] finished isdnport and pstnport get and set functionality --- nesi/keymile/keymile_resources/keymile_box.py | 8 ++ .../keymile_portgroupport.py | 7 +- .../keymile_resources/keymile_subscriber.py | 8 ++ .../api/models/portgroupport_models.py | 1 - nesi/softbox/api/models/subscriber_models.py | 4 + .../api/schemas/portgroupport_schemas.py | 2 +- .../softbox/api/schemas/subscriber_schemas.py | 4 +- .../KeyMile/login/base/get/isdnport_middle.j2 | 12 +-- .../KeyMile/login/base/get/pstnport_middle.j2 | 12 +-- .../port/portgroupportCommandProcessor.py | 88 +++++++++++++++++-- 10 files changed, 119 insertions(+), 27 deletions(-) diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index d800261..e5882bf 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -9,6 +9,7 @@ # - Alexander Dincher # # License: https://github.com/inexio/NESi/LICENSE.rst +import os from nesi.keymile.keymile_resources import * @@ -124,6 +125,13 @@ def get_subscribers(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'subscribers'), params={field: value}) + def add_subscriber(self, **fields): + """Add new ont.""" + return keymile_subscriber.KeymileSubscriber.create( + self._conn, + os.path.join(self.path, 'subscribers'), + **fields) + def get_portgroupport(self, field, value): """Get specific portgroupport object.""" return keymile_portgroupport.KeymilePortGroupPortCollection( diff --git a/nesi/keymile/keymile_resources/keymile_portgroupport.py b/nesi/keymile/keymile_resources/keymile_portgroupport.py index 97619ec..b224869 100644 --- a/nesi/keymile/keymile_resources/keymile_portgroupport.py +++ b/nesi/keymile/keymile_resources/keymile_portgroupport.py @@ -29,7 +29,6 @@ class KeymilePortGroupPort(base.Resource): label2 = base.Field('label2') type = base.Field('type') enable = base.Field('enable') - subsriber_identification = base.Field('subsriber_identification') register_as_global = base.Field('register_as_global') register_default_number_only = base.Field('register_default_number_only') layer_1_permanently_activated = base.Field('layer_1_permanently_activated') @@ -62,10 +61,9 @@ def up(self): """Set the port state to down""" self.update(operational_state='1') - def set_pstnport(self, enable, subscriberident, registerglobal, phone, sip, proxy, codec, pstn, enterprise): + def set_pstnport(self, enable, registerglobal, phone, sip, proxy, codec, pstn, enterprise): """Set the pstnport""" self.update(enable=enable) - self.update(subsriber_identification=subscriberident) self.update(register_as_global=registerglobal) self.update(pay_phone=phone) self.update(sip_profile=sip) @@ -74,10 +72,9 @@ def set_pstnport(self, enable, subscriberident, registerglobal, phone, sip, prox self.update(pstn_profile=pstn) self.update(enterprise_profile=enterprise) - def set_isdnport(self, enable, subscriberident, registerglobal, regdefault, layer1, sip, proxy, codec, isdn): + def set_isdnport(self, enable, registerglobal, regdefault, layer1, sip, proxy, codec, isdn): """Set the pstnport""" self.update(enable=enable) - self.update(subsriber_identification=subscriberident) self.update(register_as_global=registerglobal) self.update(register_default_number_only=regdefault) self.update(sip_profile=sip) diff --git a/nesi/keymile/keymile_resources/keymile_subscriber.py b/nesi/keymile/keymile_resources/keymile_subscriber.py index 5dc324d..086cf2e 100644 --- a/nesi/keymile/keymile_resources/keymile_subscriber.py +++ b/nesi/keymile/keymile_resources/keymile_subscriber.py @@ -26,6 +26,14 @@ class KeymileSubscriber(base.Resource): type = base.Field('type') address = base.Field('address') registration_state = base.Field('registration_state') + autorisation_user_name = base.Field('autorisation_user_name') + autorisation_password = base.Field('autorisation_password') + display_name = base.Field('display_name') + privacy = base.Field('privacy') + + def set(self, field, value): + mapping = {field: value} + self.update(**mapping) class KeymileSubscriberCollection(base.ResourceCollection): diff --git a/nesi/softbox/api/models/portgroupport_models.py b/nesi/softbox/api/models/portgroupport_models.py index 788bf0e..4a1a0f9 100644 --- a/nesi/softbox/api/models/portgroupport_models.py +++ b/nesi/softbox/api/models/portgroupport_models.py @@ -15,7 +15,6 @@ class PortGroupPort(db.Model): #isdn enable = db.Column(db.Boolean(), default=False) - subsriber_identification = db.Column(db.String(), default=None) register_as_global = db.Column(db.Boolean, default=None) register_default_number_only = db.Column(db.Boolean, default=None) layer_1_permanently_activated = db.Column(db.Boolean, default=None) diff --git a/nesi/softbox/api/models/subscriber_models.py b/nesi/softbox/api/models/subscriber_models.py index 1dc9cd1..a94baff 100644 --- a/nesi/softbox/api/models/subscriber_models.py +++ b/nesi/softbox/api/models/subscriber_models.py @@ -10,4 +10,8 @@ class Subscriber(db.Model): type = db.Column(db.Enum('unit', 'port'), default='port') address = db.Column(db.String(), default='') registration_state = db.Column(db.Enum('registered'), default='registered') + autorisation_user_name = db.Column(db.String(), default='') + autorisation_password = db.Column(db.String(), default='""') + display_name = db.Column(db.String(), default='') + privacy = db.Column(db.String(), default=None) diff --git a/nesi/softbox/api/schemas/portgroupport_schemas.py b/nesi/softbox/api/schemas/portgroupport_schemas.py index 82712dc..5ef8f85 100644 --- a/nesi/softbox/api/schemas/portgroupport_schemas.py +++ b/nesi/softbox/api/schemas/portgroupport_schemas.py @@ -18,7 +18,7 @@ class PortGroupPortSchema(ma.ModelSchema): class Meta: model = PortGroupPort fields = ('id', 'name', 'box_id', 'card_id', 'operational_state', 'admin_state', 'description', 'label1', - 'label2', 'type', 'enable', 'subsriber_identification', 'register_as_global', + 'label2', 'type', 'enable', 'register_as_global', 'register_default_number_only', 'layer_1_permanently_activated', 'sip_profile', 'isdnba_profile', 'proxy_registrar_profile', 'codec_sdp_profile', 'pay_phone', 'pstn_profile', 'enterprise_profile', '_links') diff --git a/nesi/softbox/api/schemas/subscriber_schemas.py b/nesi/softbox/api/schemas/subscriber_schemas.py index 3efa31c..98c07b8 100644 --- a/nesi/softbox/api/schemas/subscriber_schemas.py +++ b/nesi/softbox/api/schemas/subscriber_schemas.py @@ -17,7 +17,9 @@ class SubscriberSchema(ma.ModelSchema): class Meta: model = Subscriber - fields = ('id', 'name', 'box', 'box_id', 'number', 'type', 'address', 'registration_state', '_links') + fields = ('id', 'name', 'box', 'box_id', 'number', 'type', 'address', 'registration_state', 'display_name', + 'autorisation_user_name', 'autorisation_password', 'privacy', + '_links') box = ma.Hyperlinks( {'_links': { diff --git a/templates/KeyMile/login/base/get/isdnport_middle.j2 b/templates/KeyMile/login/base/get/isdnport_middle.j2 index 19f929b..051b842 100644 --- a/templates/KeyMile/login/base/get/isdnport_middle.j2 +++ b/templates/KeyMile/login/base/get/isdnport_middle.j2 @@ -1,9 +1,9 @@ - \ # [0] # + \ # [{{ context.i }}] # \ # SubscriberId - "9108007" \ # SubscriberNumber - "4962329108007" \ # AuthorisationUserName - "5yhnxz7x" \ # AuthorisationPassword - "" \ # DisplayName - None \ # privacy + "{{ context.subscriber.number }}"{{ context.spacer10 }}\ # SubscriberNumber + "{{ context.subscriber.autorisation_user_name }}"{{ context.spacer11 }}\ # AuthorisationUserName + "{{ context.subscriber.autorisation_password }}"{{ context.spacer12 }}\ # AuthorisationPassword + "{{ context.subscriber.display_name }}"{{ context.spacer13 }}\ # DisplayName + {{ context.subscriber.privacy }}{{ context.spacer14 }}\ # privacy ; \ diff --git a/templates/KeyMile/login/base/get/pstnport_middle.j2 b/templates/KeyMile/login/base/get/pstnport_middle.j2 index 19f929b..051b842 100644 --- a/templates/KeyMile/login/base/get/pstnport_middle.j2 +++ b/templates/KeyMile/login/base/get/pstnport_middle.j2 @@ -1,9 +1,9 @@ - \ # [0] # + \ # [{{ context.i }}] # \ # SubscriberId - "9108007" \ # SubscriberNumber - "4962329108007" \ # AuthorisationUserName - "5yhnxz7x" \ # AuthorisationPassword - "" \ # DisplayName - None \ # privacy + "{{ context.subscriber.number }}"{{ context.spacer10 }}\ # SubscriberNumber + "{{ context.subscriber.autorisation_user_name }}"{{ context.spacer11 }}\ # AuthorisationUserName + "{{ context.subscriber.autorisation_password }}"{{ context.spacer12 }}\ # AuthorisationPassword + "{{ context.subscriber.display_name }}"{{ context.spacer13 }}\ # DisplayName + {{ context.subscriber.privacy }}{{ context.spacer14 }}\ # privacy ; \ diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index b88c025..159651e 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -37,7 +37,7 @@ def get_property(self, command, *args, context=None): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'port': # TODO: show only subscriber of this port + if subscriber.type == 'port' and subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id: context['i'] = i context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' @@ -59,7 +59,19 @@ def get_property(self, command, *args, context=None): context['spacer7'] = self.create_spacers((67,), (port.isdnba_profile,))[0] * ' ' context['spacer8'] = self.create_spacers((67,), (port.layer_1_permanently_activated,))[0] * ' ' text = self._render('isdnport_top', *scopes, context=dict(context, port=port)) - text += self._render('isdnport_middle', *scopes, context=dict(context, subscriber=port)) #TODO: subscriber dynamic + + i = 0 + for subscriber in self._model.subscribers: + if subscriber.type == 'port' and subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id: + context['i'] = i + context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' + context['spacer11'] = self.create_spacers((63,), (subscriber.autorisation_user_name,))[0] * ' ' + context['spacer12'] = self.create_spacers((63,), (subscriber.autorisation_password,))[0] * ' ' + context['spacer13'] = self.create_spacers((63,), (subscriber.display_name,))[0] * ' ' + context['spacer14'] = self.create_spacers((63,), (subscriber.privacy,))[0] * ' ' + i += 1 + text += self._render('isdnport_middle', *scopes, context=dict(context, subscriber=subscriber)) + text += self._render('isdnport_bottom', *scopes, context=dict(context, port=port)) self._write(text) elif self._validate((args[0],), 'pstnport') and context['component_path'].split('/')[-1] == 'cfgm' and \ @@ -73,7 +85,19 @@ def get_property(self, command, *args, context=None): context['spacer7'] = self.create_spacers((67,), (port.pstn_profile,))[0] * ' ' context['spacer8'] = self.create_spacers((67,), (port.enterprise_profile,))[0] * ' ' text = self._render('pstnport_top', *scopes, context=dict(context, port=port)) - text += self._render('pstnport_middle', *scopes, context=dict(context, subscriber=port)) #TODO: subscriber dynamic + + i = 0 + for subscriber in self._model.subscribers: + if subscriber.type == 'port' and subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id: + context['i'] = i + context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' + context['spacer11'] = self.create_spacers((63,), (subscriber.autorisation_user_name,))[0] * ' ' + context['spacer12'] = self.create_spacers((63,), (subscriber.autorisation_password,))[0] * ' ' + context['spacer13'] = self.create_spacers((63,), (subscriber.display_name,))[0] * ' ' + context['spacer14'] = self.create_spacers((65,), (subscriber.privacy,))[0] * ' ' + i += 1 + text += self._render('pstnport_middle', *scopes, context=dict(context, subscriber=subscriber)) + text += self._render('pstnport_bottom', *scopes, context=dict(context, port=port)) self._write(text) else: @@ -102,26 +126,76 @@ def set(self, command, *args, context=None): str, str, str, str, str, str, str, str, str) try: port = self.get_port_component() - #TODO: integrate subscriber instead of string enable = True if enable.lower() == 'true' else False register = True if register.lower() == 'true' else False phone = True if phone.lower() == 'true' else False - port.set_pstnport(enable, subident, register, phone, sip, proxy, codec, pstn, enterprise) + port.set_pstnport(enable, register, phone, sip, proxy, codec, pstn, enterprise) except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'pstnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, + str) and context['component_path'].split('/')[-1] == 'cfgm': + enable, number, username, password, displayname, privacy, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) + try: + port = self.get_port_component() + try: + subscriber = self._model.get_subscriber('number', int(number)) + subscriber.set('autorisation_user_name', username) + subscriber.set('autorisation_password', password) + subscriber.set('display_name', displayname) + subscriber.set('privacy', privacy) + except exceptions.SoftboxenError: + address = self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id + subscriber = self._model.add_subscriber(number=int(number), autorisation_user_name=username, + address=address, privacy=privacy, type='port', + display_name=displayname, autorisation_password=password) + pass + enable = True if enable.lower() == 'true' else False + register = True if register.lower() == 'true' else False + phone = True if phone.lower() == 'true' else False + port.set_pstnport(enable, register, phone, sip, proxy, codec, pstn, enterprise) + except exceptions.SoftboxenError as exe: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'isdnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, + str) and context['component_path'].split('/')[-1] == 'cfgm': + enable, number, username, password, displayname, privacy, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) + try: + port = self.get_port_component() + try: + subscriber = self._model.get_subscriber('number', int(number)) + assert subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id + subscriber.set('autorisation_user_name', username) + subscriber.set('autorisation_password', password) + subscriber.set('display_name', displayname) + subscriber.set('privacy', privacy) + except exceptions.SoftboxenError: + address = self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id + subscriber = self._model.add_subscriber(number=int(number), autorisation_user_name=username, + address=address, privacy=privacy, type='port', + display_name=displayname, autorisation_password=password) + pass + except AssertionError: + raise exceptions.SoftboxenError() + enable = True if enable.lower() == 'true' else False + register = True if register.lower() == 'true' else False + regdefault = True if regdefault.lower() == 'true' else False + layer1 = True if layer1.lower() == 'true' else False + port.set_isdnport(enable, register, regdefault, layer1, sip, proxy, codec, isdnba) + except exceptions.SoftboxenError as exe: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'isdnport', str, str, str, str, str, str, str, str, str) and \ context['component_path'].split('/')[-1] == 'cfgm': enable, subident, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', str, str, str, str, str, str, str, str, str) try: port = self.get_port_component() - #TODO: integrate subscriber instead of string enable = True if enable.lower() == 'true' else False register = True if register.lower() == 'true' else False regdefault = True if regdefault.lower() == 'true' else False layer1 = True if layer1.lower() == 'true' else False - port.set_isdnport(enable, subident, register, regdefault, layer1, sip, proxy, codec, isdnba) + port.set_isdnport(enable, register, regdefault, layer1, sip, proxy, codec, isdnba) except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) From 09f9da40803833a93fcc7a714f0ab8877e97a088 Mon Sep 17 00:00:00 2001 From: png2000 Date: Wed, 14 Oct 2020 09:15:32 +0200 Subject: [PATCH 231/318] =?UTF-8?q?create-keymile-MG2500:=20Name=20hinzuge?= =?UTF-8?q?f=C3=BCgt=20currTemperature=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootup/conf/bootstraps/create-keymile-MG2500.sh | 4 +++- nesi/keymile/api/schemas/keymile_box_schemas.py | 5 +++-- nesi/keymile/keymile_resources/keymile_box.py | 3 +++ nesi/softbox/api/models/box_models.py | 5 +++++ nesi/softbox/api/schemas/box_schemas.py | 13 +++++++++++-- templates/KeyMile/login/base/get/currTemperature.j2 | 3 +++ .../accessPoints/root/rootCommandProcessor.py | 8 ++++++++ 7 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 templates/KeyMile/login/base/get/currTemperature.j2 diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index ecb035e..0132aa3 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -8,6 +8,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst # @@ -31,7 +32,8 @@ req='{ "network_protocol": "telnet", "network_address": "127.0.0.1", "network_port": 9023, - "uuid": "2200" + "uuid": "2200", + "currTemperature": 15 }' box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 diff --git a/nesi/keymile/api/schemas/keymile_box_schemas.py b/nesi/keymile/api/schemas/keymile_box_schemas.py index b4e571e..37352a2 100644 --- a/nesi/keymile/api/schemas/keymile_box_schemas.py +++ b/nesi/keymile/api/schemas/keymile_box_schemas.py @@ -7,16 +7,17 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst from nesi.softbox.api.schemas.box_schemas import * -class HuaweiBoxSchema(BoxSchema): +class KeymileBoxSchema(BoxSchema): class Meta: model = Box - fields = BoxSchema.Meta.fields + ('channels', 'interfaces') + fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature') interfaces = ma.Hyperlinks( {'_links': { diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index e5882bf..de1842a 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst import os @@ -28,6 +29,8 @@ class KeyMileBox(Box): """ # Define Keymile Properties + currTemperature = base.Field("currTemperature") + @property def channels(self): """Return `CpePortCollection` object.""" diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index af447ad..5854077 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst import uuid @@ -55,10 +56,13 @@ class Box(db.Model): credentials = db.relationship('Credential', backref='Box', lazy='dynamic') credential_details = db.relationship('Credential', backref='credentials', lazy='dynamic') users = db.relationship('User', backref='Box', lazy='dynamic') + subracks = db.relationship('Subrack', backref='Box', lazy='dynamic') subrack_details = db.relationship('Subrack', backref='subracks', lazy='dynamic') cards = db.relationship('Card', backref='Box', lazy='dynamic') + mgmt_cards = db.relationship('MgmtCard', backref='Box', lazy='dynamic') ports = db.relationship('Port', backref='Box', lazy='dynamic') + mgmt_ports = db.relationship('MgmtPort', backref='Box', lazy='dynamic') channels = db.relationship('Channel', backref='Box', lazy='dynamic') interfaces = db.relationship('Interface', backref='Box', lazy='dynamic') cpes = db.relationship('Cpe', backref='Box', lazy='dynamic') @@ -116,3 +120,4 @@ class Box(db.Model): pitp_mode = db.Column(db.String(), default='') dsl_mode = db.Column(db.Enum('tr165', 'tr129'), default='tr165') + currTemperature = db.Column(db.Integer(), default=15) \ No newline at end of file diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index 87a9215..cb13c4b 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst @@ -34,8 +35,8 @@ class Meta: 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', - 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', - 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') + 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'mgmt_cards', 'mgmt_ports', + 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links', 'currTemperature') credentials = ma.Hyperlinks( {'_links': { @@ -57,10 +58,18 @@ class Meta: {'_links': { 'self': ma.URLFor('show_cards', box_id='')}}) + mgmt_cards = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_mgmt_cards', box_id='')}}) + ports = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_ports', box_id='')}}) + mgmt_ports = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_mgmt_ports', box_id='')}}) + channels = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_channels', box_id='')}}) diff --git a/templates/KeyMile/login/base/get/currTemperature.j2 b/templates/KeyMile/login/base/get/currTemperature.j2 new file mode 100644 index 0000000..95d1608 --- /dev/null +++ b/templates/KeyMile/login/base/get/currTemperature.j2 @@ -0,0 +1,3 @@ + \ # Current +{{ context.currTemperature }}{{ context.spacer }}\ # Temperature + diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 0e465c6..0029077 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -7,6 +7,7 @@ # - Janis Groß # - Philip Konrath # - Alexander Dincher +# - Philipp-Noah Groß # # License: https://github.com/inexio/NESi/LICENSE.rst @@ -24,6 +25,13 @@ class RootCommandProcessor(BaseCommandProcessor): from .rootManagementFunctions import fm from .rootManagementFunctions import status + def do_get(self, command, *args, context=None): + if self._validate(args, "CurrTemperature"): + context['currTemperature'] = self._model.currTemperature + context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' + self._write(self._render('currTemperature', 'login', 'base', 'get', context=context)) + + def _init_access_points(self, context=None): for card in self._model.cards: if 'unit-' + card.name in self.access_points: From 4412d71327e33c9285b5884b7b5b64058f159ec2 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Wed, 14 Oct 2020 09:45:02 +0200 Subject: [PATCH 232/318] Added the concept of logports (still WIP) --- .../conf/bootstraps/create-keymile-MG2500.sh | 13 +- nesi/keymile/api/schemas/__init__.py | 2 +- .../api/schemas/keymile_box_schemas.py | 6 +- .../api/schemas/keymile_channel_schemas.py | 2 +- .../api/schemas/keymile_logport_schemas.py | 19 + nesi/keymile/keymile_resources/__init__.py | 2 +- nesi/keymile/keymile_resources/keymile_box.py | 22 +- .../keymile_resources/keymile_interface.py | 2 + .../keymile_resources/keymile_logport.py | 33 ++ .../keymile/keymile_resources/keymile_port.py | 2 +- nesi/softbox/api/models/box_models.py | 3 + nesi/softbox/api/models/interface_models.py | 1 + nesi/softbox/api/models/logport_models.py | 23 + nesi/softbox/api/schemas/box_schemas.py | 6 +- nesi/softbox/api/schemas/interface_schemas.py | 2 +- nesi/softbox/api/schemas/logport_schemas.py | 50 ++ nesi/softbox/api/views/__init__.py | 2 +- nesi/softbox/api/views/box_views.py | 1 + nesi/softbox/api/views/logport_views.py | 53 ++ nesi/softbox/base_resources/box.py | 4 - .../unit/logport/logportsCommandProcessor.py | 11 +- .../logport/logportsManagementFunctions.py | 10 +- .../logport/port/logportCommandProcessor.py | 28 +- .../port/logportManagementFunctions.py | 489 ++++++++++-------- .../root/unit/unitCommandProcessor.py | 7 + vendors/KeyMile/baseCommandProcessor.py | 24 +- 26 files changed, 560 insertions(+), 257 deletions(-) create mode 100644 nesi/keymile/api/schemas/keymile_logport_schemas.py create mode 100644 nesi/keymile/keymile_resources/keymile_logport.py create mode 100644 nesi/softbox/api/models/logport_models.py create mode 100644 nesi/softbox/api/schemas/logport_schemas.py create mode 100644 nesi/softbox/api/views/logport_views.py diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 0132aa3..af898a8 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -32,7 +32,7 @@ req='{ "network_protocol": "telnet", "network_address": "127.0.0.1", "network_port": 9023, - "uuid": "2200", + "uuid": "2500", "currTemperature": 15 }' @@ -243,6 +243,17 @@ req='{ port_2_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +### LogPort 1 ### + +# Create a logical logport object at the network device (admin operation) +req='{ + "card_id": '$unit_2', + "name": "2/L/2", + "ports": "ports:2" +}' + +logport_2_l_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/logports) + ### Unit-3 ### # Create a physical card at the network device (admin operation) diff --git a/nesi/keymile/api/schemas/__init__.py b/nesi/keymile/api/schemas/__init__.py index 04e408d..4bcd514 100644 --- a/nesi/keymile/api/schemas/__init__.py +++ b/nesi/keymile/api/schemas/__init__.py @@ -14,4 +14,4 @@ if isclass(attribute): # Add the class to this package's variables - globals()[attribute_name] = attribute \ No newline at end of file + globals()[attribute_name] = attribute diff --git a/nesi/keymile/api/schemas/keymile_box_schemas.py b/nesi/keymile/api/schemas/keymile_box_schemas.py index 37352a2..5458c05 100644 --- a/nesi/keymile/api/schemas/keymile_box_schemas.py +++ b/nesi/keymile/api/schemas/keymile_box_schemas.py @@ -17,7 +17,7 @@ class KeymileBoxSchema(BoxSchema): class Meta: model = Box - fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature') + fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature', 'logports') interfaces = ma.Hyperlinks( {'_links': { @@ -26,3 +26,7 @@ class Meta: channels = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_channels', box_id='')}}) + + logports = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_logports', box_id='')}}) diff --git a/nesi/keymile/api/schemas/keymile_channel_schemas.py b/nesi/keymile/api/schemas/keymile_channel_schemas.py index 5d1e101..9808e4b 100644 --- a/nesi/keymile/api/schemas/keymile_channel_schemas.py +++ b/nesi/keymile/api/schemas/keymile_channel_schemas.py @@ -16,4 +16,4 @@ class KeyMileChannelSchema(ChannelSchema): class Meta: model = Channel - fields = ChannelSchema.Meta.fields + ('vccs', 'interfaces') \ No newline at end of file + fields = ChannelSchema.Meta.fields + ('vccs', 'interfaces') diff --git a/nesi/keymile/api/schemas/keymile_logport_schemas.py b/nesi/keymile/api/schemas/keymile_logport_schemas.py new file mode 100644 index 0000000..8a8ae3c --- /dev/null +++ b/nesi/keymile/api/schemas/keymile_logport_schemas.py @@ -0,0 +1,19 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.logport_schemas import * + + +class KeyMileLogPortSchema(LogPortSchema): + class Meta: + model = LogPort + fields = LogPortSchema.Meta.fields + ('interfaces',) diff --git a/nesi/keymile/keymile_resources/__init__.py b/nesi/keymile/keymile_resources/__init__.py index fcea829..4226c8c 100644 --- a/nesi/keymile/keymile_resources/__init__.py +++ b/nesi/keymile/keymile_resources/__init__.py @@ -1,2 +1,2 @@ __all__ = ["keymile_card", "keymile_port", "keymile_subrack", "keymile_channel", "keymile_interface", - "keymile_subscriber", "keymile_portgroupport"] + "keymile_subscriber", "keymile_portgroupport", "keymile_logport"] diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index de1842a..6e462e0 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -27,19 +27,18 @@ class KeyMileBox(Box): :param connection: A RestClient instance :param identity: The identity of the System resource """ - # Define Keymile Properties currTemperature = base.Field("currTemperature") @property def channels(self): - """Return `CpePortCollection` object.""" + """Return `ChannelCollection` object.""" return keymile_channel.KeyMileChannelCollection( self._conn, base.get_sub_resource_path_by(self, 'channels')) @property def interfaces(self): - """Return `CpePortCollection` object.""" + """Return `InterfaceCollection` object.""" return keymile_interface.KeyMileInterfaceCollection( self._conn, base.get_sub_resource_path_by(self, 'interfaces')) @@ -69,6 +68,11 @@ def portgroupsports(self): return keymile_portgroupport.KeymilePortGroupPortCollection( self._conn, base.get_sub_resource_path_by(self, 'portgrouports')) + def logports(self): + """Return `LogPortCollection` object.""" + return keymile_logport.KeyMileLogPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'logports')) + def get_card(self, field, value): """Get specific card object.""" return keymile_card.KeyMileCardCollection( @@ -93,6 +97,18 @@ def get_ports(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'ports'), params={field: value}) + def get_logport(self, field, value): + """Get specific logport object.""" + return keymile_logport.KeyMileLogPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'logports'), + params={field: value}).find_by_field_value(field, value) + + def get_logports(self, field, value): + """Get al logport objects with a specific trait.""" + return keymile_logport.KeyMileLogPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'logports'), + params={field: value}) + def get_chan(self, field, value): """Get specific channel object.""" return keymile_channel.KeyMileChannelCollection( diff --git a/nesi/keymile/keymile_resources/keymile_interface.py b/nesi/keymile/keymile_resources/keymile_interface.py index 24c8b82..11bcd1e 100644 --- a/nesi/keymile/keymile_resources/keymile_interface.py +++ b/nesi/keymile/keymile_resources/keymile_interface.py @@ -24,6 +24,8 @@ class KeyMileInterface(base.Resource): port_id = base.Field('port_id') name = base.Field('name') description = base.Field('description') + chan_id = base.Field('chan_id') + logport_id = base.Field('logport_id') class KeyMileInterfaceCollection(base.ResourceCollection): diff --git a/nesi/keymile/keymile_resources/keymile_logport.py b/nesi/keymile/keymile_resources/keymile_logport.py new file mode 100644 index 0000000..0655631 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_logport.py @@ -0,0 +1,33 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.service_port import logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class KeyMileLogPort(base.Resource): + """Represent logical log_port resource.""" + + id = base.Field('id') + name = base.Field('name') + card_id = base.Field('card_id') + ports = base.Field('ports') + + +class KeyMileLogPortCollection(base.ResourceCollection): + """Represent a collection of logical log_ports.""" + + @property + def _resource_type(self): + return KeyMileLogPort diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py index ea36140..c90e06f 100644 --- a/nesi/keymile/keymile_resources/keymile_port.py +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -31,4 +31,4 @@ class KeyMilePortCollection(PortCollection): @property def _resource_type(self): - return KeyMilePort \ No newline at end of file + return KeyMilePort diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 5854077..72fbeba 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -31,6 +31,8 @@ from .channel_models import Channel from .subscriber_models import Subscriber from .portgroupport_models import PortGroupPort +from .logport_models import LogPort +from .interface_models import Interface class Box(db.Model): @@ -78,6 +80,7 @@ class Box(db.Model): emus = db.relationship('Emu', backref='Box', lazy='dynamic') subscribers = db.relationship('Subscriber', backref='Box', lazy='dynamic') portgroupports = db.relationship('PortGroupPort', backref='Box', lazy='dynamic') + logports = db.relationship('LogPort', backref='Box', lazy='dynamic') board_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_instl_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_init_reporting_logging = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/models/interface_models.py b/nesi/softbox/api/models/interface_models.py index 38dc722..d37fede 100644 --- a/nesi/softbox/api/models/interface_models.py +++ b/nesi/softbox/api/models/interface_models.py @@ -20,3 +20,4 @@ class Interface(db.Model): box_id = db.Column(db.Integer, db.ForeignKey('box.id')) chan_id = db.Column(db.Integer, db.ForeignKey('channel.id')) port_id = db.Column(db.Integer, db.ForeignKey('port.id')) + logport_id = db.Column(db.Integer, db.ForeignKey('log_port.id')) diff --git a/nesi/softbox/api/models/logport_models.py b/nesi/softbox/api/models/logport_models.py new file mode 100644 index 0000000..df96174 --- /dev/null +++ b/nesi/softbox/api/models/logport_models.py @@ -0,0 +1,23 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from ..models.interface_models import Interface +from nesi.softbox.api import db + + +class LogPort(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + ports = db.Column(db.String(), default='') + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + card_id = db.Column(db.Integer, db.ForeignKey('card.id')) + interfaces = db.relationship('Interface', backref='LogPort', lazy='dynamic') diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index cb13c4b..5cfa939 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -31,7 +31,7 @@ class BoxSchema(ma.ModelSchema): class Meta: model = Box fields = ('id', 'vendor', 'model', 'version', 'software_version', 'network_protocol', 'network_address', - 'network_port', 'uuid', 'description', 'interfaces', + 'network_port', 'uuid', 'description', 'interfaces', 'logports', 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', @@ -94,6 +94,10 @@ class Meta: {'_links': { 'self': ma.URLFor('show_portgroupports', box_id='')}}) + logports = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_logports', box_id='')}}) + onts = ma.Hyperlinks({'_links': { 'self': ma.URLFor('show_onts', box_id='')}}) diff --git a/nesi/softbox/api/schemas/interface_schemas.py b/nesi/softbox/api/schemas/interface_schemas.py index a98b4a5..1095031 100644 --- a/nesi/softbox/api/schemas/interface_schemas.py +++ b/nesi/softbox/api/schemas/interface_schemas.py @@ -17,7 +17,7 @@ class InterfaceSchema(ma.ModelSchema): class Meta: model = Interface - fields = ('id', 'box_id', 'box', 'chan_id', 'port_id', + fields = ('id', 'box_id', 'box', 'chan_id', 'port_id', 'logport_id', 'name', 'description', '_links') box = ma.Hyperlinks( diff --git a/nesi/softbox/api/schemas/logport_schemas.py b/nesi/softbox/api/schemas/logport_schemas.py new file mode 100644 index 0000000..059ea12 --- /dev/null +++ b/nesi/softbox/api/schemas/logport_schemas.py @@ -0,0 +1,50 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from .interface_schemas import InterfacesSchema +from ..models.logport_models import LogPort + + +class LogPortSchema(ma.ModelSchema): + class Meta: + model = LogPort + fields = ('id', 'box_id', 'box', 'card_id', 'name', 'ports', 'interfaces', '_links') + + interfaces = ma.Nested(InterfacesSchema.InterfaceSchema, many=True) + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_logport', box_id='', id=''), + 'collection': ma.URLFor('show_logports', box_id='')}) + + +class LogPortsSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class LogPortSchema(ma.ModelSchema): + class Meta: + model = LogPort + fields = ('id', 'name', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_logport', box_id='', id='')}) + + members = ma.Nested(LogPortSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_logports', box_id='')}) diff --git a/nesi/softbox/api/views/__init__.py b/nesi/softbox/api/views/__init__.py index 2bc77b7..340544e 100644 --- a/nesi/softbox/api/views/__init__.py +++ b/nesi/softbox/api/views/__init__.py @@ -2,4 +2,4 @@ "ontport_views", "cpe_views", "cpeport_views", "vlan_views", "portprofile_views", "emu_views", "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views", - "mgmt_card_views", "mgmt_port_views", "subscriber_views", "portgroupport_views"] + "mgmt_card_views", "mgmt_port_views", "subscriber_views", "portgroupport_views", "logport_views"] diff --git a/nesi/softbox/api/views/box_views.py b/nesi/softbox/api/views/box_views.py index a08b6b9..ba6c867 100644 --- a/nesi/softbox/api/views/box_views.py +++ b/nesi/softbox/api/views/box_views.py @@ -10,6 +10,7 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst +# TODO: When no more new components are being created, update new_box, clone_box, and del_box from .base_views import * from ..models.box_models import Box diff --git a/nesi/softbox/api/views/logport_views.py b/nesi/softbox/api/views/logport_views.py new file mode 100644 index 0000000..81b49c8 --- /dev/null +++ b/nesi/softbox/api/views/logport_views.py @@ -0,0 +1,53 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from ..schemas.logport_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//logports', methods=['GET']) +def show_logports(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(LogPortsSchema(), LogPort, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//logports/', methods=['GET']) +def show_logport(box_id, id): + response = show_component(LogPort, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//logports', methods=['POST']) +def new_logport(box_id): + req = flask.request.json + response = new_component(LogPortSchema(), LogPort, req, box_id) + return response, 201 + + +@app.route(PREFIX + '/boxen//logports/', methods=['PUT']) +def update_logport(box_id, id): + req = flask.request.json + update_component(LogPort, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//logports/', methods=['DELETE']) +def del_logport(box_id, id): + del_component(LogPort, box_id, id) + return flask.Response(status=204) diff --git a/nesi/softbox/base_resources/box.py b/nesi/softbox/base_resources/box.py index df93d87..b050b5c 100644 --- a/nesi/softbox/base_resources/box.py +++ b/nesi/softbox/base_resources/box.py @@ -113,10 +113,6 @@ def vlans(self): def service_vlans(self): raise PropertyNotFoundError("abstract service_vlans properties") - @property - def vlans_connections(self): - raise PropertyNotFoundError("abstract vlans properties") - @property def port_profiles(self): raise PropertyNotFoundError("abstract port_profiles properties") diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 9e76d86..d8faa3b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -14,7 +14,7 @@ from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor -class LogPortsCommandProcessor(BaseCommandProcessor): +class LogportsCommandProcessor(BaseCommandProcessor): __name__ = 'logports' management_functions = ('main', 'cfgm') access_points = () @@ -23,12 +23,11 @@ class LogPortsCommandProcessor(BaseCommandProcessor): from .logportsManagementFunctions import cfgm def _init_access_points(self, context=None): # work in progress - card = self._model.get_card('name', context['unit']) - logports = context['logports'] + card = self._model.get_card('name', self._parent.component_id) - for port in self._model.get_ports('card_id', card.id): - if port.name.count('/') == 2 and port.name.strip('/')[1] == 'logports-' + logports: - identifier = 'port-' + port.name.split('/')[-1] + for logport in self._model.get_logports('card_id', card.id): + if logport.name.count('/') == 2: + identifier = 'logport-' + logport.name.split('/')[-1] if identifier in self.access_points: continue self.access_points += (identifier,) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py index d281df9..b9fc7b2 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsManagementFunctions.py @@ -8,10 +8,10 @@ } cfgm = { - 'General': { - 'Cmd': { - 'CreatePort', - 'DeletePort' - } + 'Logicalport': { + 'Cmd': ( + 'Create', + 'Delete' + ) } } \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 193cfe5..7f277c8 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -14,21 +14,24 @@ from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor -class LogPortCommandProcessor(PortCommandProcessor): +class LogportCommandProcessor(PortCommandProcessor): __name__ = 'logport' - management_functions = ('main', 'cfgm', 'status') + management_functions = ('main', 'cfgm', 'fm', 'pm', 'status', 'ifMIB') access_points = () from .logportManagementFunctions import main from .logportManagementFunctions import cfgm + from .logportManagementFunctions import fm + from .logportManagementFunctions import pm from .logportManagementFunctions import status + from .logportManagementFunctions import ifMIB - def do_get(self, command, *args, context=None): + def get_property(self, command, *args, context=None): scopes = ('login', 'base', 'get') try: - super().do_get(command, *args, context=None) + super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: - if self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': + if self._validate((args[0],), 'AttainableRate') and context['component_path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) else: @@ -36,7 +39,18 @@ def do_get(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors')) def _init_access_points(self, context=None): - port = self._model.get_port('name', context['unit'] + '/' + context['portgroup'] + '/' + context['port']) + logport_name = self._parent._parent.component_id + '/L/' + self.component_id + logport = self._model.get_logport('name', logport_name) + try: + _ = self._model.get_interface('logport_id', logport.id) + except exceptions.SoftboxenError: + pass + else: + for interface in self._model.get_interfaces('logport_id', logport.id): + identifier = 'interface-' + interface.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) @@ -44,7 +58,7 @@ def on_unknown_command(self, command, *args, context=None): def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') try: - super().set(command, *args, context=None) + super().set(command, *args, context=context) except exceptions.CommandExecutionError: if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py index 5add929..f2fa827 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportManagementFunctions.py @@ -1,264 +1,313 @@ main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'AdminAndOperStatus': { - 'Prop': { - 'AdministrativeStatus': 'rw', - 'OperationalStatus': 'r-' + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + }, + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } } } -} cfgm = { - 'Multicast': { - 'Prop': { - 'MaxNumberOfMulticastStreams': 'rw', - 'EnableIgmpClassifier': 'rw', - 'AllowStaticStreams': 'rw', - 'EnableFastLeave': 'rw', - 'GroupManagement': 'rw', - 'Bandwidth': 'rw' + 'Multicast': { + 'Prop': { + 'MaxNumberOfMulticastStreams': 'rw', + 'EnableIgmpClassifier': 'rw', + 'AllowStaticStreams': 'rw', + 'EnableFastLeave': 'rw', + 'GroupManagement': 'rw', + 'Bandwidth': 'rw' + }, + 'Cmd': ( + 'GetGroupList', + ) }, - 'Cmd': ( - 'GetGroupList', - ) - }, - 'Traceability': { - 'Prop': { - 'AgentRemoteId': 'rw' - } - }, - 'Security': { - 'Prop': { - 'ServiceOptions': 'rw', - 'MaxNumberOfMac': 'rw' - } - }, - 'AccessControl': { - 'Prop': { - 'ClassificationKey': 'rw', - 'MAT': 'rw' - } - }, - 'RateLimiter': { - 'Prop': { - 'RateLimiting': 'rw', - 'RateLimitingCoS': 'rw' - } - }, - 'Qos': { - 'Prop': { - 'WfqProfile': 'rw' - } - }, - 'Wire': { - 'Prop': { - 'MeltConfiguration': 'rw' - } - }, - 'Profiles': { - 'Prop': { - 'PortProfiles': 'rw' - } - }, - 'Misc': { - 'Prop': { - 'SpecificDPBO': 'rw', - 'SpecificUPBO': 'rw' + 'Traceability': { + 'Prop': { + 'AgentRemoteId': 'rw' + } + }, + 'Security': { + 'Prop': { + 'ServiceOptions': 'rw', + 'MaxNumberOfMac': 'rw' + } + }, + 'AccessControl': { + 'Prop': { + 'ClassificationKey': 'rw', + 'MAT': 'rw' + } + }, + 'RateLimiter': { + 'Prop': { + 'RateLimiting': 'rw', + 'RateLimitingCoS': 'rw' + } + }, + 'Qos': { + 'Prop': { + 'WfqProfile': 'rw' + } + }, + 'subinterface': { + 'Cmd': ( + 'CreateInterface', + 'DeleteInterface' + ) + }, + 'Clock': { + 'Prop': { + 'Referenceclk': 'rw' + } } } -} -status = { - 'General': { - 'Prop': { - 'Standard': 'r-', - 'PowerMgmStatus': 'r-', - 'Vdsl2Parameters': 'r-', - 'EstUPBOElectricalLength': 'r-', - 'LineRate': 'r-', - 'LineSnrMargin': 'r-', - 'AttainableNetDataRate': 'r-', - 'AttainableRate': 'r-', - 'OutputPower': 'r-', - 'BandStatus': 'r-' +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } } - }, - 'statistics': { - 'Prop': { - 'counters': 'r-', - 'PolicingCounters': 'r-' + } + +pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } }, - 'Cmd': ( - 'ResetPortCounters', - ) - }, - 'Nto1MacAccessDynamicList': { - 'Prop': { - 'UnicastList': 'r-' + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) } - }, - 'HostPortStatistics': { - 'GeneralCounters': { + } + +status = { + 'statistics': { 'Prop': { - 'GeneralList': 'r-' + 'counters': 'r-', + 'PolicingCounters': 'r-' }, 'Cmd': ( - 'ResetGeneralCounters', + 'ResetPortCounters', ) }, - 'ProtocolCounters': { - 'IgmpCounters': { - 'Prop': { - 'IgmpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetIgmpCounters', - ) - }, - 'DhcpCounters': { - 'Prop': { - 'DhcpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetDhcpCounters', - ) - }, - 'ArpCounters': { - 'Prop': { - 'ArpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetArpCounters', - ) - }, - 'PPPoECounters': { - 'Prop': { - 'PPPoEProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetPPPoECounters', - ) - }, - 'UnknownSourceMACCounters': { + 'Nto1MacAccessDynamicList': { + 'Prop': { + 'UnicastList': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { 'Prop': { - 'UnknownSrcMACProtocolList': 'r-' + 'GeneralList': 'r-' }, 'Cmd': ( - 'ResetUnknownSrcMACCounters', + 'ResetGeneralCounters', ) }, - }, - }, - 'TLSMacForwardingList': { - 'Prop': { - 'MacForwardingList': 'r-' - }, - 'Cmd': ( - 'FlushMacForwardingList', - ) - }, - '1to1MacForwardingList': { - 'Prop': { - 'One2OneMacForwardingList': 'r-' - } - }, - 'Qos': { - 'Prop': { - 'wfqueues': 'r-' - } - }, - 'Multicast': { - 'stream': { - 'Dynamic': { - 'Prop': { - 'ActiveStreams': 'r-' + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) }, - 'Cmd': ( - 'ClearActiveStreams', + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'Dhcpv6Counters': { + 'Prop': { + 'Dhcpv6ProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpv6Counters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + 'Ndp': { + 'Prop': { + 'NdpList': 'r-' + }, + 'Cmd': ( + 'ResetNdpCounters', ) }, - 'Static': { - 'Prop': { - 'StaticStreams': 'r-' - } }, }, - - 'Vlan': { + 'TLSMacForwardingList': { 'Prop': { - 'AttachedVlans': 'r-' - } - }, - 'Preview': { + 'MacForwardingList': 'r-' + }, 'Cmd': ( - 'ResetPreviewSettings', + 'FlushMacForwardingList', ) }, - 'Bandwidth': { + '1to1MacForwardingList': { 'Prop': { - 'bandwidthStatus': 'r-' + 'One2OneMacForwardingList': 'r-' } }, - }, - 'LineTest': { - 'MELT': { + 'Qos': { 'Prop': { - 'MeltResults': 'r-' - }, + 'wfqueues': 'r-' + } + }, + 'Support': { 'Cmd': ( - 'StartMeltMeasurement', - ) + 'StartReport', + ), + 'File': { + 'ReportFile': 'r-' + } }, - 'Delt': { - 'Prop': { - 'DeltMeasurementStatus': 'r-', - 'RecordedDeltMeasurements': 'r-' + 'Multicast': { + 'stream': { + 'Dynamic': { + 'Prop': { + 'ActiveStreams': 'r-' + }, + 'Cmd': ( + 'ClearActiveStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticStreams': 'r-' + } + }, + }, + + 'Vlan': { + 'Prop': { + 'AttachedVlans': 'r-' + } + }, + 'Preview': { + 'Cmd': ( + 'ResetPreviewSettings', + ) + }, + 'Bandwidth': { + 'Prop': { + 'bandwidthStatus': 'r-' + } }, - 'Cmd': ( - 'StartDeltMeasurement', - ) }, - 'Selt': { + 'General': { 'Prop': { - 'SeltMeasurementStatus': 'r-', - 'RecordedSeltMeasurements': 'r-', - 'CableType': 'rw', - 'BandplanProfile': 'rw', - 'TargetSnrm': 'rw' - }, - 'Cmd': ( - 'StartSeltMeasurement', - ) + 'OperationalWireState': 'r-', + 'ActualStatus': 'r-', + 'DSLMode': 'r-', + 'ReferenceCLK': 'r-' + } }, - }, - 'Defects': { - 'Prop': { - 'Defects': 'r-' - } - }, - 'LineInventory': { - 'Prop': { - 'VendorId': 'r-' - } - }, - 'Maintenance': { - 'Prop': { - 'DslOperationStatus': 'r-' + 'Inventory': { + 'Prop': { + 'Inventory': 'r-' + } } - }, - 'Subcarrier': { - 'Cmd': ( - 'ShowBitAllocation', - ) - }, - 'RfiBands': { - 'Prop': { - 'NotchStatus': 'r-' + } + +ifMIB = { + 'Interfaces': { + 'Prop': { + 'IfTable': 'rw' + } + }, + 'IfMIB': { + 'Objects': { + 'Prop': { + 'XTable': 'rw', + 'StackTable': 'rw' + } + + } } } -} diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 4e8d4dd..87b94de 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -30,6 +30,13 @@ def _init_access_points(self, context=None): self.management_functions = ('main', 'cfgm', 'fm', 'status') + try: + _ = self._model.get_logport('card_id', card.id) + except exceptions.SoftboxenError: + pass + else: + self.access_points += ('logports',) + for port in self._model.get_ports('card_id', card.id): identifier = 'port-' + port.name.split('/')[-1] if identifier in self.access_points: diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 3ed7fe9..8fc80b6 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -205,7 +205,7 @@ def change_directory(self, path, context=None): components = [x for x in path.split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|logports|logport-[0-9]|\.|\.\.)$', components[0]): raise exceptions.SoftboxenError() @@ -301,6 +301,11 @@ def change_directory(self, path, context=None): if self.__name__ != 'port' and self.__name__ != 'chan': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'logport': + if self.__name__ != 'logports': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): if self.__name__ != 'root': raise exceptions.CommandExecutionError(command=None, template=None, @@ -331,6 +336,9 @@ def change_directory(self, path, context=None): PortgroupCommandProcessor from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import \ PortgroupportCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.logport.logportsCommandProcessor import LogportsCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ + LogportCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if component_id is not None and self.component_id is not None: @@ -379,7 +387,9 @@ def get_parent_and_child_relation(self, search, parent=None, node=None, parent_k } }, "portgroups": {"portgroupports": {}}, - "logports": {"logport": {}}, + "logports": { + "logport": { + "interface": {}}}, "vectoringports": {"vectorport": {}}, "internalports": {"internalport": {}} }, @@ -490,6 +500,9 @@ def get_command_processor(self, current_processor, component_type=None): PortgroupCommandProcessor from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import \ PortgroupportCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.logport.logportsCommandProcessor import LogportsCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ + LogportCommandProcessor if current_processor.__class__ == RootCommandProcessor: return_to = RootCommandProcessor if component_type not in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services', 'unit') \ @@ -498,7 +511,7 @@ def get_command_processor(self, current_processor, component_type=None): template_scopes=()) # TODO: fix exception to not require all fields as empty elif current_processor.__class__ == UnitCommandProcessor: return_to = RootCommandProcessor - if component_type != 'port' and component_type is not None: + if (component_type != 'port' or component_type != 'logports') and component_type is not None: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif current_processor.__class__ == PortCommandProcessor: @@ -512,6 +525,7 @@ def get_command_processor(self, current_processor, component_type=None): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif current_processor.__class__ == InterfaceCommandProcessor: + return_to = LogportCommandProcessor return_to = ChanCommandProcessor return_to = PortCommandProcessor elif current_processor.__class__ == FanCommandProcessor: @@ -530,6 +544,10 @@ def get_command_processor(self, current_processor, component_type=None): return_to = PortgroupCommandProcessor elif current_processor.__class__ == PortgroupCommandProcessor: return_to = UnitCommandProcessor + elif current_processor.__class__ == LogportsCommandProcessor: + return_to = UnitCommandProcessor + elif current_processor.__class__ == LogportCommandProcessor: + return_to = LogportsCommandProcessor return return_to From afeb7d440e3cb256668080c1813af6ececba785c Mon Sep 17 00:00:00 2001 From: png2000 Date: Wed, 14 Oct 2020 12:29:11 +0200 Subject: [PATCH 233/318] Resolved merge conflicts --- nesi/keymile/keymile_resources/keymile_box.py | 2 ++ nesi/softbox/api/schemas/box_schemas.py | 2 +- vendors/KeyMile/accessPoints/root/rootCommandProcessor.py | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 6e462e0..2d83fcd 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -30,6 +30,8 @@ class KeyMileBox(Box): currTemperature = base.Field("currTemperature") + currTemperature = base.Field("currTemperature") + @property def channels(self): """Return `ChannelCollection` object.""" diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index 5cfa939..8ca7c8b 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -36,7 +36,7 @@ class Meta: 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'mgmt_cards', 'mgmt_ports', - 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links', 'currTemperature') + 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', 'currTemperature', '_links') credentials = ma.Hyperlinks( {'_links': { diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 0029077..811a236 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -32,6 +32,13 @@ def do_get(self, command, *args, context=None): self._write(self._render('currTemperature', 'login', 'base', 'get', context=context)) + def do_get(self, command, *args, context=None): + if self._validate(args, "CurrTemperature"): + context['currTemperature'] = self._model.currTemperature + context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' + self._write(self._render('currTemperature', 'login', 'base', 'get', context=context)) + + def _init_access_points(self, context=None): for card in self._model.cards: if 'unit-' + card.name in self.access_points: From 5846ac3852ea7e9fd17171b57cfde30618c7bbf7 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 14 Oct 2020 13:41:11 +0200 Subject: [PATCH 234/318] Added Delete logport command --- nesi/keymile/keymile_resources/keymile_box.py | 2 -- .../keymile_resources/keymile_logport.py | 26 +++++++++++++++++++ nesi/softbox/api/models/logport_models.py | 5 ++++ nesi/softbox/api/schemas/logport_schemas.py | 4 ++- .../accessPoints/root/rootCommandProcessor.py | 14 +++++----- .../unit/logport/logportsCommandProcessor.py | 19 ++++++++++++-- .../logport/port/logportCommandProcessor.py | 4 +++ .../root/unit/unitCommandProcessor.py | 1 - 8 files changed, 62 insertions(+), 13 deletions(-) diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 2d83fcd..6e462e0 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -30,8 +30,6 @@ class KeyMileBox(Box): currTemperature = base.Field("currTemperature") - currTemperature = base.Field("currTemperature") - @property def channels(self): """Return `ChannelCollection` object.""" diff --git a/nesi/keymile/keymile_resources/keymile_logport.py b/nesi/keymile/keymile_resources/keymile_logport.py index 0655631..e619636 100644 --- a/nesi/keymile/keymile_resources/keymile_logport.py +++ b/nesi/keymile/keymile_resources/keymile_logport.py @@ -23,6 +23,32 @@ class KeyMileLogPort(base.Resource): name = base.Field('name') card_id = base.Field('card_id') ports = base.Field('ports') + label1 = base.Field('label1') + label2 = base.Field('label2') + description = base.Field('description') + admin_state = base.Field('admin_state') + operational_state = base.Field('operational_state') + + def admin_up(self): + """Set the admin port state to up""" + self.update(admin_state='1') + + def admin_down(self): + """Set the admin port state to down""" + self.update(admin_state='0') + + def down(self): + """Set the port state to down""" + self.update(operational_state='0') + + def up(self): + """Set the port state to down""" + self.update(operational_state='1') + + def set_label(self, l1, l2, desc): + self.update(label1=l1) + self.update(label2=l2) + self.update(description=desc) class KeyMileLogPortCollection(base.ResourceCollection): diff --git a/nesi/softbox/api/models/logport_models.py b/nesi/softbox/api/models/logport_models.py index df96174..c5d471d 100644 --- a/nesi/softbox/api/models/logport_models.py +++ b/nesi/softbox/api/models/logport_models.py @@ -21,3 +21,8 @@ class LogPort(db.Model): box_id = db.Column(db.Integer, db.ForeignKey('box.id')) card_id = db.Column(db.Integer, db.ForeignKey('card.id')) interfaces = db.relationship('Interface', backref='LogPort', lazy='dynamic') + label1 = db.Column(db.String(), default='""') + label2 = db.Column(db.String(), default='""') + description = db.Column(db.String(), default='""') + operational_state = db.Column(db.Enum('0', '1'), default='0') + admin_state = db.Column(db.Enum('0', '1'), default='0') diff --git a/nesi/softbox/api/schemas/logport_schemas.py b/nesi/softbox/api/schemas/logport_schemas.py index 059ea12..28b634e 100644 --- a/nesi/softbox/api/schemas/logport_schemas.py +++ b/nesi/softbox/api/schemas/logport_schemas.py @@ -18,7 +18,9 @@ class LogPortSchema(ma.ModelSchema): class Meta: model = LogPort - fields = ('id', 'box_id', 'box', 'card_id', 'name', 'ports', 'interfaces', '_links') + fields = ('id', 'box_id', 'box', 'card_id', 'name', 'ports', 'interfaces', 'description', 'admin_state', + 'operational_state', 'label1', 'label2', + '_links') interfaces = ma.Nested(InterfacesSchema.InterfaceSchema, many=True) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 811a236..9bff9eb 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -32,12 +32,6 @@ def do_get(self, command, *args, context=None): self._write(self._render('currTemperature', 'login', 'base', 'get', context=context)) - def do_get(self, command, *args, context=None): - if self._validate(args, "CurrTemperature"): - context['currTemperature'] = self._model.currTemperature - context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' - self._write(self._render('currTemperature', 'login', 'base', 'get', context=context)) - def _init_access_points(self, context=None): for card in self._model.cards: @@ -84,5 +78,11 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def get_property(self, command, *args, context=None): - raise exceptions.CommandExecutionError(command=command, template='invalid_property', + scopes = ('login', 'base', 'set') + if self._validate(args, "CurrTemperature"): + context['currTemperature'] = self._model.currTemperature + context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' + self._write(self._render('currTemperature', *scopes, context=context)) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index d8faa3b..b4817e3 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -35,6 +35,21 @@ def _init_access_points(self, context=None): # work in progress def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + def do_delete(self, command, *args, context=None): + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm': + name, = self._dissect(args, str) + if name.startswith('logport-'): + id = name.split('-')[1] + try: + port = self._model.get_logport('name', self._parent.component_id + '/L/' + id) + port.delete() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -42,8 +57,8 @@ def set(self, command, *args, context=None): exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case + name, = self._dissect(args, 'test', str) + #todo testcase return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 7f277c8..3ca08bb 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -27,6 +27,7 @@ class LogportCommandProcessor(PortCommandProcessor): from .logportManagementFunctions import ifMIB def get_property(self, command, *args, context=None): + port = self.get_port_component() scopes = ('login', 'base', 'get') try: super().get_property(command, *args, context=context) @@ -38,6 +39,9 @@ def get_property(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + def get_port_component(self): + return self._model.get_logport('name', self._parent._parent.component_id + '/L/' + self.component_id) + def _init_access_points(self, context=None): logport_name = self._parent._parent.component_id + '/L/' + self.component_id logport = self._model.get_logport('name', logport_name) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 87b94de..8bfcb36 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -51,7 +51,6 @@ def _init_access_points(self, context=None): except exceptions.InvalidInputError: pass - # todo: add portgroup to access_points def get_property(self, command, *args, context=None): card = self._model.get_card('name', self.component_id) From 0e40644fa85a08e866c1a3207f53fae80d874120 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 14 Oct 2020 15:32:12 +0200 Subject: [PATCH 235/318] Added create logport command --- nesi/keymile/keymile_resources/keymile_box.py | 9 +++++- .../unit/logport/logportsCommandProcessor.py | 28 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 6e462e0..50c5f92 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -109,6 +109,13 @@ def get_logports(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'logports'), params={field: value}) + def add_logport(self, **fields): + """Add new logport.""" + return keymile_logport.KeyMileLogPort.create( + self._conn, + os.path.join(self.path, 'logports'), + **fields) + def get_chan(self, field, value): """Get specific channel object.""" return keymile_channel.KeyMileChannelCollection( @@ -145,7 +152,7 @@ def get_subscribers(self, field, value): params={field: value}) def add_subscriber(self, **fields): - """Add new ont.""" + """Add new subscriber.""" return keymile_subscriber.KeymileSubscriber.create( self._conn, os.path.join(self.path, 'subscribers'), diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index b4817e3..0946d86 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -31,6 +31,9 @@ def _init_access_points(self, context=None): # work in progress if identifier in self.access_points: continue self.access_points += (identifier,) + accpoint = list(self.access_points) + accpoint.sort(key=lambda x: int(x.split('-')[1])) + self.access_points = tuple(accpoint) def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) @@ -50,6 +53,31 @@ def do_delete(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_create(self, command, *args, context=None): + if self._validate(args, str, str, str, str) and context['component_path'].split('/')[-1] == 'cfgm': + p1, p2, p3, p4, = self._dissect(args, str, str, str, str) + ids = [] + ids.append(int(p1.split('-')[1])) if p1.startswith('port-') else ids + ids.append(int(p2.split('-')[1])) if p2.startswith('port-') else ids + ids.append(int(p3.split('-')[1])) if p3.startswith('port-') else ids + ids.append(int(p4.split('-')[1])) if p4.startswith('port-') else ids + if len(ids) >= 0: + ids.sort() + try: + for x in ids: + _ = self._model.get_logport('name', self._parent.component_id + '/L/' + str(x)) + break + except exceptions.SoftboxenError: + name = self._parent.component_id + '/L/' + str(ids[0]) + ports = 'ports: ' + for x in ids: + ports += str(x) + ', ' + logport = self._model.add_logport(card_id=self._parent.component_id, name=name, ports=ports[:-2]) + else: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) From 0c71976f2e8a8fed3393eb92257ffc1ab1289150 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 15 Oct 2020 11:27:43 +0200 Subject: [PATCH 236/318] Added Set and Get for proxy, registrar and sip --- .../api/schemas/keymile_card_schemas.py | 9 ++- .../keymile/keymile_resources/keymile_card.py | 66 +++++++++++++++++ nesi/softbox/api/models/card_models.py | 38 ++++++++++ nesi/softbox/cli/base.py | 4 +- templates/KeyMile/login/base/get/proxy.j2 | 13 ++++ templates/KeyMile/login/base/get/registrar.j2 | 6 ++ templates/KeyMile/login/base/get/sip.j2 | 28 ++++---- .../accessPoints/root/rootCommandProcessor.py | 6 ++ .../root/unit/unitCommandProcessor.py | 70 ++++++++++++++++++- 9 files changed, 221 insertions(+), 19 deletions(-) create mode 100644 templates/KeyMile/login/base/get/proxy.j2 create mode 100644 templates/KeyMile/login/base/get/registrar.j2 diff --git a/nesi/keymile/api/schemas/keymile_card_schemas.py b/nesi/keymile/api/schemas/keymile_card_schemas.py index 7b658b8..eeaf6aa 100644 --- a/nesi/keymile/api/schemas/keymile_card_schemas.py +++ b/nesi/keymile/api/schemas/keymile_card_schemas.py @@ -20,4 +20,11 @@ class Meta: 'software_name', 'software_revision', 'state', 'serial_number', 'manufacturer_name', 'model_name', 'short_text', 'manufacturer_id', 'manufacturer_part_number', 'manufacturer_build_state', 'customer_id', - 'customer_product_id', 'boot_loader', 'processor', 'label1', 'label2') + 'customer_product_id', 'boot_loader', 'processor', 'label1', 'label2', + 'gateway_name', 'home_domain', 'sip_port_number', 'country_code', 'area_code', + 'retransmission_timer', 'max_retransmission_interval', 'sip_extension', + 'asserted_id_mode', 'overlap_signalling', 'overlap_timer', + 'uac_request_timer', 'uas_request_timer', 'session_expiration', 'proxy_mode', + 'proxy_address', 'proxy_port', 'proxy_address_sec', 'proxy_port_sec', + 'proxy_enable', 'proxy_method', 'proxy_interval', 'registrar_adress', + 'registrar_port', 'registration_mode', 'registration_expiration_time') diff --git a/nesi/keymile/keymile_resources/keymile_card.py b/nesi/keymile/keymile_resources/keymile_card.py index 7680fbc..71fae65 100644 --- a/nesi/keymile/keymile_resources/keymile_card.py +++ b/nesi/keymile/keymile_resources/keymile_card.py @@ -41,11 +41,77 @@ class KeyMileCard(Card): label1 = base.Field('label1') label2 = base.Field('label2') + # Keymile ipsx2/3 card SIP specifications + gateway_name = base.Field('gateway_name') + home_domain = base.Field('home_domain') + sip_port_number = base.Field('sip_port_number') + country_code = base.Field('country_code') + area_code = base.Field('area_code') + retransmission_timer = base.Field('retransmission_timer') + max_retransmission_interval = base.Field('max_retransmission_interval') + sip_extension = base.Field('sip_extension') + asserted_id_mode = base.Field('asserted_id_mode') + overlap_signalling = base.Field('overlap_signalling') + overlap_timer = base.Field('overlap_timer') + uac_request_timer = base.Field('uac_request_timer') + uas_request_timer = base.Field('uas_request_timer') + session_expiration = base.Field('session_expiration') + # Keymile ipsx2/3 card Proxy specification + proxy_mode = base.Field('proxy_mode') + proxy_address = base.Field('proxy_address') + proxy_port = base.Field('proxy_port') + proxy_address_sec = base.Field('proxy_address_sec') + proxy_port_sec = base.Field('proxy_port_sec') + proxy_enable = base.Field('proxy_enable') + proxy_method = base.Field('proxy_method') + proxy_interval = base.Field('proxy_interval') + # Keymile ipsx2/3 card Registrar specification + registrar_adress = base.Field('registrar_adress') + registrar_port = base.Field('registrar_port') + registration_mode = base.Field('registration_mode') + registration_expiration_time = base.Field('registration_expiration_time') + + def set_sip(self, gateway_name, home_domain, sip_port_number, country_code, area_code, retransmission_timer, + max_retransmission_interval, sip_extension, asserted_id_mode, overlap_signalling, overlap_timer, + uac_request_timer, uas_request_timer, session_expiration): + self.update(gateway_name=gateway_name) + self.update(home_domain=home_domain) + self.update(sip_port_number=sip_port_number) + self.update(country_code=country_code) + self.update(area_code=area_code) + self.update(retransmission_timer=retransmission_timer) + self.update(max_retransmission_interval=max_retransmission_interval) + self.update(sip_extension=sip_extension) + self.update(asserted_id_mode=asserted_id_mode) + self.update(overlap_signalling=overlap_signalling) + self.update(overlap_timer=overlap_timer) + self.update(uac_request_timer=uac_request_timer) + self.update(uas_request_timer=uas_request_timer) + self.update(session_expiration=session_expiration) + + def set_label(self, l1, l2, desc): self.update(label1=l1) self.update(label2=l2) self.update(description=desc) + def set_proxy(self, proxy_mode, proxy_address, proxy_port, proxy_address_sec, proxy_port_sec, proxy_enable, + proxy_method, proxy_interval): + self.update(proxy_mode=proxy_mode) + self.update(proxy_address=proxy_address) + self.update(proxy_port=proxy_port) + self.update(proxy_address_sec=proxy_address_sec) + self.update(proxy_port_sec=proxy_port_sec) + self.update(proxy_enable=proxy_enable) + self.update(proxy_method=proxy_method) + self.update(proxy_interval=proxy_interval) + + def set_registrar(self, registrar_adress, registrar_port, registration_mode, registration_expiration_time): + self.update(registrar_adress=registrar_adress) + self.update(registrar_port=registrar_port) + self.update(registration_mode=registration_mode) + self.update(registration_expiration_time=registration_expiration_time) + class KeyMileCardCollection(CardCollection): """Represent a collection of cards.""" diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index aa1855f..f3fc2f9 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -103,3 +103,41 @@ class Card(db.Model): processor = db.Column(db.String(), default='') label1 = db.Column(db.String(), default='""') label2 = db.Column(db.String(), default='""') + + # Keymile ipsx2/3 card SIP specifications + gateway_name = db.Column(db.String(), default='""') + home_domain = db.Column(db.String(), default='""') + sip_port_number = db.Column(db.Integer(), default=0) + country_code = db.Column(db.String(), default='') + area_code = db.Column(db.String(), default='') + retransmission_timer = db.Column(db.Integer(), default=0) + max_retransmission_interval = db.Column(db.Integer(), default=0) + sip_extension = db.Column(db.Boolean, default=False) + asserted_id_mode = db.Column(db.Enum('Asserted', 'Preferred'), default=None) + overlap_signalling = db.Column(db.Boolean, default=False) + overlap_timer = db.Column(db.Integer(), default=0) + uac_request_timer = db.Column(db.Boolean, default=False) + uas_request_timer = db.Column(db.Boolean, default=False) + session_expiration = db.Column(db.Integer(), default=0) + # Keymile ipsx2/3 card Proxy specification + proxy_mode = db.Column(db.Enum('PrimaryOnly', 'Revertive', 'NonRevertive', 'DnsRfc3263'), default='PrimaryOnly') + proxy_address = db.Column(db.String(), default='""') + proxy_port = db.Column(db.Integer(), default=5060) + proxy_address_sec = db.Column(db.String(), default='""') + proxy_port_sec = db.Column(db.Integer(), default=0) + proxy_enable = db.Column(db.Boolean, default=True) + proxy_method = db.Column(db.Enum('Options', 'Register'), default='Options') + proxy_interval = db.Column(db.Integer(), default=10) + # Keymile ipsx2/3 card Registrar specification + registrar_adress = db.Column(db.String(), default='') + registrar_port = db.Column(db.Integer(), default=5060) + registration_mode = db.Column(db.Enum('NoRegistration', 'OneByOneRegistration'), default='OneByOneRegistration') + registration_expiration_time = db.Column(db.Integer(), default=100) + + + # Keymile ipsx2/3 card digimap specification + #digimap_uri_schema = db.Column(db.Enum('sip', 'tel'), default='sip') + #digit_map = db.Column(db.String(), default='') + #digimap_domain_phone_context = db.Column(db.String(), default='') + #digimap_prestrip = db.Column(db.Integer(), default=0) + #digimap_prepend = db.Column(db.String(), default='') diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 04cbce4..500f646 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -449,8 +449,8 @@ def _dissect(self, args, *tokens): raise exceptions.CommandSyntaxError(command=' '.join(args)) if self.case_sensitive is False: - arg = arg.lower() if not isinstance(token, type): + arg = arg.lower() token = token.lower() if type(token) == type: @@ -472,8 +472,8 @@ def _validate(self, args, *tokens): return False if self.case_sensitive is False: - arg = arg.lower() if not isinstance(token, type): + arg = arg.lower() token = token.lower() if arg != token and type(token) != type: diff --git a/templates/KeyMile/login/base/get/proxy.j2 b/templates/KeyMile/login/base/get/proxy.j2 new file mode 100644 index 0000000..c20a356 --- /dev/null +++ b/templates/KeyMile/login/base/get/proxy.j2 @@ -0,0 +1,13 @@ + \ # Proxy +{{ context.card.proxy_mode }}{{ context.spacer1 }}\ # ProxyMode + \ # PrimaryProxy +{{ context.card.proxy_address | safe }}{{ context.spacer2 }}\ # ProxyAddress +{{ context.card.proxy_port }}{{ context.spacer3 }}\ # ProxyPort + \ # SecondaryProxy +{{ context.card.proxy_address_sec | safe }}{{ context.spacer4 }}\ # ProxyAddress +{{ context.card.proxy_port_sec }}{{ context.spacer5 }}\ # ProxyPort + \ # ProxyAvailabilityCheck +{{ context.card.proxy_enable }}{{ context.spacer6 }}\ # Enabled +{{ context.card.proxy_method }}{{ context.spacer7 }}\ # Method +{{ context.card.proxy_interval }}{{ context.spacer8 }}\ # Interval + diff --git a/templates/KeyMile/login/base/get/registrar.j2 b/templates/KeyMile/login/base/get/registrar.j2 new file mode 100644 index 0000000..e4da7e2 --- /dev/null +++ b/templates/KeyMile/login/base/get/registrar.j2 @@ -0,0 +1,6 @@ + \ # Registrar +{{ context.card.registrar_adress | safe }}{{ context.spacer1 }}\ # RegistrarAddress +{{ context.card.registrar_port }}{{ context.spacer2 }}\ # RegistrarPort +{{ context.card.registration_mode }}{{ context.spacer3 }}\ # RegistrationMode +{{ context.card.registration_expiration_time }}{{ context.spacer4 }}\ # RegistrationExpirationTime + diff --git a/templates/KeyMile/login/base/get/sip.j2 b/templates/KeyMile/login/base/get/sip.j2 index fa1eed3..6bfb4e9 100644 --- a/templates/KeyMile/login/base/get/sip.j2 +++ b/templates/KeyMile/login/base/get/sip.j2 @@ -1,17 +1,17 @@ \ # sip -"Name" \ # GatewayName -"hab.dich.loieb.net" \ # HomeDomain -500 \ # SipPortNumber -"+49" \ # CountryCode -"6567" \ # AreaCode -500 \ # RetransmissionTimerT1 -4 \ # MaxRetransmissionIntervalT2 -false \ # SipExtension100relRequired -None \ # assertedIdentityMode -true \ # OverlapSignalling -30 \ # OverlapT10timer +{{ context.card.gateway_name | safe }}{{ context.spacer1 }}\ # GatewayName +{{ context.card.home_domain | safe }}{{ context.spacer2 }}\ # HomeDomain +{{ context.card.sip_port_number }}{{ context.spacer3 }}\ # SipPortNumber +"{{ context.card.country_code | safe }}"{{ context.spacer4 }}\ # CountryCode +"{{ context.card.area_code | safe }}"{{ context.spacer5 }}\ # AreaCode +{{ context.card.retransmission_timer }}{{ context.spacer6 }}\ # RetransmissionTimerT1 +{{ context.card.max_retransmission_interval }}{{ context.spacer7 }}\ # MaxRetransmissionIntervalT2 +{{ context.card.sip_extension }}{{ context.spacer8 }}\ # SipExtension100relRequired +{{ context.card.asserted_id_mode }}{{ context.spacer9 }}\ # assertedIdentityMode +{{ context.card.overlap_signalling }}{{ context.spacer10 }}\ # OverlapSignalling +{{ context.card.overlap_timer }}{{ context.spacer11 }}\ # OverlapT10timer \ # SessionTimer -false \ # UacRequestSessionTimer -false \ # UasRequestSessionTimer -1800 \ # SessionExpiration +{{ context.card.uac_request_timer }}{{ context.spacer12 }}\ # UacRequestSessionTimer +{{ context.card.uas_request_timer }}{{ context.spacer13 }}\ # UasRequestSessionTimer +{{ context.card.session_expiration }}{{ context.spacer14 }}\ # SessionExpiration diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 9bff9eb..75579bb 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -74,6 +74,12 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + def do_save(self, command, *args, context=None): + if len(args) == 0 and context['component_path'].split('/')[-1] == 'cfgm': + pass + else: + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 8bfcb36..1c4ee08 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -78,8 +78,33 @@ def get_property(self, command, *args, context=None): self._write(text) elif self._validate(args, 'SIP') and context['component_path'].split('/')[-1] == 'cfgm' and \ (card.product == 'isdn' or card.product == 'analog'): - # TODO: dynamic fields - text = self._render('sip', *scopes, context=context) + context['spacer1'] = self.create_spacers((67,), (card.gateway_name,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (card.home_domain,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (card.sip_port_number,))[0] * ' ' + context['spacer4'] = self.create_spacers((65,), (card.country_code,))[0] * ' ' + context['spacer5'] = self.create_spacers((65,), (card.area_code,))[0] * ' ' + context['spacer6'] = self.create_spacers((67,), (card.retransmission_timer,))[0] * ' ' + context['spacer7'] = self.create_spacers((67,), (card.max_retransmission_interval,))[0] * ' ' + context['spacer8'] = self.create_spacers((67,), (card.sip_extension,))[0] * ' ' + context['spacer9'] = self.create_spacers((67,), (card.asserted_id_mode,))[0] * ' ' + context['spacer10'] = self.create_spacers((67,), (card.overlap_signalling,))[0] * ' ' + context['spacer11'] = self.create_spacers((67,), (card.overlap_timer,))[0] * ' ' + context['spacer12'] = self.create_spacers((67,), (card.uac_request_timer,))[0] * ' ' + context['spacer13'] = self.create_spacers((67,), (card.uas_request_timer,))[0] * ' ' + context['spacer14'] = self.create_spacers((67,), (card.session_expiration,))[0] * ' ' + text = self._render('sip', *scopes, context=dict(context, card=card)) + self._write(text) + elif self._validate(args, 'Proxy') and context['component_path'].split('/')[-1] == 'cfgm' and \ + (card.product == 'isdn' or card.product == 'analog'): + context['spacer1'] = self.create_spacers((67,), (card.proxy_mode,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (card.proxy_address,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (card.proxy_port,))[0] * ' ' + context['spacer4'] = self.create_spacers((67,), (card.proxy_address_sec,))[0] * ' ' + context['spacer5'] = self.create_spacers((67,), (card.proxy_port_sec,))[0] * ' ' + context['spacer6'] = self.create_spacers((67,), (card.proxy_enable,))[0] * ' ' + context['spacer7'] = self.create_spacers((67,), (card.proxy_method,))[0] * ' ' + context['spacer8'] = self.create_spacers((67,), (card.proxy_interval,))[0] * ' ' + text = self._render('proxy', *scopes, context=dict(context, card=card)) self._write(text) elif self._validate(args, 'IP') and context['component_path'].split('/')[-1] == 'cfgm' and \ (card.product == 'isdn' or card.product == 'analog'): @@ -94,6 +119,14 @@ def get_property(self, command, *args, context=None): text = self._render('labels', *scopes, context=dict(context, port=card)) self._write(text) + elif self._validate(args, 'Registrar') and context['component_path'].split('/')[-1] == 'cfgm': + context['spacer1'] = self.create_spacers((67,), (card.registrar_adress,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (card.registrar_port,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (card.registration_mode,))[0] * ' ' + context['spacer4'] = self.create_spacers((67,), (card.registration_expiration_time,))[0] * ' ' + text = self._render('registrar', *scopes, context=dict(context, card=card)) + self._write(text) + elif self._validate(args, 'HardwareAndSoftware') and context['component_path'].split('/')[-1] == 'main': unit_hardware = '"' + card.board_name + '"' context['unit_hardware'] = unit_hardware @@ -198,6 +231,10 @@ def get_component(self): return self._model.get_card('name', self.component_id) def set(self, command, *args, context=None): + try: + card = self._model.get_card('name', self.component_id) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' @@ -211,5 +248,34 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'SIP', str, str, str, str, str, str, str, str, str, str, str, str, str, str) and \ + context['component_path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): + gw, hd, spn, cc, ac, rt, mri, se, aim, os, ot, uac, uas, sessione = self._dissect( + args, 'Sip', str, str, str, str, str, str, str, str, str, str, str, str, str, str) + try: + se = True if se.lower() == 'true' else False + os = True if os.lower() == 'true' else False + uac = True if uac.lower() == 'true' else False + uas = True if uas.lower() == 'true' else False + aim = None if aim.lower() == 'none' else aim + + card.set_sip(gw, hd, int(spn), cc, ac, int(rt), int(mri), se, aim, os, int(ot), uac, uas, int(sessione)) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args, 'Registrar', str, str, str, str) and \ + context['component_path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): + ra, rp, rm, rt = self._dissect(args, 'Registrar', str, str, str, str) + try: + card.set_registrar(ra, int(rp), rm, int(rt)) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args, 'Proxy', str, str, str, str, str, str, str, str) and \ + context['component_path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): + pm, pa1, pp1, pa2, pp2, pe, pmethod, pi = self._dissect(args, 'Proxy', str, str, str, str, str, str, str, str) + try: + pe = True if pe.lower() == 'true' else False + card.set_proxy(pm, pa1, int(pp1), pa2, int(pp2), pe, pmethod, int(pi)) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) else: raise exceptions.CommandSyntaxError(command=command) From eb5139b22382905686b8735b32c044394f6c336e Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 15 Oct 2020 14:44:49 +0200 Subject: [PATCH 237/318] Added create and delete of vcc after a chanel --- nesi/keymile/keymile_resources/keymile_box.py | 7 ++ .../keymile_resources/keymile_interface.py | 4 + nesi/softbox/api/models/interface_models.py | 4 + nesi/softbox/api/schemas/interface_schemas.py | 2 +- .../KeyMile/login/base/set/vcc_success.j2 | 3 + .../accessPoints/root/rootCommandProcessor.py | 1 + .../unit/logport/logportsCommandProcessor.py | 1 + .../logport/port/logportCommandProcessor.py | 1 + .../unit/port/chan/chanCommandProcessor.py | 83 +++++++++++++++++-- .../unit/port/chan/vcc/vccCommandProcessor.py | 12 +++ .../root/unit/port/portCommandProcessor.py | 1 + .../portgroup/portgroupCommandProcessor.py | 1 + .../root/unit/unitCommandProcessor.py | 2 +- vendors/KeyMile/baseCommandProcessor.py | 9 +- 14 files changed, 121 insertions(+), 10 deletions(-) create mode 100644 templates/KeyMile/login/base/set/vcc_success.j2 diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 50c5f92..328d755 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -139,6 +139,13 @@ def get_interfaces(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'interfaces'), params={field: value}) + def add_interface(self, **fields): + """Add new interface/vcc.""" + return keymile_interface.KeyMileInterface.create( + self._conn, + os.path.join(self.path, 'interfaces'), + **fields) + def get_subscriber(self, field, value): """Get specific subscriber object.""" return keymile_subscriber.KeymileSubscriberCollection( diff --git a/nesi/keymile/keymile_resources/keymile_interface.py b/nesi/keymile/keymile_resources/keymile_interface.py index 11bcd1e..b827fbe 100644 --- a/nesi/keymile/keymile_resources/keymile_interface.py +++ b/nesi/keymile/keymile_resources/keymile_interface.py @@ -27,6 +27,10 @@ class KeyMileInterface(base.Resource): chan_id = base.Field('chan_id') logport_id = base.Field('logport_id') + #vcc + vcc_profile = base.Field('vcc_profile') + vlan_profile = base.Field('vlan_profile') + class KeyMileInterfaceCollection(base.ResourceCollection): """Represent a collection of interfaces.""" diff --git a/nesi/softbox/api/models/interface_models.py b/nesi/softbox/api/models/interface_models.py index d37fede..b8e3322 100644 --- a/nesi/softbox/api/models/interface_models.py +++ b/nesi/softbox/api/models/interface_models.py @@ -21,3 +21,7 @@ class Interface(db.Model): chan_id = db.Column(db.Integer, db.ForeignKey('channel.id')) port_id = db.Column(db.Integer, db.ForeignKey('port.id')) logport_id = db.Column(db.Integer, db.ForeignKey('log_port.id')) + + #vcc + vcc_profile = db.Column(db.String(), default=None) # default or profile_name, default:= vpi=0 and vci=33 + vlan_profile = db.Column(db.String(), default=None) # default or profile_name, must be untagged diff --git a/nesi/softbox/api/schemas/interface_schemas.py b/nesi/softbox/api/schemas/interface_schemas.py index 1095031..159b4e3 100644 --- a/nesi/softbox/api/schemas/interface_schemas.py +++ b/nesi/softbox/api/schemas/interface_schemas.py @@ -18,7 +18,7 @@ class InterfaceSchema(ma.ModelSchema): class Meta: model = Interface fields = ('id', 'box_id', 'box', 'chan_id', 'port_id', 'logport_id', - 'name', 'description', '_links') + 'name', 'description', 'vcc_profile', 'vlan_profile', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/templates/KeyMile/login/base/set/vcc_success.j2 b/templates/KeyMile/login/base/set/vcc_success.j2 new file mode 100644 index 0000000..b5a9cf3 --- /dev/null +++ b/templates/KeyMile/login/base/set/vcc_success.j2 @@ -0,0 +1,3 @@ + \ # CreateVcc +vcc-{{ context.id }}{{ context.spacer1 }}\ # VCC ID + diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 75579bb..699d6ca 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -34,6 +34,7 @@ def do_get(self, command, *args, context=None): def _init_access_points(self, context=None): + self.access_points = () for card in self._model.cards: if 'unit-' + card.name in self.access_points: continue diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 0946d86..0e540e3 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -23,6 +23,7 @@ class LogportsCommandProcessor(BaseCommandProcessor): from .logportsManagementFunctions import cfgm def _init_access_points(self, context=None): # work in progress + self.access_points = () card = self._model.get_card('name', self._parent.component_id) for logport in self._model.get_logports('card_id', card.id): diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 3ca08bb..f0a62d1 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -43,6 +43,7 @@ def get_port_component(self): return self._model.get_logport('name', self._parent._parent.component_id + '/L/' + self.component_id) def _init_access_points(self, context=None): + self.access_points = () logport_name = self._parent._parent.component_id + '/L/' + self.component_id logport = self._model.get_logport('name', logport_name) try: diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 288e2db..3562f7c 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -26,18 +26,75 @@ class ChanCommandProcessor(BaseCommandProcessor): from .chanManagementFunctions import status def _init_access_points(self, context=None): + self.access_points = () chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) card = self._model.get_card('name', self._parent._parent.component_id) for interface in self._model.get_interfaces('chan_id', chan.id): - if card.product != 'adsl': - ap_name = 'interface-' + if interface.chan_id is not None: + if card.product != 'adsl': + ap_name = 'interface-' + else: + ap_name = 'vcc-' + identifier = ap_name + interface.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + + def do_deletevcc(self, command, *args, context=None): + card = self._model.get_card('name', self._parent._parent.component_id) + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': + # all or vcc_id + name, = self._dissect(args, str) + if name == 'all': + chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + for vcc in self._model.get_interfaces('chan_id', chan.id): + vcc.delete() + elif name.startswith('vcc-'): + id = name.split('-')[1] + try: + vcc = self._model.get_interface('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + id) + vcc.delete() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) else: - ap_name = 'vcc-' - identifier = ap_name + interface.name.split('/')[-1] - if identifier in self.access_points: - continue - self.access_points += (identifier,) + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_createvcc(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + card = self._model.get_card('name', self._parent._parent.component_id) + if self._validate(args, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': + # vcc profile and vlan profile + vcc_prof, vlan_prof = self._dissect(args, str, str) + # TODO: Check if profiles := default or profile names + try: + chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + id = 1 + for vcc in self._model.get_interfaces('chan_id', chan.id): + if vcc.chan_id is not None: + new_id = int(vcc.name[-1]) + 1 + id = new_id if new_id > id else id + try: + name = self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + str(id) + _ = self._model.get_interface('name', name) + assert False + except exceptions.SoftboxenError as exe: + vcc = self._model.add_interface(name=name, chan_id=chan.id, vcc_profile=vcc_prof, + vlan_profile=vlan_prof) + context['spacer1'] = self.create_spacers((63,), (str(id),))[0] * ' ' + context['id'] = str(id) + # TODO: Template is unknown + text = self._render('vcc_success', *scopes, context=context) + self._write(text) + except AssertionError: + raise exceptions.CommandSyntaxError(command=command) + + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) @@ -54,3 +111,15 @@ def set(self, command, *args, context=None): return else: raise exceptions.CommandSyntaxError(command=command) + + def get_property(self, command, *args, context=None): + #card = self._model.get_card('name', self.component_id) + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py index c0e0842..fca7430 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py @@ -35,3 +35,15 @@ def set(self, command, *args, context=None): raise exc else: raise exceptions.CommandSyntaxError(command=command) + + def get_property(self, command, *args, context=None): + #card = self._model.get_card('name', self.component_id) + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 30f0d40..505f08e 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -59,6 +59,7 @@ def get_property(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors')) def _init_access_points(self, context=None): + self.access_points = () port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) for chan in self._model.get_chans('port_id', port.id): diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index 988535a..9c51c4c 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -23,6 +23,7 @@ class PortgroupCommandProcessor(BaseCommandProcessor): from .portgroupManagementFunctions import cfgm def _init_access_points(self, context=None): # work in progress + self.access_points = () card = self._model.get_card('name', self._parent.component_id) for gport in self._model.get_portgroupports('card_id', card.id): diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 1c4ee08..5826e8e 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -25,6 +25,7 @@ class UnitCommandProcessor(BaseCommandProcessor): from .unitManagementFunctions import status def _init_access_points(self, context=None): + self.access_points = () try: card = self._model.get_card('name', self.component_id) @@ -51,7 +52,6 @@ def _init_access_points(self, context=None): except exceptions.InvalidInputError: pass - def get_property(self, command, *args, context=None): card = self._model.get_card('name', self.component_id) scopes = ('login', 'base', 'get') diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 8fc80b6..db62303 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -305,7 +305,10 @@ def change_directory(self, path, context=None): if self.__name__ != 'logports': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - + elif component_type == 'vcc': + if self.__name__ != 'chan': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): if self.__name__ != 'root': raise exceptions.CommandExecutionError(command=None, template=None, @@ -339,6 +342,7 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.unit.logport.logportsCommandProcessor import LogportsCommandProcessor from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ LogportCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.chan.vcc.vccCommandProcessor import VccCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if component_id is not None and self.component_id is not None: @@ -503,6 +507,7 @@ def get_command_processor(self, current_processor, component_type=None): from vendors.KeyMile.accessPoints.root.unit.logport.logportsCommandProcessor import LogportsCommandProcessor from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ LogportCommandProcessor + from vendors.KeyMile.accessPoints.root.unit.port.chan.vcc.vccCommandProcessor import VccCommandProcessor if current_processor.__class__ == RootCommandProcessor: return_to = RootCommandProcessor if component_type not in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services', 'unit') \ @@ -548,6 +553,8 @@ def get_command_processor(self, current_processor, component_type=None): return_to = UnitCommandProcessor elif current_processor.__class__ == LogportCommandProcessor: return_to = LogportsCommandProcessor + elif current_processor.__class__ == VccCommandProcessor: + return_to = ChanCommandProcessor return return_to From ff683b8aab3f7400db584d49e55800473e6ef41d Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 15 Oct 2020 15:55:24 +0200 Subject: [PATCH 238/318] Added delete of interface after a chanel, port and logports --- .../logport/port/logportCommandProcessor.py | 22 +++++++++++++++++++ .../unit/port/chan/chanCommandProcessor.py | 21 ++++++++++++++++++ .../root/unit/port/portCommandProcessor.py | 22 +++++++++++++++++++ .../port/portgroupportCommandProcessor.py | 3 +++ 4 files changed, 68 insertions(+) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index f0a62d1..fce9dc3 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -57,6 +57,28 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) + def do_deleteinterface(self, command, *args, context=None): + card = self._model.get_card('name', self._parent._parent.component_id) + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': + # all or interface_id + name, = self._dissect(args, str) + if name == 'all': + logport_name = self._parent._parent.component_id + '/L/' + self.component_id + logport = self._model.get_logport('name', logport_name) + for interface in self._model.get_interfaces('logport_id', logport.id): + interface.delete() + elif name.startswith('interface-'): + id = name.split('-')[1] + try: + interface = self._model.get_interface('name', self._parent._parent.component_id + '/L/' + self.component_id + '/' + id) + interface.delete() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 3562f7c..7f51a20 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -62,6 +62,27 @@ def do_deletevcc(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_deleteinterface(self, command, *args, context=None): + card = self._model.get_card('name', self._parent._parent.component_id) + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product != 'adsl' and card.product != 'sdsl': + # all or interface_id + name, = self._dissect(args, str) + if name == 'all': + chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + for interface in self._model.get_interfaces('chan_id', chan.id): + interface.delete() + elif name.startswith('interface-'): + id = name.split('-')[1] + try: + interface = self._model.get_interface('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + id) + interface.delete() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def do_createvcc(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent._parent.component_id) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 505f08e..ebe6514 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -62,6 +62,7 @@ def _init_access_points(self, context=None): self.access_points = () port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + #TODO: add interfaces for ftth and special cards for chan in self._model.get_chans('port_id', port.id): identifier = 'chan-' + chan.name.split('/')[-1] if identifier in self.access_points: @@ -71,6 +72,27 @@ def _init_access_points(self, context=None): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + def do_deleteinterface(self, command, *args, context=None): + card = self._model.get_card('name', self._parent.component_id) + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'ftth': + # all or interface_id + name, = self._dissect(args, str) + if name == 'all': + port = self.get_port_component() + for interface in self._model.get_interfaces('port_id', port.id): + interface.delete() + elif name.startswith('interface-'): + id = name.split('-')[1] + try: + interface = self._model.get_interface('name', self._parent.component_id + '/' + self.component_id + '/' + id) + interface.delete() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def get_port_component(self): return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 159651e..a6986a8 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -107,6 +107,9 @@ def get_property(self, command, *args, context=None): def _init_access_points(self, context=None): pass + def do_deleteinterface(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) From 6e8b429ef1345ea7bef0fdb633f4583185c7e0cc Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 15 Oct 2020 16:49:24 +0200 Subject: [PATCH 239/318] Added create interface after a chanel, port and logports --- .../login/base/set/interface_success.j2 | 3 + .../logport/port/logportCommandProcessor.py | 34 +++++++++++ .../unit/port/chan/chanCommandProcessor.py | 61 +++++++++++++++++++ .../root/unit/port/portCommandProcessor.py | 33 ++++++++++ .../port/portgroupportCommandProcessor.py | 3 + 5 files changed, 134 insertions(+) create mode 100644 templates/KeyMile/login/base/set/interface_success.j2 diff --git a/templates/KeyMile/login/base/set/interface_success.j2 b/templates/KeyMile/login/base/set/interface_success.j2 new file mode 100644 index 0000000..96bd08d --- /dev/null +++ b/templates/KeyMile/login/base/set/interface_success.j2 @@ -0,0 +1,3 @@ + \ # CreateInterface +interface-{{ context.id }}{{ context.spacer1 }}\ # Interface ID + diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index fce9dc3..16e3827 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -79,6 +79,40 @@ def do_deleteinterface(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_createinterface(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + card = self._model.get_card('name', self._parent._parent.component_id) + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': + # vcc profile and vlan profile + vlan_prof, = self._dissect(args, str) + # TODO: Check if profiles := default or profile names + try: + logport_name = self._parent._parent.component_id + '/L/' + self.component_id + logport = self._model.get_logport('name', logport_name) + id = 1 + for interface in self._model.get_interfaces('logport_id', logport.id): + if interface.logport_id is not None: + new_id = int(interface.name[-1]) + 1 + id = new_id if new_id > id else id + try: + name = self._parent._parent.component_id + '/L/' + self.component_id + '/' + str(id) + _ = self._model.get_interface('name', name) + assert False + except exceptions.SoftboxenError as exe: + vcc = self._model.add_interface(name=name, logport_id=logport.id, vlan_profile=vlan_prof) + context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' + context['id'] = str(id) + # TODO: Template is unknown + text = self._render('interface_success', *scopes, context=context) + self._write(text) + except AssertionError: + raise exceptions.CommandSyntaxError(command=command) + + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 7f51a20..1c4646b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -83,6 +83,67 @@ def do_deleteinterface(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_createinterface(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + card = self._model.get_card('name', self._parent._parent.component_id) + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.board_name.contains('SUV'): + # vcc profile and vlan profile + vlan_prof, = self._dissect(args, str) + # TODO: Check if profiles := default or profile names + try: + chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + id = 1 + for interface in self._model.get_interfaces('chan_id', chan.id): + if interface.chan_id is not None: + new_id = int(interface.name[-1]) + 1 + id = new_id if new_id > id else id + try: + name = self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + str(id) + _ = self._model.get_interface('name', name) + assert False + except exceptions.SoftboxenError as exe: + interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof) + context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' + context['id'] = str(id) + # TODO: Template is unknown + text = self._render('interface_success', *scopes, context=context) + self._write(text) + except AssertionError: + raise exceptions.CommandSyntaxError(command=command) + + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.board_name.contains('SUV'): + # vcc profile and vlan profile + vlan_prof, vcc_prof = self._dissect(args, str, str) + # TODO: Check if profiles := default or profile names + try: + chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + id = 1 + for interface in self._model.get_interfaces('chan_id', chan.id): + if interface.chan_id is not None: + new_id = int(interface.name[-1]) + 1 + id = new_id if new_id > id else id + try: + name = self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + str(id) + _ = self._model.get_interface('name', name) + assert False + except exceptions.SoftboxenError as exe: + interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof, + vcc_profile=vcc_prof) + context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' + context['id'] = str(id) + # TODO: Template is unknown + text = self._render('interface_success', *scopes, context=context) + self._write(text) + except AssertionError: + raise exceptions.CommandSyntaxError(command=command) + + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def do_createvcc(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent._parent.component_id) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index ebe6514..a4a6468 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -93,6 +93,39 @@ def do_deleteinterface(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_createinterface(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + card = self._model.get_card('name', self._parent.component_id) + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.board_name.contains('SUE'): + # vcc profile and vlan profile + vlan_prof, = self._dissect(args, str) + # TODO: Check if profiles := default or profile names + try: + port = self.get_port_component() + id = 1 + for interface in self._model.get_interfaces('port_id', port.id): + if interface.port_id is not None: + new_id = int(interface.name[-1]) + 1 + id = new_id if new_id > id else id + try: + name = self._parent.component_id + '/' + self.component_id + '/' + str(id) + _ = self._model.get_interface('name', name) + assert False + except exceptions.SoftboxenError as exe: + interf = self._model.add_interface(name=name, port_id=port.id, vlan_profile=vlan_prof) + context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' + context['id'] = str(id) + # TODO: Template is unknown + text = self._render('interface_success', *scopes, context=context) + self._write(text) + except AssertionError: + raise exceptions.CommandSyntaxError(command=command) + + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def get_port_component(self): return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index a6986a8..cb73492 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -110,6 +110,9 @@ def _init_access_points(self, context=None): def do_deleteinterface(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + def do_createinterface(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) From 82686d806fa1a89e9126868bc50e064591b6975f Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 16 Oct 2020 13:12:58 +0200 Subject: [PATCH 240/318] Added new (6-in1) 'subpacket'-commandProcessor --- nesi/softbox/api/schemas/box_schemas.py | 4 +- .../accessPoints/root/rootCommandProcessor.py | 2 +- ...or.py => macaccessctrlCommandProcessor.py} | 10 ++--- ...py => macaccessctrlManagementFunctions.py} | 0 .../services/subpacketCommandProcessor.py | 27 ++++++++++++ .../services/subpacketManagementFunctions.py | 15 +++++++ vendors/KeyMile/baseCommandProcessor.py | 42 ++++++++++++++++--- 7 files changed, 87 insertions(+), 13 deletions(-) rename vendors/KeyMile/accessPoints/root/services/{macAccessCtrlCommandProcessor.py => macaccessctrlCommandProcessor.py} (85%) rename vendors/KeyMile/accessPoints/root/services/{macAccessCtrlManagementFunctions.py => macaccessctrlManagementFunctions.py} (100%) create mode 100644 vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/services/subpacketManagementFunctions.py diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index 8ca7c8b..7d13b82 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -33,10 +33,10 @@ class Meta: fields = ('id', 'vendor', 'model', 'version', 'software_version', 'network_protocol', 'network_address', 'network_port', 'uuid', 'description', 'interfaces', 'logports', 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', - 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', + 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'currTemperature', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'mgmt_cards', 'mgmt_ports', - 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', 'currTemperature', '_links') + 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') credentials = ma.Hyperlinks( {'_links': { diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 699d6ca..cacd03f 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -34,7 +34,7 @@ def do_get(self, command, *args, context=None): def _init_access_points(self, context=None): - self.access_points = () + self.access_points = ('eoam', 'fan', 'multicast', 'services', 'tdmConnections') for card in self._model.cards: if 'unit-' + card.name in self.access_points: continue diff --git a/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py similarity index 85% rename from vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py rename to vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py index 42dbfba..a2e56c6 100644 --- a/vendors/KeyMile/accessPoints/root/services/macAccessCtrlCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py @@ -14,15 +14,15 @@ from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor -class MacAccessCtrlCommandProcessor(BaseCommandProcessor): +class MacaccessctrlCommandProcessor(BaseCommandProcessor): __name__ = 'macAccessCtrl' management_functions = ('main', 'cfgm', 'fm', 'status') access_points = () - from .macAccessCtrlManagementFunctions import main - from .macAccessCtrlManagementFunctions import cfgm - from .macAccessCtrlManagementFunctions import fm - from .macAccessCtrlManagementFunctions import status + from .macaccessctrlManagementFunctions import main + from .macaccessctrlManagementFunctions import cfgm + from .macaccessctrlManagementFunctions import fm + from .macaccessctrlManagementFunctions import status def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/services/macAccessCtrlManagementFunctions.py b/vendors/KeyMile/accessPoints/root/services/macaccessctrlManagementFunctions.py similarity index 100% rename from vendors/KeyMile/accessPoints/root/services/macAccessCtrlManagementFunctions.py rename to vendors/KeyMile/accessPoints/root/services/macaccessctrlManagementFunctions.py diff --git a/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py new file mode 100644 index 0000000..706cc3b --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py @@ -0,0 +1,27 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class SubpacketCommandProcessor(BaseCommandProcessor): + __name__ = 'subpacket' + management_functions = ('main', 'cfgm') + access_points = () + + from .subpacketManagementFunctions import main + from .subpacketManagementFunctions import cfgm + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/services/subpacketManagementFunctions.py b/vendors/KeyMile/accessPoints/root/services/subpacketManagementFunctions.py new file mode 100644 index 0000000..aa446e7 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/subpacketManagementFunctions.py @@ -0,0 +1,15 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + } + } + +cfgm = { + 'Cmd': ( + 'CreateService', + 'DeleteService' + ) + } diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index db62303..1e9088d 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -194,6 +194,9 @@ def do_ls(self, command, *args, context=None): command=command) def change_directory(self, path, context=None): + if re.match("1to1DoubleTag|1to1SingleTag|mcast|nto1|pls|tls", path): + context['ServiceType'] = path + path = 'subpacket' path = path.lower() if path == '/': if self.__name__ != 'root': @@ -205,7 +208,7 @@ def change_directory(self, path, context=None): components = [x for x in path.split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|tdmConnection|logports|logport-[0-9]|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|macaccessctrl|tdmconnection|logports|logport-[0-9]|\.|\.\.)$', components[0]): raise exceptions.SoftboxenError() @@ -309,6 +312,10 @@ def change_directory(self, path, context=None): if self.__name__ != 'chan': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'packet' or component_type == 'macAccessCtrl': + if self.__name__ != 'services': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): if self.__name__ != 'root': raise exceptions.CommandExecutionError(command=None, template=None, @@ -343,6 +350,10 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ LogportCommandProcessor from vendors.KeyMile.accessPoints.root.unit.port.chan.vcc.vccCommandProcessor import VccCommandProcessor + from vendors.KeyMile.accessPoints.root.services.packetCommandProcessor import PacketCommandProcessor + from vendors.KeyMile.accessPoints.root.services.macaccessctrlCommandProcessor import \ + MacaccessctrlCommandProcessor + from vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor import SubpacketCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if component_id is not None and self.component_id is not None: @@ -354,7 +365,10 @@ def change_directory(self, path, context=None): if context['component_path'] == '/': new_path = components[0] else: - new_path = '/' + components[0] + if path == 'subpacket': + new_path = '/' + context['ServiceType'] + else: + new_path = '/' + components[0] context['component_path'] += new_path if len(remaining_args) > 0: @@ -398,8 +412,13 @@ def get_parent_and_child_relation(self, search, parent=None, node=None, parent_k "internalports": {"internalport": {}} }, "eoam": {}, - "tdmConnections": {}, - "services": {}, + "tdmconnections": {}, + "services": { + "packet": { + "subpacket": {} + }, + "macaccessctrl": {} + }, "multicast": {} }} for x, y in node.items(): @@ -471,6 +490,9 @@ def do_cd(self, command, *args, context=None): raise exceptions.CommandSyntaxError() elif self._validate(args, str): path = args[0] + if re.match("1to1DoubleTag|1to1SingleTag|mcast|nto1|pls|tls", path): + context['ServiceType'] = path + path = 'subpacket' try: subprocessor = self.change_directory(path, context=context) @@ -508,9 +530,13 @@ def get_command_processor(self, current_processor, component_type=None): from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ LogportCommandProcessor from vendors.KeyMile.accessPoints.root.unit.port.chan.vcc.vccCommandProcessor import VccCommandProcessor + from vendors.KeyMile.accessPoints.root.services.packetCommandProcessor import PacketCommandProcessor + from vendors.KeyMile.accessPoints.root.services.macaccessctrlCommandProcessor import\ + MacaccessctrlCommandProcessor + from vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor import SubpacketCommandProcessor if current_processor.__class__ == RootCommandProcessor: return_to = RootCommandProcessor - if component_type not in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services', 'unit') \ + if component_type not in ('fan', 'eoam', 'tdmconnections', 'multicast', 'services', 'unit') \ and component_type is not None: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty @@ -555,6 +581,12 @@ def get_command_processor(self, current_processor, component_type=None): return_to = LogportsCommandProcessor elif current_processor.__class__ == VccCommandProcessor: return_to = ChanCommandProcessor + elif current_processor.__class__ == PacketCommandProcessor: + return_to = ServicesCommandProcessor + elif current_processor.__class__ == MacaccessctrlCommandProcessor: + return_to = ServicesCommandProcessor + elif current_processor.__class__ == SubpacketCommandProcessor: + return_to = PacketCommandProcessor return return_to From 1661417305be6e9d47a7699ca1b5b1e1c2df946f Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Mon, 19 Oct 2020 08:31:06 +0200 Subject: [PATCH 241/318] small fixes according to create Interfaces --- .../conf/bootstraps/create-keymile-MG2500.sh | 51 +++++++++++++++++-- .../unit/port/chan/chanCommandProcessor.py | 4 +- .../root/unit/port/portCommandProcessor.py | 9 +++- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index af898a8..73f9f84 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -328,6 +328,17 @@ req='{ unit_4=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_4', + "admin_state": "1", + "operational_state": "1" +}' + +port_4_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + ### Unit-5 ### # Create a physical card at the network device (admin operation) @@ -355,6 +366,27 @@ req='{ unit_5=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_5', + "admin_state": "1", + "operational_state": "1" +}' + +port_5_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Chan-1 ### + +# Create a logical channel at the network device (admin operation) +req='{ + "port_id": '$port_5_1', + "description": "Channel #1" +}' + +chan_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/channels) + ### Unit-6 ### # Create a physical card at the network device (admin operation) @@ -387,19 +419,19 @@ unit_6=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) # Create a physical card at the network device (admin operation) req='{ "subrack_id": '$subrack_id', - "product": "vdsl", - "board_name": "SUVM6", + "product": "ftth", + "board_name": "SUEN3", "supplier_build_state": "R1K", "board_id": "377", "hardware_key": 14, "software": "suvm6_r3e10_01.esw", - "software_name": "SUVM6", + "software_name": "SUEN3", "software_revision": "R3E10_01", "state": "Ok", "serial_number": "6135149854", "manufacturer_name": "KEYMILE", "model_name": "37900528", - "short_text": "MG SUVM6 VDSL2/17MHz ISDN 48pt", + "short_text": "MG SUEN3 VDSL2/17MHz ISDN 48pt", "manufacturer_id": "100989", "manufacturer_part_number": "09869778", "manufacturer_build_state": "20", @@ -409,6 +441,17 @@ req='{ unit_7=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_7', + "admin_state": "1", + "operational_state": "1" +}' + +port_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + ### Unit-8 ### # Create a physical card at the network device (admin operation) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 1c4646b..67bb191 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -86,7 +86,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.board_name.contains('SUV'): + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name: # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names @@ -113,7 +113,7 @@ def do_createinterface(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.board_name.contains('SUV'): + elif self._validate(args, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name : # vcc profile and vlan profile vlan_prof, vcc_prof = self._dissect(args, str, str) # TODO: Check if profiles := default or profile names diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index a4a6468..59dca98 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -62,13 +62,18 @@ def _init_access_points(self, context=None): self.access_points = () port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) - #TODO: add interfaces for ftth and special cards for chan in self._model.get_chans('port_id', port.id): identifier = 'chan-' + chan.name.split('/')[-1] if identifier in self.access_points: continue self.access_points += (identifier,) + for interface in self._model.get_interfaces('port_id', port.id): + identifier = 'interface-' + interface.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) @@ -96,7 +101,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.board_name.contains('SUE'): + if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUE' in card.board_name: # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names From ae545df172a6f9baef17d7640454573851693cec Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Mon, 19 Oct 2020 10:35:36 +0200 Subject: [PATCH 242/318] Added Backup functionality --- .../api/schemas/keymile_box_schemas.py | 5 +++-- nesi/keymile/keymile_resources/keymile_box.py | 12 +++++++++++ nesi/softbox/api/models/box_models.py | 6 +++++- .../accessPoints/root/rootCommandProcessor.py | 20 +++++++++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/nesi/keymile/api/schemas/keymile_box_schemas.py b/nesi/keymile/api/schemas/keymile_box_schemas.py index 5458c05..de66bed 100644 --- a/nesi/keymile/api/schemas/keymile_box_schemas.py +++ b/nesi/keymile/api/schemas/keymile_box_schemas.py @@ -14,10 +14,11 @@ from nesi.softbox.api.schemas.box_schemas import * -class KeymileBoxSchema(BoxSchema): +class KeyMileBoxSchema(BoxSchema): class Meta: model = Box - fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature', 'logports') + fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature', 'logports', 'backup_ip', 'login', + 'password', 'backup_path') interfaces = ma.Hyperlinks( {'_links': { diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 328d755..fdb8cf1 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -29,6 +29,18 @@ class KeyMileBox(Box): """ currTemperature = base.Field("currTemperature") + backup_ip = base.Field("backup_ip") + login = base.Field("login") + password = base.Field("password") + backup_path = base.Field("backup_path") + + def set_backup(self, backup_ip, login, password): + self.update(backup_ip=backup_ip) + self.update(login=login) + self.update(password=password) + + def set_path(self, path): + self.update(backup_path=path) @property def channels(self): diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 72fbeba..aa91ddd 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -123,4 +123,8 @@ class Box(db.Model): pitp_mode = db.Column(db.String(), default='') dsl_mode = db.Column(db.Enum('tr165', 'tr129'), default='tr165') - currTemperature = db.Column(db.Integer(), default=15) \ No newline at end of file + currTemperature = db.Column(db.Integer(), default=15) + backup_ip = db.Column(db.String(), default='') + login = db.Column(db.String(), default='') + password = db.Column(db.String(), default='') + backup_path = db.Column(db.String(), default='') diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index cacd03f..24ce5a0 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -81,6 +81,26 @@ def do_save(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_ftpserver(self, command, *args, context=None): + if self._validate(args, str, str, str) and context['component_path'].split('/')[-1] != 'cfgm': + ip, login, pw = self._dissect(args, str, str, str) + try: + self._model.set_backup(ip, login, pw) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_upload(self, command, *args, context=None): + if self._validate(args, '/cfgm/configuration', str) and context['component_path'].split('/')[-1] != 'cfgm': + path, = self._dissect(args, '/cfgm/configuration', str) + try: + self._model.set_path(path) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) From aac38fd52f2090f84d766a07b908bf9d404f59fe Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Mon, 19 Oct 2020 12:02:32 +0200 Subject: [PATCH 243/318] Added Loopback tests --- .../conf/bootstraps/create-keymile-MG2500.sh | 11 +++++ .../api/schemas/keymile_port_schemas.py | 2 +- .../keymile/keymile_resources/keymile_port.py | 12 ++++++ nesi/softbox/api/models/port_models.py | 3 +- .../login/base/get/quickloopbacktest.j2 | 3 ++ .../root/unit/port/portCommandProcessor.py | 42 +++++++++++++++++++ .../root/unit/unitCommandProcessor.py | 1 - vendors/KeyMile/baseCommandProcessor.py | 6 +++ 8 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 templates/KeyMile/login/base/get/quickloopbacktest.j2 diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 73f9f84..7819f8b 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -490,6 +490,17 @@ req='{ unit_19=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_19', + "admin_state": "1", + "operational_state": "1" +}' + +port_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + ### PortGroupPort-1 ### # Create a physical port at the network device (admin operation) diff --git a/nesi/keymile/api/schemas/keymile_port_schemas.py b/nesi/keymile/api/schemas/keymile_port_schemas.py index c8a1f07..99356da 100644 --- a/nesi/keymile/api/schemas/keymile_port_schemas.py +++ b/nesi/keymile/api/schemas/keymile_port_schemas.py @@ -16,6 +16,6 @@ class KeyMilePortSchema(PortSchema): class Meta: model = Port - fields = PortSchema.Meta.fields + ('channels', 'label1', 'label2') + fields = PortSchema.Meta.fields + ('channels', 'label1', 'label2', 'loopbacktest_state') channels = ma.Nested(CpesSchema.CpeSchema, many=True) diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py index c90e06f..3c45b71 100644 --- a/nesi/keymile/keymile_resources/keymile_port.py +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -19,12 +19,24 @@ class KeyMilePort(Port): """Represent physical port resource.""" label1 = base.Field('label1') label2 = base.Field('label2') + loopbacktest_state = base.Field('loopbacktest_state') def set_label(self, l1, l2, desc): self.update(label1=l1) self.update(label2=l2) self.update(description=desc) + def set_test_state(self, state): + self.update(loopbacktest_state=state) + + def lock_admin(self): + """Set the admin port state to up""" + self.update(admin_state='2') + + def unlock_admin(self): + """Set the admin port state to down""" + self.update(admin_state='3') + class KeyMilePortCollection(PortCollection): """Represent a collection of ports.""" diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 1705e0c..61bf14f 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -32,7 +32,7 @@ class Port(db.Model): shutdown = db.Column(db.Boolean(), default=False) speed = db.Column(db.Enum('10M', '1G', '10G'), default='1G') operational_state = db.Column(db.Enum('0', '1', '2'), default='0') # Alcatel: 0 => down, 1 => up, 2 => not-appl; Huawei: 0 => deactivated, 1 => activated, 2 => activating - admin_state = db.Column(db.Enum('0', '1', '2'), default='0') # Alcatel: 0 => down, 1 => up, 2 => not-appl; Huawei: 0 => deactivated, 1 => activated, 2 => activating + admin_state = db.Column(db.Enum('0', '1', '2', '3'), default='0') # Alcatel: 0 => down, 1 => up, 2 => not-appl; Huawei: 0 => deactivated, 1 => activated, 2 => activating; KeyMile: 0 => down, 1 => up, 2 => locked, 3 => unlocked upstream = db.Column(db.Integer(), default=0) downstream = db.Column(db.Integer(), default=0) upstream_max = db.Column(db.String(), default="100000") @@ -313,3 +313,4 @@ class Port(db.Model): interfaces = db.relationship('Interface', backref='Port', lazy='dynamic') label1 = db.Column(db.String(), default='""') label2 = db.Column(db.String(), default='""') + loopbacktest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NoTestResult', 'Stopped', 'Interrupted'), default='NoTestResult') diff --git a/templates/KeyMile/login/base/get/quickloopbacktest.j2 b/templates/KeyMile/login/base/get/quickloopbacktest.j2 new file mode 100644 index 0000000..38b4f82 --- /dev/null +++ b/templates/KeyMile/login/base/get/quickloopbacktest.j2 @@ -0,0 +1,3 @@ + \ # QuickLoopbackTest +{{ context.loopbacktest_state }}{{ context.spacer1 }}\ # State + diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 59dca98..726e628 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -12,6 +12,7 @@ from nesi import exceptions from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor +import time class PortCommandProcessor(BaseCommandProcessor): @@ -27,6 +28,7 @@ class PortCommandProcessor(BaseCommandProcessor): def get_property(self, command, *args, context=None): port = self.get_port_component() + card = self._model.get_card('name', self._parent.component_id) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -36,6 +38,12 @@ def get_property(self, command, *args, context=None): elif self._validate((args[0],), 'AttainableRate') and context['component_path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) + elif self._validate((args[0],), 'QuickLoopbackTest') and context['component_path'].split('/')[-1] == 'status'\ + and (card.product == 'isdn' or 'SUI' in card.board_name): + context['spacer1'] = self.create_spacers((67,), (port.loopbacktest_state,))[0] * ' ' + context['loopbacktest_state'] = port.loopbacktest_state + text = self._render('quickloopbacktest', *scopes, context=context) + self._write(text) elif self._validate((args[0],), 'AdministrativeStatus') and context['component_path'].split('/')[-1] == 'main': self.map_states(port, 'port') context['spacer'] = self.create_spacers((67,), (port.admin_state,))[0] * ' ' @@ -74,6 +82,40 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) + def do_lock(self, command, *args, context=None): + card = self._model.get_card('name', self._parent.component_id) + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn': + try: + port = self.get_port_component() + port.lock_admin() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_startquickloopbacktest(self, command, *args, context=None): + card = self._model.get_card('name', self._parent.component_id) + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn': + try: + port = self.get_port_component() + time.sleep(5) + port.set_test_state('Passed') + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_unlock(self, command, *args, context=None): + card = self._model.get_card('name', self._parent.component_id) + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn': + try: + port = self.get_port_component() + port.unlock_admin() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 5826e8e..a12beba 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -60,7 +60,6 @@ def get_property(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'SubscriberList') and context['component_path'].split('/')[-1] == 'status' and \ (card.product == 'isdn' or card.product == 'analog'): text = self._render('subscriberList_top', *scopes, context=context) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 1e9088d..e465c52 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -43,6 +43,12 @@ def map_states(self, object, type): elif object.admin_state == '1': if type == 'port': object.admin_state = 'Up' + elif object.admin_state == '2': + if type == 'port': + object.admin_state = 'Locked' + elif object.admin_state == '3': + if type == 'port': + object.admin_state = 'Unlocked' if object.operational_state == '0': if type == 'port': From 4435a8f07927b6ac3f50057db41f07fa09e7bd2f Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Mon, 19 Oct 2020 13:58:20 +0200 Subject: [PATCH 244/318] Added Service (srvc) buisness object --- .../conf/bootstraps/create-keymile-MG2500.sh | 14 +++- nesi/keymile/keymile_resources/__init__.py | 2 +- nesi/keymile/keymile_resources/keymile_box.py | 33 +++++++--- .../keymile_portgroupport.py | 6 +- .../keymile/keymile_resources/keymile_srvc.py | 35 ++++++++++ .../keymile_resources/keymile_subscriber.py | 6 +- nesi/softbox/api/models/box_models.py | 2 + nesi/softbox/api/models/srvc_models.py | 23 +++++++ nesi/softbox/api/models/subscriber_models.py | 13 ++++ nesi/softbox/api/schemas/box_schemas.py | 6 +- nesi/softbox/api/schemas/srvc_schemas.py | 48 ++++++++++++++ nesi/softbox/api/views/__init__.py | 2 +- nesi/softbox/api/views/srvc_views.py | 53 +++++++++++++++ .../KeyMile/login/base/get/service_mcast.j2 | 6 ++ .../KeyMile/login/base/get/service_nto1.j2 | 16 +++++ .../base/get/service_onetoonedoubletag.j2 | 6 ++ .../base/get/service_onetoonesingletag.j2 | 8 +++ .../KeyMile/login/base/get/service_pls.j2 | 6 ++ .../KeyMile/login/base/get/service_tls.j2 | 6 ++ .../root/services/srvcCommandProcessor.py | 64 +++++++++++++++++++ .../root/services/srvcManagementFunctions.py | 31 +++++++++ .../services/subpacketCommandProcessor.py | 15 +++++ vendors/KeyMile/baseCommandProcessor.py | 22 +++++-- 23 files changed, 401 insertions(+), 22 deletions(-) create mode 100644 nesi/keymile/keymile_resources/keymile_srvc.py create mode 100644 nesi/softbox/api/models/srvc_models.py create mode 100644 nesi/softbox/api/schemas/srvc_schemas.py create mode 100644 nesi/softbox/api/views/srvc_views.py create mode 100644 templates/KeyMile/login/base/get/service_mcast.j2 create mode 100644 templates/KeyMile/login/base/get/service_nto1.j2 create mode 100644 templates/KeyMile/login/base/get/service_onetoonedoubletag.j2 create mode 100644 templates/KeyMile/login/base/get/service_onetoonesingletag.j2 create mode 100644 templates/KeyMile/login/base/get/service_pls.j2 create mode 100644 templates/KeyMile/login/base/get/service_tls.j2 create mode 100644 vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/services/srvcManagementFunctions.py diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 7819f8b..f224350 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -525,4 +525,16 @@ req='{ "type": "ISDN" }' -port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) \ No newline at end of file +port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) + +### Nto1-Service-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "name": "srvc-1", + "service_type": "nto1", + "svid": 123, + "address": "/unit-1/port-1/chan-1/interface-1" +}' + +srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) \ No newline at end of file diff --git a/nesi/keymile/keymile_resources/__init__.py b/nesi/keymile/keymile_resources/__init__.py index 4226c8c..9e17078 100644 --- a/nesi/keymile/keymile_resources/__init__.py +++ b/nesi/keymile/keymile_resources/__init__.py @@ -1,2 +1,2 @@ __all__ = ["keymile_card", "keymile_port", "keymile_subrack", "keymile_channel", "keymile_interface", - "keymile_subscriber", "keymile_portgroupport", "keymile_logport"] + "keymile_subscriber", "keymile_logport", "keymile_portgroupport", "keymile_srvc"] diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index fdb8cf1..8a2d68c 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -14,7 +14,6 @@ from nesi.keymile.keymile_resources import * - from nesi.softbox.base_resources import credentials, base from nesi.softbox.base_resources.box import BoxCollection, Box, logging @@ -71,13 +70,13 @@ def cards(self): @property def subscribers(self): """Return `SubscriberCollection` object.""" - return keymile_subscriber.KeymileSubscriberCollection( + return keymile_subscriber.KeyMileSubscriberCollection( self._conn, base.get_sub_resource_path_by(self, 'subscribers')) @property def portgroupsports(self): """Return `PortgrouportCollection` object.""" - return keymile_portgroupport.KeymilePortGroupPortCollection( + return keymile_portgroupport.KeyMilePortGroupPortCollection( self._conn, base.get_sub_resource_path_by(self, 'portgrouports')) def logports(self): @@ -85,6 +84,12 @@ def logports(self): return keymile_logport.KeyMileLogPortCollection( self._conn, base.get_sub_resource_path_by(self, 'logports')) + @property + def srvcs(self): + """Return `SrvcCollection` object.""" + return keymile_srvc.KeyMileSrvcCollection( + self._conn, base.get_sub_resource_path_by(self, 'srvcs')) + def get_card(self, field, value): """Get specific card object.""" return keymile_card.KeyMileCardCollection( @@ -160,34 +165,46 @@ def add_interface(self, **fields): def get_subscriber(self, field, value): """Get specific subscriber object.""" - return keymile_subscriber.KeymileSubscriberCollection( + return keymile_subscriber.KeyMileSubscriberCollection( self._conn, base.get_sub_resource_path_by(self, 'subscribers'), params={field: value}).find_by_field_value(field, value) def get_subscribers(self, field, value): """Get specific subscribers object.""" - return keymile_subscriber.KeymileSubscriberCollection( + return keymile_subscriber.KeyMileSubscriberCollection( self._conn, base.get_sub_resource_path_by(self, 'subscribers'), params={field: value}) def add_subscriber(self, **fields): """Add new subscriber.""" - return keymile_subscriber.KeymileSubscriber.create( + return keymile_subscriber.KeyMileSubscriber.create( self._conn, os.path.join(self.path, 'subscribers'), **fields) def get_portgroupport(self, field, value): """Get specific portgroupport object.""" - return keymile_portgroupport.KeymilePortGroupPortCollection( + return keymile_portgroupport.KeyMilePortGroupPortCollection( self._conn, base.get_sub_resource_path_by(self, 'portgroupports'), params={field: value}).find_by_field_value(field, value) def get_portgroupports(self, field, value): """Get specific portgroupports object.""" - return keymile_portgroupport.KeymilePortGroupPortCollection( + return keymile_portgroupport.KeyMilePortGroupPortCollection( self._conn, base.get_sub_resource_path_by(self, 'portgroupports'), params={field: value}) + + def get_srvc(self, field, value): + """Get specific srvc object.""" + return keymile_srvc.KeyMileSrvcCollection( + self._conn, base.get_sub_resource_path_by(self, 'srvcs'), + params={field: value}).find_by_field_value(field, value) + + def get_srvcs(self, field, value): + """Get specific srvcs object.""" + return keymile_srvc.KeyMileSrvcCollection( + self._conn, base.get_sub_resource_path_by(self, 'srvcs'), + params={field: value}) class KeyMileBoxCollection(BoxCollection): diff --git a/nesi/keymile/keymile_resources/keymile_portgroupport.py b/nesi/keymile/keymile_resources/keymile_portgroupport.py index b224869..ce52bb6 100644 --- a/nesi/keymile/keymile_resources/keymile_portgroupport.py +++ b/nesi/keymile/keymile_resources/keymile_portgroupport.py @@ -16,7 +16,7 @@ LOG = logging.getLogger(__name__) -class KeymilePortGroupPort(base.Resource): +class KeyMilePortGroupPort(base.Resource): """Represent logical subscriber resource.""" # fields @@ -84,9 +84,9 @@ def set_isdnport(self, enable, registerglobal, regdefault, layer1, sip, proxy, c self.update(isdnba_profile=isdn) -class KeymilePortGroupPortCollection(base.ResourceCollection): +class KeyMilePortGroupPortCollection(base.ResourceCollection): """Represent a collection of logical subscribers.""" @property def _resource_type(self): - return KeymilePortGroupPort + return KeyMilePortGroupPort diff --git a/nesi/keymile/keymile_resources/keymile_srvc.py b/nesi/keymile/keymile_resources/keymile_srvc.py new file mode 100644 index 0000000..fad2756 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_srvc.py @@ -0,0 +1,35 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.service_port import logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class KeyMileSrvc(base.Resource): + """Represent logical srvc resource.""" + + id = base.Field('id') + name = base.Field('name') + service_type = base.Field('service_type') + address = base.Field('address') + svid = base.Field('svid') + + +class KeyMileSrvcCollection(base.ResourceCollection): + """Represent a collection of logical srvcs.""" + + @property + def _resource_type(self): + return KeyMileSrvc diff --git a/nesi/keymile/keymile_resources/keymile_subscriber.py b/nesi/keymile/keymile_resources/keymile_subscriber.py index 086cf2e..6eaefbf 100644 --- a/nesi/keymile/keymile_resources/keymile_subscriber.py +++ b/nesi/keymile/keymile_resources/keymile_subscriber.py @@ -16,7 +16,7 @@ LOG = logging.getLogger(__name__) -class KeymileSubscriber(base.Resource): +class KeyMileSubscriber(base.Resource): """Represent logical subscriber resource.""" # fields @@ -36,9 +36,9 @@ def set(self, field, value): self.update(**mapping) -class KeymileSubscriberCollection(base.ResourceCollection): +class KeyMileSubscriberCollection(base.ResourceCollection): """Represent a collection of logical subscribers.""" @property def _resource_type(self): - return KeymileSubscriber + return KeyMileSubscriber diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index aa91ddd..b411a6b 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -33,6 +33,7 @@ from .portgroupport_models import PortGroupPort from .logport_models import LogPort from .interface_models import Interface +from .srvc_models import Srvc class Box(db.Model): @@ -81,6 +82,7 @@ class Box(db.Model): subscribers = db.relationship('Subscriber', backref='Box', lazy='dynamic') portgroupports = db.relationship('PortGroupPort', backref='Box', lazy='dynamic') logports = db.relationship('LogPort', backref='Box', lazy='dynamic') + srvcs = db.relationship('Srvc', backref='Box', lazy='dynamic') board_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_instl_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_init_reporting_logging = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/models/srvc_models.py b/nesi/softbox/api/models/srvc_models.py new file mode 100644 index 0000000..6452ac2 --- /dev/null +++ b/nesi/softbox/api/models/srvc_models.py @@ -0,0 +1,23 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst +import uuid +from nesi.softbox.api import db + + +class Srvc(db.Model): + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(64)) + box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + service_type = db.Column(db.Enum('1to1DoubleTag', '1to1SingleTag', 'mcast', 'nto1', 'pls', 'tls', ''), default='') + address = db.Column(db.String(), default='') + svid = db.Column(db.Integer(), default=None) diff --git a/nesi/softbox/api/models/subscriber_models.py b/nesi/softbox/api/models/subscriber_models.py index a94baff..ec22ecf 100644 --- a/nesi/softbox/api/models/subscriber_models.py +++ b/nesi/softbox/api/models/subscriber_models.py @@ -1,3 +1,16 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + from nesi.softbox.api import db diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index 7d13b82..bb78496 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -33,7 +33,7 @@ class Meta: fields = ('id', 'vendor', 'model', 'version', 'software_version', 'network_protocol', 'network_address', 'network_port', 'uuid', 'description', 'interfaces', 'logports', 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', - 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'currTemperature', + 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'currTemperature', 'srvcs', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'mgmt_cards', 'mgmt_ports', 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') @@ -98,6 +98,10 @@ class Meta: {'_links': { 'self': ma.URLFor('show_logports', box_id='')}}) + srvcs = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_srvcs', box_id='')}}) + onts = ma.Hyperlinks({'_links': { 'self': ma.URLFor('show_onts', box_id='')}}) diff --git a/nesi/softbox/api/schemas/srvc_schemas.py b/nesi/softbox/api/schemas/srvc_schemas.py new file mode 100644 index 0000000..f1bba10 --- /dev/null +++ b/nesi/softbox/api/schemas/srvc_schemas.py @@ -0,0 +1,48 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api import ma +from ..models.srvc_models import Srvc + + +class SrvcSchema(ma.ModelSchema): + class Meta: + model = Srvc + fields = ('id', 'box', 'box_id', 'name', 'service_type', 'address', 'svid', '_links') + + box = ma.Hyperlinks( + {'_links': { + 'self': ma.URLFor('show_box', id='')}}) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_srvc', box_id='', id=''), + 'collection': ma.URLFor('show_srvcs', box_id='')}) + + +class SrvcsSchema(ma.ModelSchema): + class Meta: + fields = ('members', 'count', '_links') + + class SrvcSchema(ma.ModelSchema): + class Meta: + model = Srvc + fields = ('id', '_links') + + _links = ma.Hyperlinks( + {'self': ma.URLFor( + 'show_srvc', box_id='', id='')}) + + members = ma.Nested(SrvcSchema, many=True) + + _links = ma.Hyperlinks( + {'self': ma.URLFor('show_srvcs', box_id='')}) diff --git a/nesi/softbox/api/views/__init__.py b/nesi/softbox/api/views/__init__.py index 340544e..e87d03d 100644 --- a/nesi/softbox/api/views/__init__.py +++ b/nesi/softbox/api/views/__init__.py @@ -1,5 +1,5 @@ __all__ = ["box_views", "credential_views", "route_views", "subrack_views", "card_views", "port_views", "ont_views", "ontport_views", "cpe_views", "cpeport_views", "vlan_views", "portprofile_views", "emu_views", - "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", + "model_views", "vendor_views", "version_views", "service_port_views", "service_vlan_views", "srvc_views", "qos_interface_views", "vlan_interface_views", "user_views", "channel_views", "interface_views", "mgmt_card_views", "mgmt_port_views", "subscriber_views", "portgroupport_views", "logport_views"] diff --git a/nesi/softbox/api/views/srvc_views.py b/nesi/softbox/api/views/srvc_views.py new file mode 100644 index 0000000..263a2b9 --- /dev/null +++ b/nesi/softbox/api/views/srvc_views.py @@ -0,0 +1,53 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from .base_views import * +from ..schemas.srvc_schemas import * + +PREFIX = '/nesi/v1' + + +@app.route(PREFIX + '/boxen//srvcs', methods=['GET']) +def show_srvcs(box_id): + if flask.request.args is None: + req = {} + else: + req = flask.request.args + + response = show_components(SrvcsSchema(), Srvc, req, box_id) + return response, 200 + + +@app.route(PREFIX + '/boxen//srvcs/', methods=['GET']) +def show_srvc(box_id, id): + response = show_component(Srvc, box_id, id) + return response, 200 + + +@app.route(PREFIX + '/boxen//srvcs/', methods=['PUT']) +def update_srvc(box_id, id): + req = flask.request.json + update_component(Srvc, req, box_id, id) + return flask.Response(status=200) + + +@app.route(PREFIX + '/boxen//srvcs', methods=['POST']) +def new_srvc(box_id): + req = flask.request.json + response = new_component(SrvcSchema(), Srvc, req, box_id) + return response, 201 + +@app.route(PREFIX + '/boxen//srvcs/', methods=['DELETE']) +def del_srvc(box_id, id): + del_component(Srvc, box_id, id) + return flask.Response(status=204) diff --git a/templates/KeyMile/login/base/get/service_mcast.j2 b/templates/KeyMile/login/base/get/service_mcast.j2 new file mode 100644 index 0000000..bcbaf3b --- /dev/null +++ b/templates/KeyMile/login/base/get/service_mcast.j2 @@ -0,0 +1,6 @@ + \ # MCastAccessService + \ # Interface +{{ context.service.address }}{{ context.spacer1 }}\ # Address + \ # Specific +{{ context.service.svid }}{{ context.spacer2 }}\ # Svid + diff --git a/templates/KeyMile/login/base/get/service_nto1.j2 b/templates/KeyMile/login/base/get/service_nto1.j2 new file mode 100644 index 0000000..edb2127 --- /dev/null +++ b/templates/KeyMile/login/base/get/service_nto1.j2 @@ -0,0 +1,16 @@ + \ # Nto1AccessService + \ # Interface +{{ context.service.address }}{{ context.spacer1 }}\ # Address + \ # Specific +{{ context.service.svid }}{{ context.spacer2 }}\ # Svid +CoS0 \ # STagPriority +PPPoE \ # LogonMethod +Add \ # VLANHandling +false \ # SourceFilter +false \ # DestinationFilter +false \ # SourceIPFilter +false \ # DynamicARPInspection +false \ # MacForcedForwarding +Assigned \ # PriorityHandling +default \ # CoSProfile + diff --git a/templates/KeyMile/login/base/get/service_onetoonedoubletag.j2 b/templates/KeyMile/login/base/get/service_onetoonedoubletag.j2 new file mode 100644 index 0000000..60476ca --- /dev/null +++ b/templates/KeyMile/login/base/get/service_onetoonedoubletag.j2 @@ -0,0 +1,6 @@ + \ # OnetoOneDoubleTagAccessService + \ # Interface +{{ context.service.address }}{{ context.spacer1 }}\ # Address + \ # Specific +{{ context.service.svid }}{{ context.spacer2 }}\ # Svid + diff --git a/templates/KeyMile/login/base/get/service_onetoonesingletag.j2 b/templates/KeyMile/login/base/get/service_onetoonesingletag.j2 new file mode 100644 index 0000000..be29c7c --- /dev/null +++ b/templates/KeyMile/login/base/get/service_onetoonesingletag.j2 @@ -0,0 +1,8 @@ + \ # OnetoOneSingleTagAccessService + \ # Interface +{{ context.service.address }}{{ context.spacer1 }}\ # Address + \ # Specific +{{ context.service.svid }}{{ context.spacer2 }}\ # Svid +CoS0 \ # STagPriority +Add \ # VLANHandling + diff --git a/templates/KeyMile/login/base/get/service_pls.j2 b/templates/KeyMile/login/base/get/service_pls.j2 new file mode 100644 index 0000000..d0f3789 --- /dev/null +++ b/templates/KeyMile/login/base/get/service_pls.j2 @@ -0,0 +1,6 @@ + \ # PLSAccessService + \ # Interface +{{ context.service.address }}{{ context.spacer1 }}\ # Address + \ # Specific +{{ context.service.svid }}{{ context.spacer2 }}\ # Svid + diff --git a/templates/KeyMile/login/base/get/service_tls.j2 b/templates/KeyMile/login/base/get/service_tls.j2 new file mode 100644 index 0000000..9c22053 --- /dev/null +++ b/templates/KeyMile/login/base/get/service_tls.j2 @@ -0,0 +1,6 @@ + \ # TLSAccessService + \ # Interface +{{ context.service.address }}{{ context.spacer1 }}\ # Address + \ # Specific +{{ context.service.svid }}{{ context.spacer2 }}\ # Svid + diff --git a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py new file mode 100644 index 0000000..edd2132 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py @@ -0,0 +1,64 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class SrvcCommandProcessor(BaseCommandProcessor): + __name__ = 'srvc' + management_functions = ('main', 'cfgm', 'status') + access_points = () + + from .srvcManagementFunctions import main + from .srvcManagementFunctions import cfgm + from .srvcManagementFunctions import status + + def get_property(self, command, *args, context=None): + service_name = 'srvc-' + self.component_id + services = self._model.get_srvcs('name', service_name) + for s in services: + if s.service_type == context['ServiceType']: + service = s + context['service'] = service + break + scopes = ('login', 'base', 'get') + try: + super().get_property(command, *args, context=context) + except exceptions.CommandExecutionError: + if self._validate((args[0],), 'Service') and context['component_path'].split('/')[-1] == 'cfgm': + if service.service_type == '1to1DoubleTag': + template_name = 'service_onetoonedoubletag' + elif service.service_type == '1to1SingleTag': + template_name = 'service_onetoonesingletag' + elif service.service_type == 'mcast': + template_name = 'service_mcast' + elif service.service_type == 'nto1': + template_name = 'service_nto1' + elif service.service_type == 'pls': + template_name = 'service_pls' + elif service.service_type == 'tls': + template_name = 'service_tls' + else: + raise exceptions.CommandExecutionError(command=command) + context['spacer1'] = self.create_spacers((67,), (service.address,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (service.svid,))[0] * ' ' + text = self._render(template_name, *scopes, context=context) + self._write(text) + + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/services/srvcManagementFunctions.py b/vendors/KeyMile/accessPoints/root/services/srvcManagementFunctions.py new file mode 100644 index 0000000..be32883 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/services/srvcManagementFunctions.py @@ -0,0 +1,31 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminOperStatus': { + 'Prop': { + 'AdminState': 'rw', + 'OperState': 'r-' + } + } + } + +cfgm = { + 'Nto1AccessService': { + 'Prop': { + 'Service': 'rw' + } + } + } + +status = { + 'mgmt': { + 'Prop': { + 'maList': 'r-', + 'mepList': 'r-' + } + } + } diff --git a/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py index 706cc3b..27d0c7c 100644 --- a/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py @@ -23,5 +23,20 @@ class SubpacketCommandProcessor(BaseCommandProcessor): from .subpacketManagementFunctions import main from .subpacketManagementFunctions import cfgm + def _init_access_points(self, context=None): + self.access_points = () + try: + self.management_functions = ('main', 'cfgm') + s_type = context['ServiceType'] + + srvcs = self._model.get_srvcs('service_type', s_type) + for srvc in srvcs: + identifier = srvc.name + if identifier in self.access_points: + continue + self.access_points += (identifier,) + except exceptions.InvalidInputError: + pass + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index e465c52..5a46f19 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -214,7 +214,7 @@ def change_directory(self, path, context=None): components = [x for x in path.split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|macaccessctrl|tdmconnection|logports|logport-[0-9]|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|srvc-[0-9]|macaccessctrl|tdmconnection|logports|logport-[0-9]|\.|\.\.)$', components[0]): raise exceptions.SoftboxenError() @@ -307,7 +307,7 @@ def change_directory(self, path, context=None): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'interface': - if self.__name__ != 'port' and self.__name__ != 'chan': + if self.__name__ != 'port' and self.__name__ != 'chan' and self.__name__ != 'logport': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'logport': @@ -322,6 +322,14 @@ def change_directory(self, path, context=None): if self.__name__ != 'services': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'subpacket': + if self.__name__ != 'packet': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'srvc': + if self.__name__ != 'subpacket': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): if self.__name__ != 'root': raise exceptions.CommandExecutionError(command=None, template=None, @@ -360,6 +368,7 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.services.macaccessctrlCommandProcessor import \ MacaccessctrlCommandProcessor from vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor import SubpacketCommandProcessor + from vendors.KeyMile.accessPoints.root.services.srvcCommandProcessor import SrvcCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if component_id is not None and self.component_id is not None: @@ -401,7 +410,7 @@ def get_parent_and_child_relation(self, search, parent=None, node=None, parent_k "control": {}, "media": {}, "port": { - "chanel": { + "channel": { "interfaces": { "hell": {} } @@ -421,7 +430,9 @@ def get_parent_and_child_relation(self, search, parent=None, node=None, parent_k "tdmconnections": {}, "services": { "packet": { - "subpacket": {} + "subpacket": { + "srvc": {} + } }, "macaccessctrl": {} }, @@ -540,6 +551,7 @@ def get_command_processor(self, current_processor, component_type=None): from vendors.KeyMile.accessPoints.root.services.macaccessctrlCommandProcessor import\ MacaccessctrlCommandProcessor from vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor import SubpacketCommandProcessor + from vendors.KeyMile.accessPoints.root.services.srvcCommandProcessor import SrvcCommandProcessor if current_processor.__class__ == RootCommandProcessor: return_to = RootCommandProcessor if component_type not in ('fan', 'eoam', 'tdmconnections', 'multicast', 'services', 'unit') \ @@ -593,6 +605,8 @@ def get_command_processor(self, current_processor, component_type=None): return_to = ServicesCommandProcessor elif current_processor.__class__ == SubpacketCommandProcessor: return_to = PacketCommandProcessor + elif current_processor.__class__ == SrvcCommandProcessor: + return_to = SubpacketCommandProcessor return return_to From 22ec8ecf630d70843c90a48ab6205364f01aec27 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Mon, 19 Oct 2020 14:07:01 +0200 Subject: [PATCH 245/318] Added Melt and Line tests --- .../api/schemas/keymile_port_schemas.py | 3 +- .../keymile/keymile_resources/keymile_port.py | 8 +++ nesi/softbox/api/models/port_models.py | 2 + .../KeyMile/login/base/get/line__results.j2 | 13 +++++ .../KeyMile/login/base/get/melt_results.j2 | 13 +++++ .../root/unit/port/portCommandProcessor.py | 52 +++++++++++++++++-- 6 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 templates/KeyMile/login/base/get/line__results.j2 create mode 100644 templates/KeyMile/login/base/get/melt_results.j2 diff --git a/nesi/keymile/api/schemas/keymile_port_schemas.py b/nesi/keymile/api/schemas/keymile_port_schemas.py index 99356da..fba20f5 100644 --- a/nesi/keymile/api/schemas/keymile_port_schemas.py +++ b/nesi/keymile/api/schemas/keymile_port_schemas.py @@ -16,6 +16,7 @@ class KeyMilePortSchema(PortSchema): class Meta: model = Port - fields = PortSchema.Meta.fields + ('channels', 'label1', 'label2', 'loopbacktest_state') + fields = PortSchema.Meta.fields + ('channels', 'label1', 'label2', 'loopbacktest_state', 'melttest_state', + 'linetest_state') channels = ma.Nested(CpesSchema.CpeSchema, many=True) diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py index 3c45b71..80865e8 100644 --- a/nesi/keymile/keymile_resources/keymile_port.py +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -20,6 +20,8 @@ class KeyMilePort(Port): label1 = base.Field('label1') label2 = base.Field('label2') loopbacktest_state = base.Field('loopbacktest_state') + melttest_state = base.Field('melttest_state') + linetest_state = base.Field('linetest_state') def set_label(self, l1, l2, desc): self.update(label1=l1) @@ -37,6 +39,12 @@ def unlock_admin(self): """Set the admin port state to down""" self.update(admin_state='3') + def set_melttest_state(self, state): + self.update(melttest_state=state) + + def set_linetest_state(self, state): + self.update(linetest_state=state) + class KeyMilePortCollection(PortCollection): """Represent a collection of ports.""" diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 61bf14f..7f99aab 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -314,3 +314,5 @@ class Port(db.Model): label1 = db.Column(db.String(), default='""') label2 = db.Column(db.String(), default='""') loopbacktest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NoTestResult', 'Stopped', 'Interrupted'), default='NoTestResult') + melttest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NotTested'), default='NotTested') + linetest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NotTested'), default='NotTested') diff --git a/templates/KeyMile/login/base/get/line__results.j2 b/templates/KeyMile/login/base/get/line__results.j2 new file mode 100644 index 0000000..a8b7151 --- /dev/null +++ b/templates/KeyMile/login/base/get/line__results.j2 @@ -0,0 +1,13 @@ +TimeStamp 2010-09-21T10:36:11 +State {{ context.test_state }} +Results + | TestDescription | Status | MeasuredValue +---+--------------------------+-----------+--------------- + 0 | Foreign DC Voltage a-b | Ok | -30 mV + 1 | Foreign DC Voltage a-GND | Ok | -162 mV + 2 | Foreign DC Voltage b-GND | Ok | -133 mV + 3 | Foreign AC Voltage a-b | Ok | 11 mV + 4 | Foreign AC Voltage a-GND | Ok | 12 mV + 5 | Foreign AC Voltage b-GND | Ok | 11 mV + 6 | Resistance a-b | Ok | 10000.000 kOhm + diff --git a/templates/KeyMile/login/base/get/melt_results.j2 b/templates/KeyMile/login/base/get/melt_results.j2 new file mode 100644 index 0000000..a8b7151 --- /dev/null +++ b/templates/KeyMile/login/base/get/melt_results.j2 @@ -0,0 +1,13 @@ +TimeStamp 2010-09-21T10:36:11 +State {{ context.test_state }} +Results + | TestDescription | Status | MeasuredValue +---+--------------------------+-----------+--------------- + 0 | Foreign DC Voltage a-b | Ok | -30 mV + 1 | Foreign DC Voltage a-GND | Ok | -162 mV + 2 | Foreign DC Voltage b-GND | Ok | -133 mV + 3 | Foreign AC Voltage a-b | Ok | 11 mV + 4 | Foreign AC Voltage a-GND | Ok | 12 mV + 5 | Foreign AC Voltage b-GND | Ok | 11 mV + 6 | Resistance a-b | Ok | 10000.000 kOhm + diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 726e628..cf02d77 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -39,11 +39,23 @@ def get_property(self, command, *args, context=None): text = self._render('attainable_rate', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'QuickLoopbackTest') and context['component_path'].split('/')[-1] == 'status'\ - and (card.product == 'isdn' or 'SUI' in card.board_name): + and (card.product == 'isdn' or 'SUI' in card.board_name) and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.loopbacktest_state,))[0] * ' ' context['loopbacktest_state'] = port.loopbacktest_state text = self._render('quickloopbacktest', *scopes, context=context) self._write(text) + elif self._validate((args[0],), 'LineTestResults') and context['component_path'].split('/')[-1] == 'status'\ + and 'SUP' in card.board_name and self.__name__ == 'port': + context['spacer1'] = self.create_spacers((67,), (port.linetest_state,))[0] * ' ' + context['test_state'] = port.linetest_state + text = self._render('line_results', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'MeltResults') and context['component_path'].split('/')[-1] == 'status'\ + and card.product != 'isdn' and self.__name__ == 'port': + context['spacer1'] = self.create_spacers((67,), (port.melttest_state,))[0] * ' ' + context['test_state'] = port.melttest_state + text = self._render('melt_results', *scopes, context=context) + self._write(text) elif self._validate((args[0],), 'AdministrativeStatus') and context['component_path'].split('/')[-1] == 'main': self.map_states(port, 'port') context['spacer'] = self.create_spacers((67,), (port.admin_state,))[0] * ' ' @@ -84,7 +96,8 @@ def _init_access_points(self, context=None): def do_lock(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn': + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn' \ + and self.__name__ == 'port': try: port = self.get_port_component() port.lock_admin() @@ -95,9 +108,11 @@ def do_lock(self, command, *args, context=None): def do_startquickloopbacktest(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn': + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn' \ + and self.__name__ == 'port': try: port = self.get_port_component() + port.set_test_state('Running') time.sleep(5) port.set_test_state('Passed') except exceptions.SoftboxenError: @@ -105,9 +120,38 @@ def do_startquickloopbacktest(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) + def do_startlinetest(self, command, *args, context=None): + card = self._model.get_card('name', self._parent.component_id) + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and 'SUP' in card.board_name \ + and self.__name__ == 'port': + try: + port = self.get_port_component() + port.set_test_state('Running') + time.sleep(5) + port.set_linetest_state('Passed') + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_startmeltmeasurement(self, command, *args, context=None): + card = self._model.get_card('name', self._parent.component_id) + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product != 'isdn' \ + and self.__name__ == 'port': + try: + port = self.get_port_component() + port.set_melttest_state('Running') + time.sleep(5) + port.set_melttest_state('Passed') + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def do_unlock(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn': + if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn' \ + and self.__name__ == 'port': try: port = self.get_port_component() port.unlock_admin() From 5fc3c9fa475a15b71886ad3977e7468fe92c86ae Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 19 Oct 2020 14:57:35 +0200 Subject: [PATCH 246/318] Fixed a bug where cd'ing up from an management function resulted in the path being broken --- vendors/KeyMile/baseCommandProcessor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 5a46f19..7ce2615 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -247,7 +247,8 @@ def change_directory(self, path, context=None): if exit_component in ('main', 'cfgm', 'fm', 'pm', 'status'): self.set_prompt_end_pos(context=context) if path != '..': - return self._parent.change_directory(path[3:], context=context) + context['path'] = context['component_path'] + return self.change_directory(path[3:], context=context) return self if path == '..': From 57c68f8c7e3cb45769623c92ada10d0ac9cfe2ea Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 19 Oct 2020 15:19:55 +0200 Subject: [PATCH 247/318] Fixed broken navigation to tdmConnections --- ...mandProcessor.py => tdmconnectionsCommandProcessor.py} | 6 +++--- ...tFunctions.py => tdmconnectionsManagementFunctions.py} | 0 vendors/KeyMile/baseCommandProcessor.py | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) rename vendors/KeyMile/accessPoints/root/{tdmConnectionsCommandProcessor.py => tdmconnectionsCommandProcessor.py} (87%) rename vendors/KeyMile/accessPoints/root/{tdmConnectionsManagementFunctions.py => tdmconnectionsManagementFunctions.py} (100%) diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py similarity index 87% rename from vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py rename to vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py index 15fe3fd..a50788a 100644 --- a/vendors/KeyMile/accessPoints/root/tdmConnectionsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py @@ -14,13 +14,13 @@ from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor -class TdmConnectionsCommandProcessor(BaseCommandProcessor): +class TdmconnectionsCommandProcessor(BaseCommandProcessor): __name__ = 'tdmConnections' management_functions = ('main', 'cfgm') access_points = () - from .tdmConnectionsManagementFunctions import main - from .tdmConnectionsManagementFunctions import cfgm + from .tdmconnectionsManagementFunctions import main + from .tdmconnectionsManagementFunctions import cfgm def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/tdmConnectionsManagementFunctions.py b/vendors/KeyMile/accessPoints/root/tdmconnectionsManagementFunctions.py similarity index 100% rename from vendors/KeyMile/accessPoints/root/tdmConnectionsManagementFunctions.py rename to vendors/KeyMile/accessPoints/root/tdmconnectionsManagementFunctions.py diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 7ce2615..93ab5cd 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -214,7 +214,7 @@ def change_directory(self, path, context=None): components = [x for x in path.split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|srvc-[0-9]|macaccessctrl|tdmconnection|logports|logport-[0-9]|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|srvc-[0-9]|macaccessctrl|tdmconnections|logports|logport-[0-9]|\.|\.\.)$', components[0]): raise exceptions.SoftboxenError() @@ -355,7 +355,7 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor import AlarmCommandProcessor from vendors.KeyMile.accessPoints.root.eoamCommandProcessor import EoamCommandProcessor from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor - from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor + from vendors.KeyMile.accessPoints.root.tdmconnectionsCommandProcessor import TdmconnectionsCommandProcessor from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import \ PortgroupCommandProcessor @@ -538,7 +538,7 @@ def get_command_processor(self, current_processor, component_type=None): from vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor import AlarmCommandProcessor from vendors.KeyMile.accessPoints.root.eoamCommandProcessor import EoamCommandProcessor from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor - from vendors.KeyMile.accessPoints.root.tdmConnectionsCommandProcessor import TdmConnectionsCommandProcessor + from vendors.KeyMile.accessPoints.root.tdmconnectionsCommandProcessor import TdmconnectionsCommandProcessor from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import \ PortgroupCommandProcessor @@ -586,7 +586,7 @@ def get_command_processor(self, current_processor, component_type=None): return_to = RootCommandProcessor elif current_processor.__class__ == MulticastCommandProcessor: return_to = RootCommandProcessor - elif current_processor.__class__ == TdmConnectionsCommandProcessor: + elif current_processor.__class__ == TdmconnectionsCommandProcessor: return_to = RootCommandProcessor elif current_processor.__class__ == ServicesCommandProcessor: return_to = RootCommandProcessor From f4b8d7f2f3716e1dbac26f4f034e3eae93f13a0c Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Mon, 19 Oct 2020 15:47:42 +0200 Subject: [PATCH 248/318] Added set and get channel profile --- .../api/schemas/keymile_channel_schemas.py | 2 +- .../keymile_resources/keymile_channel.py | 4 ++ nesi/softbox/api/models/channel_models.py | 1 + .../KeyMile/login/base/get/chan_profile.j2 | 2 +- .../unit/port/chan/chanCommandProcessor.py | 37 ++++++++++++++++--- 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/nesi/keymile/api/schemas/keymile_channel_schemas.py b/nesi/keymile/api/schemas/keymile_channel_schemas.py index 9808e4b..8d4555b 100644 --- a/nesi/keymile/api/schemas/keymile_channel_schemas.py +++ b/nesi/keymile/api/schemas/keymile_channel_schemas.py @@ -16,4 +16,4 @@ class KeyMileChannelSchema(ChannelSchema): class Meta: model = Channel - fields = ChannelSchema.Meta.fields + ('vccs', 'interfaces') + fields = ChannelSchema.Meta.fields + ('vccs', 'interfaces', 'chan_profile_name') diff --git a/nesi/keymile/keymile_resources/keymile_channel.py b/nesi/keymile/keymile_resources/keymile_channel.py index 18e4a80..1fc9462 100644 --- a/nesi/keymile/keymile_resources/keymile_channel.py +++ b/nesi/keymile/keymile_resources/keymile_channel.py @@ -24,6 +24,10 @@ class KeyMileChannel(base.Resource): port_id = base.Field('port_id') name = base.Field('name') description = base.Field('description') + chan_profile_name = base.Field('chan_profile_name') + + def set_profile_name(self, name): + self.update(chan_profile_name=name) class KeyMileChannelCollection(base.ResourceCollection): diff --git a/nesi/softbox/api/models/channel_models.py b/nesi/softbox/api/models/channel_models.py index 4837c8f..4c3cc18 100644 --- a/nesi/softbox/api/models/channel_models.py +++ b/nesi/softbox/api/models/channel_models.py @@ -18,6 +18,7 @@ class Channel(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) description = db.Column(db.String()) + chan_profile_name = db.Column(db.String(), default='') box_id = db.Column(db.Integer, db.ForeignKey('box.id')) port_id = db.Column(db.Integer, db.ForeignKey('port.id')) interfaces = db.relationship('Interface', backref='Channel', lazy='dynamic') diff --git a/templates/KeyMile/login/base/get/chan_profile.j2 b/templates/KeyMile/login/base/get/chan_profile.j2 index 7691f6d..c60d36c 100644 --- a/templates/KeyMile/login/base/get/chan_profile.j2 +++ b/templates/KeyMile/login/base/get/chan_profile.j2 @@ -1,3 +1,3 @@ \ # ChannelProfile -{{ context.port_profile.name }}{{ context.spacer }}\ # Name +{{ context.profile_name }}{{ context.spacer1 }}\ # Name diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 67bb191..220b516 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -167,7 +167,7 @@ def do_createvcc(self, command, *args, context=None): vlan_profile=vlan_prof) context['spacer1'] = self.create_spacers((63,), (str(id),))[0] * ' ' context['id'] = str(id) - # TODO: Template is unknown + # TODO: unknown Template text = self._render('vcc_success', *scopes, context=context) self._write(text) except AssertionError: @@ -182,26 +182,51 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def set(self, command, *args, context=None): + card = self._model.get_card('name', self._parent._parent.component_id) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return + elif self._validate(args, 'chanprofile', str) and 'SUV' in card.board_name: + name, = self._dissect(args, 'chanprofile', str) + try: + #TODO: Check if profile with this name exists or default + channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + channel.set_profile_name(name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args, 'ProfileName', str) and 'SUV' not in card.board_name: + name, = self._dissect(args, 'ProfileName', str) + try: + # TODO: Check if profile with this name exists or default + channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + channel.set_profile_name(name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) else: raise exceptions.CommandSyntaxError(command=command) def get_property(self, command, *args, context=None): - #card = self._model.get_card('name', self.component_id) + card = self._model.get_card('name', self._parent._parent.component_id) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'Chanprofile') and 'SUV' in card.board_name: + channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + context['spacer1'] = self.create_spacers((67,), (channel.chan_profile_name,))[0] * ' ' + context['profile_name'] = channel.chan_profile_name + text = self._render('chan_profile', *scopes, context=context) + self._write(text) + elif self._validate(args, 'ProfileName') and 'SUV' not in card.board_name: + channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + context['spacer1'] = self.create_spacers((67,), (channel.chan_profile_name,))[0] * ' ' + context['profile_name'] = channel.chan_profile_name + text = self._render('chan_profile', *scopes, context=context) + self._write(text) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) From 4deb735262a39c35d0d80bbc8b3c1299027264a4 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 20 Oct 2020 08:44:16 +0200 Subject: [PATCH 249/318] Fixed navigation for packet accessPoints --- .../root/services/servicesCommandProcessor.py | 2 +- vendors/KeyMile/baseCommandProcessor.py | 65 ++++++++++++------- 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py index 47ca719..0604db8 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -17,7 +17,7 @@ class ServicesCommandProcessor(BaseCommandProcessor): __name__ = 'services' management_functions = ('main', 'fm', 'status') - access_points = ('packet', 'macAccessCtrl') + access_points = ('macAccessCtrl', 'packet') from .servicesManagementFunctions import main from .servicesManagementFunctions import fm diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 93ab5cd..6fe36b9 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -200,9 +200,6 @@ def do_ls(self, command, *args, context=None): command=command) def change_directory(self, path, context=None): - if re.match("1to1DoubleTag|1to1SingleTag|mcast|nto1|pls|tls", path): - context['ServiceType'] = path - path = 'subpacket' path = path.lower() if path == '/': if self.__name__ != 'root': @@ -214,9 +211,11 @@ def change_directory(self, path, context=None): components = [x for x in path.split('/') if x] if not re.search( - '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|srvc-[0-9]|macaccessctrl|tdmconnections|logports|logport-[0-9]|\.|\.\.)$', + '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|srvc-[0-9]|macaccessctrl|tdmconnections|logports|logport-[0-9]|1to1doubletag|1to1singletag|mcast|nto1|pls|tls|\.|\.\.)$', components[0]): - raise exceptions.SoftboxenError() + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) if path == '.': return self @@ -280,7 +279,17 @@ def change_directory(self, path, context=None): command_processor = component_type.capitalize() + 'CommandProcessor' else: - command_processor = components[0].capitalize() + 'CommandProcessor' + if components[0] in ('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'): + if context['path'].split('/')[-1] in ( + '1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'): + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + + context['ServiceType'] = components[0] + + command_processor = 'SubpacketCommandProcessor' + else: + command_processor = components[0].capitalize() + 'CommandProcessor' if component_type == 'unit': if (self._model.version == '2200' and not 9 <= int(component_id) <= 12) or (self._model.version == '2300' and not 7 <= int(component_id) <= 14) or (self._model.version == '2500' and not 1 <= int(component_id) <= 21): @@ -319,26 +328,40 @@ def change_directory(self, path, context=None): if self.__name__ != 'chan': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'packet' or component_type == 'macAccessCtrl': + + elif components[0] in ('packet', 'macAccessCtrl'): if self.__name__ != 'services': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'subpacket': - if self.__name__ != 'packet': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'srvc': - if self.__name__ != 'subpacket': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): if self.__name__ != 'root': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + if components[0] in ('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'): + if self.__name__ != 'packet': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty if components[0] in ('main', 'cfgm', 'fm', 'pm', 'status'): - if re.search('(main|cfgm|fm|pm|status)', context['path']): - return self + if context['path'].split('/')[-1] in ('main', 'cfgm', 'fm', 'pm', 'status'): + raise exceptions.CommandExecutionError(command=None, template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors')) + + mf_layers = {} + if components[0] == 'status': + mf_layers = self.status + elif components[0] == 'cfgm': + mf_layers = self.cfgm + elif components[0] == 'fm': + mf_layers = self.fm + elif components[0] == 'pm': + mf_layers = self.pm + elif components[0] == 'main': + mf_layers = self.main + + if len(mf_layers) == 0: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if context['component_path'] == '/': new_path = components[0] else: @@ -508,18 +531,12 @@ def do_cd(self, command, *args, context=None): raise exceptions.CommandSyntaxError() elif self._validate(args, str): path = args[0] - if re.match("1to1DoubleTag|1to1SingleTag|mcast|nto1|pls|tls", path): - context['ServiceType'] = path - path = 'subpacket' - try: subprocessor = self.change_directory(path, context=context) return_to = self.get_command_processor(subprocessor) except: context['component_path'] = context['path'] - raise exceptions.CommandExecutionError(template='invalid_management_function_error', - template_scopes=('login', 'base', 'execution_errors'), - command=None) + raise context['path'] = context['component_path'] subprocessor.loop(context=context, return_to=return_to) else: From 8e4f65fc0bb34b4d7d6549928464d48cdcdf165e Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 20 Oct 2020 09:18:11 +0200 Subject: [PATCH 250/318] Added set and get port profile --- .../api/schemas/keymile_port_schemas.py | 5 +- .../keymile/keymile_resources/keymile_port.py | 30 +++++++++ nesi/softbox/api/models/port_models.py | 13 ++++ .../KeyMile/login/base/get/port_profile.j2 | 3 + .../KeyMile/login/base/get/port_profiles.j2 | 19 ++++++ .../root/unit/port/portCommandProcessor.py | 67 ++++++++++++++++++- 6 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 templates/KeyMile/login/base/get/port_profile.j2 create mode 100644 templates/KeyMile/login/base/get/port_profiles.j2 diff --git a/nesi/keymile/api/schemas/keymile_port_schemas.py b/nesi/keymile/api/schemas/keymile_port_schemas.py index fba20f5..687a495 100644 --- a/nesi/keymile/api/schemas/keymile_port_schemas.py +++ b/nesi/keymile/api/schemas/keymile_port_schemas.py @@ -17,6 +17,9 @@ class KeyMilePortSchema(PortSchema): class Meta: model = Port fields = PortSchema.Meta.fields + ('channels', 'label1', 'label2', 'loopbacktest_state', 'melttest_state', - 'linetest_state') + 'linetest_state', 'profile1_enable', 'profile1_name', 'profile1_elength', + 'profile2_enable', 'profile2_name', 'profile2_elength', 'profile3_enable', + 'profile3_name', 'profile3_elength', 'profile4_enable', 'profile4_name', + 'profile_mode') channels = ma.Nested(CpesSchema.CpeSchema, many=True) diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py index 80865e8..1555ef7 100644 --- a/nesi/keymile/keymile_resources/keymile_port.py +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -22,6 +22,36 @@ class KeyMilePort(Port): loopbacktest_state = base.Field('loopbacktest_state') melttest_state = base.Field('melttest_state') linetest_state = base.Field('linetest_state') + profile1_enable = base.Field('profile1_enable') + profile1_name = base.Field('profile1_name') + profile1_elength = base.Field('profile1_elength') + profile2_enable = base.Field('profile2_enable') + profile2_name = base.Field('profile2_name') + profile2_elength = base.Field('profile2_elength') + profile3_enable = base.Field('profile3_enable') + profile3_name = base.Field('profile3_name') + profile3_elength = base.Field('profile3_elength') + profile4_enable = base.Field('profile4_enable') + profile4_name = base.Field('profile4_name') + profile_mode = base.Field('profile_mode') + + def set_profile(self, name): + self.update(profile1_name=name) + + + def set_profiles(self, e1, n1, el1, e2, n2, el2, e3, n3, el3, e4, n4, mode): + self.update(profile1_enable=e1) + self.update(profile1_name=n1) + self.update(profile1_elength=el1) + self.update(profile2_enable=e2) + self.update(profile2_name=n2) + self.update(profile2_elength=el2) + self.update(profile3_enable=e3) + self.update(profile3_name=n3) + self.update(profile3_elength=el3) + self.update(profile4_enable=e4) + self.update(profile4_name=n4) + self.update(profile_mode=mode) def set_label(self, l1, l2, desc): self.update(label1=l1) diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 7f99aab..32e0380 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -316,3 +316,16 @@ class Port(db.Model): loopbacktest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NoTestResult', 'Stopped', 'Interrupted'), default='NoTestResult') melttest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NotTested'), default='NotTested') linetest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NotTested'), default='NotTested') + #profiles + profile1_enable = db.Column(db.Boolean(), default=False) + profile1_name = db.Column(db.String(), default='') + profile1_elength = db.Column(db.Integer, default=0) + profile2_enable = db.Column(db.Boolean(), default=False) + profile2_name = db.Column(db.String(), default='') + profile2_elength = db.Column(db.Integer, default=0) + profile3_enable = db.Column(db.Boolean(), default=False) + profile3_name = db.Column(db.String(), default='') + profile3_elength = db.Column(db.Integer, default=0) + profile4_enable = db.Column(db.Boolean(), default=False) + profile4_name = db.Column(db.String(), default='') + profile_mode = db.Column(db.Enum('Priority', 'ElectricalLoopLength'), default=None) diff --git a/templates/KeyMile/login/base/get/port_profile.j2 b/templates/KeyMile/login/base/get/port_profile.j2 new file mode 100644 index 0000000..cd044d5 --- /dev/null +++ b/templates/KeyMile/login/base/get/port_profile.j2 @@ -0,0 +1,3 @@ + \ # PortProfile +{{ context.profile_name }}{{ context.spacer1 }}\ # Name + diff --git a/templates/KeyMile/login/base/get/port_profiles.j2 b/templates/KeyMile/login/base/get/port_profiles.j2 new file mode 100644 index 0000000..89af093 --- /dev/null +++ b/templates/KeyMile/login/base/get/port_profiles.j2 @@ -0,0 +1,19 @@ + \ # Profiles + \ # VDSLxPrio1 +{{ context.port.profile1_enable }}{{ context.spacer1 }}\ # Enabled +{{ context.port.profile1_name }}{{ context.spacer2 }}\ # Name +{{ context.port.profile1_elength }}{{ context.spacer3 }}\ # MaxElectricalLoopLength + \ # VDSLxPrio2 +{{ context.port.profile2_enable }}{{ context.spacer4 }}\ # Enabled +{{ context.port.profile2_name }}{{ context.spacer5 }}\ # Name +{{ context.port.profile2_elength }}{{ context.spacer6 }}\ # MaxElectricalLoopLength + \ # VDSLxPrio3 +{{ context.port.profile3_enable }}{{ context.spacer7 }}\ # Enabled +{{ context.port.profile3_name }}{{ context.spacer8 }}\ # Name +{{ context.port.profile3_elength }}{{ context.spacer9 }}\ # MaxElectricalLoopLength + \ # ADSLxPrio4 +{{ context.port.profile4_enable }}{{ context.spacer10 }}\ # Enabled +{{ context.port.profile4_name }}{{ context.spacer11 }}\ # Name + \ # AutomaticProfileSwitching +{{ context.port.profile_mode }}{{ context.spacer12 }}\ # Mode + diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index cf02d77..23e03c1 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -35,6 +35,35 @@ def get_property(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + + elif self._validate(args, 'Portprofile') and context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM'\ + not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': + context['spacer1'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' + context['profile_name'] = port.profile1_name + text = self._render('port_profile', *scopes, context=context) + self._write(text) + elif self._validate(args, 'Portprofiles') and context['component_path'].split('/')[-1] == 'cfgm' and \ + 'SUVD2' in card.board_name and self.__name__ == 'port': + context['spacer1'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' + context['profile_name'] = port.profile1_name + text = self._render('port_profile', *scopes, context=context) + self._write(text) + elif self._validate(args, 'Portprofiles') and self.__name__ == 'port' and \ + context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM' in card.board_name: + context['spacer1'] = self.create_spacers((67,), (port.profile1_enable,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (port.profile1_elength,))[0] * ' ' + context['spacer4'] = self.create_spacers((67,), (port.profile2_enable,))[0] * ' ' + context['spacer5'] = self.create_spacers((67,), (port.profile2_name,))[0] * ' ' + context['spacer6'] = self.create_spacers((67,), (port.profile2_elength,))[0] * ' ' + context['spacer7'] = self.create_spacers((67,), (port.profile3_enable,))[0] * ' ' + context['spacer8'] = self.create_spacers((67,), (port.profile3_name,))[0] * ' ' + context['spacer9'] = self.create_spacers((67,), (port.profile3_elength,))[0] * ' ' + context['spacer10'] = self.create_spacers((67,), (port.profile4_enable,))[0] * ' ' + context['spacer11'] = self.create_spacers((67,), (port.profile4_name,))[0] * ' ' + context['spacer12'] = self.create_spacers((67,), (port.profile_mode,))[0] * ' ' + text = self._render('port_profiles', *scopes, context=dict(context, port=port)) + self._write(text) elif self._validate((args[0],), 'AttainableRate') and context['component_path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) @@ -206,7 +235,7 @@ def do_createinterface(self, command, *args, context=None): interf = self._model.add_interface(name=name, port_id=port.id, vlan_profile=vlan_prof) context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' context['id'] = str(id) - # TODO: Template is unknown + # TODO: unknown Template text = self._render('interface_success', *scopes, context=context) self._write(text) except AssertionError: @@ -222,11 +251,47 @@ def get_port_component(self): def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') + card = self._model.get_card('name', self._parent.component_id) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'Portprofile', str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM'\ + not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': + profile, = self._dissect(args, 'Portprofile', str) + try: + port = self.get_port_component() + port.set_profile(profile) + + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'Portprofiles', str) and context['component_path'].split('/')[-1] == 'cfgm' and \ + 'SUVD2' in card.board_name and self.__name__ == 'port': + profile, = self._dissect(args, 'Portprofiles', str) + try: + port = self.get_port_component() + port.set_profile(profile) + + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'Portprofiles', str, str, str, str, str, str, str, str, str, str, str, str) and \ + context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM' in card.board_name and self.__name__ == 'port': + en1, name1, elen1, en2, name2, elen2, en3, name3, elen3, en4, name4, mode = self._dissect(args, + 'Portprofiles', str, str, str, str, str, str, str, str, str, str, str, str) + try: + port = self.get_port_component() + en1 = True if en1.lower() == 'true' else False + en2 = True if en2.lower() == 'true' else False + en3 = True if en3.lower() == 'true' else False + en4 = True if en4.lower() == 'true' else False + port.set_profiles(en1, name1, int(elen1), en2, name2, int(elen2), en3, name3, int(elen3), en4, name4, mode) + + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'AdministrativeStatus', str) and context['component_path'].split('/')[-1] == 'main': state, = self._dissect(args, 'AdministrativeStatus', str) try: From 72b01321491583b9951840bbb2430d89c28157e2 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 20 Oct 2020 10:30:29 +0200 Subject: [PATCH 251/318] Removed 'component_path' --- templates/KeyMile/login/base/ls/ls_header.j2 | 2 +- .../accessPoints/root/rootCommandProcessor.py | 6 +-- .../root/services/srvcCommandProcessor.py | 2 +- .../unit/logport/logportsCommandProcessor.py | 4 +- .../logport/port/logportCommandProcessor.py | 6 +-- .../unit/port/chan/chanCommandProcessor.py | 10 ++--- .../root/unit/port/portCommandProcessor.py | 32 ++++++++-------- .../port/portgroupportCommandProcessor.py | 14 +++---- .../root/unit/unitCommandProcessor.py | 26 ++++++------- vendors/KeyMile/baseCommandProcessor.py | 37 +++++++++---------- vendors/KeyMile/main.py | 1 - 11 files changed, 69 insertions(+), 71 deletions(-) diff --git a/templates/KeyMile/login/base/ls/ls_header.j2 b/templates/KeyMile/login/base/ls/ls_header.j2 index 2f31160..e0a8150 100644 --- a/templates/KeyMile/login/base/ls/ls_header.j2 +++ b/templates/KeyMile/login/base/ls/ls_header.j2 @@ -1,4 +1,4 @@ -Infos of AP: {{ context.ls_path }} +Infos of AP: {{ context.path }} Name : MileGate 2200 Main Mode : Equipment State : Ok diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 24ce5a0..674f148 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -76,13 +76,13 @@ def set(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors')) def do_save(self, command, *args, context=None): - if len(args) == 0 and context['component_path'].split('/')[-1] == 'cfgm': + if len(args) == 0 and context['path'].split('/')[-1] == 'cfgm': pass else: raise exceptions.CommandSyntaxError(command=command) def do_ftpserver(self, command, *args, context=None): - if self._validate(args, str, str, str) and context['component_path'].split('/')[-1] != 'cfgm': + if self._validate(args, str, str, str) and context['path'].split('/')[-1] != 'cfgm': ip, login, pw = self._dissect(args, str, str, str) try: self._model.set_backup(ip, login, pw) @@ -92,7 +92,7 @@ def do_ftpserver(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_upload(self, command, *args, context=None): - if self._validate(args, '/cfgm/configuration', str) and context['component_path'].split('/')[-1] != 'cfgm': + if self._validate(args, '/cfgm/configuration', str) and context['path'].split('/')[-1] != 'cfgm': path, = self._dissect(args, '/cfgm/configuration', str) try: self._model.set_path(path) diff --git a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py index edd2132..02c5dcc 100644 --- a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py @@ -36,7 +36,7 @@ def get_property(self, command, *args, context=None): try: super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: - if self._validate((args[0],), 'Service') and context['component_path'].split('/')[-1] == 'cfgm': + if self._validate((args[0],), 'Service') and context['path'].split('/')[-1] == 'cfgm': if service.service_type == '1to1DoubleTag': template_name = 'service_onetoonedoubletag' elif service.service_type == '1to1SingleTag': diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 0e540e3..9e76d14 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -40,7 +40,7 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_delete(self, command, *args, context=None): - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm': + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm': name, = self._dissect(args, str) if name.startswith('logport-'): id = name.split('-')[1] @@ -55,7 +55,7 @@ def do_delete(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_create(self, command, *args, context=None): - if self._validate(args, str, str, str, str) and context['component_path'].split('/')[-1] == 'cfgm': + if self._validate(args, str, str, str, str) and context['path'].split('/')[-1] == 'cfgm': p1, p2, p3, p4, = self._dissect(args, str, str, str, str) ids = [] ids.append(int(p1.split('-')[1])) if p1.startswith('port-') else ids diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 16e3827..8d7b5b7 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -32,7 +32,7 @@ def get_property(self, command, *args, context=None): try: super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: - if self._validate((args[0],), 'AttainableRate') and context['component_path'].split('/')[-1] == 'status': + if self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) else: @@ -59,7 +59,7 @@ def _init_access_points(self, context=None): def do_deleteinterface(self, command, *args, context=None): card = self._model.get_card('name', self._parent._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': # all or interface_id name, = self._dissect(args, str) if name == 'all': @@ -82,7 +82,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 220b516..147e4d8 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -43,7 +43,7 @@ def _init_access_points(self, context=None): def do_deletevcc(self, command, *args, context=None): card = self._model.get_card('name', self._parent._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': # all or vcc_id name, = self._dissect(args, str) if name == 'all': @@ -64,7 +64,7 @@ def do_deletevcc(self, command, *args, context=None): def do_deleteinterface(self, command, *args, context=None): card = self._model.get_card('name', self._parent._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product != 'adsl' and card.product != 'sdsl': + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product != 'adsl' and card.product != 'sdsl': # all or interface_id name, = self._dissect(args, str) if name == 'all': @@ -86,7 +86,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name: + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name: # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names @@ -113,7 +113,7 @@ def do_createinterface(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name : + elif self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name : # vcc profile and vlan profile vlan_prof, vcc_prof = self._dissect(args, str, str) # TODO: Check if profiles := default or profile names @@ -147,7 +147,7 @@ def do_createinterface(self, command, *args, context=None): def do_createvcc(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent._parent.component_id) - if self._validate(args, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': + if self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': # vcc profile and vlan profile vcc_prof, vlan_prof = self._dissect(args, str, str) # TODO: Check if profiles := default or profile names diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 23e03c1..b355f31 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -64,39 +64,39 @@ def get_property(self, command, *args, context=None): context['spacer12'] = self.create_spacers((67,), (port.profile_mode,))[0] * ' ' text = self._render('port_profiles', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate((args[0],), 'AttainableRate') and context['component_path'].split('/')[-1] == 'status': + elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'QuickLoopbackTest') and context['component_path'].split('/')[-1] == 'status'\ + elif self._validate((args[0],), 'QuickLoopbackTest') and context['path'].split('/')[-1] == 'status'\ and (card.product == 'isdn' or 'SUI' in card.board_name) and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.loopbacktest_state,))[0] * ' ' context['loopbacktest_state'] = port.loopbacktest_state text = self._render('quickloopbacktest', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'LineTestResults') and context['component_path'].split('/')[-1] == 'status'\ + elif self._validate((args[0],), 'LineTestResults') and context['path'].split('/')[-1] == 'status'\ and 'SUP' in card.board_name and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.linetest_state,))[0] * ' ' context['test_state'] = port.linetest_state text = self._render('line_results', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'MeltResults') and context['component_path'].split('/')[-1] == 'status'\ + elif self._validate((args[0],), 'MeltResults') and context['path'].split('/')[-1] == 'status'\ and card.product != 'isdn' and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.melttest_state,))[0] * ' ' context['test_state'] = port.melttest_state text = self._render('melt_results', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'AdministrativeStatus') and context['component_path'].split('/')[-1] == 'main': + elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': self.map_states(port, 'port') context['spacer'] = self.create_spacers((67,), (port.admin_state,))[0] * ' ' text = self._render('administrative_status', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate(args, 'Labels') and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'Labels') and context['path'].split('/')[-1] == 'main': context['spacer1'] = self.create_spacers((67,), (port.label1,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (port.label2,))[0] * ' ' context['spacer3'] = self.create_spacers((67,), (port.description,))[0] * ' ' text = self._render('labels', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate((args[0],), 'OperationalStatus') and context['component_path'].split('/')[-1] == 'main': + elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': self.map_states(port, 'port') port_operational_state = port.operational_state context['port_operational_state'] = port_operational_state @@ -125,7 +125,7 @@ def _init_access_points(self, context=None): def do_lock(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn' \ + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: port = self.get_port_component() @@ -137,7 +137,7 @@ def do_lock(self, command, *args, context=None): def do_startquickloopbacktest(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn' \ + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: port = self.get_port_component() @@ -151,7 +151,7 @@ def do_startquickloopbacktest(self, command, *args, context=None): def do_startlinetest(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and 'SUP' in card.board_name \ + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and 'SUP' in card.board_name \ and self.__name__ == 'port': try: port = self.get_port_component() @@ -165,7 +165,7 @@ def do_startlinetest(self, command, *args, context=None): def do_startmeltmeasurement(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product != 'isdn' \ + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product != 'isdn' \ and self.__name__ == 'port': try: port = self.get_port_component() @@ -179,7 +179,7 @@ def do_startmeltmeasurement(self, command, *args, context=None): def do_unlock(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if len(args) == 0 and context['component_path'].split('/')[-1] == 'status' and card.product == 'isdn' \ + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: port = self.get_port_component() @@ -194,7 +194,7 @@ def on_unknown_command(self, command, *args, context=None): def do_deleteinterface(self, command, *args, context=None): card = self._model.get_card('name', self._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and card.product == 'ftth': + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'ftth': # all or interface_id name, = self._dissect(args, str) if name == 'all': @@ -216,7 +216,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') card = self._model.get_card('name', self._parent.component_id) - if self._validate(args, str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUE' in card.board_name: + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUE' in card.board_name: # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names @@ -292,7 +292,7 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'AdministrativeStatus', str) and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'AdministrativeStatus', str) and context['path'].split('/')[-1] == 'main': state, = self._dissect(args, 'AdministrativeStatus', str) try: port = self.get_port_component() @@ -305,7 +305,7 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'Labels', str, str, str) and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': label1, label2, description = self._dissect(args, 'Labels', str, str, str) try: port = self.get_port_component() diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index cb73492..e22f293 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -32,7 +32,7 @@ def get_property(self, command, *args, context=None): try: super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: - if self._validate((args[0],), 'SubscriberList') and context['component_path'].split('/')[-1] == 'status' and \ + if self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ self._model.get_card('name', self._parent._parent.component_id).product == 'isdn': text = self._render('subscriberList_top', *scopes, context=context) i = 0 @@ -48,7 +48,7 @@ def get_property(self, command, *args, context=None): text += self._render('subscriberList_bottom', *scopes, context=context) self._write(text) - elif self._validate((args[0],), 'Isdnport') and context['component_path'].split('/')[-1] == 'cfgm' and \ + elif self._validate((args[0],), 'Isdnport') and context['path'].split('/')[-1] == 'cfgm' and \ port.type == 'ISDN': context['spacer1'] = self.create_spacers((67,), (port.enable,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (port.register_as_global,))[0] * ' ' @@ -74,7 +74,7 @@ def get_property(self, command, *args, context=None): text += self._render('isdnport_bottom', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate((args[0],), 'pstnport') and context['component_path'].split('/')[-1] == 'cfgm' and \ + elif self._validate((args[0],), 'pstnport') and context['path'].split('/')[-1] == 'cfgm' and \ port.type == 'PSTN': context['spacer1'] = self.create_spacers((67,), (port.enable,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (port.register_as_global,))[0] * ' ' @@ -127,7 +127,7 @@ def set(self, command, *args, context=None): exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc elif self._validate(args, 'pstnport', str, str, str, str, str, str, str, str, str) and \ - context['component_path'].split('/')[-1] == 'cfgm': + context['path'].split('/')[-1] == 'cfgm': enable, subident, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', str, str, str, str, str, str, str, str, str) try: @@ -140,7 +140,7 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'pstnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, - str) and context['component_path'].split('/')[-1] == 'cfgm': + str) and context['path'].split('/')[-1] == 'cfgm': enable, number, username, password, displayname, privacy, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) try: port = self.get_port_component() @@ -164,7 +164,7 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'isdnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, - str) and context['component_path'].split('/')[-1] == 'cfgm': + str) and context['path'].split('/')[-1] == 'cfgm': enable, number, username, password, displayname, privacy, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) try: port = self.get_port_component() @@ -192,7 +192,7 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'isdnport', str, str, str, str, str, str, str, str, str) and \ - context['component_path'].split('/')[-1] == 'cfgm': + context['path'].split('/')[-1] == 'cfgm': enable, subident, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', str, str, str, str, str, str, str, str, str) try: diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index a12beba..5b675a2 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -60,7 +60,7 @@ def get_property(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'SubscriberList') and context['component_path'].split('/')[-1] == 'status' and \ + elif self._validate(args, 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ (card.product == 'isdn' or card.product == 'analog'): text = self._render('subscriberList_top', *scopes, context=context) i = 0 @@ -75,7 +75,7 @@ def get_property(self, command, *args, context=None): text += self._render('subscriberList_item', *scopes, context=dict(context, subscriber=subscriber)) text += self._render('subscriberList_bottom', *scopes, context=context) self._write(text) - elif self._validate(args, 'SIP') and context['component_path'].split('/')[-1] == 'cfgm' and \ + elif self._validate(args, 'SIP') and context['path'].split('/')[-1] == 'cfgm' and \ (card.product == 'isdn' or card.product == 'analog'): context['spacer1'] = self.create_spacers((67,), (card.gateway_name,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (card.home_domain,))[0] * ' ' @@ -93,7 +93,7 @@ def get_property(self, command, *args, context=None): context['spacer14'] = self.create_spacers((67,), (card.session_expiration,))[0] * ' ' text = self._render('sip', *scopes, context=dict(context, card=card)) self._write(text) - elif self._validate(args, 'Proxy') and context['component_path'].split('/')[-1] == 'cfgm' and \ + elif self._validate(args, 'Proxy') and context['path'].split('/')[-1] == 'cfgm' and \ (card.product == 'isdn' or card.product == 'analog'): context['spacer1'] = self.create_spacers((67,), (card.proxy_mode,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (card.proxy_address,))[0] * ' ' @@ -105,20 +105,20 @@ def get_property(self, command, *args, context=None): context['spacer8'] = self.create_spacers((67,), (card.proxy_interval,))[0] * ' ' text = self._render('proxy', *scopes, context=dict(context, card=card)) self._write(text) - elif self._validate(args, 'IP') and context['component_path'].split('/')[-1] == 'cfgm' and \ + elif self._validate(args, 'IP') and context['path'].split('/')[-1] == 'cfgm' and \ (card.product == 'isdn' or card.product == 'analog'): # TODO: dynamic fields text = self._render('ip', *scopes, context=context) self._write(text) - elif self._validate(args, 'Labels') and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'Labels') and context['path'].split('/')[-1] == 'main': context['spacer1'] = self.create_spacers((67,), (card.label1,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (card.label2,))[0] * ' ' context['spacer3'] = self.create_spacers((67,), (card.description,))[0] * ' ' text = self._render('labels', *scopes, context=dict(context, port=card)) self._write(text) - elif self._validate(args, 'Registrar') and context['component_path'].split('/')[-1] == 'cfgm': + elif self._validate(args, 'Registrar') and context['path'].split('/')[-1] == 'cfgm': context['spacer1'] = self.create_spacers((67,), (card.registrar_adress,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (card.registrar_port,))[0] * ' ' context['spacer3'] = self.create_spacers((67,), (card.registration_mode,))[0] * ' ' @@ -126,7 +126,7 @@ def get_property(self, command, *args, context=None): text = self._render('registrar', *scopes, context=dict(context, card=card)) self._write(text) - elif self._validate(args, 'HardwareAndSoftware') and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'HardwareAndSoftware') and context['path'].split('/')[-1] == 'main': unit_hardware = '"' + card.board_name + '"' context['unit_hardware'] = unit_hardware context['spacer_1'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' @@ -151,7 +151,7 @@ def get_property(self, command, *args, context=None): text = self._render('hardware_and_software', *scopes, context=context) self._write(text) - elif self._validate(args, 'CurrentStatus') and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'CurrentStatus') and context['path'].split('/')[-1] == 'main': unit_state = card.state context['unit_state'] = unit_state context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' @@ -173,7 +173,7 @@ def get_property(self, command, *args, context=None): text = self._render('current_status', *scopes, context=context) self._write(text) - elif self._validate(args, 'EquipmentInventory') and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'EquipmentInventory') and context['path'].split('/')[-1] == 'main': unit_symbol = '"' + card.board_name + '"' context['unit_symbol'] = unit_symbol context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' @@ -239,7 +239,7 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'Labels', str, str, str) and context['component_path'].split('/')[-1] == 'main': + elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': label1, label2, description = self._dissect(args, 'Labels', str, str, str) try: component = self.get_component() @@ -248,7 +248,7 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'SIP', str, str, str, str, str, str, str, str, str, str, str, str, str, str) and \ - context['component_path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): + context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): gw, hd, spn, cc, ac, rt, mri, se, aim, os, ot, uac, uas, sessione = self._dissect( args, 'Sip', str, str, str, str, str, str, str, str, str, str, str, str, str, str) try: @@ -262,14 +262,14 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) elif self._validate(args, 'Registrar', str, str, str, str) and \ - context['component_path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): + context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): ra, rp, rm, rt = self._dissect(args, 'Registrar', str, str, str, str) try: card.set_registrar(ra, int(rp), rm, int(rt)) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) elif self._validate(args, 'Proxy', str, str, str, str, str, str, str, str) and \ - context['component_path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): + context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): pm, pa1, pp1, pa2, pp2, pe, pmethod, pi = self._dissect(args, 'Proxy', str, str, str, str, str, str, str, str) try: pe = True if pe.lower() == 'true' else False diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 6fe36b9..ca9206a 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -111,13 +111,12 @@ def do_pwd(self, command, *args, context=None): context['spacer'] = self.create_spacers((67,), (context['path'],))[0] * ' ' self._write(self._render('pwd', 'login', 'base', context=context)) - def ls(self, context=None, path_type='path'): + def ls(self, context=None): scopes = ('login', 'base', 'ls') - context['ls_path'] = context[path_type] - if re.search('(pm|fm|status|main|cfgm)', context['ls_path']): - mf_type = context['ls_path'].split('/')[-1] + if re.search('(pm|fm|status|main|cfgm)', context['path']): + mf_type = context['path'].split('/')[-1] - mf_layers = None + mf_layers = {} if mf_type == 'status': mf_layers = self.status elif mf_type == 'cfgm': @@ -183,17 +182,18 @@ def do_ls(self, command, *args, context=None): pass elif self._validate(args, str): path = args[0] + current_path = context['path'] try: tmp_cmdproc = self.change_directory(path, context=context) - tmp_cmdproc.ls(context=context, path_type='component_path') + tmp_cmdproc.ls(context=context) except exceptions.CommandExecutionError: - context['component_path'] = context['path'] + context['path'] = current_path raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) - context['component_path'] = context['path'] + context['path'] = current_path else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), @@ -205,7 +205,7 @@ def change_directory(self, path, context=None): if self.__name__ != 'root': return self._parent.change_directory(path, context=context) else: - context['component_path'] = '/' + context['path'] = '/' return self components = [x for x in path.split('/') if x] @@ -237,16 +237,15 @@ def change_directory(self, path, context=None): command=None) if path.startswith('..'): - splitted_path = [x for x in context['component_path'].split('/') if x] + splitted_path = [x for x in context['path'].split('/') if x] exit_component = None if len(splitted_path) != 0: exit_component = splitted_path.pop() - context['component_path'] = '/' + '/'.join(splitted_path) + context['path'] = '/' + '/'.join(splitted_path) if exit_component in ('main', 'cfgm', 'fm', 'pm', 'status'): self.set_prompt_end_pos(context=context) if path != '..': - context['path'] = context['component_path'] return self.change_directory(path[3:], context=context) return self @@ -263,7 +262,7 @@ def change_directory(self, path, context=None): if self.__name__ != 'root': subprocessor = self._parent.change_directory(path, context=context) else: - context['component_path'] = '/' + context['path'] = '/' subprocessor = self.change_directory(path.lstrip('/'), context=context) else: remaining_args = '/'.join(components[1:]) @@ -362,11 +361,11 @@ def change_directory(self, path, context=None): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - if context['component_path'] == '/': + if context['path'] == '/': new_path = components[0] else: new_path = '/' + components[0] - context['component_path'] += new_path + context['path'] += new_path return self from vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor import UnitCommandProcessor @@ -401,14 +400,14 @@ def change_directory(self, path, context=None): if component_id is not None: subprocessor.set_component_id(component_id) - if context['component_path'] == '/': + if context['path'] == '/': new_path = components[0] else: if path == 'subpacket': new_path = '/' + context['ServiceType'] else: new_path = '/' + components[0] - context['component_path'] += new_path + context['path'] += new_path if len(remaining_args) > 0: subprocessor = subprocessor.change_directory(remaining_args, context=context) @@ -531,13 +530,13 @@ def do_cd(self, command, *args, context=None): raise exceptions.CommandSyntaxError() elif self._validate(args, str): path = args[0] + current_path = context['path'] try: subprocessor = self.change_directory(path, context=context) return_to = self.get_command_processor(subprocessor) except: - context['component_path'] = context['path'] + context['path'] = current_path raise - context['path'] = context['component_path'] subprocessor.loop(context=context, return_to=return_to) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', diff --git a/vendors/KeyMile/main.py b/vendors/KeyMile/main.py index 95e03f6..ff9abd4 100644 --- a/vendors/KeyMile/main.py +++ b/vendors/KeyMile/main.py @@ -56,7 +56,6 @@ def on_unknown_command(self, command, *args, context=None): RootCommandProcessor, 'login', 'base') context['path'] = '/' - context['component_path'] = '/' self._write(self._render('login_message', 'login', 'base', context=context)) From 4f50915dbaef1d77c79da1849a685da073b6f07f Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 20 Oct 2020 10:37:50 +0200 Subject: [PATCH 252/318] Now completely removed 'component_path' --- .../root/unit/port/portCommandProcessor.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index b355f31..69f8a04 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -36,20 +36,20 @@ def get_property(self, command, *args, context=None): exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'Portprofile') and context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM'\ + elif self._validate(args, 'Portprofile') and context['path'].split('/')[-1] == 'cfgm' and 'SUVM'\ not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' context['profile_name'] = port.profile1_name text = self._render('port_profile', *scopes, context=context) self._write(text) - elif self._validate(args, 'Portprofiles') and context['component_path'].split('/')[-1] == 'cfgm' and \ + elif self._validate(args, 'Portprofiles') and context['path'].split('/')[-1] == 'cfgm' and \ 'SUVD2' in card.board_name and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' context['profile_name'] = port.profile1_name text = self._render('port_profile', *scopes, context=context) self._write(text) elif self._validate(args, 'Portprofiles') and self.__name__ == 'port' and \ - context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM' in card.board_name: + context['path'].split('/')[-1] == 'cfgm' and 'SUVM' in card.board_name: context['spacer1'] = self.create_spacers((67,), (port.profile1_enable,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' context['spacer3'] = self.create_spacers((67,), (port.profile1_elength,))[0] * ' ' @@ -257,7 +257,7 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'Portprofile', str) and context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM'\ + elif self._validate(args, 'Portprofile', str) and context['path'].split('/')[-1] == 'cfgm' and 'SUVM'\ not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': profile, = self._dissect(args, 'Portprofile', str) try: @@ -267,7 +267,7 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'Portprofiles', str) and context['component_path'].split('/')[-1] == 'cfgm' and \ + elif self._validate(args, 'Portprofiles', str) and context['path'].split('/')[-1] == 'cfgm' and \ 'SUVD2' in card.board_name and self.__name__ == 'port': profile, = self._dissect(args, 'Portprofiles', str) try: @@ -278,7 +278,7 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'Portprofiles', str, str, str, str, str, str, str, str, str, str, str, str) and \ - context['component_path'].split('/')[-1] == 'cfgm' and 'SUVM' in card.board_name and self.__name__ == 'port': + context['path'].split('/')[-1] == 'cfgm' and 'SUVM' in card.board_name and self.__name__ == 'port': en1, name1, elen1, en2, name2, elen2, en3, name3, elen3, en4, name4, mode = self._dissect(args, 'Portprofiles', str, str, str, str, str, str, str, str, str, str, str, str) try: From a0f5af977a3faf1d175638be1f641f971f4b7d80 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Tue, 20 Oct 2020 10:39:45 +0200 Subject: [PATCH 253/318] Added more features to srvc objects --- .../conf/bootstraps/create-keymile-MG2500.sh | 1 - nesi/keymile/keymile_resources/keymile_box.py | 7 ++++ nesi/softbox/api/models/srvc_models.py | 2 +- nesi/softbox/api/schemas/srvc_schemas.py | 2 +- nesi/softbox/api/views/srvc_views.py | 14 +++++++ .../unknown_service_fragment.j2 | 2 + .../root/services/srvcCommandProcessor.py | 7 ++-- .../services/subpacketCommandProcessor.py | 38 +++++++++++++++++++ 8 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 templates/KeyMile/login/base/execution_errors/unknown_service_fragment.j2 diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index f224350..ac248e6 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -531,7 +531,6 @@ port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) # Create a physical port at the network device (admin operation) req='{ - "name": "srvc-1", "service_type": "nto1", "svid": 123, "address": "/unit-1/port-1/chan-1/interface-1" diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 8a2d68c..2e7964a 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -206,6 +206,13 @@ def get_srvcs(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'srvcs'), params={field: value}) + def add_srvc(self, **fields): + """Add new srvc.""" + return keymile_srvc.KeyMileSrvc.create( + self._conn, + os.path.join(self.path, 'srvcs'), + **fields) + class KeyMileBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/softbox/api/models/srvc_models.py b/nesi/softbox/api/models/srvc_models.py index 6452ac2..8e0ec84 100644 --- a/nesi/softbox/api/models/srvc_models.py +++ b/nesi/softbox/api/models/srvc_models.py @@ -18,6 +18,6 @@ class Srvc(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) - service_type = db.Column(db.Enum('1to1DoubleTag', '1to1SingleTag', 'mcast', 'nto1', 'pls', 'tls', ''), default='') + service_type = db.Column(db.Enum('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls')) address = db.Column(db.String(), default='') svid = db.Column(db.Integer(), default=None) diff --git a/nesi/softbox/api/schemas/srvc_schemas.py b/nesi/softbox/api/schemas/srvc_schemas.py index f1bba10..482b246 100644 --- a/nesi/softbox/api/schemas/srvc_schemas.py +++ b/nesi/softbox/api/schemas/srvc_schemas.py @@ -36,7 +36,7 @@ class Meta: class SrvcSchema(ma.ModelSchema): class Meta: model = Srvc - fields = ('id', '_links') + fields = ('id', 'name', '_links') _links = ma.Hyperlinks( {'self': ma.URLFor( diff --git a/nesi/softbox/api/views/srvc_views.py b/nesi/softbox/api/views/srvc_views.py index 263a2b9..3315341 100644 --- a/nesi/softbox/api/views/srvc_views.py +++ b/nesi/softbox/api/views/srvc_views.py @@ -44,9 +44,23 @@ def update_srvc(box_id, id): @app.route(PREFIX + '/boxen//srvcs', methods=['POST']) def new_srvc(box_id): req = flask.request.json + + if 'name' not in req or req['name'] == "": + srvcs = json.loads(show_components(SrvcsSchema(), Srvc, req={'service_type': req['service_type']}, box_id=box_id).data.decode('utf-8')) + last_srvc = None + for s in srvcs['members']: + last_srvc = s + + if last_srvc is not None: + _, num = last_srvc['name'].split('-') + req['name'] = 'srvc-' + str(int(num)+1) + else: + req['name'] = 'srvc-1' + response = new_component(SrvcSchema(), Srvc, req, box_id) return response, 201 + @app.route(PREFIX + '/boxen//srvcs/', methods=['DELETE']) def del_srvc(box_id, id): del_component(Srvc, box_id, id) diff --git a/templates/KeyMile/login/base/execution_errors/unknown_service_fragment.j2 b/templates/KeyMile/login/base/execution_errors/unknown_service_fragment.j2 new file mode 100644 index 0000000..46fd889 --- /dev/null +++ b/templates/KeyMile/login/base/execution_errors/unknown_service_fragment.j2 @@ -0,0 +1,2 @@ +error: Unknown service fragment + diff --git a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py index 02c5dcc..7a9e401 100644 --- a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py @@ -28,7 +28,7 @@ def get_property(self, command, *args, context=None): service_name = 'srvc-' + self.component_id services = self._model.get_srvcs('name', service_name) for s in services: - if s.service_type == context['ServiceType']: + if s.service_type.lower() == context['ServiceType']: service = s context['service'] = service break @@ -37,9 +37,10 @@ def get_property(self, command, *args, context=None): super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: if self._validate((args[0],), 'Service') and context['path'].split('/')[-1] == 'cfgm': - if service.service_type == '1to1DoubleTag': + # TODO: Find missing templates, and replace placeholder templates + if service.service_type == '1to1doubletag': template_name = 'service_onetoonedoubletag' - elif service.service_type == '1to1SingleTag': + elif service.service_type == '1to1singletag': template_name = 'service_onetoonesingletag' elif service.service_type == 'mcast': template_name = 'service_mcast' diff --git a/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py index 27d0c7c..10db20e 100644 --- a/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py @@ -38,5 +38,43 @@ def _init_access_points(self, context=None): except exceptions.InvalidInputError: pass + def do_deleteservice(self, command, *args, context=None): + if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm': + srvc_id, = self._dissect(args, str) + service_name = 'srvc-' + srvc_id + service = None + services = self._model.get_srvcs('name', service_name) + for s in services: + if s.service_type == context['ServiceType']: + service = s + break + if service is None: + raise exceptions.CommandExecutionError(command=command, template='unknown_service_fragment', + template_scopes=('login', 'base', 'execution_errors')) + service.delete() + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_createservice(self, command, *args, context=None): + if context['ServiceType'] == 'nto1' and context['path'].split('/')[-1] == 'cfgm': + if len(args) == 12: + address, svid = self._dissect(args[:2], str, str) + # TODO: validate address + srvc = self._model.add_srvc(service_type='nto1', address=address, svid=svid) + + else: + raise exceptions.CommandSyntaxError(command=command) + + elif context['ServiceType'] == '1to1singletag' and context['path'].split('/')[-1] == 'cfgm': + if len(args) == 4: + address, svid = self._dissect(args[:2], str, str) + # TODO: validate address + srvc = self._model.add_srvc(service_type='1to1singletag', address=address, svid=svid) + + else: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) From 4c150ec92e9dedb1a8244698ee87f13f43bc6cac Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 20 Oct 2020 11:00:19 +0200 Subject: [PATCH 254/318] Added ip commands and reset mode --- .../api/schemas/keymile_card_schemas.py | 3 ++- .../keymile/keymile_resources/keymile_card.py | 8 ++++++ nesi/softbox/api/models/card_models.py | 3 +++ templates/KeyMile/login/base/get/ip.j2 | 6 ++--- .../root/unit/unitCommandProcessor.py | 25 +++++++++++++++++-- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/nesi/keymile/api/schemas/keymile_card_schemas.py b/nesi/keymile/api/schemas/keymile_card_schemas.py index eeaf6aa..7f62849 100644 --- a/nesi/keymile/api/schemas/keymile_card_schemas.py +++ b/nesi/keymile/api/schemas/keymile_card_schemas.py @@ -27,4 +27,5 @@ class Meta: 'uac_request_timer', 'uas_request_timer', 'session_expiration', 'proxy_mode', 'proxy_address', 'proxy_port', 'proxy_address_sec', 'proxy_port_sec', 'proxy_enable', 'proxy_method', 'proxy_interval', 'registrar_adress', - 'registrar_port', 'registration_mode', 'registration_expiration_time') + 'registrar_port', 'registration_mode', 'registration_expiration_time', + 'gateway_ipaddress', 'subnet_mask', 'default_gateway') diff --git a/nesi/keymile/keymile_resources/keymile_card.py b/nesi/keymile/keymile_resources/keymile_card.py index 71fae65..4e65f98 100644 --- a/nesi/keymile/keymile_resources/keymile_card.py +++ b/nesi/keymile/keymile_resources/keymile_card.py @@ -41,6 +41,10 @@ class KeyMileCard(Card): label1 = base.Field('label1') label2 = base.Field('label2') + gateway_ipaddress = base.Field('gateway_ipaddress') + subnet_mask = base.Field('subnet_mask') + default_gateway = base.Field('default_gateway') + # Keymile ipsx2/3 card SIP specifications gateway_name = base.Field('gateway_name') home_domain = base.Field('home_domain') @@ -89,6 +93,10 @@ def set_sip(self, gateway_name, home_domain, sip_port_number, country_code, area self.update(uas_request_timer=uas_request_timer) self.update(session_expiration=session_expiration) + def set_ip(self, gateway_ipaddress, subnet_mask, default_gateway): + self.update(gateway_ipaddress=gateway_ipaddress) + self.update(subnet_mask=subnet_mask) + self.update(default_gateway=default_gateway) def set_label(self, l1, l2, desc): self.update(label1=l1) diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index f3fc2f9..efbadfd 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -103,6 +103,9 @@ class Card(db.Model): processor = db.Column(db.String(), default='') label1 = db.Column(db.String(), default='""') label2 = db.Column(db.String(), default='""') + gateway_ipaddress = db.Column(db.String(), default='""') + subnet_mask = db.Column(db.String(), default='""') + default_gateway = db.Column(db.String(), default='""') # Keymile ipsx2/3 card SIP specifications gateway_name = db.Column(db.String(), default='""') diff --git a/templates/KeyMile/login/base/get/ip.j2 b/templates/KeyMile/login/base/get/ip.j2 index c5d5e83..e9fe969 100644 --- a/templates/KeyMile/login/base/get/ip.j2 +++ b/templates/KeyMile/login/base/get/ip.j2 @@ -1,5 +1,5 @@ \ # Ip -10.16.12.14 \ # GatewayIpAddress -255.255.255.0 \ # SubnetMask -10.16.12.1 \ # DefaultGateway +{{ context.card.gateway_ipaddress }}{{ context.spacer1 }}\ # GatewayIpAddress +{{ context.card.subnet_mask }}{{ context.spacer2 }}\ # SubnetMask +{{ context.card.default_gateway }}{{ context.spacer3 }}\ # DefaultGateway diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 5b675a2..cc7a690 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -9,6 +9,7 @@ # - Alexander Dincher # # License: https://github.com/inexio/NESi/LICENSE.rst +import time from nesi import exceptions from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor @@ -107,8 +108,10 @@ def get_property(self, command, *args, context=None): self._write(text) elif self._validate(args, 'IP') and context['path'].split('/')[-1] == 'cfgm' and \ (card.product == 'isdn' or card.product == 'analog'): - # TODO: dynamic fields - text = self._render('ip', *scopes, context=context) + context['spacer1'] = self.create_spacers((67,), (card.gateway_ipaddress,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (card.subnet_mask,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (card.default_gateway,))[0] * ' ' + text = self._render('ip', *scopes, context=dict(context, card=card)) self._write(text) elif self._validate(args, 'Labels') and context['path'].split('/')[-1] == 'main': @@ -247,6 +250,14 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'Ip', str, str, str) and context['component_path'].split('/')[-1] == 'cfgm': + ip1, ip2, ip3 = self._dissect(args, 'Ip', str, str, str) + try: + component = self.get_component() + component.set_ip(ip1, ip2, ip3) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'SIP', str, str, str, str, str, str, str, str, str, str, str, str, str, str) and \ context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): gw, hd, spn, cc, ac, rt, mri, se, aim, os, ot, uac, uas, sessione = self._dissect( @@ -278,3 +289,13 @@ def set(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) else: raise exceptions.CommandSyntaxError(command=command) + + def do_restart(self, command, *args, context=None): + card = self._model.get_card('name', self.component_id) + if len(args) == 0 and context['path'].split('/')[-1] == 'main' and (card.product == 'isdn' or card.product == 'analog'): + time.sleep(10) + exc = exceptions.TerminalExitError() + exc.return_to = 'sysreboot' + raise exc + else: + raise exceptions.CommandSyntaxError(command=command) From 9764218cd19d1460e30cb0bc2c1887e4db841fc8 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 20 Oct 2020 12:42:11 +0200 Subject: [PATCH 255/318] Removed obsolete functions and fixed some navigation bugs --- vendors/KeyMile/baseCommandProcessor.py | 177 ++---------------------- 1 file changed, 15 insertions(+), 162 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index ca9206a..f300be3 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -201,6 +201,15 @@ def do_ls(self, command, *args, context=None): def change_directory(self, path, context=None): path = path.lower() + if re.search('^(?:[^.]+/)+\.\.$', path): + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + if re.search('^(?:[^.]+/)+\.\.(?:/.+)+$', path): + raise exceptions.CommandExecutionError(template='invalid_address_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + if path == '/': if self.__name__ != 'root': return self._parent.change_directory(path, context=context) @@ -226,16 +235,6 @@ def change_directory(self, path, context=None): return self.change_directory(path[2:], context=context) - if re.search('\.\./(?:[^.]+/)+\.\.', path): - if path.endswith('..'): - raise exceptions.CommandExecutionError(template='invalid_management_function_error', - template_scopes=('login', 'base', 'execution_errors'), - command=None) - else: - raise exceptions.CommandExecutionError(template='invalid_address_error', - template_scopes=('login', 'base', 'execution_errors'), - command=None) - if path.startswith('..'): splitted_path = [x for x in context['path'].split('/') if x] exit_component = None @@ -250,8 +249,13 @@ def change_directory(self, path, context=None): return self if path == '..': + if self.__name__ == 'root': + return self return self._parent + if self.__name__ == 'root': + return self.change_directory(path[3:], context=context) + return self._parent.change_directory(path[3:], context=context) if path.startswith('/'): if 'unit-' not in components[0] and components[0] not in ( @@ -414,72 +418,6 @@ def change_directory(self, path, context=None): return subprocessor - ''' - search := string keyword like "unit" or "port" - parent := string keyword to describe the parent of search like "root" - node := contains the dict tree or - None for default tree structure - parent_keys := should be None / important for recursive call - return := Tuple of (ParentList, ChildList) or ([],[]) - ''' - - def get_parent_and_child_relation(self, search, parent=None, node=None, parent_keys=None): - if parent == "": - return ([], []) - if node is None: - node = { - "root": { - "unit": { - "control": {}, - "media": {}, - "port": { - "channel": { - "interfaces": { - "hell": {} - } - }, - "interfaces": { - "hell2": {} - } - }, - "portgroups": {"portgroupports": {}}, - "logports": { - "logport": { - "interface": {}}}, - "vectoringports": {"vectorport": {}}, - "internalports": {"internalport": {}} - }, - "eoam": {}, - "tdmconnections": {}, - "services": { - "packet": { - "subpacket": { - "srvc": {} - } - }, - "macaccessctrl": {} - }, - "multicast": {} - }} - for x, y in node.items(): - if x == search and (parent is None or parent_keys.__contains__(parent)): - if parent is not None: - pp = [parent] - elif parent_keys is None: - pp = [] - else: - pp = [parent_keys] - pc = list(y.keys()) - return (pp, pc) - else: - (pp, pc) = self.get_parent_and_child_relation(search=search, parent=parent, node=y, parent_keys=x) - if pp == [] and pc == []: - pass - else: - return (pp, pc) - else: - return ([], []) - def do_get(self, command, *args, context=None): if len(args) >= 1: if '/' in args[0]: @@ -533,100 +471,15 @@ def do_cd(self, command, *args, context=None): current_path = context['path'] try: subprocessor = self.change_directory(path, context=context) - return_to = self.get_command_processor(subprocessor) except: context['path'] = current_path raise - subprocessor.loop(context=context, return_to=return_to) + subprocessor.loop(context=context, return_to=subprocessor._parent) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=command) - def get_command_processor(self, current_processor, component_type=None): - from vendors.KeyMile.accessPoints.root.rootCommandProcessor import RootCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor import UnitCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.chan.chanCommandProcessor import ChanCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor import \ - InterfaceCommandProcessor - from vendors.KeyMile.accessPoints.root.fan.fanCommandProcessor import FanCommandProcessor - from vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor import AlarmCommandProcessor - from vendors.KeyMile.accessPoints.root.eoamCommandProcessor import EoamCommandProcessor - from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor - from vendors.KeyMile.accessPoints.root.tdmconnectionsCommandProcessor import TdmconnectionsCommandProcessor - from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import \ - PortgroupCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import \ - PortgroupportCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.logport.logportsCommandProcessor import LogportsCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ - LogportCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.chan.vcc.vccCommandProcessor import VccCommandProcessor - from vendors.KeyMile.accessPoints.root.services.packetCommandProcessor import PacketCommandProcessor - from vendors.KeyMile.accessPoints.root.services.macaccessctrlCommandProcessor import\ - MacaccessctrlCommandProcessor - from vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor import SubpacketCommandProcessor - from vendors.KeyMile.accessPoints.root.services.srvcCommandProcessor import SrvcCommandProcessor - if current_processor.__class__ == RootCommandProcessor: - return_to = RootCommandProcessor - if component_type not in ('fan', 'eoam', 'tdmconnections', 'multicast', 'services', 'unit') \ - and component_type is not None: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif current_processor.__class__ == UnitCommandProcessor: - return_to = RootCommandProcessor - if (component_type != 'port' or component_type != 'logports') and component_type is not None: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif current_processor.__class__ == PortCommandProcessor: - return_to = UnitCommandProcessor - if component_type != 'chan' and component_type is not None: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif current_processor.__class__ == ChanCommandProcessor: - return_to = PortCommandProcessor - if component_type != 'interface' and component_type is not None: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif current_processor.__class__ == InterfaceCommandProcessor: - return_to = LogportCommandProcessor - return_to = ChanCommandProcessor - return_to = PortCommandProcessor - elif current_processor.__class__ == FanCommandProcessor: - return_to = RootCommandProcessor - elif current_processor.__class__ == AlarmCommandProcessor: - return_to = FanCommandProcessor - elif current_processor.__class__ == EoamCommandProcessor: - return_to = RootCommandProcessor - elif current_processor.__class__ == MulticastCommandProcessor: - return_to = RootCommandProcessor - elif current_processor.__class__ == TdmconnectionsCommandProcessor: - return_to = RootCommandProcessor - elif current_processor.__class__ == ServicesCommandProcessor: - return_to = RootCommandProcessor - elif current_processor.__class__ == PortgroupportCommandProcessor: - return_to = PortgroupCommandProcessor - elif current_processor.__class__ == PortgroupCommandProcessor: - return_to = UnitCommandProcessor - elif current_processor.__class__ == LogportsCommandProcessor: - return_to = UnitCommandProcessor - elif current_processor.__class__ == LogportCommandProcessor: - return_to = LogportsCommandProcessor - elif current_processor.__class__ == VccCommandProcessor: - return_to = ChanCommandProcessor - elif current_processor.__class__ == PacketCommandProcessor: - return_to = ServicesCommandProcessor - elif current_processor.__class__ == MacaccessctrlCommandProcessor: - return_to = ServicesCommandProcessor - elif current_processor.__class__ == SubpacketCommandProcessor: - return_to = PacketCommandProcessor - elif current_processor.__class__ == SrvcCommandProcessor: - return_to = SubpacketCommandProcessor - - return return_to - def do_exit(self, command, *args, context=None): exc = exceptions.TerminalExitError() exc.return_to = 'sysexit' From e8943f1f18f40787085b679b764fa124f4827884 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 20 Oct 2020 13:08:10 +0200 Subject: [PATCH 256/318] Added Mgmt Card system in KeyMile --- .../conf/bootstraps/create-keymile-MG2500.sh | 40 +++++++++++++ .../api/schemas/keymile_mgmt_card_schemas.py | 24 ++++++++ .../api/schemas/keymile_mgmt_port_schemas.py | 20 +++++++ nesi/keymile/keymile_resources/__init__.py | 3 +- nesi/keymile/keymile_resources/keymile_box.py | 28 +++++++++- .../keymile_resources/keymile_mgmt_card.py | 56 +++++++++++++++++++ .../keymile_resources/keymile_mgmt_port.py | 34 +++++++++++ nesi/softbox/api/models/box_models.py | 2 + nesi/softbox/api/models/mgmt_card_models.py | 26 ++++++++- nesi/softbox/api/models/mgmt_port_models.py | 2 +- nesi/softbox/base_resources/mgmt_card.py | 20 ++++++- .../root/unit/port/portCommandProcessor.py | 40 +++++++------ .../root/unit/unitCommandProcessor.py | 27 ++++++--- vendors/KeyMile/baseCommandProcessor.py | 5 +- 14 files changed, 295 insertions(+), 32 deletions(-) create mode 100644 nesi/keymile/api/schemas/keymile_mgmt_card_schemas.py create mode 100644 nesi/keymile/api/schemas/keymile_mgmt_port_schemas.py create mode 100644 nesi/keymile/keymile_resources/keymile_mgmt_card.py create mode 100644 nesi/keymile/keymile_resources/keymile_mgmt_port.py diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index ac248e6..dd35d3c 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -479,6 +479,46 @@ req='{ unit_8=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Mgmt-Unit-11 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "board_name": "COGE1", + "supplier_build_state": "R3D", + "board_id": "305", + "hardware_key": 104, + "software": "COGE1_r5c01.esw", + "software_name": "COGE1", + "software_revision": "R5C01", + "state": "Ok", + "serial_number": "4810312946", + "manufacturer_name": "KEYMILE", + "model_name": "37900030", + "short_text": "MG COGE1 COGE1+ AnnexB 32-port", + "manufacturer_id": "100989", + "manufacturer_part_number": "09860762", + "manufacturer_build_state": "05", + "boot_loader": "BLSU1_R1F01/CT18388", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" +}' + +unit_11=$(create_resource "$req" $ENDPOINT/boxen/$box_id/mgmt_cards) + +### Mgmt-Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "mgmt_card_id": '$unit_11', + "admin_state": "1", + "operational_state": "1" +}' + +port_4_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/mgmt_ports) + + + ### Unit-19 ### # Create a physical card at the network device (admin operation) diff --git a/nesi/keymile/api/schemas/keymile_mgmt_card_schemas.py b/nesi/keymile/api/schemas/keymile_mgmt_card_schemas.py new file mode 100644 index 0000000..d4be416 --- /dev/null +++ b/nesi/keymile/api/schemas/keymile_mgmt_card_schemas.py @@ -0,0 +1,24 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.mgmt_card_schemas import * + + +class KeyMileMgmtCardSchema(MgmtCardSchema): + class Meta: + model = MgmtCard + fields = MgmtCardSchema.Meta.fields + ('board_name', 'supplier_build_state', 'board_id', 'hardware_key', + 'software','software_name', 'software_revision', 'state', 'serial_number', + 'manufacturer_name', 'model_name', 'short_text', 'manufacturer_id', + 'manufacturer_part_number', 'manufacturer_build_state', 'customer_id', + 'customer_product_id', 'boot_loader', 'processor', 'label1', 'label2', + 'product') diff --git a/nesi/keymile/api/schemas/keymile_mgmt_port_schemas.py b/nesi/keymile/api/schemas/keymile_mgmt_port_schemas.py new file mode 100644 index 0000000..9b0a12f --- /dev/null +++ b/nesi/keymile/api/schemas/keymile_mgmt_port_schemas.py @@ -0,0 +1,20 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.mgmt_port_schemas import * + + +class KeyMilePortSchema(MgmtPortSchema): + class Meta: + model = MgmtPort + fields = MgmtPortSchema.Meta.fields + ('label1', 'label2') + diff --git a/nesi/keymile/keymile_resources/__init__.py b/nesi/keymile/keymile_resources/__init__.py index 9e17078..4d2603c 100644 --- a/nesi/keymile/keymile_resources/__init__.py +++ b/nesi/keymile/keymile_resources/__init__.py @@ -1,2 +1,3 @@ __all__ = ["keymile_card", "keymile_port", "keymile_subrack", "keymile_channel", "keymile_interface", - "keymile_subscriber", "keymile_logport", "keymile_portgroupport", "keymile_srvc"] + "keymile_subscriber", "keymile_logport", "keymile_portgroupport", "keymile_srvc", "keymile_mgmt_card", + "keymile_mgmt_port"] diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 2e7964a..1166957 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -62,11 +62,25 @@ def credentials(self): @property def cards(self): - """Return `CredentialsCollection` object.""" + """Return `cardCollection` object.""" return keymile_card.KeyMileCardCollection( self._conn, base.get_sub_resource_path_by( self, 'cards')) + @property + def mgmt_cards(self): + """Return `mgmtcardCollection` object.""" + return keymile_mgmt_card.KeyMileMgntCardCollection( + self._conn, base.get_sub_resource_path_by( + self, 'mgmt_cards')) + + @property + def mgmt_ports(self): + """Return `mgmtportCollection` object.""" + return keymile_mgmt_port.KeyMileMgmtPortCollection( + self._conn, base.get_sub_resource_path_by( + self, 'mgmt_ports')) + @property def subscribers(self): """Return `SubscriberCollection` object.""" @@ -102,6 +116,18 @@ def get_cards(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'cards'), params={field: value}) + def get_mgmt_card(self, field, value): + """Get specific mgnt card object.""" + return keymile_mgmt_card.KeyMileMgntCardCollection( + self._conn, base.get_sub_resource_path_by(self, 'mgmt_cards'), + params={field: value}).find_by_field_value(field, value) + + def get_mgmt_port(self, field, value): + """Get specific mgmtport object.""" + return keymile_mgmt_port.KeyMileMgmtPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'mgmt_ports'), + params={field: value}).find_by_field_value(field, value) + def get_port(self, field, value): """Get specific port object.""" return keymile_port.KeyMilePortCollection( diff --git a/nesi/keymile/keymile_resources/keymile_mgmt_card.py b/nesi/keymile/keymile_resources/keymile_mgmt_card.py new file mode 100644 index 0000000..acfa59f --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_mgmt_card.py @@ -0,0 +1,56 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.mgmt_card import MgmtCard, MgmtCardCollection, logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class KeyMileMgmtCard(MgmtCard): + """Represent physical shelf resource.""" + + board_name = base.Field('board_name') + supplier_build_state = base.Field('supplier_build_state') + board_id = base.Field('board_id') + hardware_key = base.Field('hardware_key') + software = base.Field('software') + software_name = base.Field('software_name') + software_revision = base.Field('software_revision') + state = base.Field('state') + serial_number = base.Field('serial_number') + manufacturer_name = base.Field('manufacturer_name') + model_name = base.Field('model_name') + short_text = base.Field('short_text') + manufacturer_id = base.Field('manufacturer_id') + manufacturer_part_number = base.Field('manufacturer_part_number') + manufacturer_build_state = base.Field('manufacturer_build_state') + customer_id = base.Field('customer_id') + customer_product_id = base.Field('customer_product_id') + boot_loader = base.Field('boot_loader') + processor = base.Field('processor') + label1 = base.Field('label1') + label2 = base.Field('label2') + product = base.Field('product') + + def set_label(self, l1, l2, desc): + self.update(label1=l1) + self.update(label2=l2) + self.update(description=desc) + + +class KeyMileMgntCardCollection(MgmtCardCollection): + """Represent a collection of cards.""" + + @property + def _resource_type(self): + return KeyMileMgmtCard diff --git a/nesi/keymile/keymile_resources/keymile_mgmt_port.py b/nesi/keymile/keymile_resources/keymile_mgmt_port.py new file mode 100644 index 0000000..fa92b38 --- /dev/null +++ b/nesi/keymile/keymile_resources/keymile_mgmt_port.py @@ -0,0 +1,34 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.mgmt_port import MgmtPortCollection, MgmtPort, logging, base + +LOG = logging.getLogger(__name__) + + +class KeyMileMgmtPort(MgmtPort): + """Represent physical port resource.""" + label1 = base.Field('label1') + label2 = base.Field('label2') + + def set_label(self, l1, l2, desc): + self.update(label1=l1) + self.update(label2=l2) + self.update(description=desc) + + +class KeyMileMgmtPortCollection(MgmtPortCollection): + """Represent a collection of ports.""" + + @property + def _resource_type(self): + return KeyMileMgmtPort diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index b411a6b..9ed22a9 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -34,6 +34,8 @@ from .logport_models import LogPort from .interface_models import Interface from .srvc_models import Srvc +from .mgmt_card_models import MgmtCard +from .mgmt_port_models import MgmtPort class Box(db.Model): diff --git a/nesi/softbox/api/models/mgmt_card_models.py b/nesi/softbox/api/models/mgmt_card_models.py index 80cd845..2c24945 100644 --- a/nesi/softbox/api/models/mgmt_card_models.py +++ b/nesi/softbox/api/models/mgmt_card_models.py @@ -20,8 +20,30 @@ class MgmtCard(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) - description = db.Column(db.String(), default='None') subrack_id = db.Column(db.Integer, db.ForeignKey('subrack.id')) + mgmt_ports = db.relationship('MgmtPort', backref='MgmtCard', lazy='dynamic') + + description = db.Column(db.String(), default='') admin_state = db.Column(db.Enum('0', '1'), default='0') operational_state = db.Column(db.Enum('0', '1'), default='0') - mgmt_ports = db.relationship('MgmtPort', backref='MgmtCard', lazy='dynamic') + board_name = db.Column(db.String(), default='') + supplier_build_state = db.Column(db.Enum('R1G', 'R1D', 'R2B', 'R2A', 'R1K', 'R1H', 'R2B', 'R1E', 'R3D', 'R1C', + 'R1A', ''), default='') + board_id = db.Column(db.Enum('345', '332', '303', '308', '377', '356', '305', '307', '330', '0'), default='0') + hardware_key = db.Column(db.Integer(), default=0) + software = db.Column(db.String(), default='') + software_name = db.Column(db.String(), default='') + software_revision = db.Column(db.String(), default='') + state = db.Column(db.Enum('Ok', 'Empty'), default='Empty') + serial_number = db.Column(db.String(), default='') + manufacturer_name = db.Column(db.String(), default='') + model_name = db.Column(db.String(), default='') + short_text = db.Column(db.String(), default='') + manufacturer_id = db.Column(db.String(), default='') + manufacturer_part_number = db.Column(db.String(), default='') + manufacturer_build_state = db.Column(db.String(), default='') + customer_id = db.Column(db.String(), default='') + customer_product_id = db.Column(db.String(), default='') + boot_loader = db.Column(db.String(), default='') + processor = db.Column(db.String(), default='') + product = db.Column(db.Enum('mgmt'), nullable=False, default='mgmt') diff --git a/nesi/softbox/api/models/mgmt_port_models.py b/nesi/softbox/api/models/mgmt_port_models.py index 5fa2437..eb1b56e 100644 --- a/nesi/softbox/api/models/mgmt_port_models.py +++ b/nesi/softbox/api/models/mgmt_port_models.py @@ -17,7 +17,7 @@ class MgmtPort(db.Model): name = db.Column(db.String(64)) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) mgmt_card_id = db.Column(db.Integer, db.ForeignKey('mgmt_card.id')) + admin_state = db.Column(db.Enum('0', '1'), default='0') operational_state = db.Column(db.Enum('0', '1'), default='0') - description = db.Column(db.String(64)) diff --git a/nesi/softbox/base_resources/mgmt_card.py b/nesi/softbox/base_resources/mgmt_card.py index feef2d0..09c9273 100644 --- a/nesi/softbox/base_resources/mgmt_card.py +++ b/nesi/softbox/base_resources/mgmt_card.py @@ -22,9 +22,25 @@ class MgmtCard(base.Resource): """Represent physical shelf resource.""" id = base.Field('id') name = base.Field('name') - box_id = base.Field('box_id') description = base.Field('description') - subrack_id = base.Field('subrack_id') + admin_state = base.Field('admin_state') + operational_state = base.Field('operational_state') + + def admin_up(self): + """Set the admin port state to up""" + self.update(admin_state='1') + + def admin_down(self): + """Set the admin port state to down""" + self.update(admin_state='0') + + def down(self): + """Set the port state to down""" + self.update(operational_state='0') + + def up(self): + """Set the port state to down""" + self.update(operational_state='1') class MgmtCardCollection(base.ResourceCollection): diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 69f8a04..d5b5f38 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -28,7 +28,7 @@ class PortCommandProcessor(BaseCommandProcessor): def get_property(self, command, *args, context=None): port = self.get_port_component() - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -37,7 +37,7 @@ def get_property(self, command, *args, context=None): raise exc elif self._validate(args, 'Portprofile') and context['path'].split('/')[-1] == 'cfgm' and 'SUVM'\ - not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': + not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port' and card.product != 'mgmt': context['spacer1'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' context['profile_name'] = port.profile1_name text = self._render('port_profile', *scopes, context=context) @@ -64,7 +64,7 @@ def get_property(self, command, *args, context=None): context['spacer12'] = self.create_spacers((67,), (port.profile_mode,))[0] * ' ' text = self._render('port_profiles', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': + elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status' and card.product != 'mgmt': text = self._render('attainable_rate', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'QuickLoopbackTest') and context['path'].split('/')[-1] == 'status'\ @@ -80,7 +80,7 @@ def get_property(self, command, *args, context=None): text = self._render('line_results', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'MeltResults') and context['path'].split('/')[-1] == 'status'\ - and card.product != 'isdn' and self.__name__ == 'port': + and card.product != 'isdn' and self.__name__ == 'port' and card.product != 'mgmt': context['spacer1'] = self.create_spacers((67,), (port.melttest_state,))[0] * ' ' context['test_state'] = port.melttest_state text = self._render('melt_results', *scopes, context=context) @@ -109,7 +109,10 @@ def get_property(self, command, *args, context=None): def _init_access_points(self, context=None): self.access_points = () - port = self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + port = self.get_port_component() + + if port.name.startswith('11') or port.name.startswith('13'): + return for chan in self._model.get_chans('port_id', port.id): identifier = 'chan-' + chan.name.split('/')[-1] @@ -124,7 +127,7 @@ def _init_access_points(self, context=None): self.access_points += (identifier,) def do_lock(self, command, *args, context=None): - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: @@ -136,7 +139,7 @@ def do_lock(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_startquickloopbacktest(self, command, *args, context=None): - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: @@ -150,7 +153,7 @@ def do_startquickloopbacktest(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_startlinetest(self, command, *args, context=None): - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if len(args) == 0 and context['path'].split('/')[-1] == 'status' and 'SUP' in card.board_name \ and self.__name__ == 'port': try: @@ -164,9 +167,9 @@ def do_startlinetest(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_startmeltmeasurement(self, command, *args, context=None): - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product != 'isdn' \ - and self.__name__ == 'port': + and self.__name__ == 'port' and card.product != 'mgmt': try: port = self.get_port_component() port.set_melttest_state('Running') @@ -178,7 +181,7 @@ def do_startmeltmeasurement(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_unlock(self, command, *args, context=None): - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: @@ -193,7 +196,7 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_deleteinterface(self, command, *args, context=None): - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'ftth': # all or interface_id name, = self._dissect(args, str) @@ -215,7 +218,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUE' in card.board_name: # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) @@ -247,18 +250,21 @@ def do_createinterface(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def get_port_component(self): - return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + if self._parent.component_id == '11' or self._parent.component_id == '13': + return self._model.get_mgmt_port('name', self._parent.component_id + '/' + self.component_id) + else: + return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._model.get_card('name', self._parent.component_id) + card = self._parent.get_component() if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc elif self._validate(args, 'Portprofile', str) and context['path'].split('/')[-1] == 'cfgm' and 'SUVM'\ - not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': + not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port' and card.product != 'mgmt': profile, = self._dissect(args, 'Portprofile', str) try: port = self.get_port_component() @@ -268,7 +274,7 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'Portprofiles', str) and context['path'].split('/')[-1] == 'cfgm' and \ - 'SUVD2' in card.board_name and self.__name__ == 'port': + 'SUVD2' in card.board_name and self.__name__ == 'port' and card.product != 'mgmt': profile, = self._dissect(args, 'Portprofiles', str) try: port = self.get_port_component() diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index cc7a690..8c1d5d9 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -28,7 +28,7 @@ class UnitCommandProcessor(BaseCommandProcessor): def _init_access_points(self, context=None): self.access_points = () try: - card = self._model.get_card('name', self.component_id) + card = self.get_component() self.management_functions = ('main', 'cfgm', 'fm', 'status') @@ -45,6 +45,12 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) + for port in self._model.get_mgmt_port('mgmt_card_id', card.id): + identifier = 'port-' + port.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + for gport in self._model.get_portgroupports('card_id', card.id): identifier = 'portgroup-' + gport.name.split('/')[1][1] if identifier in self.access_points: @@ -54,7 +60,7 @@ def _init_access_points(self, context=None): pass def get_property(self, command, *args, context=None): - card = self._model.get_card('name', self.component_id) + card = self.get_component() scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -121,7 +127,7 @@ def get_property(self, command, *args, context=None): text = self._render('labels', *scopes, context=dict(context, port=card)) self._write(text) - elif self._validate(args, 'Registrar') and context['path'].split('/')[-1] == 'cfgm': + elif self._validate(args, 'Registrar') and context['path'].split('/')[-1] == 'cfgm' and card.product != 'mgmt': context['spacer1'] = self.create_spacers((67,), (card.registrar_adress,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (card.registrar_port,))[0] * ' ' context['spacer3'] = self.create_spacers((67,), (card.registration_mode,))[0] * ' ' @@ -230,11 +236,17 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def get_component(self): - return self._model.get_card('name', self.component_id) + try: + if self.component_id == '11' or self.component_id == '13': + return self._model.get_mgmt_card('name', self.component_id) + else: + return self._model.get_card('name', self.component_id) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError() def set(self, command, *args, context=None): try: - card = self._model.get_card('name', self.component_id) + card = self.get_component() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) if self._validate(args, *()): @@ -250,7 +262,8 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'Ip', str, str, str) and context['component_path'].split('/')[-1] == 'cfgm': + elif self._validate(args, 'Ip', str, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and \ + card.product != 'mgmt': ip1, ip2, ip3 = self._dissect(args, 'Ip', str, str, str) try: component = self.get_component() @@ -291,7 +304,7 @@ def set(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_restart(self, command, *args, context=None): - card = self._model.get_card('name', self.component_id) + card = self.get_component() if len(args) == 0 and context['path'].split('/')[-1] == 'main' and (card.product == 'isdn' or card.product == 'analog'): time.sleep(10) exc = exceptions.TerminalExitError() diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index f300be3..9dc2cab 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -307,7 +307,10 @@ def change_directory(self, path, context=None): template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'port': try: - self._model.get_port('name', self.component_id + '/' + component_id) + if self.component_id == '11' or self.component_id == '13': + self._model.get_mgmt_port('name', self.component_id + '/' + component_id) + else: + self._model.get_port('name', self.component_id + '/' + component_id) except exceptions.InvalidInputError: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty From f885eb5bbb63da9ca79358dc39e19d893f478151 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 20 Oct 2020 14:36:16 +0200 Subject: [PATCH 257/318] Added Mgmt Card and Mgmt Port Command Processors --- nesi/keymile/keymile_resources/keymile_box.py | 6 + .../mgmt_port/mgmtportCommandProcessor.py | 104 ++++++ .../mgmt_port/mgmtportManagementFunctions.py | 334 ++++++++++++++++++ .../mgmt_unit/mgmtunitCommandProcessor.py | 139 ++++++++ .../mgmt_unit/mgmtunitManagementFunctions.py | 194 ++++++++++ .../unit/logport/logportsCommandProcessor.py | 2 +- .../logport/port/logportCommandProcessor.py | 4 +- .../root/unit/port/portCommandProcessor.py | 50 ++- .../port/portgroupportCommandProcessor.py | 12 +- .../root/unit/unitCommandProcessor.py | 13 +- vendors/KeyMile/baseCommandProcessor.py | 15 + 11 files changed, 826 insertions(+), 47 deletions(-) create mode 100644 vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py create mode 100644 vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py create mode 100644 vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 1166957..33da588 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -128,6 +128,12 @@ def get_mgmt_port(self, field, value): self._conn, base.get_sub_resource_path_by(self, 'mgmt_ports'), params={field: value}).find_by_field_value(field, value) + def get_mgmt_ports(self, field, value): + """Get specific mgmtport object.""" + return keymile_mgmt_port.KeyMileMgmtPortCollection( + self._conn, base.get_sub_resource_path_by(self, 'mgmt_ports'), + params={field: value}) + def get_port(self, field, value): """Get specific port object.""" return keymile_port.KeyMilePortCollection( diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py new file mode 100644 index 0000000..dae5325 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py @@ -0,0 +1,104 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor +import time + + +class MgmtportCommandProcessor(BaseCommandProcessor): + __name__ = 'mgmtport' + management_functions = ('main', 'cfgm', 'fm', 'pm', 'status') + access_points = () + + from .mgmtportManagementFunctions import main + from .mgmtportManagementFunctions import cfgm + from .mgmtportManagementFunctions import fm + from .mgmtportManagementFunctions import pm + from .mgmtportManagementFunctions import status + + def get_property(self, command, *args, context=None): + port = self.get_port_component() + card = self._parent.get_component() + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + + elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': + self.map_states(port, 'port') + context['spacer'] = self.create_spacers((67,), (port.admin_state,))[0] * ' ' + text = self._render('administrative_status', *scopes, context=dict(context, port=port)) + self._write(text) + elif self._validate(args, 'Labels') and context['path'].split('/')[-1] == 'main': + context['spacer1'] = self.create_spacers((67,), (port.label1,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (port.label2,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (port.description,))[0] * ' ' + text = self._render('labels', *scopes, context=dict(context, port=port)) + self._write(text) + elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': + self.map_states(port, 'port') + port_operational_state = port.operational_state + context['port_operational_state'] = port_operational_state + context['spacer'] = self.create_spacers((67,), (port_operational_state,))[0] * ' ' + text = self._render('operational_status', *scopes, context=context) + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + + def _init_access_points(self, context=None): + self.access_points = () + return + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) + + def get_port_component(self): + if self._parent.component_id == '11' or self._parent.component_id == '13': + raise exceptions.CommandSyntaxError() + else: + return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + + def set(self, command, *args, context=None): + scopes = ('login', 'base', 'set') + card = self._parent.get_component() + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'AdministrativeStatus', str) and context['path'].split('/')[-1] == 'main': + state, = self._dissect(args, 'AdministrativeStatus', str) + try: + port = self.get_port_component() + if state == 'up': + port.admin_up() + elif state == 'down': + port.admin_down() + else: + raise exceptions.SoftboxenError() + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': + label1, label2, description = self._dissect(args, 'Labels', str, str, str) + try: + port = self.get_port_component() + port.set_label(label1, label2, description) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py new file mode 100644 index 0000000..9529dba --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py @@ -0,0 +1,334 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } + } +} + +cfgm = { + 'Multicast': { + 'Prop': { + 'MaxNumberOfMulticastStreams': 'rw', + 'EnableIgmpClassifier': 'rw', + 'AllowStaticStreams': 'rw', + 'EnableFastLeave': 'rw', + 'GroupManagement': 'rw', + 'Bandwidth': 'rw' + }, + 'Cmd': ( + 'GetGroupList', + ) + }, + 'Traceability': { + 'Prop': { + 'AgentRemoteId': 'rw' + } + }, + 'Security': { + 'Prop': { + 'ServiceOptions': 'rw', + 'MaxNumberOfMac': 'rw' + } + }, + 'AccessControl': { + 'Prop': { + 'ClassificationKey': 'rw', + 'MAT': 'rw' + } + }, + 'RateLimiter': { + 'Prop': { + 'RateLimiting': 'rw', + 'RateLimitingCoS': 'rw' + } + }, + 'Qos': { + 'Prop': { + 'WfqProfile': 'rw' + } + }, + 'Wire': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Profiles': { + 'Prop': { + 'PortProfiles': 'rw' + } + }, + 'Misc': { + 'Prop': { + 'SpecificDPBO': 'rw', + 'SpecificUPBO': 'rw' + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +pm = { + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) + }, + 'UserCounter': { + 'Prop': { + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' + }, + 'Cmd': ( + 'UserCounterReset', + ) + }, + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { + 'Prop': { + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' + }, + 'Cmd': ( + 'Alarm15minReset', + ) + }, + 'Alarm24h': { + 'Prop': { + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' + }, + 'Cmd': ( + 'Alarm24hReset', + ) + } +} + +status = { + 'General': { + 'Prop': { + 'Standard': 'r-', + 'PowerMgmStatus': 'r-', + 'Vdsl2Parameters': 'r-', + 'EstUPBOElectricalLength': 'r-', + 'LineRate': 'r-', + 'LineSnrMargin': 'r-', + 'AttainableNetDataRate': 'r-', + 'AttainableRate': 'r-', + 'OutputPower': 'r-', + 'BandStatus': 'r-' + } + }, + 'statistics': { + 'Prop': { + 'counters': 'r-', + 'PolicingCounters': 'r-' + }, + 'Cmd': ( + 'ResetPortCounters', + ) + }, + 'Nto1MacAccessDynamicList': { + 'Prop': { + 'UnicastList': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters', + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + }, + }, + 'TLSMacForwardingList': { + 'Prop': { + 'MacForwardingList': 'r-' + }, + 'Cmd': ( + 'FlushMacForwardingList', + ) + }, + '1to1MacForwardingList': { + 'Prop': { + 'One2OneMacForwardingList': 'r-' + } + }, + 'Qos': { + 'Prop': { + 'wfqueues': 'r-' + } + }, + 'Multicast': { + 'stream': { + 'Dynamic': { + 'Prop': { + 'ActiveStreams': 'r-' + }, + 'Cmd': ( + 'ClearActiveStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticStreams': 'r-' + } + }, + }, + + 'Vlan': { + 'Prop': { + 'AttachedVlans': 'r-' + } + }, + 'Preview': { + 'Cmd': ( + 'ResetPreviewSettings', + ) + }, + 'Bandwidth': { + 'Prop': { + 'bandwidthStatus': 'r-' + } + }, + }, + 'LineTest': { + 'MELT': { + 'Prop': { + 'MeltResults': 'r-' + }, + 'Cmd': ( + 'StartMeltMeasurement', + ) + }, + 'Delt': { + 'Prop': { + 'DeltMeasurementStatus': 'r-', + 'RecordedDeltMeasurements': 'r-' + }, + 'Cmd': ( + 'StartDeltMeasurement', + ) + }, + 'Selt': { + 'Prop': { + 'SeltMeasurementStatus': 'r-', + 'RecordedSeltMeasurements': 'r-', + 'CableType': 'rw', + 'BandplanProfile': 'rw', + 'TargetSnrm': 'rw' + }, + 'Cmd': ( + 'StartSeltMeasurement', + ) + }, + }, + 'Defects': { + 'Prop': { + 'Defects': 'r-' + } + }, + 'LineInventory': { + 'Prop': { + 'VendorId': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'DslOperationStatus': 'r-' + } + }, + 'Subcarrier': { + 'Cmd': ( + 'ShowBitAllocation', + ) + }, + 'RfiBands': { + 'Prop': { + 'NotchStatus': 'r-' + } + } +} diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py new file mode 100644 index 0000000..78de871 --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py @@ -0,0 +1,139 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst +import time + +from nesi import exceptions +from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor + + +class MgmtunitCommandProcessor(BaseCommandProcessor): + __name__ = 'mgmtunit' + management_functions = ('main', 'fm') + access_points = () # 'internalPorts', only on certain cards + + from .mgmtunitManagementFunctions import main + from .mgmtunitManagementFunctions import cfgm + from .mgmtunitManagementFunctions import fm + from .mgmtunitManagementFunctions import status + + def _init_access_points(self, context=None): + self.access_points = () + try: + card = self.get_component() + + self.management_functions = ('main', 'cfgm', 'fm', 'status') + + for port in self._model.get_mgmt_ports('mgmt_card_id', card.id): + identifier = 'port-' + port.name.split('/')[-1] + if identifier in self.access_points: + continue + self.access_points += (identifier,) + + except exceptions.InvalidInputError: + pass + + def get_property(self, command, *args, context=None): + card = self.get_component() + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'Labels') and context['path'].split('/')[-1] == 'main': + context['spacer1'] = self.create_spacers((67,), (card.label1,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (card.label2,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (card.description,))[0] * ' ' + text = self._render('labels', *scopes, context=dict(context, port=card)) + self._write(text) + elif self._validate(args, 'EquipmentInventory') and context['path'].split('/')[-1] == 'main': + unit_symbol = '"' + card.board_name + '"' + context['unit_symbol'] = unit_symbol + context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' + unit_short_text = '"' + card.short_text + '"' + context['unit_short_text'] = unit_short_text + context['spacer_2'] = self.create_spacers((67,), (unit_short_text,))[0] * ' ' + unit_board_id = card.board_id + context['unit_board_id'] = unit_board_id + context['spacer_3'] = self.create_spacers((67,), (unit_board_id,))[0] * ' ' + unit_hardware_key = card.hardware_key + context['unit_hardware_key'] = unit_hardware_key + context['spacer_4'] = self.create_spacers((67,), (unit_hardware_key,))[0] * ' ' + unit_manufacturer_id = '"' + card.manufacturer_id + '"' + context['unit_manufacturer_id'] = unit_manufacturer_id + context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_id,))[0] * ' ' + unit_serial_number = '"' + card.serial_number + '"' + context['unit_serial_number'] = unit_serial_number + context['spacer_6'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' + unit_manufacturer_part_number = '"' + card.manufacturer_part_number + '"' + context['unit_manufacturer_part_number'] = unit_manufacturer_part_number + context['spacer_7'] = self.create_spacers((67,), (unit_manufacturer_part_number,))[0] * ' ' + unit_manufacturer_build_state = '"' + card.manufacturer_build_state + '"' + context['unit_manufacturer_build_state'] = unit_manufacturer_build_state + context['spacer_8'] = self.create_spacers((67,), (unit_manufacturer_build_state,))[0] * ' ' + unit_supplier_part_number = '"' + card.model_name + '"' + context['unit_supplier_part_number'] = unit_supplier_part_number + context['spacer_9'] = self.create_spacers((67,), (unit_supplier_part_number,))[0] * ' ' + unit_supplier_build_state = '"' + card.supplier_build_state + '"' + context['unit_supplier_build_state'] = unit_supplier_build_state + context['spacer_10'] = self.create_spacers((67,), (unit_supplier_build_state,))[0] * ' ' + unit_customer_id = '"' + card.customer_id + '"' + context['unit_customer_id'] = unit_customer_id + context['spacer_11'] = self.create_spacers((67,), (unit_customer_id,))[0] * ' ' + unit_customer_product_id = '"' + card.customer_product_id + '"' + context['unit_customer_product_id'] = unit_customer_product_id + context['spacer_12'] = self.create_spacers((67,), (unit_customer_product_id,))[0] * ' ' + unit_boot_loader = '"' + card.boot_loader + '"' + context['unit_boot_loader'] = unit_boot_loader + context['spacer_13'] = self.create_spacers((67,), (unit_boot_loader,))[0] * ' ' + unit_processor = '"' + card.processor + '"' + context['unit_processor'] = unit_processor + context['spacer_14'] = self.create_spacers((67,), (unit_processor,))[0] * ' ' + text = self._render('equipment_inventory', *scopes, context=context) + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) + + def get_component(self): + try: + if self.component_id == '11' or self.component_id == '13': + return self._model.get_mgmt_card('name', self.component_id) + else: + raise exceptions.CommandSyntaxError() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError() + + def set(self, command, *args, context=None): + try: + card = self.get_component() + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': + label1, label2, description = self._dissect(args, 'Labels', str, str, str) + try: + component = self.get_component() + component.set_label(label1, label2, description) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + else: + raise exceptions.CommandSyntaxError(command=command) + diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py new file mode 100644 index 0000000..0a5adbd --- /dev/null +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py @@ -0,0 +1,194 @@ +main = { + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } + }, + 'Equipment': { + 'Prop': { + 'AssignmentStatus': 'r-', + 'CurrentStatus': 'r-' + }, + 'Cmd': ( + 'Assign', + 'Unassign', + 'Restart', + 'StopInBoot' + ) + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + }, + 'Logbooks': { + 'Cmd': ( + 'GetAlarmLogbook', + 'GetEventLogbook', + 'GetEquipmentLogbook' + ) + }, + 'Software': { + 'Prop': { + 'DiskSpace': 'r-', + 'SoftwareOnUnit': 'r-', + 'HardwareAndSoftware': 'r-', + 'Status': 'r-', + 'Configuration': 'rw' + }, + 'Cmd': ( + 'DeleteSoftware', + 'StartSoftware' + ), + 'File': { + 'Software': 'rw' + } + } +} + +cfgm = { + 'Vlan': { + 'Prop': { + 'VlanCosTable': 'r-' + } + }, + 'Security': { + 'Prop': { + 'filtering': 'rw', + 'EoamMode': 'rw' + } + }, + 'Logon': { + 'Prop': { + 'LogonOptions': 'rw', + 'OneToOneOptions': 'rw' + } + }, + 'Mac': { + 'Prop': { + 'MacServiceBased': 'rw' + } + }, + 'HostPort': { + 'Prop': { + 'PolicerProfile': 'rw', + 'TrunkPolicerProfile': 'rw', + 'ProtRateLimiter': 'rw' + } + }, + 'QoS': { + 'Prop': { + 'ColorMarking': 'rw' + } + }, + 'Wire': { + 'General': { + 'Prop': { + 'MeltConfiguration': 'rw' + } + }, + 'Thresholds': { + 'Prop': { + 'MeltAlarmThresholds': 'rw' + } + } + } +} + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) + }, + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } + } +} + +status = { + 'MacAllocationTable': { + 'Prop': { + 'MacAllocationTableEntries': 'r-' + } + }, + 'SwitchPort': { + 'Prop': { + 'Mac': 'r-', + 'MacStatus': 'r-' + } + }, + 'HostPortStatistics': { + 'GeneralCounters': { + 'Prop': { + 'GeneralList': 'r-' + }, + 'Cmd': ( + 'ResetGeneralCounters', + ) + }, + 'ProtocolCounters': { + 'IgmpCounters': { + 'Prop': { + 'IgmpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetIgmpCounters', + ) + }, + 'DhcpCounters': { + 'Prop': { + 'DhcpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetDhcpCounters', + ) + }, + 'ArpCounters': { + 'Prop': { + 'ArpProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetArpCounters', + ) + }, + 'PPPoECounters': { + 'Prop': { + 'PPPoEProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetPPPoECounters', + ) + }, + 'UnknownSourceMACCounters': { + 'Prop': { + 'UnknownSrcMACProtocolList': 'r-' + }, + 'Cmd': ( + 'ResetUnknownSrcMACCounters', + ) + }, + }, + }, + 'BufferManagement': { + 'Prop': { + 'BufferMgmtStatus': 'r-' + } + }, + 'Maintenance': { + 'Prop': { + 'MeltLineTestStatus': 'r-', + 'SearchTone': 'rw' + }, + 'Cmd': ( + 'StartMeltAll', + 'StopMeltAll' + ) + } +} diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 9e76d14..5a36410 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -69,7 +69,7 @@ def do_create(self, command, *args, context=None): _ = self._model.get_logport('name', self._parent.component_id + '/L/' + str(x)) break except exceptions.SoftboxenError: - name = self._parent.component_id + '/L/' + str(ids[0]) + name = self._parent.component_id + '/L/' + str(ids[0]) ports = 'ports: ' for x in ids: ports += str(x) + ', ' diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 8d7b5b7..3bc74fb 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -27,7 +27,7 @@ class LogportCommandProcessor(PortCommandProcessor): from .logportManagementFunctions import ifMIB def get_property(self, command, *args, context=None): - port = self.get_port_component() + port = self.get_component() scopes = ('login', 'base', 'get') try: super().get_property(command, *args, context=context) @@ -39,7 +39,7 @@ def get_property(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - def get_port_component(self): + def get_component(self): return self._model.get_logport('name', self._parent._parent.component_id + '/L/' + self.component_id) def _init_access_points(self, context=None): diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index d5b5f38..a7a4f50 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -27,7 +27,7 @@ class PortCommandProcessor(BaseCommandProcessor): from .portManagementFunctions import status def get_property(self, command, *args, context=None): - port = self.get_port_component() + port = self.get_component() card = self._parent.get_component() scopes = ('login', 'base', 'get') if self._validate(args, *()): @@ -37,7 +37,7 @@ def get_property(self, command, *args, context=None): raise exc elif self._validate(args, 'Portprofile') and context['path'].split('/')[-1] == 'cfgm' and 'SUVM'\ - not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port' and card.product != 'mgmt': + not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.profile1_name,))[0] * ' ' context['profile_name'] = port.profile1_name text = self._render('port_profile', *scopes, context=context) @@ -64,7 +64,7 @@ def get_property(self, command, *args, context=None): context['spacer12'] = self.create_spacers((67,), (port.profile_mode,))[0] * ' ' text = self._render('port_profiles', *scopes, context=dict(context, port=port)) self._write(text) - elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status' and card.product != 'mgmt': + elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'QuickLoopbackTest') and context['path'].split('/')[-1] == 'status'\ @@ -80,7 +80,7 @@ def get_property(self, command, *args, context=None): text = self._render('line_results', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'MeltResults') and context['path'].split('/')[-1] == 'status'\ - and card.product != 'isdn' and self.__name__ == 'port' and card.product != 'mgmt': + and card.product != 'isdn' and self.__name__ == 'port': context['spacer1'] = self.create_spacers((67,), (port.melttest_state,))[0] * ' ' context['test_state'] = port.melttest_state text = self._render('melt_results', *scopes, context=context) @@ -109,10 +109,7 @@ def get_property(self, command, *args, context=None): def _init_access_points(self, context=None): self.access_points = () - port = self.get_port_component() - - if port.name.startswith('11') or port.name.startswith('13'): - return + port = self.get_component() for chan in self._model.get_chans('port_id', port.id): identifier = 'chan-' + chan.name.split('/')[-1] @@ -131,7 +128,7 @@ def do_lock(self, command, *args, context=None): if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: - port = self.get_port_component() + port = self.get_component() port.lock_admin() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -143,7 +140,7 @@ def do_startquickloopbacktest(self, command, *args, context=None): if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: - port = self.get_port_component() + port = self.get_component() port.set_test_state('Running') time.sleep(5) port.set_test_state('Passed') @@ -157,7 +154,7 @@ def do_startlinetest(self, command, *args, context=None): if len(args) == 0 and context['path'].split('/')[-1] == 'status' and 'SUP' in card.board_name \ and self.__name__ == 'port': try: - port = self.get_port_component() + port = self.get_component() port.set_test_state('Running') time.sleep(5) port.set_linetest_state('Passed') @@ -169,9 +166,9 @@ def do_startlinetest(self, command, *args, context=None): def do_startmeltmeasurement(self, command, *args, context=None): card = self._parent.get_component() if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product != 'isdn' \ - and self.__name__ == 'port' and card.product != 'mgmt': + and self.__name__ == 'port': try: - port = self.get_port_component() + port = self.get_component() port.set_melttest_state('Running') time.sleep(5) port.set_melttest_state('Passed') @@ -185,7 +182,7 @@ def do_unlock(self, command, *args, context=None): if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: - port = self.get_port_component() + port = self.get_component() port.unlock_admin() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -201,7 +198,7 @@ def do_deleteinterface(self, command, *args, context=None): # all or interface_id name, = self._dissect(args, str) if name == 'all': - port = self.get_port_component() + port = self.get_component() for interface in self._model.get_interfaces('port_id', port.id): interface.delete() elif name.startswith('interface-'): @@ -224,7 +221,7 @@ def do_createinterface(self, command, *args, context=None): vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names try: - port = self.get_port_component() + port = self.get_component() id = 1 for interface in self._model.get_interfaces('port_id', port.id): if interface.port_id is not None: @@ -249,11 +246,8 @@ def do_createinterface(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def get_port_component(self): - if self._parent.component_id == '11' or self._parent.component_id == '13': - return self._model.get_mgmt_port('name', self._parent.component_id + '/' + self.component_id) - else: - return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + def get_component(self): + return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') @@ -264,20 +258,20 @@ def set(self, command, *args, context=None): exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc elif self._validate(args, 'Portprofile', str) and context['path'].split('/')[-1] == 'cfgm' and 'SUVM'\ - not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port' and card.product != 'mgmt': + not in card.board_name and 'SUVD2' not in card.board_name and self.__name__ == 'port': profile, = self._dissect(args, 'Portprofile', str) try: - port = self.get_port_component() + port = self.get_component() port.set_profile(profile) except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'Portprofiles', str) and context['path'].split('/')[-1] == 'cfgm' and \ - 'SUVD2' in card.board_name and self.__name__ == 'port' and card.product != 'mgmt': + 'SUVD2' in card.board_name and self.__name__ == 'port': profile, = self._dissect(args, 'Portprofiles', str) try: - port = self.get_port_component() + port = self.get_component() port.set_profile(profile) except exceptions.SoftboxenError(): @@ -288,7 +282,7 @@ def set(self, command, *args, context=None): en1, name1, elen1, en2, name2, elen2, en3, name3, elen3, en4, name4, mode = self._dissect(args, 'Portprofiles', str, str, str, str, str, str, str, str, str, str, str, str) try: - port = self.get_port_component() + port = self.get_component() en1 = True if en1.lower() == 'true' else False en2 = True if en2.lower() == 'true' else False en3 = True if en3.lower() == 'true' else False @@ -301,7 +295,7 @@ def set(self, command, *args, context=None): elif self._validate(args, 'AdministrativeStatus', str) and context['path'].split('/')[-1] == 'main': state, = self._dissect(args, 'AdministrativeStatus', str) try: - port = self.get_port_component() + port = self.get_component() if state == 'up': port.admin_up() elif state == 'down': @@ -314,7 +308,7 @@ def set(self, command, *args, context=None): elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': label1, label2, description = self._dissect(args, 'Labels', str, str, str) try: - port = self.get_port_component() + port = self.get_component() port.set_label(label1, label2, description) except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index e22f293..67bcda4 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -23,11 +23,11 @@ class PortgroupportCommandProcessor(PortCommandProcessor): from .portgroupportManagementFunctions import cfgm from .portgroupportManagementFunctions import status - def get_port_component(self): + def get_component(self): return self._model.get_portgroupport('name', self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id) def get_property(self, command, *args, context=None): - port = self.get_port_component() + port = self.get_component() scopes = ('login', 'base', 'get') try: super().get_property(command, *args, context=context) @@ -131,7 +131,7 @@ def set(self, command, *args, context=None): enable, subident, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', str, str, str, str, str, str, str, str, str) try: - port = self.get_port_component() + port = self.get_component() enable = True if enable.lower() == 'true' else False register = True if register.lower() == 'true' else False phone = True if phone.lower() == 'true' else False @@ -143,7 +143,7 @@ def set(self, command, *args, context=None): str) and context['path'].split('/')[-1] == 'cfgm': enable, number, username, password, displayname, privacy, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) try: - port = self.get_port_component() + port = self.get_component() try: subscriber = self._model.get_subscriber('number', int(number)) subscriber.set('autorisation_user_name', username) @@ -167,7 +167,7 @@ def set(self, command, *args, context=None): str) and context['path'].split('/')[-1] == 'cfgm': enable, number, username, password, displayname, privacy, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) try: - port = self.get_port_component() + port = self.get_component() try: subscriber = self._model.get_subscriber('number', int(number)) assert subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id @@ -196,7 +196,7 @@ def set(self, command, *args, context=None): enable, subident, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', str, str, str, str, str, str, str, str, str) try: - port = self.get_port_component() + port = self.get_component() enable = True if enable.lower() == 'true' else False register = True if register.lower() == 'true' else False regdefault = True if regdefault.lower() == 'true' else False diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 8c1d5d9..f20ce24 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -45,12 +45,6 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) - for port in self._model.get_mgmt_port('mgmt_card_id', card.id): - identifier = 'port-' + port.name.split('/')[-1] - if identifier in self.access_points: - continue - self.access_points += (identifier,) - for gport in self._model.get_portgroupports('card_id', card.id): identifier = 'portgroup-' + gport.name.split('/')[1][1] if identifier in self.access_points: @@ -127,7 +121,7 @@ def get_property(self, command, *args, context=None): text = self._render('labels', *scopes, context=dict(context, port=card)) self._write(text) - elif self._validate(args, 'Registrar') and context['path'].split('/')[-1] == 'cfgm' and card.product != 'mgmt': + elif self._validate(args, 'Registrar') and context['path'].split('/')[-1] == 'cfgm': context['spacer1'] = self.create_spacers((67,), (card.registrar_adress,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (card.registrar_port,))[0] * ' ' context['spacer3'] = self.create_spacers((67,), (card.registration_mode,))[0] * ' ' @@ -238,7 +232,7 @@ def on_unknown_command(self, command, *args, context=None): def get_component(self): try: if self.component_id == '11' or self.component_id == '13': - return self._model.get_mgmt_card('name', self.component_id) + raise exceptions.CommandSyntaxError() else: return self._model.get_card('name', self.component_id) except exceptions.SoftboxenError: @@ -262,8 +256,7 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'Ip', str, str, str) and context['component_path'].split('/')[-1] == 'cfgm' and \ - card.product != 'mgmt': + elif self._validate(args, 'Ip', str, str, str) and context['component_path'].split('/')[-1] == 'cfgm': ip1, ip2, ip3 = self._dissect(args, 'Ip', str, str, str) try: component = self.get_component() diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 9dc2cab..70e3f22 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -279,6 +279,11 @@ def change_directory(self, path, context=None): if component_type == 'port': if self.__name__ == 'portgroup': component_type = 'portgroupport' + elif self.__name__ == 'mgmtunit': + component_type = 'mgmtport' + if component_type == 'unit': + if component_id == '11' or component_id == '13': + component_type = 'mgmtunit' command_processor = component_type.capitalize() + 'CommandProcessor' else: @@ -322,6 +327,14 @@ def change_directory(self, path, context=None): if self.__name__ != 'port': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'mgmtunit': + if self.__name__ != 'root': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'mgmtport': + if self.__name__ != 'mgmtunit': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'interface': if self.__name__ != 'port' and self.__name__ != 'chan' and self.__name__ != 'logport': raise exceptions.CommandExecutionError(command=None, template=None, @@ -399,6 +412,8 @@ def change_directory(self, path, context=None): MacaccessctrlCommandProcessor from vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor import SubpacketCommandProcessor from vendors.KeyMile.accessPoints.root.services.srvcCommandProcessor import SrvcCommandProcessor + from vendors.KeyMile.accessPoints.root.mgmt_unit.mgmtunitCommandProcessor import MgmtunitCommandProcessor + from vendors.KeyMile.accessPoints.root.mgmt_unit.mgmt_port.mgmtportCommandProcessor import MgmtportCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') if component_id is not None and self.component_id is not None: From 9211248b48372839f2db424fc792e74be3d53713 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 20 Oct 2020 15:06:51 +0200 Subject: [PATCH 258/318] Restructured change_directory function and fixed some navigation bugs --- vendors/KeyMile/baseCommandProcessor.py | 146 +++++++++++++++--------- 1 file changed, 91 insertions(+), 55 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 70e3f22..672c667 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -201,63 +201,32 @@ def do_ls(self, command, *args, context=None): def change_directory(self, path, context=None): path = path.lower() - if re.search('^(?:[^.]+/)+\.\.$', path): + + if re.search('^(?:[^.]+/)+\.{1,2}$', path): raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) - if re.search('^(?:[^.]+/)+\.\.(?:/.+)+$', path): + if re.search('^(?:[^.]+/)+\.{1,2}(?:/.+)+$', path): raise exceptions.CommandExecutionError(template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors'), command=None) - if path == '/': - if self.__name__ != 'root': - return self._parent.change_directory(path, context=context) - else: - context['path'] = '/' - return self + allowed_path_components = ( + 'unit-[0-9]+', 'port-[0-9]+', 'portgroup-[0-9]+', 'chan-[0-9]+', 'interface-[0-9]+', 'vcc-[0-9]+', + 'alarm-[0-9]+', 'main', 'cfgm', 'fm', 'pm', 'status', 'eoam', 'fan', 'multicast', 'services', 'packet', + 'srvc-[0-9]', 'macaccessctrl', 'tdmconnections', 'logports', 'logport-[0-9]', '1to1doubletag', + '1to1singletag', 'mcast', 'nto1', 'pls', 'tls', '\.', '\.\.' + ) components = [x for x in path.split('/') if x] - - if not re.search( - '^(unit-[0-9]+|port-[0-9]+|portgroup-[0-9]+|chan-[0-9]+|interface-[0-9]+|vcc-[0-9]+|alarm-[0-9]+|main|cfgm|fm|pm|status|eoam|fan|multicast|services|packet|subpacket|srvc-[0-9]|macaccessctrl|tdmconnections|logports|logport-[0-9]|1to1doubletag|1to1singletag|mcast|nto1|pls|tls|\.|\.\.)$', - components[0]): - raise exceptions.CommandExecutionError(template='invalid_management_function_error', - template_scopes=('login', 'base', 'execution_errors'), - command=None) - - if path == '.': - return self - - if path.startswith('./'): - if path == './': - return self - - return self.change_directory(path[2:], context=context) - - if path.startswith('..'): - splitted_path = [x for x in context['path'].split('/') if x] - exit_component = None - if len(splitted_path) != 0: - exit_component = splitted_path.pop() - context['path'] = '/' + '/'.join(splitted_path) - - if exit_component in ('main', 'cfgm', 'fm', 'pm', 'status'): - self.set_prompt_end_pos(context=context) - if path != '..': - return self.change_directory(path[3:], context=context) - return self - - if path == '..': - if self.__name__ == 'root': + if path.startswith('/'): + if path == '/': + if self.__name__ != 'root': + return self._parent.change_directory(path, context=context) + else: + context['path'] = '/' return self - return self._parent - if self.__name__ == 'root': - return self.change_directory(path[3:], context=context) - - return self._parent.change_directory(path[3:], context=context) - if path.startswith('/'): if 'unit-' not in components[0] and components[0] not in ( 'eoam', 'fan', 'multicast', 'services', 'tdmConnection', 'main', 'cfgm', 'fm', 'pm', 'status'): raise exceptions.CommandExecutionError(command=None, template=None, @@ -268,7 +237,44 @@ def change_directory(self, path, context=None): else: context['path'] = '/' subprocessor = self.change_directory(path.lstrip('/'), context=context) + elif path.startswith('.'): + if path == '.': + return self + + if path.startswith('./'): + if path == './': + return self + + return self.change_directory(path[2:], context=context) + + if path.startswith('..'): + splitted_path = [x for x in context['path'].split('/') if x] + exit_component = None + if len(splitted_path) != 0: + exit_component = splitted_path.pop() + context['path'] = '/' + '/'.join(splitted_path) + + if exit_component in ('main', 'cfgm', 'fm', 'pm', 'status'): + self.set_prompt_end_pos(context=context) + if path != '..': + return self.change_directory(path[3:], context=context) + return self + + if path == '..' or path == '../': + if self.__name__ == 'root': + return self + return self._parent + + if self.__name__ == 'root': + return self.change_directory(path[3:], context=context) + + return self._parent.change_directory(path[3:], context=context) else: + if not re.search('^(' + '|'.join(allowed_path_components) + ')$', components[0]): + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + remaining_args = '/'.join(components[1:]) component_type = None @@ -324,6 +330,12 @@ def change_directory(self, path, context=None): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'chan': + try: + self._model.get_chan('name', self._parent.component_id + '/' + self.component_id + '/' + component_id) + except exceptions.InvalidInputError: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if self.__name__ != 'port': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty @@ -336,19 +348,47 @@ def change_directory(self, path, context=None): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'interface': + try: + self._model.get_interface('name', self._parent.component_id + '/' + self.component_id + '/' + component_id) + except exceptions.InvalidInputError: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if self.__name__ != 'port' and self.__name__ != 'chan' and self.__name__ != 'logport': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'logport': + try: + self._model.get_logport('name', self._parent.component_id + '/L/' + component_id) + except exceptions.InvalidInputError: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if self.__name__ != 'logports': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'vcc': + try: + self._model.get_interface('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + component_id) + except exceptions.InvalidInputError: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if self.__name__ != 'chan': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty + elif component_type == 'srvc': + try: + self._model.get_srvc('name', 'srvc-' + component_id) + except exceptions.InvalidInputError: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + + if self.__name__ != 'subpacket': + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty - elif components[0] in ('packet', 'macAccessCtrl'): + if components[0] in ('packet', 'macAccessCtrl'): if self.__name__ != 'services': raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty @@ -386,6 +426,7 @@ def change_directory(self, path, context=None): else: new_path = '/' + components[0] context['path'] += new_path + self.set_prompt_end_pos(context=context) return self from vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor import UnitCommandProcessor @@ -416,19 +457,13 @@ def change_directory(self, path, context=None): from vendors.KeyMile.accessPoints.root.mgmt_unit.mgmt_port.mgmtportCommandProcessor import MgmtportCommandProcessor subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') - if component_id is not None and self.component_id is not None: - subprocessor.set_component_id(self.component_id + '/' + component_id) - if component_id is not None: subprocessor.set_component_id(component_id) if context['path'] == '/': new_path = components[0] else: - if path == 'subpacket': - new_path = '/' + context['ServiceType'] - else: - new_path = '/' + components[0] + new_path = '/' + components[0] context['path'] += new_path if len(remaining_args) > 0: @@ -492,7 +527,8 @@ def do_cd(self, command, *args, context=None): except: context['path'] = current_path raise - subprocessor.loop(context=context, return_to=subprocessor._parent) + if not isinstance(subprocessor, self.__class__): + subprocessor.loop(context=context, return_to=subprocessor._parent) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), From 98acd603005a56234f53bd41bae09cecf1ad0d02 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 20 Oct 2020 15:27:27 +0200 Subject: [PATCH 259/318] Refactored integration test files --- .../conf/bootstraps/create-keymile-MG2500.sh | 19 +++- .../keymile/getInventory2.txt | 10 +-- .../keymile/getMonitoring3.txt | 8 -- .../integration_tests/keymile/getState1.txt | 87 +++++-------------- .../integration_tests/keymile/getVoice5.txt | 6 +- .../keymile/setChannelProfile14.txt | 7 +- .../keymile/setInterface16.txt | 19 ++-- .../integration_tests/keymile/setIpAddr6.txt | 16 ++-- .../keymile/setPortProfile13.txt | 7 +- .../keymile/setSIPDomain12.txt | 10 +-- .../integration_tests/keymile/setTraffic1.txt | 13 ++- .../integration_tests/keymile/setVCC15.txt | 4 +- .../integration_tests/keymile/setconfDsl2.txt | 29 +++---- .../keymile/setconfVoice9.txt | 24 +++-- .../keymile/setdeconfVoicePort11.txt | 3 +- .../keymile/setdeconfVoicePort17.txt | 12 ++- .../keymile/setportaktiv4.txt | 14 +-- .../keymile/setportdeactiv5.txt | 15 +--- .../keymile/setunconfDsl3.txt | 20 ++--- .../{test Loopback3.txt => testLoopback3.txt} | 3 +- .../keymile/testVoicePort2.txt | 9 +- .../keymile/testmelting4.txt | 14 ++- 22 files changed, 125 insertions(+), 224 deletions(-) rename test_cases/integration_tests/keymile/{test Loopback3.txt => testLoopback3.txt} (60%) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index dd35d3c..a7209fa 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -385,7 +385,7 @@ req='{ "description": "Channel #1" }' -chan_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/channels) +chan_5_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/channels) ### Unit-6 ### @@ -414,6 +414,17 @@ req='{ unit_6=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_6', + "admin_state": "1", + "operational_state": "1" +}' + +port_6_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + ### Unit-7 ### # Create a physical card at the network device (admin operation) @@ -450,7 +461,7 @@ req='{ "operational_state": "1" }' -port_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_7_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) ### Unit-8 ### @@ -515,7 +526,7 @@ req='{ "operational_state": "1" }' -port_4_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/mgmt_ports) +port_11_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/mgmt_ports) @@ -539,7 +550,7 @@ req='{ "operational_state": "1" }' -port_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +port_19_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) ### PortGroupPort-1 ### diff --git a/test_cases/integration_tests/keymile/getInventory2.txt b/test_cases/integration_tests/keymile/getInventory2.txt index c45e0e0..16f77b4 100644 --- a/test_cases/integration_tests/keymile/getInventory2.txt +++ b/test_cases/integration_tests/keymile/getInventory2.txt @@ -3,16 +3,16 @@ secret ls cd /services/packet/nto1/ ls -cd /services/packet/nto1/srvc-{$match}/cfgm +cd /services/packet/nto1/srvc-1/cfgm get Service -cd /unit-{$slot} +cd /unit-11 ls -cd /unit-{$slot}/mai +cd /unit-19/main get HardwareAndSoftware get CurrentStatus get EquipmentInventory -cd /unit-{$slot}/port-{$port} +cd /unit-1/port-1} ls -cd /unit-{$slot}/port-{$port}/main +cd /unit-1/port-{1/main get OperationalStatus exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getMonitoring3.txt b/test_cases/integration_tests/keymile/getMonitoring3.txt index 6338665..e4259f3 100644 --- a/test_cases/integration_tests/keymile/getMonitoring3.txt +++ b/test_cases/integration_tests/keymile/getMonitoring3.txt @@ -10,12 +10,4 @@ cd .. cd unit-1 ls cd .. - - - - - - - - exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getState1.txt b/test_cases/integration_tests/keymile/getState1.txt index cdfab20..2c5d8b1 100644 --- a/test_cases/integration_tests/keymile/getState1.txt +++ b/test_cases/integration_tests/keymile/getState1.txt @@ -1,104 +1,57 @@ admin secret -#adsl SUAD2 -cd /unit-{$card}/port-{$port}/status +cd /unit-1/port-1/status get AttainableRate -cd /unit-{$card}/port-{$port}/main +cd /unit-1/port-1/main get AdministrativeStatus get OperationalStatus -cd /unit-{$card}/port-{$port}/chan-1/cfgm +cd /unit-1/port-1/chan-1/cfgm get ProfileName get ChanProfile -cd /unit-{$card}/port-{$port}/chan-1/status +cd /unit-1/port-1/chan-1/status get status -cd /unit-{$card}/port-{$port}/chan-1/vcc-1/cfgm +cd /unit-1/port-1/chan-1/vcc-1/cfgm get configuredProfiles -cd /unit-{$card}/port-{$port}/chan-1/vcc-1/status +cd /unit-1/port-1/chan-1/vcc-1/status get ServiceStatus cd /unit-11 ls -cd /unit-{$slotIpss} +cd /unit-19 ls -#vdsl SUVD2 -cd /unit-{$card}/port-{$port}/status -get AttainableRate -cd /unit-{$card}/port-{$port}/main -get AdministrativeStatus -get OperationalStatus -cd /unit-{$card}/port-{$port}/chan-1/cfgm -get ChanProfile -cd /unit-{$card}/port-{$port}/chan-1/status -get status -cd /unit-{$card}/port-{$port}/chan-1/interface-1/cfgm -get configuredProfiles -get vlanProfile -cd /unit-{$card}/port-{$port}/chan-1/interface-1/status -get ServiceStatus -cd /unit-11 -ls -cd /unit-{$card}/port-{$port} -get status/VendorId -cd /unit-{$slotIpss} -ls -#xdsl -cd /unit-{$card}/port-{$port}/status -get AttainableRate -get UnicastList -cd /unit-{$card}/port-{$port}/main -get AdministrativeStatus -get OperationalStatus -cd /unit-{$card}/port-{$port} -ls -cd /unit-{$card}/port-{$port}/chan-1/cfgm -get ChanProfile -cd /unit-{$card}/port-{$port}/chan-1/status -get status -cd /unit-{$card}/port-{$port}/chan-1/interface-1/cfgm -get configuredProfiles -cd /unit-{$card}/port-{$port}/chan-1/interface-1/status -get ServiceStatus -cd /unit-{$card} -ls -cd /unit-11 -ls -cd /unit-{$card}/port-{$port} -get status/VendorId -#ftth -cd /unit-{$card}/port-{$port}/main +cd /unit-7/port-1/main get AdministrativeStatus get OperationalStatus -cd /unit-{$card}/port-{$port} +cd /unit-7/port-1 ls -cd /unit-{$card}/port-{$port}/status +cd /unit-7/port-1/status get PortMacStatus get PortGeneralStatus -cd /unit-{$card}/port-{$port}/interface-1/cfgm +cd /unit-7/port-1/interface-1/cfgm get configuredProfiles get vlanProfile get IfRateLimiting -cd /unit-{$card}/port-{$port}/interface-1/status +cd /unit-7/port-1/interface-1/status get ServiceStatus -cd /unit-{$card}/port-{$port}/status +cd /unit-7/port-1/status get DDMStatus -#sdsl -cd /unit-{$card}/port-{$port}/main +cd /unit-2/port-1/main ls -cd /unit-{$card}/port-{$port}/status +cd /unit-2/port-1/status ls get LineActualState get LineOperationState -cd /unit-{$card}/logports/logport-{$port}/status +cd /unit-2/logports/logport-2/status get ActualStatus get OperationalWireState -cd /unit-{$card}/logports/logport-{$port}/main +cd /unit-2/logports/logport-2/main get AdministrativeStatus get OperationalStatus -cd /unit-{$card}/logports/logport-{$port}/cfgm +cd /unit-2/logports/logport-2/cfgm get SpanProfiles -cd /unit-{$card}/logports/logport-{$port}/interface-1/cfgm +cd /unit-2/logports/logport-2/interface-1/cfgm get configuredProfiles get vlanProfile -cd /unit-{$card}/logports/logport-{$port}/interface-1/status +cd /unit-2/logports/logport-2/interface-1/status get ServiceStatus ls exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getVoice5.txt b/test_cases/integration_tests/keymile/getVoice5.txt index e3318fa..e61689a 100644 --- a/test_cases/integration_tests/keymile/getVoice5.txt +++ b/test_cases/integration_tests/keymile/getVoice5.txt @@ -1,9 +1,7 @@ admin secret -#analog -cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm +cd /unit-19/portgroup-1/port-1/cfgm get pstnport -#isdn -cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm +cd /unit-19/portgroup-2/port-1/cfgm get isdnport exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setChannelProfile14.txt b/test_cases/integration_tests/keymile/setChannelProfile14.txt index 3ad57dd..00530d5 100644 --- a/test_cases/integration_tests/keymile/setChannelProfile14.txt +++ b/test_cases/integration_tests/keymile/setChannelProfile14.txt @@ -1,11 +1,10 @@ admin secret -cd /unit-$card/port-$port/chan-1/cfgm -#SUVM6/4 -set chanprofile $profile +cd /unit-5/port-1/chan-1/cfgm +set chanprofile rofile set chanprofile default #else -cd /unit-$card/port-$port/chan-1/cfgm +cd /unit-5/port-1/chan-1/cfgm set ProfileName $profile set ProfileName default exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setInterface16.txt b/test_cases/integration_tests/keymile/setInterface16.txt index 16a5569..e719a80 100644 --- a/test_cases/integration_tests/keymile/setInterface16.txt +++ b/test_cases/integration_tests/keymile/setInterface16.txt @@ -1,15 +1,12 @@ admin secret -#SUSE1 -cd /unit-$card/logports/logport-$port/cfgm -#SUEN4 -cd /unit-$card/port-$port/cfgm -#SUE16 -cd /unit-$card/port-$port/cfgm -#ftth -cd /unit-$card/port-$port/cfgm -#else -cd /unit-$card/port-$port/chan-1/cfgm -CreateInterface default VCC_1_32_10100 +cd /unit-2/logports/logport-2/cfgm +CreateInterface default VCC_1_100 +DeleteInterface all +cd /unit-7/port-1/cfgm +CreateInterface default VCC_1_32100 +DeleteInterface all +cd /unit-5/port-1/chan-1/cfgm +CreateInterface default VC 1wdf DeleteInterface all exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setIpAddr6.txt b/test_cases/integration_tests/keymile/setIpAddr6.txt index e4e5a91..ec96fcd 100644 --- a/test_cases/integration_tests/keymile/setIpAddr6.txt +++ b/test_cases/integration_tests/keymile/setIpAddr6.txt @@ -1,17 +1,15 @@ admin secret cd /services/packet/1to1SingleTag/srvc-1/cfgm -set Service /unit-{$managementSlot}/control {$input->vlan_voice_new} CoS0 Add +set Service /unit-19/control {$input->vlan_voice_new} CoS0 Add cd /services/packet/1to1SingleTag/srvc-2/cfgm -set Service /unit-{$managementSlot}/media {$input->vlan_voice_new} CoS0 Add -cd /unit-{$managementSlot}/cfgm -set Ip {$input->ip_voice} 255.255.255.0 {$input->gateway_voice} +set Service /unit-19/media {$input->vlan_voice_new} CoS0 Add +cd /unit-19/cfgm +set Ip 11.1.1.1 155.255.255.0 2.3.3.3 cd /cfgm save -cd /unit-{$managementSlot}/main +cd /unit-19/main restart -set /cfgm/IP_Address {$input->ip_new} 255.255.255.0 {$input->gateway} -/cfgm/Save -/unit-11/main/restart -set /cfgm/VlanId {$input->vlan_new} +admin +secret exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setPortProfile13.txt b/test_cases/integration_tests/keymile/setPortProfile13.txt index ed42302..6ee1f57 100644 --- a/test_cases/integration_tests/keymile/setPortProfile13.txt +++ b/test_cases/integration_tests/keymile/setPortProfile13.txt @@ -1,10 +1,5 @@ admin secret - -cd /unit-$card/port-$port/cfgm -#SUVM6 posibilities -set portprofiles true $vdslProfile 0 false default 0 false default 0 false default Priority -set portprofiles true " . $vdslProfile . " 0 false default 0 false default 0 false default Priority -set portprofiles false default 0 false default 0 false default 0 true " . $adslProfile . " Priority +cd /unit-6/port-1/cfgm set portprofiles true default 0 false default 0 false default 0 true default Priority exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setSIPDomain12.txt b/test_cases/integration_tests/keymile/setSIPDomain12.txt index d465075..fd572f6 100644 --- a/test_cases/integration_tests/keymile/setSIPDomain12.txt +++ b/test_cases/integration_tests/keymile/setSIPDomain12.txt @@ -1,12 +1,10 @@ admin secret -#analog or isdn -cd /unit-{$slotIpss}/cfgm +cd /unit-19/cfgm get Sip -set Proxy PrimaryOnly $domain 5060 "" 0 true Options 10 "" 0 true Options 10 -set Registrar $domain 5060 OneByOneRegistration 1 -set Sip $name $domain 5060 +49 $area 500 4 false None true 30 false false 1800 -set digitmap {sip "xxx" $domain 0 ""; sip "*xx*x.#" $domain 0 ""; sip "*xx*" $domain 0 ""; sip "*xx#" $domain 0 ""; sip "#xx#" $domain 0 ""; } +set Proxy PrimaryOnly domain 5060 "" 0 true Options 10 "" 0 true Options 10 +set Registrar domain 5060 OneByOneRegistration 1 +set Sip $name domain 5060 +49 area 500 4 false None true 30 false false 1800 cd /cfgm save exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setTraffic1.txt b/test_cases/integration_tests/keymile/setTraffic1.txt index a9cc539..bcaee65 100644 --- a/test_cases/integration_tests/keymile/setTraffic1.txt +++ b/test_cases/integration_tests/keymile/setTraffic1.txt @@ -1,16 +1,13 @@ admin secret -#ftth -cd /unit-$card +cd /unit-7 ls -#SUEN4 -cd /unit-$card/port-$port/cfgm +cd /unit-7/port-1/cfgm Set Mode "Speed1000 Autoneg On" Set FlowControl false -CreateInterface VLAN_$trafficVlan -#else -cd /unit-$card/port-$port/cfgm +CreateInterface VLAN_name +cd /unit-7/port-1/cfgm Set Mode "1000MbitsFullDuplex" Set FlowControl false -CreateInterface VLAN_$trafficVlan +CreateInterface VLAN_name exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setVCC15.txt b/test_cases/integration_tests/keymile/setVCC15.txt index cd9305b..dfc9f0b 100644 --- a/test_cases/integration_tests/keymile/setVCC15.txt +++ b/test_cases/integration_tests/keymile/setVCC15.txt @@ -1,6 +1,6 @@ admin secret -cd /unit-$card/port-$port/chan-1/cfgm -CreateVcc $profile default +cd /unit-1/port-1/chan-1/cfgm +CreateVcc default default DeleteVcc all exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfDsl2.txt b/test_cases/integration_tests/keymile/setconfDsl2.txt index c2e2afc..61e065d 100644 --- a/test_cases/integration_tests/keymile/setconfDsl2.txt +++ b/test_cases/integration_tests/keymile/setconfDsl2.txt @@ -1,26 +1,19 @@ admin secret #adsl -cd /unit-$card/port-$port/main -Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" +cd /unit-1/port-1/main +Set Labels "umlctId)" "arrierId" "" set AdministrativeStatus up -#vdsl -cd /unit-$card/port-$port/main -Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" +cd /unit-5/port-1/main +Set Labels "Id" "ierLind" "" set AdministrativeStatus up -#xdsl -cd /unit-$card/port-$port/main -Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" +cd /unit-7/port-1/main +Set Labels "ctId" "d" "" set AdministrativeStatus up -#ftth -cd /unit-$card/port-$port/main -Set Labels "umlaut($contactName) ($contactId)" "$carrierLineId" "" -set AdministrativeStatus up -#sdsl -cd /unit-$card/logports/cfgm -create $bonding_port $profile -cd /unit-$card/logports/logport-$port/cfgm -CreateInterface name $servicetype -cd /unit-$card/logports/logport-$port/main +cd /unit-2/logports/cfgm +create port-1 +cd /unit-$card/logports/logport-1/cfgm +CreateInterface name +cd /unit-$card/logports/logport-1/main set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfVoice9.txt b/test_cases/integration_tests/keymile/setconfVoice9.txt index 60f70f6..6c4c2fe 100644 --- a/test_cases/integration_tests/keymile/setconfVoice9.txt +++ b/test_cases/integration_tests/keymile/setconfVoice9.txt @@ -1,19 +1,17 @@ admin secret #analog -cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm -set pstnport true {$numbers} true false none none none none none -cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/main -Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" -cd /unit-$voiceCard/port-$voicePort/main +cd /unit-19/portgroup-1/port-1/cfgm +set pstnport true 11 true false none none none none none +cd /unit-19/portgroup-1/port-1/main +Set Labels "ssdd" "sssd" "" +cd /unit-19/port-1/main set AdministrativeStatus up -Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" -#isdn -cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/cfgm -set isdnport true {$numbers} true false none none none none none -cd /unit-$slotIpss/portgroup-$voiceCard/port-$voicePort/main -Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" -cd /unit-$voiceCard/port-$voicePort/main +Set Labels www "carrierLineId" "" +cd /unit-19/portgroup-2/port-1/cfgm +set isdnport true 112 true false none none none none none +cd /unit-19/portgroup-2/port-1/main +Set Labels dada "test" "" +cd /unit-19/port-1/main set AdministrativeStatus up -Set Labels umlaut($contactName) ($contactID) "$carrierLineId" "" exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt index 6704e55..c5dc42a 100644 --- a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt @@ -1,7 +1,6 @@ admin secret -#isdn or analog -cd /unit-$ipsxSlot/portgroup-$card/port-$port/cfgm +cd /unit-19/portgroup-1/port-1/cfgm get pstnport cd / exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt index d82cfe2..9099c38 100644 --- a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt @@ -1,20 +1,18 @@ admin secret -#analog cd /unit-$card/port-$port/main set AdministrativeStatus down Set Labels "" "" "" -cd /unit-$ipsxSlot/portgroup-$card/port-$port/cfgm +cd /unit-19/portgroup-1/port-1/cfgm Set pstnport false {} true false none none none none none -cd /unit-$ipsxSlot/portgroup-$card/port-$port/main +cd /unit-19/portgroup-1/port-1/main Set Labels "" "" "" -#isdn -cd /unit-$card/port-$port/main +cd /unit-19/port-1/main set AdministrativeStatus down Set Labels "" "" "" -cd /unit-$ipsxSlot/portgroup-$card/port-$port/cfgm +cd /unit-19/portgroup-2/port-1/cfgm Set isdnport false {} true false false none none none none -cd /unit-$ipsxSlot/portgroup-$card/port-$port/main +cd /unit-19/portgroup-2/port-1/main Set Labels "" "" "" diff --git a/test_cases/integration_tests/keymile/setportaktiv4.txt b/test_cases/integration_tests/keymile/setportaktiv4.txt index c917fa5..f538660 100644 --- a/test_cases/integration_tests/keymile/setportaktiv4.txt +++ b/test_cases/integration_tests/keymile/setportaktiv4.txt @@ -1,18 +1,12 @@ admin secret -#adsl -cd /unit-$card/port-$port/main +cd /unit-1/port-1/main set AdministrativeStatus up -#vdsl -cd /unit-$card/port-$port/main +cd /unit-5/port-1/main set AdministrativeStatus up -#xdsl -cd /unit-$card/port-$port/main -set AdministrativeStatus up -#ftth -cd /unit-$card/port-$port/main +cd /unit-7/port-1/main set AdministrativeStatus up #sdsl -cd /unit-$card/logports/logport-$port/main +cd /unit-2/logports/logport-2/main set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setportdeactiv5.txt b/test_cases/integration_tests/keymile/setportdeactiv5.txt index 041cd8d..88ca770 100644 --- a/test_cases/integration_tests/keymile/setportdeactiv5.txt +++ b/test_cases/integration_tests/keymile/setportdeactiv5.txt @@ -1,18 +1,11 @@ admin secret -#adsl -cd /unit-$card/port-$port/main +cd /unit-1/port-1/main set AdministrativeStatus down -#vdsl -cd /unit-$card/port-$port/main +cd /unit-5/port-1/main set AdministrativeStatus down -#xdsl -cd /unit-$card/port-$port/main +cd /unit-7/port-1/main set AdministrativeStatus down -#ftth -cd /unit-$card/port-$port/main -set AdministrativeStatus down -#sdsl -cd /unit-$card/logports/logport-$port/main +cd /unit-2/logports/logport-2/main set AdministrativeStatus down exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setunconfDsl3.txt b/test_cases/integration_tests/keymile/setunconfDsl3.txt index 7213e54..5eb92fd 100644 --- a/test_cases/integration_tests/keymile/setunconfDsl3.txt +++ b/test_cases/integration_tests/keymile/setunconfDsl3.txt @@ -1,26 +1,20 @@ admin secret -#adsl -cd /unit-$card/port-$port/main +cd /unit-1/port-1/main set AdministrativeStatus down Set Labels "" "" "" -#vdsl -cd /unit-$card/port-$port/main -set AdministrativeStatus down -Set Labels "" "" "" -#xdsl -cd /unit-$card/port-$port/main +cd /unit-5/port-1/main set AdministrativeStatus down Set Labels "" "" "" #ftth -cd /unit-$card/port-$port/main +cd /unit-7/port-1/main set AdministrativeStatus down Set Labels "" "" "" #sdsl -cd /unit-$card/logports/logport-$port/main +cd /unit-2/logports/logport-2/main set AdministrativeStatus down Set Labels "" "" "" -cd /unit-$card/logports/logport-$port/main -cd /unit-$card/logports/cfgm -Delete logport-$port +cd /unit-2/logports/logport-2/main +cd /unit-2/logports/cfgm +Delete logport-2 exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/test Loopback3.txt b/test_cases/integration_tests/keymile/testLoopback3.txt similarity index 60% rename from test_cases/integration_tests/keymile/test Loopback3.txt rename to test_cases/integration_tests/keymile/testLoopback3.txt index a4c19e2..2ebea1b 100644 --- a/test_cases/integration_tests/keymile/test Loopback3.txt +++ b/test_cases/integration_tests/keymile/testLoopback3.txt @@ -1,7 +1,6 @@ admin secret -#isdn -cd /unit-$voiceCard/port-$voicePort/status +cd /unit-19/port-1/status Lock StartQuickLoopbackTest get QuickLoopbackTest diff --git a/test_cases/integration_tests/keymile/testVoicePort2.txt b/test_cases/integration_tests/keymile/testVoicePort2.txt index 0602971..66f987f 100644 --- a/test_cases/integration_tests/keymile/testVoicePort2.txt +++ b/test_cases/integration_tests/keymile/testVoicePort2.txt @@ -1,10 +1,9 @@ admin secret -cd /unit-{$voice_card}/main +cd /unit-19/main get HardwareAndSoftware -/unit-$voice_card/port-$voice_port/status/StartLineTest -get /unit-$voice_card/port-$voice_port/status/LineTestResults -#SUVM6 -cd /unit-$card/port-$port/main +/unit-19/port-1/status/StartLineTest +get /unit-19/port-1/status/LineTestResults +cd /unit-6/port-1/main set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/testmelting4.txt b/test_cases/integration_tests/keymile/testmelting4.txt index a526c37..4f509dd 100644 --- a/test_cases/integration_tests/keymile/testmelting4.txt +++ b/test_cases/integration_tests/keymile/testmelting4.txt @@ -1,13 +1,9 @@ admin secret -#voiceport -/unit-$voice_card/port-$voice_port/status/StartLineTest -get /unit-$voice_card/port-$voice_port/status/LineTestResults -#else -/unit-$card/port-$port/status/StartMeltMeasurement -get /unit-$card/port-$port/status/MeltResults - -#SUVM6 -cd /unit-$card/port-$port/main +/unit-19/port-1/status/StartLineTest +get /unit-19/port-1/status/LineTestResults +/unit-1/port-1/status/StartMeltMeasurement +get /unit-1/port-1/status/MeltResults +cd /unit-6/port-1/main set AdministrativeStatus up exit \ No newline at end of file From 8f78b8d66e1099090e3893839bc572441a3af1f2 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Tue, 20 Oct 2020 15:38:45 +0200 Subject: [PATCH 260/318] Added more functions to ports --- .../api/schemas/keymile_port_schemas.py | 2 +- .../keymile/keymile_resources/keymile_port.py | 8 +++++ nesi/softbox/api/models/port_models.py | 4 ++- .../unit/port/chan/chanCommandProcessor.py | 2 +- .../root/unit/port/portCommandProcessor.py | 36 +++++++++++++++++++ vendors/KeyMile/baseCommandProcessor.py | 14 ++++++++ 6 files changed, 63 insertions(+), 3 deletions(-) diff --git a/nesi/keymile/api/schemas/keymile_port_schemas.py b/nesi/keymile/api/schemas/keymile_port_schemas.py index 687a495..d10607c 100644 --- a/nesi/keymile/api/schemas/keymile_port_schemas.py +++ b/nesi/keymile/api/schemas/keymile_port_schemas.py @@ -20,6 +20,6 @@ class Meta: 'linetest_state', 'profile1_enable', 'profile1_name', 'profile1_elength', 'profile2_enable', 'profile2_name', 'profile2_elength', 'profile3_enable', 'profile3_name', 'profile3_elength', 'profile4_enable', 'profile4_name', - 'profile_mode') + 'profile_mode', 'mode', 'flow_control') channels = ma.Nested(CpesSchema.CpeSchema, many=True) diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py index 1555ef7..81a248d 100644 --- a/nesi/keymile/keymile_resources/keymile_port.py +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -22,6 +22,8 @@ class KeyMilePort(Port): loopbacktest_state = base.Field('loopbacktest_state') melttest_state = base.Field('melttest_state') linetest_state = base.Field('linetest_state') + mode = base.Field('mode') + flow_control = base.Field('flow_control') profile1_enable = base.Field('profile1_enable') profile1_name = base.Field('profile1_name') profile1_elength = base.Field('profile1_elength') @@ -75,6 +77,12 @@ def set_melttest_state(self, state): def set_linetest_state(self, state): self.update(linetest_state=state) + def set_mode(self, mode): + self.update(mode=mode) + + def set_flow_control(self, ctrl): + self.update(flow_control=ctrl) + class KeyMilePortCollection(PortCollection): """Represent a collection of ports.""" diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 32e0380..6ed09a0 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -316,7 +316,9 @@ class Port(db.Model): loopbacktest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NoTestResult', 'Stopped', 'Interrupted'), default='NoTestResult') melttest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NotTested'), default='NotTested') linetest_state = db.Column(db.Enum('Failed', 'Passed', 'Running', 'NotTested'), default='NotTested') - #profiles + mode = db.Column(db.String(), default='') + flow_control = db.Column(db.String(), default='') + # profiles profile1_enable = db.Column(db.Boolean(), default=False) profile1_name = db.Column(db.String(), default='') profile1_elength = db.Column(db.Integer, default=0) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 147e4d8..fecf4ae 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -113,7 +113,7 @@ def do_createinterface(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name : + elif self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name: # vcc profile and vlan profile vlan_prof, vcc_prof = self._dissect(args, str, str) # TODO: Check if profiles := default or profile names diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index a7a4f50..7ceb588 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -313,5 +313,41 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) + + elif self._validate(args, 'Mode', str) and context['path'].split('/')[-1] == 'cfgm' and "SUE" in \ + card.board_name and self.__name__ == 'port' and card.product == 'ftth': + if '"' in args[1]: + mode = self.args_in_quotes_joiner((args[1],)) + else: + mode, = self._dissect(args, 'Mode', str) + try: + port = self.get_port_component() + port.set_mode(mode) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + + elif self._validate(args, 'Mode', str, str, str) and context['path'].split('/')[-1] == 'cfgm' and "SUE" in \ + card.board_name and self.__name__ == 'port' and card.product == 'ftth': + if '"' in args[1]: + mode = self.args_in_quotes_joiner(args[1:]) + else: + mode, = self._dissect(args, 'Mode', str) + try: + port = self.get_port_component() + port.set_mode(mode) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + + elif self._validate(args, 'FlowControl', str) and context['path'].split('/')[-1] == 'cfgm' and "SUE" in \ + card.board_name and self.__name__ == 'port' and card.product == 'ftth': + ctrl, = self._dissect(args, 'FlowControl', str) + try: + port = self.get_port_component() + port.set_flow_control(ctrl) + except exceptions.SoftboxenError(): + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 672c667..42d3a19 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -541,3 +541,17 @@ def do_exit(self, command, *args, context=None): def _init_access_points(self, context=None): pass # Abstract method not implemented + + def args_in_quotes_joiner(self, args): + saved_args = [] + save = False + for i in range(len(args)): + if args[i].startswith("\""): + save = True + if save: + saved_args.append(args[i]) + if args[i].endswith("\""): + save = False + name = ' '.join(saved_args).replace("\"", "") + + return name From f4c71086a4ab2e50f0ed7619c91d4cfe20cc0dc1 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 21 Oct 2020 08:41:07 +0200 Subject: [PATCH 261/318] Added set service on srvc- --- .../conf/bootstraps/create-keymile-MG2500.sh | 22 ++++++ .../keymile/keymile_resources/keymile_srvc.py | 8 +++ nesi/softbox/api/models/srvc_models.py | 2 + nesi/softbox/api/schemas/srvc_schemas.py | 3 +- .../KeyMile/login/base/get/service_nto1.j2 | 4 +- .../base/get/service_onetoonesingletag.j2 | 4 +- .../root/services/srvcCommandProcessor.py | 68 ++++++++++++------- 7 files changed, 81 insertions(+), 30 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index a7209fa..421825a 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -587,4 +587,26 @@ req='{ "address": "/unit-1/port-1/chan-1/interface-1" }' +srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) + +### 1to1singletag-Service-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "service_type": "1to1singletag", + "svid": 1213, + "address": "/unit-19/control" +}' + +srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) + +### 1to1singletag-Service-2 ### + +# Create a physical port at the network device (admin operation) +req='{ + "service_type": "1to1singletag", + "svid": 187, + "address": "/unit-19/media" +}' + srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) \ No newline at end of file diff --git a/nesi/keymile/keymile_resources/keymile_srvc.py b/nesi/keymile/keymile_resources/keymile_srvc.py index fad2756..d1b7a16 100644 --- a/nesi/keymile/keymile_resources/keymile_srvc.py +++ b/nesi/keymile/keymile_resources/keymile_srvc.py @@ -25,6 +25,14 @@ class KeyMileSrvc(base.Resource): service_type = base.Field('service_type') address = base.Field('address') svid = base.Field('svid') + stag_priority = base.Field('stag_priority') + vlan_handling = base.Field('vlan_handling') + + def set_service(self, address, svid, stag_prio, vlan): + self.update(address=address) + self.update(svid=svid) + self.update(stag_priority=stag_prio) + self.update(vlan_handling=vlan) class KeyMileSrvcCollection(base.ResourceCollection): diff --git a/nesi/softbox/api/models/srvc_models.py b/nesi/softbox/api/models/srvc_models.py index 8e0ec84..c0074a9 100644 --- a/nesi/softbox/api/models/srvc_models.py +++ b/nesi/softbox/api/models/srvc_models.py @@ -21,3 +21,5 @@ class Srvc(db.Model): service_type = db.Column(db.Enum('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls')) address = db.Column(db.String(), default='') svid = db.Column(db.Integer(), default=None) + stag_priority = db.Column(db.Enum('CoS0', 'CoS1', 'CoS2', 'CoS3', 'CoS4', 'CoS5', 'CoS6', 'CoS7'), default=None) + vlan_handling = db.Column(db.Enum('Add', 'Transparent', 'Swap'), default=None) diff --git a/nesi/softbox/api/schemas/srvc_schemas.py b/nesi/softbox/api/schemas/srvc_schemas.py index 482b246..034283f 100644 --- a/nesi/softbox/api/schemas/srvc_schemas.py +++ b/nesi/softbox/api/schemas/srvc_schemas.py @@ -18,7 +18,8 @@ class SrvcSchema(ma.ModelSchema): class Meta: model = Srvc - fields = ('id', 'box', 'box_id', 'name', 'service_type', 'address', 'svid', '_links') + fields = ('id', 'box', 'box_id', 'name', 'service_type', 'address', 'svid', 'stag_priority', 'vlan_handling', + '_links') box = ma.Hyperlinks( {'_links': { diff --git a/templates/KeyMile/login/base/get/service_nto1.j2 b/templates/KeyMile/login/base/get/service_nto1.j2 index edb2127..2a30929 100644 --- a/templates/KeyMile/login/base/get/service_nto1.j2 +++ b/templates/KeyMile/login/base/get/service_nto1.j2 @@ -3,9 +3,9 @@ {{ context.service.address }}{{ context.spacer1 }}\ # Address \ # Specific {{ context.service.svid }}{{ context.spacer2 }}\ # Svid -CoS0 \ # STagPriority +{{ context.service.stag_priority }}{{ context.spacer3 }}\ # STagPriority PPPoE \ # LogonMethod -Add \ # VLANHandling +{{ context.service.vlan_handling }}{{ context.spacer4 }}\ # VLANHandling false \ # SourceFilter false \ # DestinationFilter false \ # SourceIPFilter diff --git a/templates/KeyMile/login/base/get/service_onetoonesingletag.j2 b/templates/KeyMile/login/base/get/service_onetoonesingletag.j2 index be29c7c..1a31a6c 100644 --- a/templates/KeyMile/login/base/get/service_onetoonesingletag.j2 +++ b/templates/KeyMile/login/base/get/service_onetoonesingletag.j2 @@ -3,6 +3,6 @@ {{ context.service.address }}{{ context.spacer1 }}\ # Address \ # Specific {{ context.service.svid }}{{ context.spacer2 }}\ # Svid -CoS0 \ # STagPriority -Add \ # VLANHandling +{{ context.service.stag_priority }}{{ context.spacer3 }}\ # STagPriority +{{ context.service.vlan_handling }}{{ context.spacer4 }}\ # VLANHandling diff --git a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py index 7a9e401..4294e2b 100644 --- a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py @@ -28,36 +28,54 @@ def get_property(self, command, *args, context=None): service_name = 'srvc-' + self.component_id services = self._model.get_srvcs('name', service_name) for s in services: - if s.service_type.lower() == context['ServiceType']: + if s.service_type.lower() == context['ServiceType'] and s.name == service_name: service = s context['service'] = service break scopes = ('login', 'base', 'get') - try: - super().get_property(command, *args, context=context) - except exceptions.CommandExecutionError: - if self._validate((args[0],), 'Service') and context['path'].split('/')[-1] == 'cfgm': - # TODO: Find missing templates, and replace placeholder templates - if service.service_type == '1to1doubletag': - template_name = 'service_onetoonedoubletag' - elif service.service_type == '1to1singletag': - template_name = 'service_onetoonesingletag' - elif service.service_type == 'mcast': - template_name = 'service_mcast' - elif service.service_type == 'nto1': - template_name = 'service_nto1' - elif service.service_type == 'pls': - template_name = 'service_pls' - elif service.service_type == 'tls': - template_name = 'service_tls' - else: - raise exceptions.CommandExecutionError(command=command) - context['spacer1'] = self.create_spacers((67,), (service.address,))[0] * ' ' - context['spacer2'] = self.create_spacers((67,), (service.svid,))[0] * ' ' - text = self._render(template_name, *scopes, context=context) - self._write(text) - + if self._validate((args[0],), 'Service') and context['path'].split('/')[-1] == 'cfgm': + # TODO: Find missing templates, and replace placeholder templates + if service.service_type == '1to1doubletag': + template_name = 'service_onetoonedoubletag' + elif service.service_type == '1to1singletag': + template_name = 'service_onetoonesingletag' + elif service.service_type == 'mcast': + template_name = 'service_mcast' + elif service.service_type == 'nto1': + template_name = 'service_nto1' + elif service.service_type == 'pls': + template_name = 'service_pls' + elif service.service_type == 'tls': + template_name = 'service_tls' else: + raise exceptions.CommandExecutionError(command=command) + context['spacer1'] = self.create_spacers((67,), (service.address,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (service.svid,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (service.stag_priority,))[0] * ' ' + context['spacer4'] = self.create_spacers((67,), (service.vlan_handling,))[0] * ' ' + text = self._render(template_name, *scopes, context=context) + self._write(text) + else: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + + def set(self, command, *args, context=None): + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'Service', str, str, str, str) and context['path'].split('/')[-1] == 'cfgm': + address, svid, stag, vlan = self._dissect(args, 'Service', str, str, str, str) + try: + service_name = 'srvc-' + self.component_id + services = self._model.get_srvcs('name', service_name) + for s in services: + if s.service_type.lower() == context['ServiceType'] and s.name == service_name: + service = s + break + service.set_service(address, int(svid), stag, vlan) + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) From 3c6cab448694dbb3da1760c9f3a3e74bfd61e43c Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 21 Oct 2020 09:01:39 +0200 Subject: [PATCH 262/318] Restructured change_directory and fixed some navigation bugs --- vendors/KeyMile/baseCommandProcessor.py | 89 ++++++++++--------------- 1 file changed, 37 insertions(+), 52 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 42d3a19..7b8d1fd 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -238,6 +238,15 @@ def change_directory(self, path, context=None): context['path'] = '/' subprocessor = self.change_directory(path.lstrip('/'), context=context) elif path.startswith('.'): + if path.startswith('...'): + if '/' in path: + raise exceptions.CommandExecutionError(template='invalid_address_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + else: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if path == '.': return self @@ -305,17 +314,38 @@ def change_directory(self, path, context=None): else: command_processor = components[0].capitalize() + 'CommandProcessor' + def validate_relation(component_type, name): + relations = { + 'root': ('unit', 'mgmtunit', 'fan', 'eoam', 'tdmConnections', 'multicast', 'services'), + 'unit': ('port', 'portgroup', 'logports', 'huntgroup'), + 'mgmtunit': ('mgmtport',), + 'fan': ('alarm',), + 'services': ('packet', 'macaccessctrl'), + 'port': ('chan', 'interface'), + 'portgroup': ('port',), + 'chan': ('vcc', 'interface',), + 'logport': ('interface',), + 'packet': ('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'), + 'subpacket': ('srvc',), + } + + if component_type not in relations[name]: + return False + + return True + + if component_type: + validation = validate_relation(component_type, self.__name__) + else: + validation = validate_relation(components[0], self.__name__) + if validation is False: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if component_type == 'unit': if (self._model.version == '2200' and not 9 <= int(component_id) <= 12) or (self._model.version == '2300' and not 7 <= int(component_id) <= 14) or (self._model.version == '2500' and not 1 <= int(component_id) <= 21): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty# - if self.__name__ != 'root': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'portgroup' or component_type == 'logports' or component_type == 'huntgroup': - if self.__name__ != 'unit': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'port': try: if self.component_id == '11' or self.component_id == '13': @@ -325,58 +355,30 @@ def change_directory(self, path, context=None): except exceptions.InvalidInputError: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - - if self.__name__ != 'unit' and self.__name__ != 'portgroup': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'chan': try: self._model.get_chan('name', self._parent.component_id + '/' + self.component_id + '/' + component_id) except exceptions.InvalidInputError: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - - if self.__name__ != 'port': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'mgmtunit': - if self.__name__ != 'root': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'mgmtport': - if self.__name__ != 'mgmtunit': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'interface': try: self._model.get_interface('name', self._parent.component_id + '/' + self.component_id + '/' + component_id) except exceptions.InvalidInputError: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - - if self.__name__ != 'port' and self.__name__ != 'chan' and self.__name__ != 'logport': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'logport': try: self._model.get_logport('name', self._parent.component_id + '/L/' + component_id) except exceptions.InvalidInputError: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - - if self.__name__ != 'logports': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'vcc': try: self._model.get_interface('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + component_id) except exceptions.InvalidInputError: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - - if self.__name__ != 'chan': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty elif component_type == 'srvc': try: self._model.get_srvc('name', 'srvc-' + component_id) @@ -384,23 +386,6 @@ def change_directory(self, path, context=None): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty - if self.__name__ != 'subpacket': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - - if components[0] in ('packet', 'macAccessCtrl'): - if self.__name__ != 'services': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - if components[0] in ('fan', 'eoam', 'tdmConnections', 'multicast', 'services'): - if self.__name__ != 'root': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - if components[0] in ('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'): - if self.__name__ != 'packet': - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - if components[0] in ('main', 'cfgm', 'fm', 'pm', 'status'): if context['path'].split('/')[-1] in ('main', 'cfgm', 'fm', 'pm', 'status'): raise exceptions.CommandExecutionError(command=None, template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors')) From e4ef8a683866c5f853405a143fbe9226bffb741b Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 21 Oct 2020 09:19:06 +0200 Subject: [PATCH 263/318] Added history in KeyMile script --- .../conf/bootstraps/create-keymile-MG2500.sh | 113 +++++++++++++----- 1 file changed, 80 insertions(+), 33 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 421825a..7a91f28 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -20,6 +20,51 @@ path="`dirname \"$0\"`" . $path/functions.sh + +#--------------------------------------------------------# +# # +# Subrack 0 # +# |---> Unit-1 (adsl) (SUAD2) # +# | |-> Port-1 # +# | | |-> Chan-1 # +# | | |-> Interface-1 # +# | # +# |---> Unit-2 (sdsl) (SUSE1) # +# | |-> Port-1 # +# | |-> Port-2 # +# | |-> LogPorts # +# | | |-> LogPort-2 # +# | # +# |---> Unit-3 (sdsl) (SUSE1) # +# | |-> Port-1 # +# | | |-> Interface-1 # +# | # +# |---> Unit-4 (adsl) (SUAD2) # +# | |-> Port-1 # +# | # +# |---> Unit-5 (vdsl) (SUVM4) # +# | |-> Port-1 # +# | | |-> Chan-1 # +# | # +# |---> Unit-6 (vdsl) (SUVM6) # +# | |-> Port-1 # +# | # +# |---> Unit-7 (ftth) (SUEN3) # +# | |-> Port-1 # +# | # +# |---> Unit-8 (vdsl) (SUVM6) # +# | # +# |---> Unit-11 (mgmt) (COGE1) # +# | |-> Port-1 (mgmt) # +# | # +# |---> Unit-19 (isdn) (isdn) # +# | |-> Port-1 # +# | |-> PortGroup-1 (PSTN) # +# | | |-> Port-1 # +# | |-> PortGroup-2 (ISDN) # +# | | |-> Port-1 # +#--------------------------------------------------------# + # Create a network device (admin operation) req='{ "vendor": "KeyMile", @@ -127,6 +172,41 @@ req='{ subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) +### Nto1-Service-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "service_type": "nto1", + "svid": 123, + "address": "/unit-1/port-1/chan-1/interface-1" +}' + +srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) + +### 1to1singletag-Service-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "service_type": "1to1singletag", + "svid": 1213, + "address": "/unit-19/control" +}' + +srvc_1to1singletag_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) + +### 1to1singletag-Service-2 ### + +# Create a physical port at the network device (admin operation) +req='{ + "service_type": "1to1singletag", + "svid": 187, + "address": "/unit-19/media" +}' + +srvc_1to1singletag_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) + + + ### Subrack 0 ### # Create a physical subrack at the network device (admin operation) @@ -577,36 +657,3 @@ req='{ }' port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) - -### Nto1-Service-1 ### - -# Create a physical port at the network device (admin operation) -req='{ - "service_type": "nto1", - "svid": 123, - "address": "/unit-1/port-1/chan-1/interface-1" -}' - -srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) - -### 1to1singletag-Service-1 ### - -# Create a physical port at the network device (admin operation) -req='{ - "service_type": "1to1singletag", - "svid": 1213, - "address": "/unit-19/control" -}' - -srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) - -### 1to1singletag-Service-2 ### - -# Create a physical port at the network device (admin operation) -req='{ - "service_type": "1to1singletag", - "svid": 187, - "address": "/unit-19/media" -}' - -srvc_nto1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) \ No newline at end of file From ff8cccfdd90a06e3326d54c80556ccb40d4356e7 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Wed, 21 Oct 2020 09:20:05 +0200 Subject: [PATCH 264/318] Corrected Mgmt Card/Mgmt Port management functions --- .../mgmt_port/mgmtportManagementFunctions.py | 466 +++++++----------- .../mgmt_unit/mgmtunitManagementFunctions.py | 257 ++++------ 2 files changed, 263 insertions(+), 460 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py index 9529dba..c0a9d28 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportManagementFunctions.py @@ -1,334 +1,216 @@ main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'AdminAndOperStatus': { - 'Prop': { - 'AdministrativeStatus': 'rw', - 'OperationalStatus': 'r-' - } - } -} - -cfgm = { - 'Multicast': { - 'Prop': { - 'MaxNumberOfMulticastStreams': 'rw', - 'EnableIgmpClassifier': 'rw', - 'AllowStaticStreams': 'rw', - 'EnableFastLeave': 'rw', - 'GroupManagement': 'rw', - 'Bandwidth': 'rw' + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } }, - 'Cmd': ( - 'GetGroupList', - ) - }, - 'Traceability': { - 'Prop': { - 'AgentRemoteId': 'rw' - } - }, - 'Security': { - 'Prop': { - 'ServiceOptions': 'rw', - 'MaxNumberOfMac': 'rw' - } - }, - 'AccessControl': { - 'Prop': { - 'ClassificationKey': 'rw', - 'MAT': 'rw' - } - }, - 'RateLimiter': { - 'Prop': { - 'RateLimiting': 'rw', - 'RateLimitingCoS': 'rw' - } - }, - 'Qos': { - 'Prop': { - 'WfqProfile': 'rw' - } - }, - 'Wire': { - 'Prop': { - 'MeltConfiguration': 'rw' - } - }, - 'Profiles': { - 'Prop': { - 'PortProfiles': 'rw' - } - }, - 'Misc': { - 'Prop': { - 'SpecificDPBO': 'rw', - 'SpecificUPBO': 'rw' - } - } -} - -fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' + 'AdminAndOperStatus': { + 'Prop': { + 'AdministrativeStatus': 'rw', + 'OperationalStatus': 'r-' + } }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' + 'SFP': { + 'Prop': { + 'EquipmentInventory': 'r-' + } } } -} -pm = { - 'PerformanceMonitoring': { - 'Cmd': ( - 'UserCounter', - 'GetHistory15min', - 'GetHistory24h', - 'GetAlarm15min', - 'GetAlarm24hRecursive', - 'ResetUserCounter', - 'ResetAlarm15min', - 'ResetAlarm24h' - ) - }, - 'UserCounter': { - 'Prop': { - 'UserCounterDisplayMode': 'rw', - 'UserCounterTable': 'r-' - }, - 'Cmd': ( - 'UserCounterReset', - ) - }, - 'History15min': { - 'Prop': { - 'History15minDisplayMode': 'rw', - 'History15minTable': 'r-' - } - }, - 'History24h': { - 'Prop': { - 'History24hDisplayMode': 'rw', - 'History24hTable': 'r-' - } - }, - 'Alarm15min': { - 'Prop': { - 'Alarm15minDisplayMode': 'rw', - 'Alarm15minTable': 'r-' - }, - 'Cmd': ( - 'Alarm15minReset', - ) - }, - 'Alarm24h': { - 'Prop': { - 'Alarm24hDisplayMode': 'rw', - 'Alarm24hTable': 'r-' +cfgm = { + 'PortMode': { + 'Prop': { + 'PortMode': 'rw', + 'Redundancy': 'rw', + 'PortVlan': 'rw', + 'MTUSize': 'rw' + } }, - 'Cmd': ( - 'Alarm24hReset', - ) - } -} - -status = { - 'General': { - 'Prop': { - 'Standard': 'r-', - 'PowerMgmStatus': 'r-', - 'Vdsl2Parameters': 'r-', - 'EstUPBOElectricalLength': 'r-', - 'LineRate': 'r-', - 'LineSnrMargin': 'r-', - 'AttainableNetDataRate': 'r-', - 'AttainableRate': 'r-', - 'OutputPower': 'r-', - 'BandStatus': 'r-' - } - }, - 'statistics': { - 'Prop': { - 'counters': 'r-', - 'PolicingCounters': 'r-' + 'Rstp': { + 'Prop': { + 'Rstp': 'rw', + 'RstpParams': 'rw' + } }, - 'Cmd': ( - 'ResetPortCounters', - ) - }, - 'Nto1MacAccessDynamicList': { - 'Prop': { - 'UnicastList': 'r-' - } - }, - 'HostPortStatistics': { - 'GeneralCounters': { + 'VlanList': { 'Prop': { - 'GeneralList': 'r-' + 'ManagementVlan': 'r-', + 'ListType': 'rw', + 'VlanList': 'rw' }, 'Cmd': ( - 'ResetGeneralCounters', + 'FlushVlanList', ) }, - 'ProtocolCounters': { - 'IgmpCounters': { - 'Prop': { - 'IgmpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetIgmpCounters', - ) - }, - 'DhcpCounters': { - 'Prop': { - 'DhcpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetDhcpCounters', - ) - }, - 'ArpCounters': { - 'Prop': { - 'ArpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetArpCounters', - ) - }, - 'PPPoECounters': { - 'Prop': { - 'PPPoEProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetPPPoECounters', - ) - }, - 'UnknownSourceMACCounters': { - 'Prop': { - 'UnknownSrcMACProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetUnknownSrcMACCounters', - ) - }, + 'QoS': { + 'Prop': { + 'SchedulingProfileName': 'rw' + } }, - }, - 'TLSMacForwardingList': { - 'Prop': { - 'MacForwardingList': 'r-' + 'Multicast': { + 'Prop': { + 'EnableIgmpClassifier': 'rw', + 'AllowStaticStreams': 'rw', + 'MulticastPortMode': 'rw' + } }, - 'Cmd': ( - 'FlushMacForwardingList', - ) - }, - '1to1MacForwardingList': { - 'Prop': { - 'One2OneMacForwardingList': 'r-' - } - }, - 'Qos': { - 'Prop': { - 'wfqueues': 'r-' - } - }, - 'Multicast': { - 'stream': { - 'Dynamic': { - 'Prop': { - 'ActiveStreams': 'r-' - }, - 'Cmd': ( - 'ClearActiveStreams', - ) - }, - 'Static': { - 'Prop': { - 'StaticStreams': 'r-' - } - }, + 'LinkAggregation': { + 'Prop': { + 'LinkAggregation': 'rw' + } }, - - 'Vlan': { + 'PHY': { + 'Prop': { + 'PhyMode': 'rw', + 'PhyFlowControl': 'rw' + } + }, + 'Eoam': { + 'Prop': { + 'NetworkNetworkInterface': 'rw' + } + }, + 'PriorityMapping': { 'Prop': { - 'AttachedVlans': 'r-' + 'DSCPTo802Dot1qTxPriorityMapping': 'rw' } }, - 'Preview': { + 'Mirroring': { + 'Prop': { + 'MirrorPortList': 'rw' + } + } + } + +fm = { + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, 'Cmd': ( - 'ResetPreviewSettings', + 'Acknowledge', ) }, - 'Bandwidth': { + 'Configuration': { 'Prop': { - 'bandwidthStatus': 'r-' + 'AlarmConfiguration': 'rw' } - }, - }, - 'LineTest': { - 'MELT': { + } + } + +pm = { + 'UserCounter': { 'Prop': { - 'MeltResults': 'r-' + 'UserCounterDisplayMode': 'rw', + 'UserCounterTable': 'r-' }, 'Cmd': ( - 'StartMeltMeasurement', + 'UserCounterReset', ) }, - 'Delt': { + 'History15min': { + 'Prop': { + 'History15minDisplayMode': 'rw', + 'History15minTable': 'r-' + } + }, + 'History24h': { + 'Prop': { + 'History24hDisplayMode': 'rw', + 'History24hTable': 'r-' + } + }, + 'Alarm15min': { 'Prop': { - 'DeltMeasurementStatus': 'r-', - 'RecordedDeltMeasurements': 'r-' + 'Alarm15minDisplayMode': 'rw', + 'Alarm15minTable': 'r-' }, 'Cmd': ( - 'StartDeltMeasurement', + 'Alarm15minReset', ) }, - 'Selt': { + 'Alarm24h': { 'Prop': { - 'SeltMeasurementStatus': 'r-', - 'RecordedSeltMeasurements': 'r-', - 'CableType': 'rw', - 'BandplanProfile': 'rw', - 'TargetSnrm': 'rw' + 'Alarm24hDisplayMode': 'rw', + 'Alarm24hTable': 'r-' }, 'Cmd': ( - 'StartSeltMeasurement', + 'Alarm24hReset', ) }, - }, - 'Defects': { - 'Prop': { - 'Defects': 'r-' - } - }, - 'LineInventory': { - 'Prop': { - 'VendorId': 'r-' - } - }, - 'Maintenance': { - 'Prop': { - 'DslOperationStatus': 'r-' + 'PerformanceMonitoring': { + 'Cmd': ( + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' + ) } - }, - 'Subcarrier': { - 'Cmd': ( - 'ShowBitAllocation', - ) - }, - 'RfiBands': { - 'Prop': { - 'NotchStatus': 'r-' + } + +status = { + 'PortMode': { + 'Prop': { + 'DefaultConfigEnabled': 'r-' + } + }, + 'MAC': { + 'Prop': { + 'PortMacStatus': 'r-' + } + }, + 'Phy': { + 'Prop': { + 'PortLinkStatus': 'r-' + } + }, + 'Rstp': { + 'Prop': { + 'PortRstpStatus': 'r-' + } + }, + 'LinkAggregation': { + 'Prop': { + 'Status': 'r-' + } + }, + 'Ddm': { + 'Prop': { + 'DdmStatus': 'r-' + } + }, + 'QoS': { + 'Prop': { + 'QosStatus': 'r-' + } + }, + 'Multicast': { + 'stream': { + 'Dynamic': { + 'Prop': { + 'ActiveStreams': 'r-' + }, + 'Cmd': ( + 'ClearActiveStreams', + ) + }, + 'Static': { + 'Prop': { + 'StaticStreams': 'r-' + } + }, + }, + + 'Vlan': { + 'Prop': { + 'AttachedVlans': 'r-' + } + + } } } -} diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py index 0a5adbd..e7a7937 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitManagementFunctions.py @@ -1,194 +1,115 @@ main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - }, - 'Equipment': { - 'Prop': { - 'AssignmentStatus': 'r-', - 'CurrentStatus': 'r-' + 'General': { + 'Prop': { + 'Labels': 'rw', + 'AlarmStatus': 'r-' + } }, - 'Cmd': ( - 'Assign', - 'Unassign', - 'Restart', - 'StopInBoot' - ) - }, - 'Inventory': { - 'Prop': { - 'EquipmentInventory': 'r-' - } - }, - 'Logbooks': { - 'Cmd': ( - 'GetAlarmLogbook', - 'GetEventLogbook', - 'GetEquipmentLogbook' - ) - }, - 'Software': { - 'Prop': { - 'DiskSpace': 'r-', - 'SoftwareOnUnit': 'r-', - 'HardwareAndSoftware': 'r-', - 'Status': 'r-', - 'Configuration': 'rw' + 'Equipment': { + 'Prop': { + 'AssignmentStatus': 'r-', + 'CurrentStatus': 'r-' + }, + 'Cmd': ( + 'Assign', + 'Unassign', + 'Restart', + 'StopInBoot' + ) + }, + 'Inventory': { + 'Prop': { + 'EquipmentInventory': 'r-' + } + }, + 'Logbooks': { + 'Cmd': ( + 'GetAlarmLogbook', + 'GetEventLogbook', + 'GetEquipmentLogbook' + ) }, - 'Cmd': ( - 'DeleteSoftware', - 'StartSoftware' - ), - 'File': { - 'Software': 'rw' + 'Software': { + 'Prop': { + 'DiskSpace': 'r-', + 'SoftwareOnUnit': 'r-', + 'HardwareAndSoftware': 'r-', + 'Status': 'r-', + 'Configuration': 'rw' + }, + 'Cmd': ( + 'DeleteSoftware', + 'StartSoftware' + ), + 'File': { + 'Software': 'rw' + } } } -} cfgm = { - 'Vlan': { - 'Prop': { - 'VlanCosTable': 'r-' - } - }, - 'Security': { - 'Prop': { - 'filtering': 'rw', - 'EoamMode': 'rw' - } - }, - 'Logon': { - 'Prop': { - 'LogonOptions': 'rw', - 'OneToOneOptions': 'rw' - } - }, - 'Mac': { - 'Prop': { - 'MacServiceBased': 'rw' - } - }, - 'HostPort': { - 'Prop': { - 'PolicerProfile': 'rw', - 'TrunkPolicerProfile': 'rw', - 'ProtRateLimiter': 'rw' - } - }, - 'QoS': { - 'Prop': { - 'ColorMarking': 'rw' - } - }, - 'Wire': { - 'General': { + 'Filter': { 'Prop': { - 'MeltConfiguration': 'rw' + 'BroadcastFilter': 'rw' } }, - 'Thresholds': { + 'PriorityMapping': { 'Prop': { - 'MeltAlarmThresholds': 'rw' + 'DSCPTo802Dot1qPriorityMapping': 'rw' + } + }, + 'PacketBuffer': { + 'Prop': { + 'PacketBufferProfileName': 'rw' } } } -} fm = { - 'Status': { - 'Prop': { - 'AlarmStatus': 'r-' + 'Status': { + 'Prop': { + 'AlarmStatus': 'r-' + }, + 'Cmd': ( + 'Acknowledge', + ) }, - 'Cmd': ( - 'Acknowledge', - ) - }, - 'Configuration': { - 'Prop': { - 'AlarmConfiguration': 'rw' + 'Configuration': { + 'Prop': { + 'AlarmConfiguration': 'rw' + } } } -} -status = { - 'MacAllocationTable': { - 'Prop': { - 'MacAllocationTableEntries': 'r-' - } - }, - 'SwitchPort': { - 'Prop': { - 'Mac': 'r-', - 'MacStatus': 'r-' - } - }, - 'HostPortStatistics': { - 'GeneralCounters': { - 'Prop': { - 'GeneralList': 'r-' - }, +pm = { + 'PerformanceMonitoring': { 'Cmd': ( - 'ResetGeneralCounters', + 'UserCounter', + 'GetHistory15min', + 'GetHistory24h', + 'GetAlarm15min', + 'GetAlarm24hRecursive', + 'ResetUserCounter', + 'ResetAlarm15min', + 'ResetAlarm24h' ) + } + } + +status = { + 'QoS': { + 'Prop': { + 'QosPriorityMappingStatus': 'r-' + } }, - 'ProtocolCounters': { - 'IgmpCounters': { - 'Prop': { - 'IgmpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetIgmpCounters', - ) - }, - 'DhcpCounters': { - 'Prop': { - 'DhcpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetDhcpCounters', - ) - }, - 'ArpCounters': { - 'Prop': { - 'ArpProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetArpCounters', - ) - }, - 'PPPoECounters': { - 'Prop': { - 'PPPoEProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetPPPoECounters', - ) - }, - 'UnknownSourceMACCounters': { - 'Prop': { - 'UnknownSrcMACProtocolList': 'r-' - }, - 'Cmd': ( - 'ResetUnknownSrcMACCounters', - ) - }, + 'PacketBuffer': { + 'Prop': { + 'PacketBufferStatus': 'r-' + } }, - }, - 'BufferManagement': { - 'Prop': { - 'BufferMgmtStatus': 'r-' + 'Redundancy': { + 'Prop': { + 'Status': 'r-' + } } - }, - 'Maintenance': { - 'Prop': { - 'MeltLineTestStatus': 'r-', - 'SearchTone': 'rw' - }, - 'Cmd': ( - 'StartMeltAll', - 'StopMeltAll' - ) } -} From c0dad1e9c9ba2cbad09c16761ba798aa7f5f548d Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 21 Oct 2020 10:00:30 +0200 Subject: [PATCH 265/318] Fixed a navigation issue --- vendors/KeyMile/baseCommandProcessor.py | 28 +++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 7b8d1fd..5817686 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -23,9 +23,14 @@ class BaseCommandProcessor(base.CommandProcessor): component_id = None + component_name = None + def set_component_id(self, id): self.component_id = id + def set_component_name(self, name): + self.component_name = name + main = {} cfgm = {} @@ -324,23 +329,38 @@ def validate_relation(component_type, name): 'port': ('chan', 'interface'), 'portgroup': ('port',), 'chan': ('vcc', 'interface',), + 'logports': ('logport',), 'logport': ('interface',), 'packet': ('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'), 'subpacket': ('srvc',), } - if component_type not in relations[name]: + try: + if component_type not in relations[name]: + return False + except KeyError: + return False + + return True + + def check_for_component(component_type, component_name): + try: + self._model.get_ + component_type('name', component_name) + except exceptions.InvalidInputError: return False return True if component_type: validation = validate_relation(component_type, self.__name__) + #if validation: + #validation = check_for_component(component_type, self.component_name + '/' + component_id) else: validation = validate_relation(components[0], self.__name__) - if validation is False: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty + if components[0] not in ('main', 'cfgm', 'fm', 'pm', 'status'): + if validation is False: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty if component_type == 'unit': if (self._model.version == '2200' and not 9 <= int(component_id) <= 12) or (self._model.version == '2300' and not 7 <= int(component_id) <= 14) or (self._model.version == '2500' and not 1 <= int(component_id) <= 21): From 9ce8c95388992aa6fb35a7a1f1eb84509c9476f0 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 21 Oct 2020 12:39:38 +0200 Subject: [PATCH 266/318] Further restructuring of change_directory --- vendors/KeyMile/baseCommandProcessor.py | 112 +++++++++++------------- 1 file changed, 50 insertions(+), 62 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 5817686..00baae4 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -31,6 +31,26 @@ def set_component_id(self, id): def set_component_name(self, name): self.component_name = name + def get_component(self, component_type, component_name): + if component_type == 'unit': + self._model.get_card('name', component_name) + if component_type == 'mgmtunit': + self._model.get_mgmt_card('name', component_name) + elif component_type == 'port': + self._model.get_port('name', component_name) + elif component_type == 'chan': + self._model.get_chan('name', component_name) + elif component_type == 'mgmtport': + self._model.get_mgmt_port('name', component_name) + elif component_type == 'interface' or component_type == 'vcc': + self._model.get_interface('name', component_name) + elif component_type == 'logport': + self._model.get_logport('name', component_name) + elif component_type == 'srvc': + self._model.get_srvc('name', component_name) + elif component_type == 'portgroupport': + self._model.get_portgroupport('name', component_name) + main = {} cfgm = {} @@ -232,11 +252,6 @@ def change_directory(self, path, context=None): context['path'] = '/' return self - if 'unit-' not in components[0] and components[0] not in ( - 'eoam', 'fan', 'multicast', 'services', 'tdmConnection', 'main', 'cfgm', 'fm', 'pm', 'status'): - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - if self.__name__ != 'root': subprocessor = self._parent.change_directory(path, context=context) else: @@ -321,13 +336,13 @@ def change_directory(self, path, context=None): def validate_relation(component_type, name): relations = { - 'root': ('unit', 'mgmtunit', 'fan', 'eoam', 'tdmConnections', 'multicast', 'services'), + 'root': ('unit', 'mgmtunit', 'fan', 'eoam', 'tdmconnections', 'multicast', 'services'), 'unit': ('port', 'portgroup', 'logports', 'huntgroup'), 'mgmtunit': ('mgmtport',), 'fan': ('alarm',), 'services': ('packet', 'macaccessctrl'), 'port': ('chan', 'interface'), - 'portgroup': ('port',), + 'portgroup': ('portgroupport',), 'chan': ('vcc', 'interface',), 'logports': ('logport',), 'logport': ('interface',), @@ -344,8 +359,11 @@ def validate_relation(component_type, name): return True def check_for_component(component_type, component_name): + if component_type in ('portgroup', 'unit', 'mgmtunit'): + return True + try: - self._model.get_ + component_type('name', component_name) + self.get_component(component_type, component_name) except exceptions.InvalidInputError: return False @@ -353,8 +371,16 @@ def check_for_component(component_type, component_name): if component_type: validation = validate_relation(component_type, self.__name__) - #if validation: - #validation = check_for_component(component_type, self.component_name + '/' + component_id) + if validation: + if self.component_name: + if component_type == 'srvc': + validation = check_for_component(component_type, components[0]) + elif component_type == 'logport': + validation = check_for_component(component_type, self.component_name + '/L/' + component_id) + else: + validation = check_for_component(component_type, self.component_name + '/' + component_id) + else: + validation = check_for_component(component_type, component_id) else: validation = validate_relation(components[0], self.__name__) if components[0] not in ('main', 'cfgm', 'fm', 'pm', 'status'): @@ -366,63 +392,12 @@ def check_for_component(component_type, component_name): if (self._model.version == '2200' and not 9 <= int(component_id) <= 12) or (self._model.version == '2300' and not 7 <= int(component_id) <= 14) or (self._model.version == '2500' and not 1 <= int(component_id) <= 21): raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty# - elif component_type == 'port': - try: - if self.component_id == '11' or self.component_id == '13': - self._model.get_mgmt_port('name', self.component_id + '/' + component_id) - else: - self._model.get_port('name', self.component_id + '/' + component_id) - except exceptions.InvalidInputError: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'chan': - try: - self._model.get_chan('name', self._parent.component_id + '/' + self.component_id + '/' + component_id) - except exceptions.InvalidInputError: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'interface': - try: - self._model.get_interface('name', self._parent.component_id + '/' + self.component_id + '/' + component_id) - except exceptions.InvalidInputError: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'logport': - try: - self._model.get_logport('name', self._parent.component_id + '/L/' + component_id) - except exceptions.InvalidInputError: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'vcc': - try: - self._model.get_interface('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + component_id) - except exceptions.InvalidInputError: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty - elif component_type == 'srvc': - try: - self._model.get_srvc('name', 'srvc-' + component_id) - except exceptions.InvalidInputError: - raise exceptions.CommandExecutionError(command=None, template=None, - template_scopes=()) # TODO: fix exception to not require all fields as empty if components[0] in ('main', 'cfgm', 'fm', 'pm', 'status'): if context['path'].split('/')[-1] in ('main', 'cfgm', 'fm', 'pm', 'status'): raise exceptions.CommandExecutionError(command=None, template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors')) - mf_layers = {} - if components[0] == 'status': - mf_layers = self.status - elif components[0] == 'cfgm': - mf_layers = self.cfgm - elif components[0] == 'fm': - mf_layers = self.fm - elif components[0] == 'pm': - mf_layers = self.pm - elif components[0] == 'main': - mf_layers = self.main - - if len(mf_layers) == 0: + if components[0] not in self.management_functions: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty @@ -465,6 +440,19 @@ def check_for_component(component_type, component_name): if component_id is not None: subprocessor.set_component_id(component_id) + if self.component_name: + if components[0] == 'logports': + component_name = self.component_name + '/L' + elif component_type == 'portgroup': + component_name = self.component_name + '/G' + component_id + elif component_type == 'srvc': + component_name = 'srvc' + component_id + else: + component_name = self.component_name + '/' + component_id + subprocessor.set_component_name(component_name) + else: + subprocessor.set_component_name(component_id) + if context['path'] == '/': new_path = components[0] else: From d19587236a0d0b78ebb802e4701b78bd4e10a3ff Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 21 Oct 2020 12:55:21 +0200 Subject: [PATCH 267/318] Refactored integration tests and fixed small bugs --- .../conf/bootstraps/create-keymile-MG2500.sh | 13 ++++- bootup/restapi.sh | 2 +- nesi/softbox/api/views/interface_views.py | 4 ++ .../integration_tests/keymile/backup.txt | 2 +- .../integration_tests/keymile/getDslam4.txt | 2 +- .../keymile/getInventory2.txt | 2 +- .../integration_tests/keymile/getIpsx7.txt | 2 +- .../keymile/getMonitoring3.txt | 2 +- .../integration_tests/keymile/getState1.txt | 2 +- .../keymile/getSubscriber6.txt | 2 +- .../integration_tests/keymile/getVoice5.txt | 2 +- .../keymile/setChannelProfile14.txt | 2 +- .../keymile/setDslProfile8.txt | 2 +- .../keymile/setInterface16.txt | 2 +- .../integration_tests/keymile/setIpAddr6.txt | 8 +-- .../keymile/setPortProfile13.txt | 2 +- .../keymile/setSIPDomain12.txt | 2 +- .../integration_tests/keymile/setTraffic1.txt | 2 +- .../integration_tests/keymile/setVCC15.txt | 2 +- .../integration_tests/keymile/setconfDsl2.txt | 7 ++- .../keymile/setconfVoice9.txt | 3 +- .../keymile/setdeconfVoicePort11.txt | 2 +- .../keymile/setdeconfVoicePort17.txt | 2 +- .../keymile/setportaktiv4.txt | 3 +- .../keymile/setportdeactiv5.txt | 2 +- .../keymile/setunconfDsl3.txt | 4 +- .../keymile/testLoopback3.txt | 2 +- .../keymile/testVoicePort2.txt | 2 +- .../keymile/testmelting4.txt | 2 +- test_cases/unit_tests/keymile/test_keymile.py | 54 ++++++++++++++++--- .../root/unit/port/portCommandProcessor.py | 23 ++++---- .../root/unit/unitCommandProcessor.py | 5 +- 32 files changed, 109 insertions(+), 59 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 7a91f28..199f2e4 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -205,7 +205,7 @@ req='{ srvc_1to1singletag_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/srvcs) - +#################################################################################################################### ### Subrack 0 ### @@ -323,7 +323,7 @@ req='{ port_2_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) -### LogPort 1 ### +### LogPort-2 ### # Create a logical logport object at the network device (admin operation) req='{ @@ -334,6 +334,15 @@ req='{ logport_2_l_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/logports) +### Interface-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "logport_id": '$logport_2_l_2' +}' + +interface_2_l_2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) + ### Unit-3 ### # Create a physical card at the network device (admin operation) diff --git a/bootup/restapi.sh b/bootup/restapi.sh index 7071288..6d8dd93 100755 --- a/bootup/restapi.sh +++ b/bootup/restapi.sh @@ -191,7 +191,7 @@ if [ $huawei_api = "yes" ]; then bash bootup/conf/bootstraps/create-huawei-5623.sh fi if [ $keymile_api = "yes" ]; then - bash bootup/conf/bootstraps/create-keymile-MG2200.sh #work_in_progress + bash bootup/conf/bootstraps/create-keymile-MG2500.sh fi if [ $edgecore_api = "yes" ]; then bash bootup/conf/bootstraps/create-alcatel-7360.sh #work_in_progress diff --git a/nesi/softbox/api/views/interface_views.py b/nesi/softbox/api/views/interface_views.py index 9987f5a..74159f2 100644 --- a/nesi/softbox/api/views/interface_views.py +++ b/nesi/softbox/api/views/interface_views.py @@ -13,6 +13,7 @@ from .base_views import * from ..models.port_models import Port from ..models.channel_models import Channel +from ..models.logport_models import LogPort from ..schemas.interface_schemas import * PREFIX = '/nesi/v1' @@ -46,6 +47,9 @@ def new_interface(box_id): elif 'chan_id' in req: channel = json.loads(show_component(Channel, box_id, req['chan_id']).data.decode('utf-8')) req['name'] = channel['name'] + "/" + str(len(channel['interfaces']) + 1) + elif 'logport_id' in req: + logport = json.loads(show_component(LogPort, box_id, req['logport_id']).data.decode('utf-8')) + req['name'] = logport['name'] + "/" + str(len(logport['interfaces']) + 1) else: raise exceptions.Forbidden('can not have port and channel as parent') response = new_component(InterfaceSchema(), Interface, req, box_id) diff --git a/test_cases/integration_tests/keymile/backup.txt b/test_cases/integration_tests/keymile/backup.txt index 6f999b9..5db5c11 100644 --- a/test_cases/integration_tests/keymile/backup.txt +++ b/test_cases/integration_tests/keymile/backup.txt @@ -1,3 +1,3 @@ -admin +manager secret exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getDslam4.txt b/test_cases/integration_tests/keymile/getDslam4.txt index a36c092..45ada2c 100644 --- a/test_cases/integration_tests/keymile/getDslam4.txt +++ b/test_cases/integration_tests/keymile/getDslam4.txt @@ -1,4 +1,4 @@ -admin +manager secret ls exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getInventory2.txt b/test_cases/integration_tests/keymile/getInventory2.txt index 16f77b4..27a0277 100644 --- a/test_cases/integration_tests/keymile/getInventory2.txt +++ b/test_cases/integration_tests/keymile/getInventory2.txt @@ -1,4 +1,4 @@ -admin +manager secret ls cd /services/packet/nto1/ diff --git a/test_cases/integration_tests/keymile/getIpsx7.txt b/test_cases/integration_tests/keymile/getIpsx7.txt index dead751..6537d4b 100644 --- a/test_cases/integration_tests/keymile/getIpsx7.txt +++ b/test_cases/integration_tests/keymile/getIpsx7.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-19/status get SubscriberList diff --git a/test_cases/integration_tests/keymile/getMonitoring3.txt b/test_cases/integration_tests/keymile/getMonitoring3.txt index e4259f3..eaecda9 100644 --- a/test_cases/integration_tests/keymile/getMonitoring3.txt +++ b/test_cases/integration_tests/keymile/getMonitoring3.txt @@ -1,4 +1,4 @@ -admin +manager secret ls cd status diff --git a/test_cases/integration_tests/keymile/getState1.txt b/test_cases/integration_tests/keymile/getState1.txt index 2c5d8b1..542cbd6 100644 --- a/test_cases/integration_tests/keymile/getState1.txt +++ b/test_cases/integration_tests/keymile/getState1.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-1/port-1/status get AttainableRate diff --git a/test_cases/integration_tests/keymile/getSubscriber6.txt b/test_cases/integration_tests/keymile/getSubscriber6.txt index 1a0f1b4..601fc6a 100644 --- a/test_cases/integration_tests/keymile/getSubscriber6.txt +++ b/test_cases/integration_tests/keymile/getSubscriber6.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-19/portgroup-1/port-1/status get SubscriberList diff --git a/test_cases/integration_tests/keymile/getVoice5.txt b/test_cases/integration_tests/keymile/getVoice5.txt index e61689a..0f51655 100644 --- a/test_cases/integration_tests/keymile/getVoice5.txt +++ b/test_cases/integration_tests/keymile/getVoice5.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-19/portgroup-1/port-1/cfgm get pstnport diff --git a/test_cases/integration_tests/keymile/setChannelProfile14.txt b/test_cases/integration_tests/keymile/setChannelProfile14.txt index 00530d5..5135d50 100644 --- a/test_cases/integration_tests/keymile/setChannelProfile14.txt +++ b/test_cases/integration_tests/keymile/setChannelProfile14.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-5/port-1/chan-1/cfgm set chanprofile rofile diff --git a/test_cases/integration_tests/keymile/setDslProfile8.txt b/test_cases/integration_tests/keymile/setDslProfile8.txt index 6f999b9..5db5c11 100644 --- a/test_cases/integration_tests/keymile/setDslProfile8.txt +++ b/test_cases/integration_tests/keymile/setDslProfile8.txt @@ -1,3 +1,3 @@ -admin +manager secret exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setInterface16.txt b/test_cases/integration_tests/keymile/setInterface16.txt index e719a80..dc0e318 100644 --- a/test_cases/integration_tests/keymile/setInterface16.txt +++ b/test_cases/integration_tests/keymile/setInterface16.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-2/logports/logport-2/cfgm CreateInterface default VCC_1_100 diff --git a/test_cases/integration_tests/keymile/setIpAddr6.txt b/test_cases/integration_tests/keymile/setIpAddr6.txt index ec96fcd..1a31d6d 100644 --- a/test_cases/integration_tests/keymile/setIpAddr6.txt +++ b/test_cases/integration_tests/keymile/setIpAddr6.txt @@ -1,15 +1,15 @@ -admin +manager secret cd /services/packet/1to1SingleTag/srvc-1/cfgm -set Service /unit-19/control {$input->vlan_voice_new} CoS0 Add +set Service /unit-19/control 11 CoS0 Add cd /services/packet/1to1SingleTag/srvc-2/cfgm -set Service /unit-19/media {$input->vlan_voice_new} CoS0 Add +set Service /unit-19/media 1 CoS0 Add cd /unit-19/cfgm set Ip 11.1.1.1 155.255.255.0 2.3.3.3 cd /cfgm save cd /unit-19/main restart -admin +manager secret exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setPortProfile13.txt b/test_cases/integration_tests/keymile/setPortProfile13.txt index 6ee1f57..0b30451 100644 --- a/test_cases/integration_tests/keymile/setPortProfile13.txt +++ b/test_cases/integration_tests/keymile/setPortProfile13.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-6/port-1/cfgm set portprofiles true default 0 false default 0 false default 0 true default Priority diff --git a/test_cases/integration_tests/keymile/setSIPDomain12.txt b/test_cases/integration_tests/keymile/setSIPDomain12.txt index fd572f6..a973089 100644 --- a/test_cases/integration_tests/keymile/setSIPDomain12.txt +++ b/test_cases/integration_tests/keymile/setSIPDomain12.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-19/cfgm get Sip diff --git a/test_cases/integration_tests/keymile/setTraffic1.txt b/test_cases/integration_tests/keymile/setTraffic1.txt index bcaee65..0f61dff 100644 --- a/test_cases/integration_tests/keymile/setTraffic1.txt +++ b/test_cases/integration_tests/keymile/setTraffic1.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-7 ls diff --git a/test_cases/integration_tests/keymile/setVCC15.txt b/test_cases/integration_tests/keymile/setVCC15.txt index dfc9f0b..2000864 100644 --- a/test_cases/integration_tests/keymile/setVCC15.txt +++ b/test_cases/integration_tests/keymile/setVCC15.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-1/port-1/chan-1/cfgm CreateVcc default default diff --git a/test_cases/integration_tests/keymile/setconfDsl2.txt b/test_cases/integration_tests/keymile/setconfDsl2.txt index 61e065d..70dd24b 100644 --- a/test_cases/integration_tests/keymile/setconfDsl2.txt +++ b/test_cases/integration_tests/keymile/setconfDsl2.txt @@ -1,6 +1,5 @@ -admin +manager secret -#adsl cd /unit-1/port-1/main Set Labels "umlctId)" "arrierId" "" set AdministrativeStatus up @@ -12,8 +11,8 @@ Set Labels "ctId" "d" "" set AdministrativeStatus up cd /unit-2/logports/cfgm create port-1 -cd /unit-$card/logports/logport-1/cfgm +cd /unit-2/logports/logport-1/cfgm CreateInterface name -cd /unit-$card/logports/logport-1/main +cd /unit-2/logports/logport-1/main set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfVoice9.txt b/test_cases/integration_tests/keymile/setconfVoice9.txt index 6c4c2fe..c25801f 100644 --- a/test_cases/integration_tests/keymile/setconfVoice9.txt +++ b/test_cases/integration_tests/keymile/setconfVoice9.txt @@ -1,6 +1,5 @@ -admin +manager secret -#analog cd /unit-19/portgroup-1/port-1/cfgm set pstnport true 11 true false none none none none none cd /unit-19/portgroup-1/port-1/main diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt index c5dc42a..33b5824 100644 --- a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-19/portgroup-1/port-1/cfgm get pstnport diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt index 9099c38..9b41b86 100644 --- a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-$card/port-$port/main set AdministrativeStatus down diff --git a/test_cases/integration_tests/keymile/setportaktiv4.txt b/test_cases/integration_tests/keymile/setportaktiv4.txt index f538660..4f2f968 100644 --- a/test_cases/integration_tests/keymile/setportaktiv4.txt +++ b/test_cases/integration_tests/keymile/setportaktiv4.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-1/port-1/main set AdministrativeStatus up @@ -6,7 +6,6 @@ cd /unit-5/port-1/main set AdministrativeStatus up cd /unit-7/port-1/main set AdministrativeStatus up -#sdsl cd /unit-2/logports/logport-2/main set AdministrativeStatus up exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setportdeactiv5.txt b/test_cases/integration_tests/keymile/setportdeactiv5.txt index 88ca770..79b499f 100644 --- a/test_cases/integration_tests/keymile/setportdeactiv5.txt +++ b/test_cases/integration_tests/keymile/setportdeactiv5.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-1/port-1/main set AdministrativeStatus down diff --git a/test_cases/integration_tests/keymile/setunconfDsl3.txt b/test_cases/integration_tests/keymile/setunconfDsl3.txt index 5eb92fd..c8406f4 100644 --- a/test_cases/integration_tests/keymile/setunconfDsl3.txt +++ b/test_cases/integration_tests/keymile/setunconfDsl3.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-1/port-1/main set AdministrativeStatus down @@ -6,11 +6,9 @@ Set Labels "" "" "" cd /unit-5/port-1/main set AdministrativeStatus down Set Labels "" "" "" -#ftth cd /unit-7/port-1/main set AdministrativeStatus down Set Labels "" "" "" -#sdsl cd /unit-2/logports/logport-2/main set AdministrativeStatus down Set Labels "" "" "" diff --git a/test_cases/integration_tests/keymile/testLoopback3.txt b/test_cases/integration_tests/keymile/testLoopback3.txt index 2ebea1b..6e41de5 100644 --- a/test_cases/integration_tests/keymile/testLoopback3.txt +++ b/test_cases/integration_tests/keymile/testLoopback3.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-19/port-1/status Lock diff --git a/test_cases/integration_tests/keymile/testVoicePort2.txt b/test_cases/integration_tests/keymile/testVoicePort2.txt index 66f987f..cacc582 100644 --- a/test_cases/integration_tests/keymile/testVoicePort2.txt +++ b/test_cases/integration_tests/keymile/testVoicePort2.txt @@ -1,4 +1,4 @@ -admin +manager secret cd /unit-19/main get HardwareAndSoftware diff --git a/test_cases/integration_tests/keymile/testmelting4.txt b/test_cases/integration_tests/keymile/testmelting4.txt index 4f509dd..4255a3d 100644 --- a/test_cases/integration_tests/keymile/testmelting4.txt +++ b/test_cases/integration_tests/keymile/testmelting4.txt @@ -1,4 +1,4 @@ -admin +manager secret /unit-19/port-1/status/StartLineTest get /unit-19/port-1/status/LineTestResults diff --git a/test_cases/unit_tests/keymile/test_keymile.py b/test_cases/unit_tests/keymile/test_keymile.py index e5a171a..db68fa4 100644 --- a/test_cases/unit_tests/keymile/test_keymile.py +++ b/test_cases/unit_tests/keymile/test_keymile.py @@ -25,19 +25,57 @@ def test_box(self): assert True def test_card(self): - assert True + card = self.model.get_card("name", '19') + card.set_sip('gateway_name', 'home_domain', 1, 'country_code', 'area_code', 12, 11, True, 'Asserted', False, + 1, False, False, 1222) + assert card.gateway_name == 'gateway_name' + assert card.uas_request_timer is False + card.set_ip('1.1.1.1', '2.22.2.2', '111.111.111.111') + assert card.subnet_mask == '2.22.2.2' + card.set_label('"l1"', '"l2"', 'desc') + assert card.label1 == '"l1"' + card.set_proxy('PrimaryOnly', 'proxy_address', 11, 'proxy_address_sec', 12, True, + 'Register', 33) + assert card.proxy_mode == 'PrimaryOnly' + assert card.proxy_interval == 33 def test_channel(self): - assert True - - def test_interface(self): - assert True + channel = self.model.get_chan('id', 1) + channel.set_profile_name('name') + assert channel.chan_profile_name == 'name' def test_port(self): - assert True + port = self.model.get_port('id', 1) + port.set_profiles(True, 'n1', 1, False, 'n2', 0, True, 'dff', 11, False, 'n4', 'Priority') + assert port.profile1_name == 'n1' + assert port.profile1_enable is True + port.set_test_state('Passed') + assert port.loopbacktest_state == 'Passed' + port.lock_admin() + assert port.admin_state == '2' + port.unlock_admin() + assert port.admin_state == '3' + port.set_melttest_state('Passed') + assert port.melttest_state == 'Passed' + port.set_linetest_state('Passed') + assert port.linetest_state == 'Passed' + port.set_mode('mode') + assert port.mode == 'mode' + port.set_flow_control('test') + assert port.flow_control == 'test' - def test_subrack(self): - assert True + def test_portgroupport(self): + port = self.model.get_portgroupport('name', '19/G1/1') + port.set_pstnport(True, True, True, 'sip', 'proxy', 'codec', 'pstn', 'enterprise') + assert port.enable is True + assert port.enterprise_profile == 'enterprise' + port.set_isdnport(False, True, True, True, 'sip', 'proxy', 'codec', 'isdn') + assert port.enable is False + assert port.isdnba_profile == 'isdn' + + def test_srcv(self): + srvc = self.model.get_srvc('id', 2) + srvc.set_service('address', 11, 'CoS0', 'Add') @pytest.mark.parametrize("path", DATA) def test_integration(self, path): diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 7ceb588..0c36329 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -28,6 +28,7 @@ class PortCommandProcessor(BaseCommandProcessor): def get_property(self, command, *args, context=None): port = self.get_component() + context['port'] = port card = self._parent.get_component() scopes = ('login', 'base', 'get') if self._validate(args, *()): @@ -264,7 +265,7 @@ def set(self, command, *args, context=None): port = self.get_component() port.set_profile(profile) - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'Portprofiles', str) and context['path'].split('/')[-1] == 'cfgm' and \ @@ -274,7 +275,7 @@ def set(self, command, *args, context=None): port = self.get_component() port.set_profile(profile) - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'Portprofiles', str, str, str, str, str, str, str, str, str, str, str, str) and \ @@ -289,7 +290,7 @@ def set(self, command, *args, context=None): en4 = True if en4.lower() == 'true' else False port.set_profiles(en1, name1, int(elen1), en2, name2, int(elen2), en3, name3, int(elen3), en4, name4, mode) - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'AdministrativeStatus', str) and context['path'].split('/')[-1] == 'main': @@ -302,7 +303,7 @@ def set(self, command, *args, context=None): port.admin_down() else: raise exceptions.SoftboxenError() - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': @@ -310,7 +311,7 @@ def set(self, command, *args, context=None): try: port = self.get_component() port.set_label(label1, label2, description) - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) @@ -321,9 +322,9 @@ def set(self, command, *args, context=None): else: mode, = self._dissect(args, 'Mode', str) try: - port = self.get_port_component() + port = self.get_component() port.set_mode(mode) - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) @@ -334,9 +335,9 @@ def set(self, command, *args, context=None): else: mode, = self._dissect(args, 'Mode', str) try: - port = self.get_port_component() + port = self.get_component() port.set_mode(mode) - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) @@ -344,9 +345,9 @@ def set(self, command, *args, context=None): card.board_name and self.__name__ == 'port' and card.product == 'ftth': ctrl, = self._dissect(args, 'FlowControl', str) try: - port = self.get_port_component() + port = self.get_component() port.set_flow_control(ctrl) - except exceptions.SoftboxenError(): + except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) else: diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index f20ce24..8cef5d2 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -256,7 +256,7 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'Ip', str, str, str) and context['component_path'].split('/')[-1] == 'cfgm': + elif self._validate(args, 'Ip', str, str, str) and context['path'].split('/')[-1] == 'cfgm': ip1, ip2, ip3 = self._dissect(args, 'Ip', str, str, str) try: component = self.get_component() @@ -278,6 +278,9 @@ def set(self, command, *args, context=None): card.set_sip(gw, hd, int(spn), cc, ac, int(rt), int(mri), se, aim, os, int(ot), uac, uas, int(sessione)) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) + elif self._validate(args[0], 'Digitmap') and \ + context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): + pass elif self._validate(args, 'Registrar', str, str, str, str) and \ context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): ra, rp, rm, rt = self._dissect(args, 'Registrar', str, str, str, str) From d82665f4e6f62a7c5a1385f02104fd3597d7270c Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Wed, 21 Oct 2020 12:57:20 +0200 Subject: [PATCH 268/318] added interface into script description --- bootup/conf/bootstraps/create-keymile-MG2500.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 199f2e4..8716102 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -34,6 +34,7 @@ path="`dirname \"$0\"`" # | |-> Port-2 # # | |-> LogPorts # # | | |-> LogPort-2 # +# | | | |-> Interface-1 # # | # # |---> Unit-3 (sdsl) (SUSE1) # # | |-> Port-1 # From cc6f6e2a12b5b2b5c376818bd0f6a78f0afb424a Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 22 Oct 2020 10:46:07 +0200 Subject: [PATCH 269/318] Further refactoring of change_directory, added component_name class variable and refactored logic for checking existence of a component --- .../mgmt_port/mgmtportCommandProcessor.py | 11 +- .../mgmt_unit/mgmtunitCommandProcessor.py | 8 +- .../root/services/srvcCommandProcessor.py | 3 + .../logport/port/logportCommandProcessor.py | 5 +- .../unit/port/chan/chanCommandProcessor.py | 23 +-- .../unit/port/chan/vcc/vccCommandProcessor.py | 49 ----- .../port/chan/vcc/vccManagementFunctions.py | 104 ----------- .../interface/interfaceCommandProcessor.py | 3 + .../root/unit/port/portCommandProcessor.py | 2 +- .../port/portgroupportCommandProcessor.py | 4 +- .../root/unit/unitCommandProcessor.py | 8 +- vendors/KeyMile/baseCommandProcessor.py | 170 ++++++++---------- 12 files changed, 105 insertions(+), 285 deletions(-) delete mode 100644 vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py delete mode 100644 vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py index dae5325..8edc2f4 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py @@ -65,11 +65,8 @@ def _init_access_points(self, context=None): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) - def get_port_component(self): - if self._parent.component_id == '11' or self._parent.component_id == '13': - raise exceptions.CommandSyntaxError() - else: - return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + def get_component(self): + return self._model.get_mgmt_port('name', self.component_name) def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') @@ -82,7 +79,7 @@ def set(self, command, *args, context=None): elif self._validate(args, 'AdministrativeStatus', str) and context['path'].split('/')[-1] == 'main': state, = self._dissect(args, 'AdministrativeStatus', str) try: - port = self.get_port_component() + port = self.get_component() if state == 'up': port.admin_up() elif state == 'down': @@ -95,7 +92,7 @@ def set(self, command, *args, context=None): elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': label1, label2, description = self._dissect(args, 'Labels', str, str, str) try: - port = self.get_port_component() + port = self.get_component() port.set_label(label1, label2, description) except exceptions.SoftboxenError(): raise exceptions.CommandExecutionError(command=command, template='invalid_property', diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py index 78de871..8b0f59f 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py @@ -108,13 +108,7 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def get_component(self): - try: - if self.component_id == '11' or self.component_id == '13': - return self._model.get_mgmt_card('name', self.component_id) - else: - raise exceptions.CommandSyntaxError() - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError() + return self._model.get_mgmt_card('name', self.component_name) def set(self, command, *args, context=None): try: diff --git a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py index 4294e2b..a35ef8f 100644 --- a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py @@ -81,3 +81,6 @@ def set(self, command, *args, context=None): def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) + + def get_component(self): + return self._model.get_srvcs('name', self.component_name) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 3bc74fb..36de9cd 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -40,12 +40,11 @@ def get_property(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors')) def get_component(self): - return self._model.get_logport('name', self._parent._parent.component_id + '/L/' + self.component_id) + return self._model.get_logport('name', self.component_name) def _init_access_points(self, context=None): self.access_points = () - logport_name = self._parent._parent.component_id + '/L/' + self.component_id - logport = self._model.get_logport('name', logport_name) + logport = self.get_component() try: _ = self._model.get_interface('logport_id', logport.id) except exceptions.SoftboxenError: diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index fecf4ae..bcfc005 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -27,7 +27,7 @@ class ChanCommandProcessor(BaseCommandProcessor): def _init_access_points(self, context=None): self.access_points = () - chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + chan = self.get_component() card = self._model.get_card('name', self._parent._parent.component_id) for interface in self._model.get_interfaces('chan_id', chan.id): @@ -47,7 +47,7 @@ def do_deletevcc(self, command, *args, context=None): # all or vcc_id name, = self._dissect(args, str) if name == 'all': - chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + chan = self.get_component() for vcc in self._model.get_interfaces('chan_id', chan.id): vcc.delete() elif name.startswith('vcc-'): @@ -68,7 +68,7 @@ def do_deleteinterface(self, command, *args, context=None): # all or interface_id name, = self._dissect(args, str) if name == 'all': - chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + chan = self.get_component() for interface in self._model.get_interfaces('chan_id', chan.id): interface.delete() elif name.startswith('interface-'): @@ -91,7 +91,7 @@ def do_createinterface(self, command, *args, context=None): vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names try: - chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + chan = self.get_component() id = 1 for interface in self._model.get_interfaces('chan_id', chan.id): if interface.chan_id is not None: @@ -118,7 +118,7 @@ def do_createinterface(self, command, *args, context=None): vlan_prof, vcc_prof = self._dissect(args, str, str) # TODO: Check if profiles := default or profile names try: - chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + chan = self.get_component() id = 1 for interface in self._model.get_interfaces('chan_id', chan.id): if interface.chan_id is not None: @@ -152,7 +152,7 @@ def do_createvcc(self, command, *args, context=None): vcc_prof, vlan_prof = self._dissect(args, str, str) # TODO: Check if profiles := default or profile names try: - chan = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + chan = self.get_component() id = 1 for vcc in self._model.get_interfaces('chan_id', chan.id): if vcc.chan_id is not None: @@ -192,7 +192,7 @@ def set(self, command, *args, context=None): name, = self._dissect(args, 'chanprofile', str) try: #TODO: Check if profile with this name exists or default - channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + channel = self.get_component() channel.set_profile_name(name) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -200,13 +200,16 @@ def set(self, command, *args, context=None): name, = self._dissect(args, 'ProfileName', str) try: # TODO: Check if profile with this name exists or default - channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + channel = self.get_component() channel.set_profile_name(name) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) else: raise exceptions.CommandSyntaxError(command=command) + def get_component(self): + return self._model.get_chan('name', self.component_name) + def get_property(self, command, *args, context=None): card = self._model.get_card('name', self._parent._parent.component_id) scopes = ('login', 'base', 'get') @@ -216,13 +219,13 @@ def get_property(self, command, *args, context=None): exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc elif self._validate(args, 'Chanprofile') and 'SUV' in card.board_name: - channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + channel = self.get_component() context['spacer1'] = self.create_spacers((67,), (channel.chan_profile_name,))[0] * ' ' context['profile_name'] = channel.chan_profile_name text = self._render('chan_profile', *scopes, context=context) self._write(text) elif self._validate(args, 'ProfileName') and 'SUV' not in card.board_name: - channel = self._model.get_chan('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id) + channel = self.get_component() context['spacer1'] = self.create_spacers((67,), (channel.chan_profile_name,))[0] * ' ' context['profile_name'] = channel.chan_profile_name text = self._render('chan_profile', *scopes, context=context) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py deleted file mode 100644 index fca7430..0000000 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccCommandProcessor.py +++ /dev/null @@ -1,49 +0,0 @@ -# This file is part of the NESi software. -# -# Copyright (c) 2020 -# Original Software Design by Ilya Etingof . -# -# Software adapted by inexio . -# - Janis Groß -# - Philip Konrath -# - Alexander Dincher -# -# License: https://github.com/inexio/NESi/LICENSE.rst - -from nesi import exceptions -from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor - - -class VccCommandProcessor(BaseCommandProcessor): - __name__ = 'vcc' - management_functions = ('main', 'cfgm', 'pm', 'status') - access_points = () - - from .vccManagementFunctions import main - from .vccManagementFunctions import cfgm - from .vccManagementFunctions import pm - from .vccManagementFunctions import status - - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - - def set(self, command, *args, context=None): - if self._validate(args, *()): - exc = exceptions.CommandSyntaxError(command=command) - exc.template = 'syntax_error' - exc.template_scopes = ('login', 'base', 'syntax_errors') - raise exc - else: - raise exceptions.CommandSyntaxError(command=command) - - def get_property(self, command, *args, context=None): - #card = self._model.get_card('name', self.component_id) - scopes = ('login', 'base', 'get') - if self._validate(args, *()): - exc = exceptions.CommandSyntaxError(command=command) - exc.template = 'syntax_error' - exc.template_scopes = ('login', 'base', 'syntax_errors') - raise exc - else: - raise exceptions.CommandExecutionError(command=command, template='invalid_property', - template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py deleted file mode 100644 index 9278f33..0000000 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/vcc/vccManagementFunctions.py +++ /dev/null @@ -1,104 +0,0 @@ -main = { - 'General': { - 'Prop': { - 'Labels': 'rw', - 'AlarmStatus': 'r-' - } - } -} - -cfgm = { - 'Traceability': { - 'Prop': { - 'AutomaticAgentCircuitId': 'rw', - 'AgentCircuitId': 'rw' - } - }, - 'Filter': { - 'Prop': { - 'MACSourceFilteringMode': 'rw', - 'MacAccessWhitelist': 'rw', - 'NumberOfMacForFloodingPrev': 'rw', - 'L2CPFilter': 'rw', - 'DestMacBlacklistProfile': 'rw', - 'SrcMacBlacklist': 'rw' - } - }, - 'IfRateLimiter': { - 'Prop': { - 'IfRateLimiting': 'rw' - } - }, - 'Profiles': { - 'Prop': { - 'configuredProfiles': 'rw' - } - } -} - -pm = { - 'PerformanceMonitoring': { - 'Cmd': ( - 'UserCounter', - 'GetHistory15min', - 'GetHistory24h', - 'GetAlarm15min', - 'GetAlarm24hRecursive', - 'ResetUserCounter', - 'ResetAlarm15min', - 'ResetAlarm24h' - ) - }, - 'UserCounter': { - 'Prop': { - 'UserCounterDisplayMode': 'rw', - 'UserCounterTable': 'r-' - }, - 'Cmd': ( - 'UserCounterReset', - ) - }, - 'History15min': { - 'Prop': { - 'History15minDisplayMode': 'rw', - 'History15minTable': 'r-' - } - }, - 'History24h': { - 'Prop': { - 'History24hDisplayMode': 'rw', - 'History24hTable': 'r-' - } - }, - 'Alarm15min': { - 'Prop': { - 'Alarm15minDisplayMode': 'rw', - 'Alarm15minTable': 'r-' - }, - 'Cmd': ( - 'Alarm15minReset', - ) - }, - 'Alarm24h': { - 'Prop': { - 'Alarm24hDisplayMode': 'rw', - 'Alarm24hTable': 'r-' - }, - 'Cmd': ( - 'Alarm24hReset', - ) - } -} - -status = { - 'ServiceInfo': { - 'Prop': { - 'ServiceStatus': 'r-' - } - }, - 'UserConnection': { - 'Prop': { - 'CurrentPppConnectionState': 'r-' - } - } -} diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index 1073477..b73c2a6 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -39,3 +39,6 @@ def set(self, command, *args, context=None): return else: raise exceptions.CommandSyntaxError(command=command) + + def get_component(self): + return self._model.get_interface('name', self.component_name) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 0c36329..be2247b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -248,7 +248,7 @@ def do_createinterface(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def get_component(self): - return self._model.get_port('name', self._parent.component_id + '/' + self.component_id) + return self._model.get_port('name', self.component_name) def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 67bcda4..391cc16 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -24,7 +24,7 @@ class PortgroupportCommandProcessor(PortCommandProcessor): from .portgroupportManagementFunctions import status def get_component(self): - return self._model.get_portgroupport('name', self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id) + return self._model.get_portgroupport('name', self.component_name) def get_property(self, command, *args, context=None): port = self.get_component() @@ -37,7 +37,7 @@ def get_property(self, command, *args, context=None): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'port' and subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id: + if subscriber.type == 'port' and subscriber.address == self.component_name: context['i'] = i context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 8cef5d2..cd69007 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -230,13 +230,7 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def get_component(self): - try: - if self.component_id == '11' or self.component_id == '13': - raise exceptions.CommandSyntaxError() - else: - return self._model.get_card('name', self.component_id) - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError() + return self._model.get_card('name', self.component_name) def set(self, command, *args, context=None): try: diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 00baae4..11059ba 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -13,6 +13,7 @@ from nesi import exceptions from nesi.softbox.cli import base import re +import importlib class BaseCommandProcessor(base.CommandProcessor): @@ -31,26 +32,6 @@ def set_component_id(self, id): def set_component_name(self, name): self.component_name = name - def get_component(self, component_type, component_name): - if component_type == 'unit': - self._model.get_card('name', component_name) - if component_type == 'mgmtunit': - self._model.get_mgmt_card('name', component_name) - elif component_type == 'port': - self._model.get_port('name', component_name) - elif component_type == 'chan': - self._model.get_chan('name', component_name) - elif component_type == 'mgmtport': - self._model.get_mgmt_port('name', component_name) - elif component_type == 'interface' or component_type == 'vcc': - self._model.get_interface('name', component_name) - elif component_type == 'logport': - self._model.get_logport('name', component_name) - elif component_type == 'srvc': - self._model.get_srvc('name', component_name) - elif component_type == 'portgroupport': - self._model.get_portgroupport('name', component_name) - main = {} cfgm = {} @@ -319,6 +300,8 @@ def change_directory(self, path, context=None): if component_type == 'unit': if component_id == '11' or component_id == '13': component_type = 'mgmtunit' + if component_type == 'vcc': + component_type = 'interface' command_processor = component_type.capitalize() + 'CommandProcessor' else: @@ -334,57 +317,12 @@ def change_directory(self, path, context=None): else: command_processor = components[0].capitalize() + 'CommandProcessor' - def validate_relation(component_type, name): - relations = { - 'root': ('unit', 'mgmtunit', 'fan', 'eoam', 'tdmconnections', 'multicast', 'services'), - 'unit': ('port', 'portgroup', 'logports', 'huntgroup'), - 'mgmtunit': ('mgmtport',), - 'fan': ('alarm',), - 'services': ('packet', 'macaccessctrl'), - 'port': ('chan', 'interface'), - 'portgroup': ('portgroupport',), - 'chan': ('vcc', 'interface',), - 'logports': ('logport',), - 'logport': ('interface',), - 'packet': ('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'), - 'subpacket': ('srvc',), - } - - try: - if component_type not in relations[name]: - return False - except KeyError: - return False - - return True - - def check_for_component(component_type, component_name): - if component_type in ('portgroup', 'unit', 'mgmtunit'): - return True - - try: - self.get_component(component_type, component_name) - except exceptions.InvalidInputError: - return False - - return True - if component_type: - validation = validate_relation(component_type, self.__name__) - if validation: - if self.component_name: - if component_type == 'srvc': - validation = check_for_component(component_type, components[0]) - elif component_type == 'logport': - validation = check_for_component(component_type, self.component_name + '/L/' + component_id) - else: - validation = check_for_component(component_type, self.component_name + '/' + component_id) - else: - validation = check_for_component(component_type, component_id) + relation_is_valid = self._validate_layer_relation(component_type, self.__name__) else: - validation = validate_relation(components[0], self.__name__) + relation_is_valid = self._validate_layer_relation(components[0], self.__name__) if components[0] not in ('main', 'cfgm', 'fm', 'pm', 'status'): - if validation is False: + if relation_is_valid is False: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty @@ -409,33 +347,7 @@ def check_for_component(component_type, component_name): self.set_prompt_end_pos(context=context) return self - from vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor import UnitCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor import PortCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.chan.chanCommandProcessor import ChanCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor import \ - InterfaceCommandProcessor - from vendors.KeyMile.accessPoints.root.fan.fanCommandProcessor import FanCommandProcessor - from vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor import AlarmCommandProcessor - from vendors.KeyMile.accessPoints.root.eoamCommandProcessor import EoamCommandProcessor - from vendors.KeyMile.accessPoints.root.multicastCommandProcessor import MulticastCommandProcessor - from vendors.KeyMile.accessPoints.root.tdmconnectionsCommandProcessor import TdmconnectionsCommandProcessor - from vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor import ServicesCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor import \ - PortgroupCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor import \ - PortgroupportCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.logport.logportsCommandProcessor import LogportsCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor import \ - LogportCommandProcessor - from vendors.KeyMile.accessPoints.root.unit.port.chan.vcc.vccCommandProcessor import VccCommandProcessor - from vendors.KeyMile.accessPoints.root.services.packetCommandProcessor import PacketCommandProcessor - from vendors.KeyMile.accessPoints.root.services.macaccessctrlCommandProcessor import \ - MacaccessctrlCommandProcessor - from vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor import SubpacketCommandProcessor - from vendors.KeyMile.accessPoints.root.services.srvcCommandProcessor import SrvcCommandProcessor - from vendors.KeyMile.accessPoints.root.mgmt_unit.mgmtunitCommandProcessor import MgmtunitCommandProcessor - from vendors.KeyMile.accessPoints.root.mgmt_unit.mgmt_port.mgmtportCommandProcessor import MgmtportCommandProcessor - subprocessor = self._create_subprocessor(eval(command_processor), 'login', 'base') + subprocessor = self._create_command_processor_obj(command_processor) if component_id is not None: subprocessor.set_component_id(component_id) @@ -453,6 +365,12 @@ def check_for_component(component_type, component_name): else: subprocessor.set_component_name(component_id) + if component_type: + component_exists = self._check_for_component(subprocessor) + if component_exists is False: + raise exceptions.CommandExecutionError(command=None, template=None, + template_scopes=()) # TODO: fix exception to not require all fields as empty + if context['path'] == '/': new_path = components[0] else: @@ -464,6 +382,68 @@ def check_for_component(component_type, component_name): return subprocessor + def _validate_layer_relation(self, component_type, name): + relations = { + 'root': ('unit', 'mgmtunit', 'fan', 'eoam', 'tdmconnections', 'multicast', 'services'), + 'unit': ('port', 'portgroup', 'logports', 'huntgroup'), + 'mgmtunit': ('mgmtport',), + 'fan': ('alarm',), + 'services': ('packet', 'macaccessctrl'), + 'port': ('chan', 'interface'), + 'portgroup': ('portgroupport',), + 'chan': ('vcc', 'interface',), + 'logports': ('logport',), + 'logport': ('interface',), + 'packet': ('1to1doubletag', '1to1singletag', 'mcast', 'nto1', 'pls', 'tls'), + 'subpacket': ('srvc',), + } + + try: + if component_type not in relations[name]: + return False + except KeyError: + return False + + return True + + def _check_for_component(self, command_processor): + if command_processor.__name__ in ('portgroup', 'unit', 'mgmtunit'): + return True + + try: + command_processor.get_component() + except exceptions.InvalidInputError: + return False + + return True + + def _create_command_processor_obj(self, command_processor): + module_paths = { + 'UnitCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.unitCommandProcessor', + 'PortCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.port.portCommandProcessor', + 'ChanCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.port.chan.chanCommandProcessor', + 'InterfaceCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.port.interface.interfaceCommandProcessor', + 'FanCommandProcessor': 'vendors.KeyMile.accessPoints.root.fan.fanCommandProcessor', + 'AlarmCommandProcessor': 'vendors.KeyMile.accessPoints.root.fan.alarmCommandProcessor', + 'EoamCommandProcessor': 'vendors.KeyMile.accessPoints.root.eoamCommandProcessor', + 'MulticastCommandProcessor': 'vendors.KeyMile.accessPoints.root.multicastCommandProcessor', + 'TdmconnectionsCommandProcessor': 'vendors.KeyMile.accessPoints.root.tdmconnectionsCommandProcessor', + 'ServicesCommandProcessor': 'vendors.KeyMile.accessPoints.root.services.servicesCommandProcessor', + 'PortgroupCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.portgroup.portgroupCommandProcessor', + 'PortgroupportCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.portgroup.port.portgroupportCommandProcessor', + 'LogportsCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.logport.logportsCommandProcessor', + 'LogportCommandProcessor': 'vendors.KeyMile.accessPoints.root.unit.logport.port.logportCommandProcessor', + 'PacketCommandProcessor': 'vendors.KeyMile.accessPoints.root.services.packetCommandProcessor', + 'MacaccessctrlCommandProcessor': 'vendors.KeyMile.accessPoints.root.services.macaccessctrlCommandProcessor', + 'SubpacketCommandProcessor': 'vendors.KeyMile.accessPoints.root.services.subpacketCommandProcessor', + 'SrvcCommandProcessor': 'vendors.KeyMile.accessPoints.root.services.srvcCommandProcessor', + 'MgmtunitCommandProcessor': 'vendors.KeyMile.accessPoints.root.mgmt_unit.mgmtunitCommandProcessor', + 'MgmtportCommandProcessor': 'vendors.KeyMile.accessPoints.root.mgmt_unit.mgmt_port.mgmtportCommandProcessor', + } + + return self._create_subprocessor( + getattr(importlib.import_module(module_paths[command_processor]), command_processor), 'login', 'base') + def do_get(self, command, *args, context=None): if len(args) >= 1: if '/' in args[0]: From 399498c08160f2869de414a167b99fd632608418 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 22 Oct 2020 11:19:46 +0200 Subject: [PATCH 270/318] Fixed a bug where switching between two component layers the component name and id wouldn't change --- vendors/KeyMile/baseCommandProcessor.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 11059ba..6d6b13b 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -500,8 +500,7 @@ def do_cd(self, command, *args, context=None): except: context['path'] = current_path raise - if not isinstance(subprocessor, self.__class__): - subprocessor.loop(context=context, return_to=subprocessor._parent) + subprocessor.loop(context=context, return_to=subprocessor._parent) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), From ab8f06bd53bc567f3301c650166b497a38012c8e Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 22 Oct 2020 13:12:29 +0200 Subject: [PATCH 271/318] Removed now obsolete field component_id and changed all occurences to a call with component_name --- .../mgmt_port/mgmtportCommandProcessor.py | 6 ++-- .../accessPoints/root/rootCommandProcessor.py | 2 -- .../root/services/srvcCommandProcessor.py | 16 +++++++++-- .../unit/logport/logportsCommandProcessor.py | 11 ++++---- .../logport/port/logportCommandProcessor.py | 15 ++++------ .../unit/port/chan/chanCommandProcessor.py | 28 +++++++++---------- .../root/unit/port/portCommandProcessor.py | 24 ++++++++-------- .../port/portgroupportCommandProcessor.py | 12 ++++---- .../portgroup/portgroupCommandProcessor.py | 4 +-- vendors/KeyMile/baseCommandProcessor.py | 15 ++++------ 10 files changed, 67 insertions(+), 66 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py index 8edc2f4..71ac67c 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py @@ -27,8 +27,8 @@ class MgmtportCommandProcessor(BaseCommandProcessor): from .mgmtportManagementFunctions import status def get_property(self, command, *args, context=None): - port = self.get_port_component() - card = self._parent.get_component() + port = self.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -70,7 +70,7 @@ def get_component(self): def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 674f148..424554a 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -31,8 +31,6 @@ def do_get(self, command, *args, context=None): context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' self._write(self._render('currTemperature', 'login', 'base', 'get', context=context)) - - def _init_access_points(self, context=None): self.access_points = ('eoam', 'fan', 'multicast', 'services', 'tdmConnections') for card in self._model.cards: diff --git a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py index a35ef8f..efaf10c 100644 --- a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py @@ -25,13 +25,19 @@ class SrvcCommandProcessor(BaseCommandProcessor): from .srvcManagementFunctions import status def get_property(self, command, *args, context=None): - service_name = 'srvc-' + self.component_id + service_name = self.component_name services = self._model.get_srvcs('name', service_name) + service = None for s in services: if s.service_type.lower() == context['ServiceType'] and s.name == service_name: service = s context['service'] = service break + + if not service: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + scopes = ('login', 'base', 'get') if self._validate((args[0],), 'Service') and context['path'].split('/')[-1] == 'cfgm': # TODO: Find missing templates, and replace placeholder templates @@ -68,12 +74,18 @@ def set(self, command, *args, context=None): elif self._validate(args, 'Service', str, str, str, str) and context['path'].split('/')[-1] == 'cfgm': address, svid, stag, vlan = self._dissect(args, 'Service', str, str, str, str) try: - service_name = 'srvc-' + self.component_id + service_name = self.component_name services = self._model.get_srvcs('name', service_name) + service = None for s in services: if s.service_type.lower() == context['ServiceType'] and s.name == service_name: service = s break + + if not service: + raise exceptions.CommandExecutionError(command=command, template='invalid_property', + template_scopes=('login', 'base', 'execution_errors')) + service.set_service(address, int(svid), stag, vlan) except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 5a36410..f7a1383 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -24,7 +24,7 @@ class LogportsCommandProcessor(BaseCommandProcessor): def _init_access_points(self, context=None): # work in progress self.access_points = () - card = self._model.get_card('name', self._parent.component_id) + card = self._model.get_card('name', self.component_name.split('/')[0]) for logport in self._model.get_logports('card_id', card.id): if logport.name.count('/') == 2: @@ -45,7 +45,7 @@ def do_delete(self, command, *args, context=None): if name.startswith('logport-'): id = name.split('-')[1] try: - port = self._model.get_logport('name', self._parent.component_id + '/L/' + id) + port = self._model.get_logport('name', self._parent.component_name + '/L/' + id) port.delete() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -66,14 +66,15 @@ def do_create(self, command, *args, context=None): ids.sort() try: for x in ids: - _ = self._model.get_logport('name', self._parent.component_id + '/L/' + str(x)) + self._model.get_logport('name', self._parent.component_name + '/L/' + str(x)) break except exceptions.SoftboxenError: - name = self._parent.component_id + '/L/' + str(ids[0]) + name = self._parent.component_name + '/L/' + str(ids[0]) ports = 'ports: ' for x in ids: ports += str(x) + ', ' - logport = self._model.add_logport(card_id=self._parent.component_id, name=name, ports=ports[:-2]) + card = self._model.get_card('name', self._parent.component_name) + logport = self._model.add_logport(card_id=card.id, name=name, ports=ports[:-2]) else: raise exceptions.CommandSyntaxError(command=command) else: diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 36de9cd..dc57db1 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -57,19 +57,18 @@ def _init_access_points(self, context=None): self.access_points += (identifier,) def do_deleteinterface(self, command, *args, context=None): - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': # all or interface_id name, = self._dissect(args, str) if name == 'all': - logport_name = self._parent._parent.component_id + '/L/' + self.component_id - logport = self._model.get_logport('name', logport_name) + logport = self._model.get_logport('name', self.component_name) for interface in self._model.get_interfaces('logport_id', logport.id): interface.delete() elif name.startswith('interface-'): id = name.split('-')[1] try: - interface = self._model.get_interface('name', self._parent._parent.component_id + '/L/' + self.component_id + '/' + id) + interface = self._model.get_interface('name', self.component_name + '/' + id) interface.delete() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -80,22 +79,20 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) # TODO: Check if profiles := default or profile names try: - logport_name = self._parent._parent.component_id + '/L/' + self.component_id - logport = self._model.get_logport('name', logport_name) + logport = self._model.get_logport('name', self.component_name) id = 1 for interface in self._model.get_interfaces('logport_id', logport.id): if interface.logport_id is not None: new_id = int(interface.name[-1]) + 1 id = new_id if new_id > id else id try: - name = self._parent._parent.component_id + '/L/' + self.component_id + '/' + str(id) - _ = self._model.get_interface('name', name) + self._model.get_interface('name', self.component_name) assert False except exceptions.SoftboxenError as exe: vcc = self._model.add_interface(name=name, logport_id=logport.id, vlan_profile=vlan_prof) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index bcfc005..e6acac7 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -28,7 +28,7 @@ class ChanCommandProcessor(BaseCommandProcessor): def _init_access_points(self, context=None): self.access_points = () chan = self.get_component() - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self.component_name.split('/')[0]) for interface in self._model.get_interfaces('chan_id', chan.id): if interface.chan_id is not None: @@ -42,7 +42,7 @@ def _init_access_points(self, context=None): self.access_points += (identifier,) def do_deletevcc(self, command, *args, context=None): - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': # all or vcc_id name, = self._dissect(args, str) @@ -53,7 +53,7 @@ def do_deletevcc(self, command, *args, context=None): elif name.startswith('vcc-'): id = name.split('-')[1] try: - vcc = self._model.get_interface('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + id) + vcc = self._model.get_interface('name', self.component_name + '/' + id) vcc.delete() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -63,7 +63,7 @@ def do_deletevcc(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_deleteinterface(self, command, *args, context=None): - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product != 'adsl' and card.product != 'sdsl': # all or interface_id name, = self._dissect(args, str) @@ -74,7 +74,7 @@ def do_deleteinterface(self, command, *args, context=None): elif name.startswith('interface-'): id = name.split('-')[1] try: - interface = self._model.get_interface('name', self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + id) + interface = self._model.get_interface('name', self.component_name + '/' + id) interface.delete() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -85,7 +85,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name: # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) @@ -98,8 +98,7 @@ def do_createinterface(self, command, *args, context=None): new_id = int(interface.name[-1]) + 1 id = new_id if new_id > id else id try: - name = self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + str(id) - _ = self._model.get_interface('name', name) + self._model.get_interface('name', self.component_name + '/' + str(id)) assert False except exceptions.SoftboxenError as exe: interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof) @@ -125,8 +124,7 @@ def do_createinterface(self, command, *args, context=None): new_id = int(interface.name[-1]) + 1 id = new_id if new_id > id else id try: - name = self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + str(id) - _ = self._model.get_interface('name', name) + self._model.get_interface('name', self.component_name + '/' + str(id)) assert False except exceptions.SoftboxenError as exe: interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof, @@ -146,7 +144,7 @@ def do_createinterface(self, command, *args, context=None): def do_createvcc(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'adsl': # vcc profile and vlan profile vcc_prof, vlan_prof = self._dissect(args, str, str) @@ -159,8 +157,8 @@ def do_createvcc(self, command, *args, context=None): new_id = int(vcc.name[-1]) + 1 id = new_id if new_id > id else id try: - name = self._parent._parent.component_id + '/' + self._parent.component_id + '/' + self.component_id + '/' + str(id) - _ = self._model.get_interface('name', name) + name = self.component_name + '/' + str(id) + self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: vcc = self._model.add_interface(name=name, chan_id=chan.id, vcc_profile=vcc_prof, @@ -182,7 +180,7 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def set(self, command, *args, context=None): - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' @@ -211,7 +209,7 @@ def get_component(self): return self._model.get_chan('name', self.component_name) def get_property(self, command, *args, context=None): - card = self._model.get_card('name', self._parent._parent.component_id) + card = self._model.get_card('name', self._parent._parent.component_name) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index be2247b..f80794e 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -29,7 +29,7 @@ class PortCommandProcessor(BaseCommandProcessor): def get_property(self, command, *args, context=None): port = self.get_component() context['port'] = port - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -125,7 +125,7 @@ def _init_access_points(self, context=None): self.access_points += (identifier,) def do_lock(self, command, *args, context=None): - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: @@ -137,7 +137,7 @@ def do_lock(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_startquickloopbacktest(self, command, *args, context=None): - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: @@ -151,7 +151,7 @@ def do_startquickloopbacktest(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_startlinetest(self, command, *args, context=None): - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if len(args) == 0 and context['path'].split('/')[-1] == 'status' and 'SUP' in card.board_name \ and self.__name__ == 'port': try: @@ -165,7 +165,7 @@ def do_startlinetest(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_startmeltmeasurement(self, command, *args, context=None): - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product != 'isdn' \ and self.__name__ == 'port': try: @@ -179,7 +179,7 @@ def do_startmeltmeasurement(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_unlock(self, command, *args, context=None): - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ and self.__name__ == 'port': try: @@ -194,7 +194,7 @@ def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_deleteinterface(self, command, *args, context=None): - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'ftth': # all or interface_id name, = self._dissect(args, str) @@ -205,7 +205,7 @@ def do_deleteinterface(self, command, *args, context=None): elif name.startswith('interface-'): id = name.split('-')[1] try: - interface = self._model.get_interface('name', self._parent.component_id + '/' + self.component_id + '/' + id) + interface = self._model.get_interface('name', self.component_name + '/' + id) interface.delete() except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -216,7 +216,7 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUE' in card.board_name: # vcc profile and vlan profile vlan_prof, = self._dissect(args, str) @@ -229,8 +229,8 @@ def do_createinterface(self, command, *args, context=None): new_id = int(interface.name[-1]) + 1 id = new_id if new_id > id else id try: - name = self._parent.component_id + '/' + self.component_id + '/' + str(id) - _ = self._model.get_interface('name', name) + name = self.component_name + '/' + str(id) + self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: interf = self._model.add_interface(name=name, port_id=port.id, vlan_profile=vlan_prof) @@ -252,7 +252,7 @@ def get_component(self): def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') - card = self._parent.get_component() + card = self._model.get_card('name', self.component_name.split('/')[0]) if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) exc.template = 'syntax_error' diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 391cc16..0476629 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -33,7 +33,7 @@ def get_property(self, command, *args, context=None): super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: if self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ - self._model.get_card('name', self._parent._parent.component_id).product == 'isdn': + self._model.get_card('name', self._parent._parent.component_name).product == 'isdn': text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: @@ -62,7 +62,7 @@ def get_property(self, command, *args, context=None): i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'port' and subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id: + if subscriber.type == 'port' and subscriber.address == self.component_name: context['i'] = i context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' context['spacer11'] = self.create_spacers((63,), (subscriber.autorisation_user_name,))[0] * ' ' @@ -88,7 +88,7 @@ def get_property(self, command, *args, context=None): i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'port' and subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id: + if subscriber.type == 'port' and subscriber.address == self.component_name: context['i'] = i context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' context['spacer11'] = self.create_spacers((63,), (subscriber.autorisation_user_name,))[0] * ' ' @@ -151,7 +151,7 @@ def set(self, command, *args, context=None): subscriber.set('display_name', displayname) subscriber.set('privacy', privacy) except exceptions.SoftboxenError: - address = self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id + address = self.component_name subscriber = self._model.add_subscriber(number=int(number), autorisation_user_name=username, address=address, privacy=privacy, type='port', display_name=displayname, autorisation_password=password) @@ -170,13 +170,13 @@ def set(self, command, *args, context=None): port = self.get_component() try: subscriber = self._model.get_subscriber('number', int(number)) - assert subscriber.address == self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id + assert subscriber.address == self.component_name subscriber.set('autorisation_user_name', username) subscriber.set('autorisation_password', password) subscriber.set('display_name', displayname) subscriber.set('privacy', privacy) except exceptions.SoftboxenError: - address = self._parent._parent.component_id + '/G' + self._parent.component_id + '/' + self.component_id + address = self.component_name subscriber = self._model.add_subscriber(number=int(number), autorisation_user_name=username, address=address, privacy=privacy, type='port', display_name=displayname, autorisation_password=password) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index 9c51c4c..0919a53 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -24,10 +24,10 @@ class PortgroupCommandProcessor(BaseCommandProcessor): def _init_access_points(self, context=None): # work in progress self.access_points = () - card = self._model.get_card('name', self._parent.component_id) + card = self._model.get_card('name', self.component_name.split('/')[0]) for gport in self._model.get_portgroupports('card_id', card.id): - if gport.name.split('/')[1] == 'G' + self.component_id: + if gport.name.split('/')[1] == 'G' + self.component_name.split('/')[-1][1:]: identifier = 'port-' + gport.name.split('/')[-1] if identifier in self.access_points: continue diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 6d6b13b..e44e1ec 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -22,13 +22,9 @@ class BaseCommandProcessor(base.CommandProcessor): management_functions = () access_points = () - component_id = None component_name = None - def set_component_id(self, id): - self.component_id = id - def set_component_name(self, name): self.component_name = name @@ -349,21 +345,20 @@ def change_directory(self, path, context=None): subprocessor = self._create_command_processor_obj(command_processor) - if component_id is not None: - subprocessor.set_component_id(component_id) - if self.component_name: if components[0] == 'logports': component_name = self.component_name + '/L' elif component_type == 'portgroup': component_name = self.component_name + '/G' + component_id - elif component_type == 'srvc': - component_name = 'srvc' + component_id else: component_name = self.component_name + '/' + component_id subprocessor.set_component_name(component_name) else: - subprocessor.set_component_name(component_id) + if component_type == 'srvc': + component_name = 'srvc-' + component_id + else: + component_name = component_id + subprocessor.set_component_name(component_name) if component_type: component_exists = self._check_for_component(subprocessor) From b68ec3b3e6452509c778cd0940cf72010899133a Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Thu, 22 Oct 2020 13:37:22 +0200 Subject: [PATCH 272/318] Fixed ls header to display relevant fields --- .../conf/bootstraps/create-keymile-MG2500.sh | 3 --- templates/KeyMile/login/base/ls/ls_header.j2 | 6 ++--- .../root/fan/fanCommandProcessor.py | 5 ++++ .../mgmt_port/mgmtportCommandProcessor.py | 5 ++++ .../mgmt_unit/mgmtunitCommandProcessor.py | 6 +++++ .../accessPoints/root/rootCommandProcessor.py | 5 ++++ .../logport/port/logportCommandProcessor.py | 6 +++++ .../root/unit/port/portCommandProcessor.py | 27 +++++++++++++++++++ .../port/portgroupportCommandProcessor.py | 5 ++++ .../portgroup/portgroupCommandProcessor.py | 5 ++++ .../root/unit/unitCommandProcessor.py | 12 +++++++++ vendors/KeyMile/baseCommandProcessor.py | 6 +++++ 12 files changed, 85 insertions(+), 6 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 8716102..b300cc2 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -580,7 +580,6 @@ req='{ unit_8=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) - ### Mgmt-Unit-11 ### # Create a physical card at the network device (admin operation) @@ -618,8 +617,6 @@ req='{ port_11_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/mgmt_ports) - - ### Unit-19 ### # Create a physical card at the network device (admin operation) diff --git a/templates/KeyMile/login/base/ls/ls_header.j2 b/templates/KeyMile/login/base/ls/ls_header.j2 index e0a8150..ab51e15 100644 --- a/templates/KeyMile/login/base/ls/ls_header.j2 +++ b/templates/KeyMile/login/base/ls/ls_header.j2 @@ -1,7 +1,7 @@ Infos of AP: {{ context.path }} - Name : MileGate 2200 - Main Mode : - Equipment State : Ok + Name : {{ context.ls_Name }} + Main Mode : {{ context.ls_MainMode }} + Equipment State : {{ context.ls_EquipmentState }} Alarm Severity : Cleared Propagated Alarm Severity : Major User Label : diff --git a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py index cd8dff8..ced2583 100644 --- a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py @@ -30,5 +30,10 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) + def _init_context(self, context=None): + context['ls_Name'] = 'FANU4' + context['ls_MainMode'] = '' + context['ls_EquipmentState'] = 'Ok' + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py index 71ac67c..16e9877 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py @@ -62,6 +62,11 @@ def _init_access_points(self, context=None): self.access_points = () return + def _init_context(self, context=None): + context['ls_Name'] = '10/100/1000BASE-T' + context['ls_MainMode'] = 'Management' + context['ls_EquipmentState'] = '' + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py index 8b0f59f..ace3e3f 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py @@ -41,6 +41,12 @@ def _init_access_points(self, context=None): except exceptions.InvalidInputError: pass + def _init_context(self, context=None): + card = self.get_component() + context['ls_Name'] = card.board_name + ' ' + card.supplier_build_state + context['ls_MainMode'] = card.software[:-4] + context['ls_EquipmentState'] = 'Ok' + def get_property(self, command, *args, context=None): card = self.get_component() scopes = ('login', 'base', 'get') diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 424554a..991b3f7 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -59,6 +59,11 @@ def _init_access_points(self, context=None): else: self.access_points = self.access_points[:self.access_points.index('unit-' + str(i - 1)) + 1] + ('unit-' + str(i),) + self.access_points[self.access_points.index('unit-' + str(i - 1)) + 1:] + def _init_context(self, context=None): + context['ls_Name'] = self._model.model + ' ' + self._model.version + context['ls_MainMode'] = '' + context['ls_EquipmentState'] = 'Ok' + def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index dc57db1..c36aea3 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -56,6 +56,12 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) + def _init_context(self, context=None): + logport = self.get_component() + context['ls_Name'] = 'SHDSL Spam' + context['ls_MainMode'] = logport.ports + context['ls_EquipmentState'] = '' + def do_deleteinterface(self, command, *args, context=None): card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'sdsl': diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index f80794e..8d925eb 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -124,6 +124,33 @@ def _init_access_points(self, context=None): continue self.access_points += (identifier,) + def _init_context(self, context=None): + port = self.get_component() + card = self._model.get_card('id', port.card_id) + print(card.product) + if card.product == 'vdsl' or card.product == 'xdsl': + context['ls_Name'] = 'VDSL' + context['ls_MainMode'] = 'VDSL2' + elif card.product == 'sdsl': + context['ls_Name'] = 'SHDSL' + context['ls_MainMode'] = '' + elif card.product == 'adsl': + context['ls_Name'] = 'ADSL' + context['ls_MainMode'] = '' + elif card.product == 'isdn': + context['ls_Name'] = 'ISDN' + context['ls_MainMode'] = 'BA' + elif card.product == 'analog': + context['ls_Name'] = 'PSTN' + context['ls_MainMode'] = '' + elif card.product == 'ftth': + context['ls_Name'] = '100/1000Base-BX10 cSFP' + context['ls_MainMode'] = '' + else: + context['ls_Name'] = '' + context['ls_MainMode'] = '' + context['ls_EquipmentState'] = '' + def do_lock(self, command, *args, context=None): card = self._model.get_card('name', self.component_name.split('/')[0]) if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 0476629..83b8e0c 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -107,6 +107,11 @@ def get_property(self, command, *args, context=None): def _init_access_points(self, context=None): pass + def _init_context(self, context=None): + context['ls_Name'] = 'ISDN-BA' + context['ls_MainMode'] = '' + context['ls_EquipmentState'] = '' + def do_deleteinterface(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index 0919a53..1eaa4f3 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -33,6 +33,11 @@ def _init_access_points(self, context=None): # work in progress continue self.access_points += (identifier,) + def _init_context(self, context=None): + context['ls_Name'] = 'ISDN-BA' + context['ls_MainMode'] = '16 Ports' + context['ls_EquipmentState'] = '' + def on_unknown_command(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index cd69007..bc60d77 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -53,6 +53,18 @@ def _init_access_points(self, context=None): except exceptions.InvalidInputError: pass + def _init_context(self, context=None): + try: + card = self.get_component() + except exceptions.SoftboxenError: + context['ls_Name'] = '' + context['ls_MainMode'] = '' + context['ls_EquipmentState'] = 'Empty' + else: + context['ls_Name'] = card.board_name + ' ' + card.supplier_build_state + context['ls_MainMode'] = card.software[:-4] + context['ls_EquipmentState'] = 'Ok' + def get_property(self, command, *args, context=None): card = self.get_component() scopes = ('login', 'base', 'get') diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index e44e1ec..b74ce31 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -160,6 +160,7 @@ def generate_ls_text(layers, depth): self._write(text) else: + self._init_context(context=context) text = self._render('ls_header', *scopes, context=context) self._init_access_points(context=context) @@ -509,6 +510,11 @@ def do_exit(self, command, *args, context=None): def _init_access_points(self, context=None): pass # Abstract method not implemented + def _init_context(self, context=None): + context['ls_Name'] = '' + context['ls_MainMode'] = '' + context['ls_EquipmentState'] = '' + def args_in_quotes_joiner(self, args): saved_args = [] save = False From 29bc005cdbe1c3e2f0e39899042dbf4b14f6123c Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 22 Oct 2020 14:46:21 +0200 Subject: [PATCH 273/318] Now ignoring alarm cmdProcessors when checking for component, added pre-check to validate if unit-13 is a management_card --- vendors/KeyMile/baseCommandProcessor.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index b74ce31..58ae051 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -295,8 +295,15 @@ def change_directory(self, path, context=None): elif self.__name__ == 'mgmtunit': component_type = 'mgmtport' if component_type == 'unit': - if component_id == '11' or component_id == '13': + if component_id == '11': component_type = 'mgmtunit' + if component_id == '13': + try: + self._model.get_mgmt_card('name', '13') + except exceptions.InvalidInputError: + component_type = 'unit' + else: + component_type = 'mgmtunit' if component_type == 'vcc': component_type = 'interface' @@ -403,7 +410,7 @@ def _validate_layer_relation(self, component_type, name): return True def _check_for_component(self, command_processor): - if command_processor.__name__ in ('portgroup', 'unit', 'mgmtunit'): + if command_processor.__name__ in ('portgroup', 'unit', 'mgmtunit', 'alarm'): return True try: From cf5a676609fcf3179be6e55b9725d5ae6846cd87 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 22 Oct 2020 16:54:52 +0200 Subject: [PATCH 274/318] Fixed a problem where some management functions of active cards weren't reachable, also now allowing more args as tokens for set Proxy command --- vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py | 2 +- vendors/KeyMile/baseCommandProcessor.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index bc60d77..0588df2 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -294,7 +294,7 @@ def set(self, command, *args, context=None): card.set_registrar(ra, int(rp), rm, int(rt)) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args, 'Proxy', str, str, str, str, str, str, str, str) and \ + elif self._validate(args[:9], 'Proxy', str, str, str, str, str, str, str, str) and \ context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): pm, pa1, pp1, pa2, pp2, pe, pmethod, pi = self._dissect(args, 'Proxy', str, str, str, str, str, str, str, str) try: diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 58ae051..701b1c8 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -339,6 +339,8 @@ def change_directory(self, path, context=None): if context['path'].split('/')[-1] in ('main', 'cfgm', 'fm', 'pm', 'status'): raise exceptions.CommandExecutionError(command=None, template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors')) + self._init_access_points() # make sure all management_functions are loaded correctly + if components[0] not in self.management_functions: raise exceptions.CommandExecutionError(command=None, template=None, template_scopes=()) # TODO: fix exception to not require all fields as empty From 9bffa2c99d6ec70677f4f9a300a8e365471ef495 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 23 Oct 2020 14:49:11 +0200 Subject: [PATCH 275/318] Implemented on_unknown_command method to process command execution when given with a path --- .../accessPoints/root/eoamCommandProcessor.py | 3 --- .../root/fan/alarmCommandProcessor.py | 3 --- .../root/fan/fanCommandProcessor.py | 3 --- .../mgmt_port/mgmtportCommandProcessor.py | 3 --- .../mgmt_unit/mgmtunitCommandProcessor.py | 3 --- .../root/multicastCommandProcessor.py | 3 --- .../accessPoints/root/rootCommandProcessor.py | 3 --- .../services/macaccessctrlCommandProcessor.py | 3 --- .../root/services/packetCommandProcessor.py | 3 --- .../root/services/servicesCommandProcessor.py | 3 --- .../root/services/srvcCommandProcessor.py | 3 --- .../services/subpacketCommandProcessor.py | 3 --- .../root/tdmconnectionsCommandProcessor.py | 3 --- .../unit/logport/logportsCommandProcessor.py | 3 --- .../logport/port/logportCommandProcessor.py | 3 --- .../unit/port/chan/chanCommandProcessor.py | 3 --- .../interface/interfaceCommandProcessor.py | 3 --- .../root/unit/port/portCommandProcessor.py | 3 --- .../port/portgroupportCommandProcessor.py | 3 --- .../portgroup/portgroupCommandProcessor.py | 3 --- .../root/unit/unitCommandProcessor.py | 3 --- vendors/KeyMile/baseCommandProcessor.py | 27 ++++++++++++++++++- 22 files changed, 26 insertions(+), 64 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py index ea461fb..b93f9c8 100644 --- a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py @@ -23,9 +23,6 @@ class EoamCommandProcessor(BaseCommandProcessor): from .eoamManagementFunctions import cfgm from .eoamManagementFunctions import status - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py index a88d5ef..22266a9 100644 --- a/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/alarmCommandProcessor.py @@ -22,6 +22,3 @@ class AlarmCommandProcessor(BaseCommandProcessor): from .alarmManagementFunctions import main from .alarmManagementFunctions import cfgm from .alarmManagementFunctions import fm - - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py index ced2583..bffb664 100644 --- a/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/fan/fanCommandProcessor.py @@ -34,6 +34,3 @@ def _init_context(self, context=None): context['ls_Name'] = 'FANU4' context['ls_MainMode'] = '' context['ls_EquipmentState'] = 'Ok' - - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py index 16e9877..a4e50c1 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmt_port/mgmtportCommandProcessor.py @@ -67,9 +67,6 @@ def _init_context(self, context=None): context['ls_MainMode'] = 'Management' context['ls_EquipmentState'] = '' - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def get_component(self): return self._model.get_mgmt_port('name', self.component_name) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py index ace3e3f..1a0edf5 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py @@ -110,9 +110,6 @@ def get_property(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def get_component(self): return self._model.get_mgmt_card('name', self.component_name) diff --git a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py index c724daf..f431b36 100644 --- a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py @@ -25,9 +25,6 @@ class MulticastCommandProcessor(BaseCommandProcessor): from .multicastManagementFunctions import pm from .multicastManagementFunctions import status - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 991b3f7..46bf7b0 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -104,9 +104,6 @@ def do_upload(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def get_property(self, command, *args, context=None): scopes = ('login', 'base', 'set') if self._validate(args, "CurrTemperature"): diff --git a/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py index a2e56c6..62a9227 100644 --- a/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py @@ -24,9 +24,6 @@ class MacaccessctrlCommandProcessor(BaseCommandProcessor): from .macaccessctrlManagementFunctions import fm from .macaccessctrlManagementFunctions import status - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') try: diff --git a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py index a8dffac..68d1d83 100644 --- a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py @@ -21,9 +21,6 @@ class PacketCommandProcessor(BaseCommandProcessor): from .packetManagementFunctions import main - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') try: diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py index 0604db8..522103d 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -23,9 +23,6 @@ class ServicesCommandProcessor(BaseCommandProcessor): from .servicesManagementFunctions import fm from .servicesManagementFunctions import status - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') try: diff --git a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py index efaf10c..8681383 100644 --- a/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/srvcCommandProcessor.py @@ -91,8 +91,5 @@ def set(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def get_component(self): return self._model.get_srvcs('name', self.component_name) diff --git a/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py index 10db20e..9d46cbb 100644 --- a/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/subpacketCommandProcessor.py @@ -75,6 +75,3 @@ def do_createservice(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) else: raise exceptions.CommandSyntaxError(command=command) - - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py index a50788a..2c3ff28 100644 --- a/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py @@ -22,9 +22,6 @@ class TdmconnectionsCommandProcessor(BaseCommandProcessor): from .tdmconnectionsManagementFunctions import main from .tdmconnectionsManagementFunctions import cfgm - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index f7a1383..22233c0 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -36,9 +36,6 @@ def _init_access_points(self, context=None): # work in progress accpoint.sort(key=lambda x: int(x.split('-')[1])) self.access_points = tuple(accpoint) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def do_delete(self, command, *args, context=None): if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm': name, = self._dissect(args, str) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index c36aea3..1776404 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -115,9 +115,6 @@ def do_createinterface(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') try: diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index e6acac7..8716789 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -176,9 +176,6 @@ def do_createvcc(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): card = self._model.get_card('name', self._parent._parent.component_name) if self._validate(args, *()): diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index b73c2a6..c876d7f 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -24,9 +24,6 @@ class InterfaceCommandProcessor(BaseCommandProcessor): from .interfaceManagementFunctions import pm from .interfaceManagementFunctions import status - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 8d925eb..2fda6b1 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -217,9 +217,6 @@ def do_unlock(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def do_deleteinterface(self, command, *args, context=None): card = self._model.get_card('name', self.component_name.split('/')[0]) if self._validate(args, str) and context['path'].split('/')[-1] == 'cfgm' and card.product == 'ftth': diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 83b8e0c..2f92f60 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -118,9 +118,6 @@ def do_deleteinterface(self, command, *args, context=None): def do_createinterface(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): scopes = ('login', 'base', 'set') try: diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index 1eaa4f3..96d132c 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -38,9 +38,6 @@ def _init_context(self, context=None): context['ls_MainMode'] = '16 Ports' context['ls_EquipmentState'] = '' - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def set(self, command, *args, context=None): if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 0588df2..a13d52b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -238,9 +238,6 @@ def get_property(self, command, *args, context=None): raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - def on_unknown_command(self, command, *args, context=None): - raise exceptions.CommandSyntaxError(command=command) - def get_component(self): return self._model.get_card('name', self.component_name) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 701b1c8..90f8903 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -22,7 +22,6 @@ class BaseCommandProcessor(base.CommandProcessor): management_functions = () access_points = () - component_name = None def set_component_name(self, name): @@ -38,6 +37,32 @@ def set_component_name(self, name): status = {} + def on_unknown_command(self, command, *args, context=None): + if len(args) == 0: + if '/' in command: + path = '/'.join([x for x in command.split('/') if x][:-1]).replace('_', '-') + command = [x for x in command.split('/') if x][-1] + + current_path = context['path'] + try: + command_proc = self.change_directory(path, context=context) + command_proc._parse_and_execute_command(command, context=context) + except exceptions.SoftboxenError: + context['path'] = current_path + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + context['path'] = current_path + else: + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + else: + raise exceptions.CommandExecutionError(template='invalid_management_function_error', + template_scopes=('login', 'base', 'execution_errors'), + command=None) + + def map_states(self, object, type): if object.admin_state == '0': if type == 'port': From 49e4860137f265a3515e26daed664d8c72272269 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 23 Oct 2020 16:56:33 +0200 Subject: [PATCH 276/318] Fixes for tests --- .../conf/bootstraps/create-keymile-MG2500.sh | 19 +++++++++++++- .../api/schemas/keymile_channel_schemas.py | 3 ++- .../keymile_resources/keymile_channel.py | 6 +++++ .../keymile_resources/keymile_interface.py | 5 +++- nesi/softbox/api/models/channel_models.py | 6 +++++ nesi/softbox/api/models/interface_models.py | 9 ++++--- nesi/softbox/api/schemas/channel_schemas.py | 4 +-- nesi/softbox/api/schemas/interface_schemas.py | 5 ++-- .../login/base/get/configured_profiles.j2 | 6 +++++ templates/KeyMile/login/base/get/ip.j2 | 6 ++--- .../KeyMile/login/base/get/service_status.j2 | 5 ++++ templates/KeyMile/login/base/get/status.j2 | 10 ++++++++ .../keymile/getInventory2.txt | 4 +-- .../integration_tests/keymile/getState1.txt | 1 - .../keymile/setChannelProfile14.txt | 2 +- .../accessPoints/root/rootCommandProcessor.py | 2 +- .../unit/port/chan/chanCommandProcessor.py | 10 ++++++++ .../interface/interfaceCommandProcessor.py | 25 +++++++++++++++++++ .../root/unit/port/portCommandProcessor.py | 1 - 19 files changed, 110 insertions(+), 19 deletions(-) create mode 100644 templates/KeyMile/login/base/get/configured_profiles.j2 create mode 100644 templates/KeyMile/login/base/get/service_status.j2 create mode 100644 templates/KeyMile/login/base/get/status.j2 diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index b300cc2..b48ac37 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -623,7 +623,24 @@ port_11_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/mgmt_ports) req='{ "subrack_id": '$subrack_id', "product": "isdn", - "name": "19" + "name": "19", + "board_name": "IPSX3", + "supplier_build_state": "R2B", + "board_id": "308", + "hardware_key": 105, + "software": "ipss2_r4e05_02.esw", + "software_name": "IPSS2", + "software_revision": "R4E05_02", + "state": "Ok", + "serial_number": "4936551973", + "manufacturer_name": "KEYMILE", + "model_name": "37900315", + "short_text": "MG IPSX3 VoIP SMG 912ch", + "manufacturer_id": "100989", + "manufacturer_part_number": "37900315", + "manufacturer_build_state": "09", + "boot_loader": "BLSU2_R1J01/CT40500", + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" }' unit_19=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) diff --git a/nesi/keymile/api/schemas/keymile_channel_schemas.py b/nesi/keymile/api/schemas/keymile_channel_schemas.py index 8d4555b..010810c 100644 --- a/nesi/keymile/api/schemas/keymile_channel_schemas.py +++ b/nesi/keymile/api/schemas/keymile_channel_schemas.py @@ -16,4 +16,5 @@ class KeyMileChannelSchema(ChannelSchema): class Meta: model = Channel - fields = ChannelSchema.Meta.fields + ('vccs', 'interfaces', 'chan_profile_name') + fields = ChannelSchema.Meta.fields + ('interfaces', 'chan_profile_name', 'curr_rate_u', 'curr_rate_d', + 'prev_rate_u', 'prev_rate_d', 'curr_delay_u') diff --git a/nesi/keymile/keymile_resources/keymile_channel.py b/nesi/keymile/keymile_resources/keymile_channel.py index 1fc9462..62acb04 100644 --- a/nesi/keymile/keymile_resources/keymile_channel.py +++ b/nesi/keymile/keymile_resources/keymile_channel.py @@ -25,6 +25,12 @@ class KeyMileChannel(base.Resource): name = base.Field('name') description = base.Field('description') chan_profile_name = base.Field('chan_profile_name') + curr_rate_u = base.Field('curr_rate_u') + curr_rate_d = base.Field('curr_rate_d') + prev_rate_u = base.Field('prev_rate_u') + prev_rate_d = base.Field('prev_rate_d') + curr_delay_u = base.Field('curr_delay_u') + curr_delay_d = base.Field('curr_delay_d') def set_profile_name(self, name): self.update(chan_profile_name=name) diff --git a/nesi/keymile/keymile_resources/keymile_interface.py b/nesi/keymile/keymile_resources/keymile_interface.py index b827fbe..dc1c446 100644 --- a/nesi/keymile/keymile_resources/keymile_interface.py +++ b/nesi/keymile/keymile_resources/keymile_interface.py @@ -27,9 +27,12 @@ class KeyMileInterface(base.Resource): chan_id = base.Field('chan_id') logport_id = base.Field('logport_id') - #vcc + # vcc vcc_profile = base.Field('vcc_profile') vlan_profile = base.Field('vlan_profile') + number_of_conn_services = base.Field('number_of_conn_services') + reconfiguration_allowed = base.Field('reconfiguration_allowed') + services_connected = base.Field('services_connected') class KeyMileInterfaceCollection(base.ResourceCollection): diff --git a/nesi/softbox/api/models/channel_models.py b/nesi/softbox/api/models/channel_models.py index 4c3cc18..bbbed86 100644 --- a/nesi/softbox/api/models/channel_models.py +++ b/nesi/softbox/api/models/channel_models.py @@ -19,6 +19,12 @@ class Channel(db.Model): name = db.Column(db.String(64)) description = db.Column(db.String()) chan_profile_name = db.Column(db.String(), default='') + curr_rate_u = db.Column(db.String(), default=0) + curr_rate_d = db.Column(db.String(), default=0) + prev_rate_u = db.Column(db.String(), default=0) + prev_rate_d = db.Column(db.String(), default=0) + curr_delay_u = db.Column(db.String(), default=0) + curr_delay_d = db.Column(db.String(), default=0) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) port_id = db.Column(db.Integer, db.ForeignKey('port.id')) interfaces = db.relationship('Interface', backref='Channel', lazy='dynamic') diff --git a/nesi/softbox/api/models/interface_models.py b/nesi/softbox/api/models/interface_models.py index b8e3322..cb24720 100644 --- a/nesi/softbox/api/models/interface_models.py +++ b/nesi/softbox/api/models/interface_models.py @@ -22,6 +22,9 @@ class Interface(db.Model): port_id = db.Column(db.Integer, db.ForeignKey('port.id')) logport_id = db.Column(db.Integer, db.ForeignKey('log_port.id')) - #vcc - vcc_profile = db.Column(db.String(), default=None) # default or profile_name, default:= vpi=0 and vci=33 - vlan_profile = db.Column(db.String(), default=None) # default or profile_name, must be untagged + # vcc + vcc_profile = db.Column(db.String(), default='') # default or profile_name, default:= vpi=0 and vci=33 + vlan_profile = db.Column(db.String(), default='') # default or profile_name, must be untagged + number_of_conn_services = db.Column(db.Integer(), default=0) + reconfiguration_allowed = db.Column(db.Enum('true', 'false'), default='true') + services_connected = db.Column(db.String(), default='') diff --git a/nesi/softbox/api/schemas/channel_schemas.py b/nesi/softbox/api/schemas/channel_schemas.py index d496e3a..a9842ee 100644 --- a/nesi/softbox/api/schemas/channel_schemas.py +++ b/nesi/softbox/api/schemas/channel_schemas.py @@ -18,8 +18,8 @@ class ChannelSchema(ma.ModelSchema): class Meta: model = Channel - fields = ('id', 'box_id', 'box', 'port_id', 'interfaces', - 'name', 'description', '_links') + fields = ('id', 'box_id', 'box', 'port_id', 'interfaces', 'curr_rate_u', 'curr_rate_d', 'prev_rate_u', + 'name', 'description', 'prev_rate_d', 'curr_delay_u', 'curr_delay_d', '_links') interfaces = ma.Nested(InterfacesSchema.InterfaceSchema, many=True) diff --git a/nesi/softbox/api/schemas/interface_schemas.py b/nesi/softbox/api/schemas/interface_schemas.py index 159b4e3..a93ba52 100644 --- a/nesi/softbox/api/schemas/interface_schemas.py +++ b/nesi/softbox/api/schemas/interface_schemas.py @@ -17,8 +17,9 @@ class InterfaceSchema(ma.ModelSchema): class Meta: model = Interface - fields = ('id', 'box_id', 'box', 'chan_id', 'port_id', 'logport_id', - 'name', 'description', 'vcc_profile', 'vlan_profile', '_links') + fields = ('id', 'box_id', 'box', 'chan_id', 'port_id', 'logport_id', 'number_of_conn_services', + 'name', 'description', 'reconfiguration_allowed', 'vcc_profile', 'vlan_profile', 'services_connected', + '_links') box = ma.Hyperlinks( {'_links': { diff --git a/templates/KeyMile/login/base/get/configured_profiles.j2 b/templates/KeyMile/login/base/get/configured_profiles.j2 new file mode 100644 index 0000000..ae4c784 --- /dev/null +++ b/templates/KeyMile/login/base/get/configured_profiles.j2 @@ -0,0 +1,6 @@ + \ # configuredProfiles + \ # vccProfile +{{ context.vcc.vcc_profile }}{{ context.spacer1 }}\ # name + \ # vlanProfile +{{ context.vcc.vlan_profile }}{{ context.spacer2 }}\ # Name + diff --git a/templates/KeyMile/login/base/get/ip.j2 b/templates/KeyMile/login/base/get/ip.j2 index e9fe969..b6082d3 100644 --- a/templates/KeyMile/login/base/get/ip.j2 +++ b/templates/KeyMile/login/base/get/ip.j2 @@ -1,5 +1,5 @@ \ # Ip -{{ context.card.gateway_ipaddress }}{{ context.spacer1 }}\ # GatewayIpAddress -{{ context.card.subnet_mask }}{{ context.spacer2 }}\ # SubnetMask -{{ context.card.default_gateway }}{{ context.spacer3 }}\ # DefaultGateway +{{ context.card.gateway_ipaddress | safe }}{{ context.spacer1 }}\ # GatewayIpAddress +{{ context.card.subnet_mask | safe }}{{ context.spacer2 }}\ # SubnetMask +{{ context.card.default_gateway | safe }}{{ context.spacer3 }}\ # DefaultGateway diff --git a/templates/KeyMile/login/base/get/service_status.j2 b/templates/KeyMile/login/base/get/service_status.j2 new file mode 100644 index 0000000..a5ce7f6 --- /dev/null +++ b/templates/KeyMile/login/base/get/service_status.j2 @@ -0,0 +1,5 @@ + \ # serviceStatus +{{ context.vcc.number_of_conn_services }}{{ context.spacer1 }}\ # NumberOfConnectedServices +{{ context.vcc.reconfiguration_allowed }}{{ context.spacer2 }}\ # ReconfigurationAllowed +{{ context.vcc_services_connected | safe }}{{ context.spacer3 }}\ # ServicesCurrentConnected + diff --git a/templates/KeyMile/login/base/get/status.j2 b/templates/KeyMile/login/base/get/status.j2 new file mode 100644 index 0000000..aa19e07 --- /dev/null +++ b/templates/KeyMile/login/base/get/status.j2 @@ -0,0 +1,10 @@ + \ # Status + \ # Downstream +{{ context.channel.curr_rate_d }}{{ context.spacer1 }}\ # CurrentRate +{{ context.channel.prev_rate_d }}{{ context.spacer2 }}\ # PreviousRate +{{ context.channel.curr_delay_d }}{{ context.spacer3 }}\ # CurrentDelay + \ # Upstream +{{ context.channel.curr_rate_u }}{{ context.spacer4 }}\ # CurrentRate +{{ context.channel.prev_rate_u }}{{ context.spacer5 }}\ # PreviousRate +{{ context.channel.curr_delay_u }}{{ context.spacer6 }}\ # CurrentDelay + diff --git a/test_cases/integration_tests/keymile/getInventory2.txt b/test_cases/integration_tests/keymile/getInventory2.txt index 27a0277..9af6ec6 100644 --- a/test_cases/integration_tests/keymile/getInventory2.txt +++ b/test_cases/integration_tests/keymile/getInventory2.txt @@ -11,8 +11,8 @@ cd /unit-19/main get HardwareAndSoftware get CurrentStatus get EquipmentInventory -cd /unit-1/port-1} +cd /unit-1/port-1 ls -cd /unit-1/port-{1/main +cd /unit-1/port-1/main get OperationalStatus exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/getState1.txt b/test_cases/integration_tests/keymile/getState1.txt index 542cbd6..b314dba 100644 --- a/test_cases/integration_tests/keymile/getState1.txt +++ b/test_cases/integration_tests/keymile/getState1.txt @@ -7,7 +7,6 @@ get AdministrativeStatus get OperationalStatus cd /unit-1/port-1/chan-1/cfgm get ProfileName -get ChanProfile cd /unit-1/port-1/chan-1/status get status cd /unit-1/port-1/chan-1/vcc-1/cfgm diff --git a/test_cases/integration_tests/keymile/setChannelProfile14.txt b/test_cases/integration_tests/keymile/setChannelProfile14.txt index 5135d50..52f2a2d 100644 --- a/test_cases/integration_tests/keymile/setChannelProfile14.txt +++ b/test_cases/integration_tests/keymile/setChannelProfile14.txt @@ -1,7 +1,7 @@ manager secret cd /unit-5/port-1/chan-1/cfgm -set chanprofile rofile +set chanprofile profile set chanprofile default #else cd /unit-5/port-1/chan-1/cfgm diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 46bf7b0..525dfa8 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -112,4 +112,4 @@ def get_property(self, command, *args, context=None): self._write(self._render('currTemperature', *scopes, context=context)) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', - template_scopes=('login', 'base', 'execution_errors')) + template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 8716789..b4caf46 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -225,6 +225,16 @@ def get_property(self, command, *args, context=None): context['profile_name'] = channel.chan_profile_name text = self._render('chan_profile', *scopes, context=context) self._write(text) + elif self._validate(args, 'Status') and context['path'].split('/')[-1] == 'status': + channel = self.get_component() + context['spacer1'] = self.create_spacers((67,), (channel.curr_rate_d,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (channel.prev_rate_d,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (channel.curr_delay_d,))[0] * ' ' + context['spacer4'] = self.create_spacers((67,), (channel.curr_rate_u,))[0] * ' ' + context['spacer5'] = self.create_spacers((67,), (channel.prev_rate_u,))[0] * ' ' + context['spacer6'] = self.create_spacers((67,), (channel.curr_delay_u,))[0] * ' ' + text = self._render('status', *scopes, context=dict(context, channel=channel)) + self._write(text) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index c876d7f..32af8ca 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -39,3 +39,28 @@ def set(self, command, *args, context=None): def get_component(self): return self._model.get_interface('name', self.component_name) + + def get_property(self, command, *args, context=None): + scopes = ('login', 'base', 'get') + if self._validate(args, *()): + exc = exceptions.CommandSyntaxError(command=command) + exc.template = 'syntax_error' + exc.template_scopes = ('login', 'base', 'syntax_errors') + raise exc + elif self._validate(args, 'ServiceStatus') and context['path'].split('/')[-1] == 'status': + vcc = self.get_component() + context['spacer1'] = self.create_spacers((67,), (vcc.vcc_profile,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (vcc.vlan_profile,))[0] * ' ' + text = self._render('configured_profiles', *scopes, context=dict(context, vcc=vcc)) + self._write(text) + elif self._validate(args, 'configuredProfiles') and context['path'].split('/')[-1] == 'cfgm': + vcc = self.get_component() + services_connected = '"' + vcc.services_connected + '"' + context['vcc_services_connected'] = services_connected + context['spacer1'] = self.create_spacers((67,), (vcc.number_of_conn_services,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (vcc.reconfiguration_allowed,))[0] * ' ' + context['spacer3'] = self.create_spacers((67,), (services_connected,))[0] * ' ' + text = self._render('service_status', *scopes, context=dict(context, vcc=vcc)) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 2fda6b1..d41b4e2 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -127,7 +127,6 @@ def _init_access_points(self, context=None): def _init_context(self, context=None): port = self.get_component() card = self._model.get_card('id', port.card_id) - print(card.product) if card.product == 'vdsl' or card.product == 'xdsl': context['ls_Name'] = 'VDSL' context['ls_MainMode'] = 'VDSL2' From fba378b677422e49d10618bddc1762d07bbdd49c Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 26 Oct 2020 10:26:09 +0100 Subject: [PATCH 277/318] Fixed a bug where giving an absolut path to execute a command while in a directory wouldn't work --- vendors/KeyMile/baseCommandProcessor.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 90f8903..4b006ac 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -40,7 +40,10 @@ def set_component_name(self, name): def on_unknown_command(self, command, *args, context=None): if len(args) == 0: if '/' in command: - path = '/'.join([x for x in command.split('/') if x][:-1]).replace('_', '-') + if command.startswith('/'): + path = '/' + '/'.join([x for x in command.split('/') if x][:-1]).replace('_', '-') + else: + path = '/'.join([x for x in command.split('/') if x][:-1]).replace('_', '-') command = [x for x in command.split('/') if x][-1] current_path = context['path'] From c932044670e557a387d13c8f207655c053103cea Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 26 Oct 2020 11:24:03 +0100 Subject: [PATCH 278/318] Fixed some integration tests --- .../integration_tests/alcatel/configureTrafficVlanOnPort.txt | 4 ++-- test_cases/integration_tests/keymile/getState1.txt | 2 ++ test_cases/integration_tests/keymile/testLoopback3.txt | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/test_cases/integration_tests/alcatel/configureTrafficVlanOnPort.txt b/test_cases/integration_tests/alcatel/configureTrafficVlanOnPort.txt index 6fd8515..a464a68 100644 --- a/test_cases/integration_tests/alcatel/configureTrafficVlanOnPort.txt +++ b/test_cases/integration_tests/alcatel/configureTrafficVlanOnPort.txt @@ -4,10 +4,10 @@ configure bridge port 1/1/1/1 no pvid configure bridge port 1/1/1/1 no vlan-id 7 configure bridge port 1/1/1/1:1:32 no pvid configure bridge port 1/1/1/1:1:32 noi vlan-id 7 -confiugre bridge port 1/1/1/1:1:32 vlan-id 7 network-vlan 2620 vlan-scope local +configure bridge port 1/1/1/1:1:32 vlan-id 7 network-vlan 2620 vlan-scope local configure bridge port 1/1/1/1 pvid 7 configure bridge port 1/1/1/1:1:32 pvid 7 -configure birdge port 1/1/4/1 vlan-id 2620 tag single-tagged +configure bridge port 1/1/4/1 vlan-id 2620 tag single-tagged configure bridge port 1/1/4/1 vlan-id 2620 l2fwder-vlan 2620 vlan-scope local tag single-tagged configure bridge port 1/1/4/1 vlan-id 7 l2fwder-vlan 2620 vlan-scope local tag single-tagged configure bridge port 1/1/4/1 vlan-id 7 network-vlan 2620 vlan-scope local single-tagged diff --git a/test_cases/integration_tests/keymile/getState1.txt b/test_cases/integration_tests/keymile/getState1.txt index b314dba..0cd3a14 100644 --- a/test_cases/integration_tests/keymile/getState1.txt +++ b/test_cases/integration_tests/keymile/getState1.txt @@ -7,6 +7,8 @@ get AdministrativeStatus get OperationalStatus cd /unit-1/port-1/chan-1/cfgm get ProfileName +cd /unit-5/port-1/chan-1/cfgm +get ChanProfile cd /unit-1/port-1/chan-1/status get status cd /unit-1/port-1/chan-1/vcc-1/cfgm diff --git a/test_cases/integration_tests/keymile/testLoopback3.txt b/test_cases/integration_tests/keymile/testLoopback3.txt index 6e41de5..898cae6 100644 --- a/test_cases/integration_tests/keymile/testLoopback3.txt +++ b/test_cases/integration_tests/keymile/testLoopback3.txt @@ -2,7 +2,7 @@ manager secret cd /unit-19/port-1/status Lock -StartQuickLoopbackTest +/unit-19/port-1/status/StartQuickLoopbackTest get QuickLoopbackTest Unlock exit \ No newline at end of file From 8c7d7cb312663810b6016ed73d126023efe118fa Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 26 Oct 2020 12:07:59 +0100 Subject: [PATCH 279/318] Fixed an huawei command issue where the command wasn't available in the correct layer --- vendors/Huawei/baseCommandProcessor.py | 2 +- vendors/Huawei/configCommandProcessor.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/vendors/Huawei/baseCommandProcessor.py b/vendors/Huawei/baseCommandProcessor.py index 88b6ad3..5c4e9c9 100644 --- a/vendors/Huawei/baseCommandProcessor.py +++ b/vendors/Huawei/baseCommandProcessor.py @@ -97,7 +97,7 @@ def do_quit(self, command, *args, context=None): def do_undo(self, command, *args, context=None): if self._validate(args, 'alarm', 'output', 'all'): - # importend for future snmp interactions + # important for future snmp interactions return elif self._validate(args, 'event', 'output', 'all'): return diff --git a/vendors/Huawei/configCommandProcessor.py b/vendors/Huawei/configCommandProcessor.py index 2b8821f..b948005 100644 --- a/vendors/Huawei/configCommandProcessor.py +++ b/vendors/Huawei/configCommandProcessor.py @@ -778,7 +778,12 @@ def do_raio_anid(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_undo(self, command, *args, context=None): - if self._validate(args, 'system', 'snmp-user', 'password', 'security'): + if self._validate(args, 'alarm', 'output', 'all'): + # important for future snmp interactions + return + elif self._validate(args, 'event', 'output', 'all'): + return + elif self._validate(args, 'system', 'snmp-user', 'password', 'security'): # importend for future snmp interactions return elif self._validate(args, 'smart'): From a609dc35ab047f5b33b7780ed955f21f71100a30 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Mon, 26 Oct 2020 12:25:16 +0100 Subject: [PATCH 280/318] added Commands and fixed small issues --- .../conf/bootstraps/create-keymile-MG2500.sh | 33 ++++++++++- .../api/schemas/keymile_port_schemas.py | 2 +- .../keymile_resources/keymile_logport.py | 4 ++ .../keymile/keymile_resources/keymile_port.py | 2 + nesi/softbox/api/models/logport_models.py | 1 + nesi/softbox/api/schemas/logport_schemas.py | 2 +- .../KeyMile/login/base/get/actual_status.j2 | 5 ++ .../KeyMile/login/base/get/attainable_rate.j2 | 4 +- .../KeyMile/login/base/get/ddm_status.j2 | 8 +++ .../login/base/get/if_rate_limiting.j2 | 8 +++ .../login/base/get/line_actual_state.j2 | 6 ++ .../login/base/get/line_operation_state.j2 | 3 + .../login/base/get/operational_wire_state.j2 | 4 ++ .../login/base/get/port_general_status.j2 | 5 ++ .../KeyMile/login/base/get/port_mac_status.j2 | 4 ++ .../KeyMile/login/base/get/span_profiles.j2 | 3 + templates/KeyMile/login/base/get/vendor_id.j2 | 12 ++++ .../KeyMile/login/base/get/vlan_profile.j2 | 3 + .../integration_tests/keymile/setconfDsl2.txt | 2 +- .../keymile/setdeconfVoicePort17.txt | 2 +- .../unit/logport/logportsCommandProcessor.py | 58 ++++++++++++------- .../logport/port/logportCommandProcessor.py | 13 ++++- .../unit/port/chan/chanCommandProcessor.py | 6 +- .../interface/interfaceCommandProcessor.py | 13 ++++- .../root/unit/port/portCommandProcessor.py | 27 ++++++++- vendors/KeyMile/baseCommandProcessor.py | 2 +- 26 files changed, 196 insertions(+), 36 deletions(-) create mode 100644 templates/KeyMile/login/base/get/actual_status.j2 create mode 100644 templates/KeyMile/login/base/get/ddm_status.j2 create mode 100644 templates/KeyMile/login/base/get/if_rate_limiting.j2 create mode 100644 templates/KeyMile/login/base/get/line_actual_state.j2 create mode 100644 templates/KeyMile/login/base/get/line_operation_state.j2 create mode 100644 templates/KeyMile/login/base/get/operational_wire_state.j2 create mode 100644 templates/KeyMile/login/base/get/port_general_status.j2 create mode 100644 templates/KeyMile/login/base/get/port_mac_status.j2 create mode 100644 templates/KeyMile/login/base/get/span_profiles.j2 create mode 100644 templates/KeyMile/login/base/get/vendor_id.j2 create mode 100644 templates/KeyMile/login/base/get/vlan_profile.j2 diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index b48ac37..7999af6 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -27,7 +27,7 @@ path="`dirname \"$0\"`" # |---> Unit-1 (adsl) (SUAD2) # # | |-> Port-1 # # | | |-> Chan-1 # -# | | |-> Interface-1 # +# | | |-> VCC-1 # # | # # |---> Unit-2 (sdsl) (SUSE1) # # | |-> Port-1 # @@ -42,6 +42,8 @@ path="`dirname \"$0\"`" # | # # |---> Unit-4 (adsl) (SUAD2) # # | |-> Port-1 # +# | | |-> Chan-1 # +# | | |-> VCC-1 # # | # # |---> Unit-5 (vdsl) (SUVM4) # # | |-> Port-1 # @@ -52,6 +54,7 @@ path="`dirname \"$0\"`" # | # # |---> Unit-7 (ftth) (SUEN3) # # | |-> Port-1 # +# | | |-> Interface-1 # # | # # |---> Unit-8 (vdsl) (SUVM6) # # | # @@ -429,6 +432,25 @@ req='{ port_4_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +### Chan-1 ### + +# Create a logical channel at the network device (admin operation) +req='{ + "port_id": '$port_4_1', + "description": "Channel #1" +}' + +chan_4_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/channels) + +### VCC-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "chan_id": '$chan_4_1_1' +}' + +interface_4_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) + ### Unit-5 ### # Create a physical card at the network device (admin operation) @@ -553,6 +575,15 @@ req='{ port_7_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) +### Interface-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "port_id": '$port_7_1' +}' + +interface_7_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) + ### Unit-8 ### # Create a physical card at the network device (admin operation) diff --git a/nesi/keymile/api/schemas/keymile_port_schemas.py b/nesi/keymile/api/schemas/keymile_port_schemas.py index d10607c..cd8dd4b 100644 --- a/nesi/keymile/api/schemas/keymile_port_schemas.py +++ b/nesi/keymile/api/schemas/keymile_port_schemas.py @@ -20,6 +20,6 @@ class Meta: 'linetest_state', 'profile1_enable', 'profile1_name', 'profile1_elength', 'profile2_enable', 'profile2_name', 'profile2_elength', 'profile3_enable', 'profile3_name', 'profile3_elength', 'profile4_enable', 'profile4_name', - 'profile_mode', 'mode', 'flow_control') + 'profile_mode', 'mode', 'flow_control', 'upstream', 'downstream') channels = ma.Nested(CpesSchema.CpeSchema, many=True) diff --git a/nesi/keymile/keymile_resources/keymile_logport.py b/nesi/keymile/keymile_resources/keymile_logport.py index e619636..c9d424b 100644 --- a/nesi/keymile/keymile_resources/keymile_logport.py +++ b/nesi/keymile/keymile_resources/keymile_logport.py @@ -28,6 +28,7 @@ class KeyMileLogPort(base.Resource): description = base.Field('description') admin_state = base.Field('admin_state') operational_state = base.Field('operational_state') + profile = base.Field('profile') def admin_up(self): """Set the admin port state to up""" @@ -45,6 +46,9 @@ def up(self): """Set the port state to down""" self.update(operational_state='1') + def set_profile(self, profile): + self.update(profile=profile) + def set_label(self, l1, l2, desc): self.update(label1=l1) self.update(label2=l2) diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py index 81a248d..c976869 100644 --- a/nesi/keymile/keymile_resources/keymile_port.py +++ b/nesi/keymile/keymile_resources/keymile_port.py @@ -36,6 +36,8 @@ class KeyMilePort(Port): profile4_enable = base.Field('profile4_enable') profile4_name = base.Field('profile4_name') profile_mode = base.Field('profile_mode') + upstream = base.Field('upstream') + downstream = base.Field('downstream') def set_profile(self, name): self.update(profile1_name=name) diff --git a/nesi/softbox/api/models/logport_models.py b/nesi/softbox/api/models/logport_models.py index c5d471d..7b9b6f8 100644 --- a/nesi/softbox/api/models/logport_models.py +++ b/nesi/softbox/api/models/logport_models.py @@ -26,3 +26,4 @@ class LogPort(db.Model): description = db.Column(db.String(), default='""') operational_state = db.Column(db.Enum('0', '1'), default='0') admin_state = db.Column(db.Enum('0', '1'), default='0') + profile = db.Column(db.String(), default='default') diff --git a/nesi/softbox/api/schemas/logport_schemas.py b/nesi/softbox/api/schemas/logport_schemas.py index 28b634e..7c09372 100644 --- a/nesi/softbox/api/schemas/logport_schemas.py +++ b/nesi/softbox/api/schemas/logport_schemas.py @@ -19,7 +19,7 @@ class LogPortSchema(ma.ModelSchema): class Meta: model = LogPort fields = ('id', 'box_id', 'box', 'card_id', 'name', 'ports', 'interfaces', 'description', 'admin_state', - 'operational_state', 'label1', 'label2', + 'operational_state', 'label1', 'label2', 'profile', '_links') interfaces = ma.Nested(InterfacesSchema.InterfaceSchema, many=True) diff --git a/templates/KeyMile/login/base/get/actual_status.j2 b/templates/KeyMile/login/base/get/actual_status.j2 new file mode 100644 index 0000000..97fd17a --- /dev/null +++ b/templates/KeyMile/login/base/get/actual_status.j2 @@ -0,0 +1,5 @@ + \ # OverallLinePayloadRate + \ # PayloadRate +0 \ # CurrentOverallPayloadRate +0 \ # AttainableOverallPayloadRate + diff --git a/templates/KeyMile/login/base/get/attainable_rate.j2 b/templates/KeyMile/login/base/get/attainable_rate.j2 index dc5e135..e5eb709 100644 --- a/templates/KeyMile/login/base/get/attainable_rate.j2 +++ b/templates/KeyMile/login/base/get/attainable_rate.j2 @@ -1,4 +1,4 @@ \ # AttainableRate -{{ context.port.downstream_max }}{{ context.spacer1 }}\ # Downstream -{{ context.port.upstream_max }}{{ context.spacer2 }}\ # Upstream +{{ context.port.downstream }}{{ context.spacer1 }}\ # Downstream +{{ context.port.upstream }}{{ context.spacer2 }}\ # Upstream diff --git a/templates/KeyMile/login/base/get/ddm_status.j2 b/templates/KeyMile/login/base/get/ddm_status.j2 new file mode 100644 index 0000000..6cf2a61 --- /dev/null +++ b/templates/KeyMile/login/base/get/ddm_status.j2 @@ -0,0 +1,8 @@ + \ # DdmStatus +Supported \ # DdmInterfaceSupport +35 \ # ModuleTemperature +3.34E0 \ # SupplyVoltage +0.0E0 \ # TxBiasCurrent +-9 \ # TxOutputPower +-40 \ # RxInputPower + diff --git a/templates/KeyMile/login/base/get/if_rate_limiting.j2 b/templates/KeyMile/login/base/get/if_rate_limiting.j2 new file mode 100644 index 0000000..0cac93a --- /dev/null +++ b/templates/KeyMile/login/base/get/if_rate_limiting.j2 @@ -0,0 +1,8 @@ + \ # IfRateLimiter + \ # UpstreamProfile +false \ # Enabled +default \ # Name + \ # DownstreamProfile +false \ # Enabled +default \ # Name + diff --git a/templates/KeyMile/login/base/get/line_actual_state.j2 b/templates/KeyMile/login/base/get/line_actual_state.j2 new file mode 100644 index 0000000..00a44f6 --- /dev/null +++ b/templates/KeyMile/login/base/get/line_actual_state.j2 @@ -0,0 +1,6 @@ + \ # LinePayloadRate + \ # PayloadRate +0 \ # ActualPayloadRate +0 \ # MaxAttainablePayloadRate +Auto \ # Tcpam + diff --git a/templates/KeyMile/login/base/get/line_operation_state.j2 b/templates/KeyMile/login/base/get/line_operation_state.j2 new file mode 100644 index 0000000..2ffbc06 --- /dev/null +++ b/templates/KeyMile/login/base/get/line_operation_state.j2 @@ -0,0 +1,3 @@ + \ # LineOperationalStatus +WaitForG.Handshaking \ # State + diff --git a/templates/KeyMile/login/base/get/operational_wire_state.j2 b/templates/KeyMile/login/base/get/operational_wire_state.j2 new file mode 100644 index 0000000..7d825a6 --- /dev/null +++ b/templates/KeyMile/login/base/get/operational_wire_state.j2 @@ -0,0 +1,4 @@ + \ # OperationalWireState +NO-WIRE \ # CurrentState +2wire \ # Attainable + diff --git a/templates/KeyMile/login/base/get/port_general_status.j2 b/templates/KeyMile/login/base/get/port_general_status.j2 new file mode 100644 index 0000000..cb6881a --- /dev/null +++ b/templates/KeyMile/login/base/get/port_general_status.j2 @@ -0,0 +1,5 @@ + \ # PHYState +LinkDown \ # Speed +LinkDown \ # Duplex +false \ # IEEE802_3FlowControl + diff --git a/templates/KeyMile/login/base/get/port_mac_status.j2 b/templates/KeyMile/login/base/get/port_mac_status.j2 new file mode 100644 index 0000000..9778239 --- /dev/null +++ b/templates/KeyMile/login/base/get/port_mac_status.j2 @@ -0,0 +1,4 @@ + \ # PortMacStatus +2000 \ # MaxPacketLength +00W0DACF4D79 \ # MACAddress + diff --git a/templates/KeyMile/login/base/get/span_profiles.j2 b/templates/KeyMile/login/base/get/span_profiles.j2 new file mode 100644 index 0000000..75e6eab --- /dev/null +++ b/templates/KeyMile/login/base/get/span_profiles.j2 @@ -0,0 +1,3 @@ + \ # LogicalPort +{{ context.port.profile }}{{ context.spacer1 }}\ # Name + diff --git a/templates/KeyMile/login/base/get/vendor_id.j2 b/templates/KeyMile/login/base/get/vendor_id.j2 new file mode 100644 index 0000000..57149cb --- /dev/null +++ b/templates/KeyMile/login/base/get/vendor_id.j2 @@ -0,0 +1,12 @@ + \ # DSLvendor + \ # CO +"B400/ITTN/0001" \ # VendorId +"14.3.3.60.0.22" \ # VersionNumber +"5610864561" \ # SerialNumber +"0x07 40 00 00 00 18 00 11" \ # DslLineTransCap + \ # CPE +"B400/ITTN/2F0A" \ # VendorId +"1.283.5.17 AB" \ # VersionNumber +"3CDH5F478B7B F!Box7550 165.70.10" \ # SerialNumber +"0x00 11 40 11 50 10 03 00" \ # DslLineTransCap + diff --git a/templates/KeyMile/login/base/get/vlan_profile.j2 b/templates/KeyMile/login/base/get/vlan_profile.j2 new file mode 100644 index 0000000..0c5d04b --- /dev/null +++ b/templates/KeyMile/login/base/get/vlan_profile.j2 @@ -0,0 +1,3 @@ + \ # vlanProfile +{{ context.vcc.vlan_profile }}{{ context.spacer1 }}\ # Name + diff --git a/test_cases/integration_tests/keymile/setconfDsl2.txt b/test_cases/integration_tests/keymile/setconfDsl2.txt index 70dd24b..fe71c9a 100644 --- a/test_cases/integration_tests/keymile/setconfDsl2.txt +++ b/test_cases/integration_tests/keymile/setconfDsl2.txt @@ -10,7 +10,7 @@ cd /unit-7/port-1/main Set Labels "ctId" "d" "" set AdministrativeStatus up cd /unit-2/logports/cfgm -create port-1 +create port-1 default cd /unit-2/logports/logport-1/cfgm CreateInterface name cd /unit-2/logports/logport-1/main diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt index 9b41b86..4af0ac6 100644 --- a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt +++ b/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt @@ -1,6 +1,6 @@ manager secret -cd /unit-$card/port-$port/main +cd /unit-19/port-1/main set AdministrativeStatus down Set Labels "" "" "" cd /unit-19/portgroup-1/port-1/cfgm diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 22233c0..9b16d08 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -52,28 +52,42 @@ def do_delete(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_create(self, command, *args, context=None): - if self._validate(args, str, str, str, str) and context['path'].split('/')[-1] == 'cfgm': - p1, p2, p3, p4, = self._dissect(args, str, str, str, str) - ids = [] - ids.append(int(p1.split('-')[1])) if p1.startswith('port-') else ids - ids.append(int(p2.split('-')[1])) if p2.startswith('port-') else ids - ids.append(int(p3.split('-')[1])) if p3.startswith('port-') else ids - ids.append(int(p4.split('-')[1])) if p4.startswith('port-') else ids - if len(ids) >= 0: - ids.sort() - try: - for x in ids: - self._model.get_logport('name', self._parent.component_name + '/L/' + str(x)) - break - except exceptions.SoftboxenError: - name = self._parent.component_name + '/L/' + str(ids[0]) - ports = 'ports: ' - for x in ids: - ports += str(x) + ', ' - card = self._model.get_card('name', self._parent.component_name) - logport = self._model.add_logport(card_id=card.id, name=name, ports=ports[:-2]) - else: - raise exceptions.CommandSyntaxError(command=command) + if self._validate(args, str, str, str, str, str) and context['path'].split('/')[-1] == 'cfgm': + p1, p2, p3, p4, profile = self._dissect(args, str, str, str, str, str) + self.create(p1, p2, p3, p4, profile, command) + elif self._validate(args, str, str, str, str) and context['path'].split('/')[-1] == 'cfgm': + p1, p2, p3, profile = self._dissect(args, str, str, str, str) + self.create(p1, p2, p3, '', profile, command) + elif self._validate(args, str, str, str) and context['path'].split('/')[-1] == 'cfgm': + p1, p2, profile = self._dissect(args, str, str, str) + self.create(p1, p2, '', '', profile, command) + elif self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm': + p1, profile = self._dissect(args, str, str) + self.create(p1, '', '', '', profile, command) + else: + raise exceptions.CommandSyntaxError(command=command) + + def create(self, p1, p2, p3, p4, profile, command): + ids = [] + ids.append(int(p1.split('-')[1])) if p1.startswith('port-') else ids + ids.append(int(p2.split('-')[1])) if p2.startswith('port-') else ids + ids.append(int(p3.split('-')[1])) if p3.startswith('port-') else ids + ids.append(int(p4.split('-')[1])) if p4.startswith('port-') else ids + if len(ids) > 0: + ids.sort() + try: + for x in ids: + self._model.get_logport('name', self._parent.component_name + '/L/' + str(x)) + break + except exceptions.SoftboxenError: + name = self._parent.component_name + '/L/' + str(ids[0]) + ports = 'ports: ' + for x in ids: + ports += str(x) + ', ' + card = self._model.get_card('name', self._parent.component_name) + logport = self._model.add_logport(card_id=card.id, name=name, ports=ports[:-2]) + logport = self._model.get_logport('name', name) + logport.set_profile(profile) else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 1776404..c4a9a61 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -28,6 +28,7 @@ class LogportCommandProcessor(PortCommandProcessor): def get_property(self, command, *args, context=None): port = self.get_component() + context['port'] = port scopes = ('login', 'base', 'get') try: super().get_property(command, *args, context=context) @@ -35,6 +36,16 @@ def get_property(self, command, *args, context=None): if self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': text = self._render('attainable_rate', *scopes, context=context) self._write(text) + elif self._validate((args[0],), 'ActualStatus') and context['path'].split('/')[-1] == 'status': + text = self._render('actual_status', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'OperationalWireState') and context['path'].split('/')[-1] == 'status': + text = self._render('operational_wire_state', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'SpanProfiles') and context['path'].split('/')[-1] == 'cfgm': + context['spacer1'] = self.create_spacers((67,), (port.profile,))[0] * ' ' + text = self._render('span_profiles', *scopes, context=context) + self._write(text) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) @@ -101,7 +112,7 @@ def do_createinterface(self, command, *args, context=None): self._model.get_interface('name', self.component_name) assert False except exceptions.SoftboxenError as exe: - vcc = self._model.add_interface(name=name, logport_id=logport.id, vlan_profile=vlan_prof) + vcc = self._model.add_interface(name=self.component_name, logport_id=logport.id, vlan_profile=vlan_prof) context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' context['id'] = str(id) # TODO: Template is unknown diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index b4caf46..27e1e46 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -98,7 +98,8 @@ def do_createinterface(self, command, *args, context=None): new_id = int(interface.name[-1]) + 1 id = new_id if new_id > id else id try: - self._model.get_interface('name', self.component_name + '/' + str(id)) + name = self.component_name + '/' + str(id) + self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof) @@ -124,7 +125,8 @@ def do_createinterface(self, command, *args, context=None): new_id = int(interface.name[-1]) + 1 id = new_id if new_id > id else id try: - self._model.get_interface('name', self.component_name + '/' + str(id)) + name = self.component_name + '/' + str(id) + self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof, diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index 32af8ca..09b833f 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -51,7 +51,7 @@ def get_property(self, command, *args, context=None): vcc = self.get_component() context['spacer1'] = self.create_spacers((67,), (vcc.vcc_profile,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (vcc.vlan_profile,))[0] * ' ' - text = self._render('configured_profiles', *scopes, context=dict(context, vcc=vcc)) + text = self._render('service_status', *scopes, context=dict(context, vcc=vcc)) self._write(text) elif self._validate(args, 'configuredProfiles') and context['path'].split('/')[-1] == 'cfgm': vcc = self.get_component() @@ -60,7 +60,16 @@ def get_property(self, command, *args, context=None): context['spacer1'] = self.create_spacers((67,), (vcc.number_of_conn_services,))[0] * ' ' context['spacer2'] = self.create_spacers((67,), (vcc.reconfiguration_allowed,))[0] * ' ' context['spacer3'] = self.create_spacers((67,), (services_connected,))[0] * ' ' - text = self._render('service_status', *scopes, context=dict(context, vcc=vcc)) + text = self._render('configured_profiles', *scopes, context=dict(context, vcc=vcc)) + self._write(text) + elif self._validate(args, 'VlanProfile') and context['path'].split('/')[-1] == 'cfgm': + vcc = self.get_component() + context['spacer1'] = self.create_spacers((67,), (vcc.vlan_profile,))[0] * ' ' + text = self._render('vlan_profile', *scopes, context=dict(context, vcc=vcc)) + self._write(text) + elif self._validate(args, 'IfRateLimiting') and context['path'].split('/')[-1] == 'cfgm': + vcc = self.get_component() + text = self._render('if_rate_limiting', *scopes, context=dict(context, vcc=vcc)) self._write(text) else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index d41b4e2..a4d16a9 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -66,7 +66,32 @@ def get_property(self, command, *args, context=None): text = self._render('port_profiles', *scopes, context=dict(context, port=port)) self._write(text) elif self._validate((args[0],), 'AttainableRate') and context['path'].split('/')[-1] == 'status': - text = self._render('attainable_rate', *scopes, context=context) + context['spacer1'] = self.create_spacers((67,), (port.downstream,))[0] * ' ' + context['spacer2'] = self.create_spacers((67,), (port.upstream,))[0] * ' ' + text = self._render('attainable_rate', *scopes, context=dict(context, port=port)) + self._write(text) + elif self._validate((args[0],), 'PortMacStatus') and context['path'].split('/')[-1] == 'status' and \ + card.product == 'ftth': + text = self._render('port_mac_status', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'DDMStatus') and context['path'].split('/')[-1] == 'status' and \ + card.product == 'ftth': + text = self._render('ddm_status', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'PortGeneralStatus') and context['path'].split('/')[-1] == 'status' and \ + card.product == 'ftth': + text = self._render('port_general_status', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'VendorId') and context['path'].split('/')[-1] == 'status': + text = self._render('vendor_id', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'LineActualState') and context['path'].split('/')[-1] == 'status' and \ + card.product == 'sdsl': + text = self._render('line_actual_state', *scopes, context=context) + self._write(text) + elif self._validate((args[0],), 'LineOperationState') and context['path'].split('/')[-1] == 'status' and \ + card.product == 'sdsl': + text = self._render('line_operation_state', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'QuickLoopbackTest') and context['path'].split('/')[-1] == 'status'\ and (card.product == 'isdn' or 'SUI' in card.board_name) and self.__name__ == 'port': diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 4b006ac..5e82c2b 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -486,7 +486,7 @@ def do_get(self, command, *args, context=None): prop = args[0].split('/')[-1] try: tmp_cmdproc = self.change_directory(path, context=context) - tmp_cmdproc.get_property(command, *prop, context=context) + tmp_cmdproc.get_property(command, prop, context=context) except exceptions.CommandExecutionError: raise exceptions.CommandExecutionError(template='syntax_error', template_scopes=('login', 'base', 'syntax_errors'), From a2015e933244f8a8189fd28dab0eee683229df26 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 26 Oct 2020 14:10:22 +0100 Subject: [PATCH 281/318] Added a bit of code that allows the cli to append the line entered by the user to stdout so a socket stream can read the given command aswell --- nesi/softbox/cli/base.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 500f646..1632d66 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -348,6 +348,9 @@ def loop(self, context=None, return_to=None, command=None): self.line_buffer = line.split('\r\n') continue context['raw_line'] = line + + if self.daemon: + self._write(line) # write line to stdout if box is in daemon mode else: line = command command = None From 9f68d2a4892b993cd663b8bd9cc524adacb3a194 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 26 Oct 2020 15:47:58 +0100 Subject: [PATCH 282/318] Fixed naming convention of get_property in rootCommandprocessor aswell as some minor bugfixes regarding do_get and do_set, also implemented get UnicastList for ports --- .../KeyMile/login/base/get/unicast_list.j2 | 10 ++++++++++ .../login/base/get/unicast_list_empty.j2 | 3 +++ .../accessPoints/root/rootCommandProcessor.py | 2 +- .../root/unit/port/portCommandProcessor.py | 10 ++++++++++ vendors/KeyMile/baseCommandProcessor.py | 17 ++++++++++++++--- 5 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 templates/KeyMile/login/base/get/unicast_list.j2 create mode 100644 templates/KeyMile/login/base/get/unicast_list_empty.j2 diff --git a/templates/KeyMile/login/base/get/unicast_list.j2 b/templates/KeyMile/login/base/get/unicast_list.j2 new file mode 100644 index 0000000..3a6dfad --- /dev/null +++ b/templates/KeyMile/login/base/get/unicast_list.j2 @@ -0,0 +1,10 @@ +{ \ # UnicastList + \ # [0] # + \ # PortDynamicListEntry + 1 \ # Index + 00A38EA34DD0 \ # MacAddress + 2620 \ # VlanId + 0.0.0.0 \ # IpAddress +; \ +} \ + diff --git a/templates/KeyMile/login/base/get/unicast_list_empty.j2 b/templates/KeyMile/login/base/get/unicast_list_empty.j2 new file mode 100644 index 0000000..a8d7a8e --- /dev/null +++ b/templates/KeyMile/login/base/get/unicast_list_empty.j2 @@ -0,0 +1,3 @@ +{ \ # UnicastList +} \ + diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 525dfa8..8f2b740 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -25,7 +25,7 @@ class RootCommandProcessor(BaseCommandProcessor): from .rootManagementFunctions import fm from .rootManagementFunctions import status - def do_get(self, command, *args, context=None): + def get_property(self, command, *args, context=None): if self._validate(args, "CurrTemperature"): context['currTemperature'] = self._model.currTemperature context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index a4d16a9..ae27fe7 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -122,6 +122,16 @@ def get_property(self, command, *args, context=None): context['spacer3'] = self.create_spacers((67,), (port.description,))[0] * ' ' text = self._render('labels', *scopes, context=dict(context, port=port)) self._write(text) + elif self._validate(args, 'UnicastList') and context['path'].split('/')[-1] == 'status': + port = self.get_component() + try: + chan = self._model.get_chan('port_id', port.id) + self._model.get_interface('chan_id', chan.id) + except exceptions.InvalidInputError: + text = self._render('unicast_list_empty', *scopes, context=context) + else: + text = self._render('unicast_list', *scopes, context=context) # where does the templates mac-address come from + self._write(text) elif self._validate((args[0],), 'OperationalStatus') and context['path'].split('/')[-1] == 'main': self.map_states(port, 'port') port_operational_state = port.operational_state diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 5e82c2b..9c48044 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -484,13 +484,16 @@ def do_get(self, command, *args, context=None): for component in args[0].split('/')[:-1]: path += component + '/' prop = args[0].split('/')[-1] + current_path = context['path'] try: tmp_cmdproc = self.change_directory(path, context=context) tmp_cmdproc.get_property(command, prop, context=context) except exceptions.CommandExecutionError: + context['path'] = current_path raise exceptions.CommandExecutionError(template='syntax_error', template_scopes=('login', 'base', 'syntax_errors'), command=None) + context['path'] = current_path else: self.get_property(command, args[0], context=context) else: @@ -510,9 +513,17 @@ def do_set(self, command, *args, context=None): path = '' for el in args[0].split('/')[:-1]: path += el + '/' - proc = self.change_directory(str(path[:-1]), context=context) - res = (args[0].split('/')[-1],) + args[1:] - proc.set(command, *res, context=context) + current_path = context['path'] + try: + proc = self.change_directory(str(path[:-1]), context=context) + res = (args[0].split('/')[-1],) + args[1:] + proc.set(command, *res, context=context) + except exceptions.CommandExecutionError: + context['path'] = current_path + raise exceptions.CommandExecutionError(template='syntax_error', + template_scopes=('login', 'base', 'syntax_errors'), + command=None) + context['path'] = current_path elif args[0].count('/') == 0: self.set(command, *args, context=context) From 59d36213ca050dd927806303da1a48ca2b87ccb9 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Mon, 26 Oct 2020 15:53:13 +0100 Subject: [PATCH 283/318] Added interface to port on unit-5 --- bootup/conf/bootstraps/create-keymile-MG2500.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 7999af6..f54a548 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -48,6 +48,7 @@ path="`dirname \"$0\"`" # |---> Unit-5 (vdsl) (SUVM4) # # | |-> Port-1 # # | | |-> Chan-1 # +# | | |-> Interface-1 # # | # # |---> Unit-6 (vdsl) (SUVM6) # # | |-> Port-1 # @@ -499,6 +500,15 @@ req='{ chan_5_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/channels) +### Interface-1 ### + +# Create a physical interface at the network device (admin operation) +req='{ + "chan_id": 'chan_5_1_1' +}' + +interface_5_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) + ### Unit-6 ### # Create a physical card at the network device (admin operation) From 7dfa1ece1cd2795d7a230732245f2166e873b99c Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 27 Oct 2020 10:45:51 +0100 Subject: [PATCH 284/318] Fixed error handling for get functio --- vendors/KeyMile/baseCommandProcessor.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 9c48044..4a6ea49 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -488,14 +488,19 @@ def do_get(self, command, *args, context=None): try: tmp_cmdproc = self.change_directory(path, context=context) tmp_cmdproc.get_property(command, prop, context=context) - except exceptions.CommandExecutionError: + except exceptions.SoftboxenError: context['path'] = current_path - raise exceptions.CommandExecutionError(template='syntax_error', + raise exceptions.CommandExecutionError(template='invalid_property', template_scopes=('login', 'base', 'syntax_errors'), command=None) context['path'] = current_path else: - self.get_property(command, args[0], context=context) + try: + self.get_property(command, args[0], context=context) + except exceptions.SoftboxenError: + raise exceptions.CommandExecutionError(template='invalid_property', + template_scopes=('login', 'base', 'execution_errors'), + command=None) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), From aac2baa4d00b2eae7bd4ef450c6dbdee03026de4 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Tue, 27 Oct 2020 10:50:44 +0100 Subject: [PATCH 285/318] refactored specific api Interfaces into keymile interfaces and general interfaces --- .../api/schemas/keymile_interface_schemas.py | 21 ++++++++++++ .../keymile_resources/keymile_interface.py | 10 ++---- nesi/softbox/api/models/interface_models.py | 5 ++- nesi/softbox/api/schemas/interface_schemas.py | 4 +-- nesi/softbox/base_resources/interface.py | 33 +++++++++++++++++++ 5 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 nesi/keymile/api/schemas/keymile_interface_schemas.py create mode 100644 nesi/softbox/base_resources/interface.py diff --git a/nesi/keymile/api/schemas/keymile_interface_schemas.py b/nesi/keymile/api/schemas/keymile_interface_schemas.py new file mode 100644 index 0000000..960a086 --- /dev/null +++ b/nesi/keymile/api/schemas/keymile_interface_schemas.py @@ -0,0 +1,21 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.interface_schemas import * + + +class KeyMileInterfaceSchema(InterfaceSchema): + class Meta: + model = Interface + fields = InterfaceSchema.Meta.fields + ('chan_id', 'port_id', 'logport_id', 'number_of_conn_services', + 'reconfiguration_allowed', 'vcc_profile', 'vlan_profile', + 'services_connected') diff --git a/nesi/keymile/keymile_resources/keymile_interface.py b/nesi/keymile/keymile_resources/keymile_interface.py index dc1c446..e5c62a3 100644 --- a/nesi/keymile/keymile_resources/keymile_interface.py +++ b/nesi/keymile/keymile_resources/keymile_interface.py @@ -10,20 +10,16 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst -import logging -from nesi.softbox.base_resources import base +from nesi.softbox.base_resources.interface import Interface, InterfaceCollection, logging, base LOG = logging.getLogger(__name__) -class KeyMileInterface(base.Resource): +class KeyMileInterface(Interface): """Represent logical interface resource.""" - id = base.Field('id') port_id = base.Field('port_id') - name = base.Field('name') - description = base.Field('description') chan_id = base.Field('chan_id') logport_id = base.Field('logport_id') @@ -35,7 +31,7 @@ class KeyMileInterface(base.Resource): services_connected = base.Field('services_connected') -class KeyMileInterfaceCollection(base.ResourceCollection): +class KeyMileInterfaceCollection(InterfaceCollection): """Represent a collection of interfaces.""" @property diff --git a/nesi/softbox/api/models/interface_models.py b/nesi/softbox/api/models/interface_models.py index cb24720..cd68d95 100644 --- a/nesi/softbox/api/models/interface_models.py +++ b/nesi/softbox/api/models/interface_models.py @@ -18,13 +18,16 @@ class Interface(db.Model): name = db.Column(db.String(64)) description = db.Column(db.String()) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + + # KeyMile chan_id = db.Column(db.Integer, db.ForeignKey('channel.id')) port_id = db.Column(db.Integer, db.ForeignKey('port.id')) logport_id = db.Column(db.Integer, db.ForeignKey('log_port.id')) - # vcc vcc_profile = db.Column(db.String(), default='') # default or profile_name, default:= vpi=0 and vci=33 vlan_profile = db.Column(db.String(), default='') # default or profile_name, must be untagged number_of_conn_services = db.Column(db.Integer(), default=0) reconfiguration_allowed = db.Column(db.Enum('true', 'false'), default='true') services_connected = db.Column(db.String(), default='') + + diff --git a/nesi/softbox/api/schemas/interface_schemas.py b/nesi/softbox/api/schemas/interface_schemas.py index a93ba52..1c68aec 100644 --- a/nesi/softbox/api/schemas/interface_schemas.py +++ b/nesi/softbox/api/schemas/interface_schemas.py @@ -17,9 +17,7 @@ class InterfaceSchema(ma.ModelSchema): class Meta: model = Interface - fields = ('id', 'box_id', 'box', 'chan_id', 'port_id', 'logport_id', 'number_of_conn_services', - 'name', 'description', 'reconfiguration_allowed', 'vcc_profile', 'vlan_profile', 'services_connected', - '_links') + fields = ('id', 'box_id', 'box', 'name', 'description', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/base_resources/interface.py b/nesi/softbox/base_resources/interface.py new file mode 100644 index 0000000..a95d664 --- /dev/null +++ b/nesi/softbox/base_resources/interface.py @@ -0,0 +1,33 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import logging + +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class Interface(base.Resource): + """Represent logical interface resource.""" + + id = base.Field('id') + name = base.Field('name') + description = base.Field('description') + + +class InterfaceCollection(base.ResourceCollection): + """Represent a collection of interfaces.""" + + @property + def _resource_type(self): + return Interface From c0726c2cb6e1b9b1a1c0e3785e210bae52395ab5 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 27 Oct 2020 11:31:38 +0100 Subject: [PATCH 286/318] Added templates and functionality for some properties on empty cards --- .../login/base/get/current_status_empty.j2 | 8 + .../base/get/equipment_inventory_empty.j2 | 16 ++ .../root/unit/unitCommandProcessor.py | 140 ++++++++++-------- 3 files changed, 101 insertions(+), 63 deletions(-) create mode 100644 templates/KeyMile/login/base/get/current_status_empty.j2 create mode 100644 templates/KeyMile/login/base/get/equipment_inventory_empty.j2 diff --git a/templates/KeyMile/login/base/get/current_status_empty.j2 b/templates/KeyMile/login/base/get/current_status_empty.j2 new file mode 100644 index 0000000..73a5a02 --- /dev/null +++ b/templates/KeyMile/login/base/get/current_status_empty.j2 @@ -0,0 +1,8 @@ + \ # EquipmentStatus +Empty \ # State +"" \ # Hardware +"" \ # Software +"" \ # SerialNumber +"" \ # ManufacturerName +"" \ # ModelName + diff --git a/templates/KeyMile/login/base/get/equipment_inventory_empty.j2 b/templates/KeyMile/login/base/get/equipment_inventory_empty.j2 new file mode 100644 index 0000000..d28b60d --- /dev/null +++ b/templates/KeyMile/login/base/get/equipment_inventory_empty.j2 @@ -0,0 +1,16 @@ + \ # EquipmentInventory +"" \ # Symbol +"" \ # ShortText +0 \ # BoardId +0 \ # HardwareKey +"" \ # ManufacturerId +"" \ # ManufacturerSerialNumber +"" \ # ManufacturerPartNumber +"" \ # ManufacturerBuildState +"" \ # SupplierPartNumber +"" \ # SupplierBuildState +"" \ # CustomerId +"" \ # CustomerProductId +"" \ # Bootloader +"" \ # Processor + diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index a13d52b..7aa21cd 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -66,7 +66,13 @@ def _init_context(self, context=None): context['ls_EquipmentState'] = 'Ok' def get_property(self, command, *args, context=None): - card = self.get_component() + try: + card = self.get_component() + except exceptions.InvalidInputError: + if args[0] in ('CurrentStatus', 'EquipmentInventory'): + card = None + else: + raise scopes = ('login', 'base', 'get') if self._validate(args, *()): exc = exceptions.CommandSyntaxError(command=command) @@ -167,71 +173,79 @@ def get_property(self, command, *args, context=None): self._write(text) elif self._validate(args, 'CurrentStatus') and context['path'].split('/')[-1] == 'main': - unit_state = card.state - context['unit_state'] = unit_state - context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' - unit_hardware = '"' + card.board_name + ' ' + card.supplier_build_state + '"' - context['unit_hardware'] = unit_hardware - context['spacer_2'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' - unit_software = '"' + card.software[:-4] + '"' - context['unit_software'] = unit_software - context['spacer_3'] = self.create_spacers((67,), (unit_software,))[0] * ' ' - unit_serial_number = '"' + card.serial_number + '"' - context['unit_serial_number'] = unit_serial_number - context['spacer_4'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' - unit_manufacturer_name = '"' + card.manufacturer_name + '"' - context['unit_manufacturer_name'] = unit_manufacturer_name - context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_name,))[0] * ' ' - unit_model_name = '"' + card.model_name + '"' - context['unit_model_name'] = unit_model_name - context['spacer_6'] = self.create_spacers((67,), (unit_model_name,))[0] * ' ' - text = self._render('current_status', *scopes, context=context) + if card is None: + text = self._render('current_status_empty', *scopes, context=context) + else: + unit_state = card.state + context['unit_state'] = unit_state + context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' + unit_hardware = '"' + card.board_name + ' ' + card.supplier_build_state + '"' + context['unit_hardware'] = unit_hardware + context['spacer_2'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' + unit_software = '"' + card.software[:-4] + '"' + context['unit_software'] = unit_software + context['spacer_3'] = self.create_spacers((67,), (unit_software,))[0] * ' ' + unit_serial_number = '"' + card.serial_number + '"' + context['unit_serial_number'] = unit_serial_number + context['spacer_4'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' + unit_manufacturer_name = '"' + card.manufacturer_name + '"' + context['unit_manufacturer_name'] = unit_manufacturer_name + context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_name,))[0] * ' ' + unit_model_name = '"' + card.model_name + '"' + context['unit_model_name'] = unit_model_name + context['spacer_6'] = self.create_spacers((67,), (unit_model_name,))[0] * ' ' + text = self._render('current_status', *scopes, context=context) + self._write(text) elif self._validate(args, 'EquipmentInventory') and context['path'].split('/')[-1] == 'main': - unit_symbol = '"' + card.board_name + '"' - context['unit_symbol'] = unit_symbol - context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' - unit_short_text = '"' + card.short_text + '"' - context['unit_short_text'] = unit_short_text - context['spacer_2'] = self.create_spacers((67,), (unit_short_text,))[0] * ' ' - unit_board_id = card.board_id - context['unit_board_id'] = unit_board_id - context['spacer_3'] = self.create_spacers((67,), (unit_board_id,))[0] * ' ' - unit_hardware_key = card.hardware_key - context['unit_hardware_key'] = unit_hardware_key - context['spacer_4'] = self.create_spacers((67,), (unit_hardware_key,))[0] * ' ' - unit_manufacturer_id = '"' + card.manufacturer_id + '"' - context['unit_manufacturer_id'] = unit_manufacturer_id - context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_id,))[0] * ' ' - unit_serial_number = '"' + card.serial_number + '"' - context['unit_serial_number'] = unit_serial_number - context['spacer_6'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' - unit_manufacturer_part_number = '"' + card.manufacturer_part_number + '"' - context['unit_manufacturer_part_number'] = unit_manufacturer_part_number - context['spacer_7'] = self.create_spacers((67,), (unit_manufacturer_part_number,))[0] * ' ' - unit_manufacturer_build_state = '"' + card.manufacturer_build_state + '"' - context['unit_manufacturer_build_state'] = unit_manufacturer_build_state - context['spacer_8'] = self.create_spacers((67,), (unit_manufacturer_build_state,))[0] * ' ' - unit_supplier_part_number = '"' + card.model_name + '"' - context['unit_supplier_part_number'] = unit_supplier_part_number - context['spacer_9'] = self.create_spacers((67,), (unit_supplier_part_number,))[0] * ' ' - unit_supplier_build_state = '"' + card.supplier_build_state + '"' - context['unit_supplier_build_state'] = unit_supplier_build_state - context['spacer_10'] = self.create_spacers((67,), (unit_supplier_build_state,))[0] * ' ' - unit_customer_id = '"' + card.customer_id + '"' - context['unit_customer_id'] = unit_customer_id - context['spacer_11'] = self.create_spacers((67,), (unit_customer_id,))[0] * ' ' - unit_customer_product_id = '"' + card.customer_product_id + '"' - context['unit_customer_product_id'] = unit_customer_product_id - context['spacer_12'] = self.create_spacers((67,), (unit_customer_product_id,))[0] * ' ' - unit_boot_loader = '"' + card.boot_loader + '"' - context['unit_boot_loader'] = unit_boot_loader - context['spacer_13'] = self.create_spacers((67,), (unit_boot_loader,))[0] * ' ' - unit_processor = '"' + card.processor + '"' - context['unit_processor'] = unit_processor - context['spacer_14'] = self.create_spacers((67,), (unit_processor,))[0] * ' ' - text = self._render('equipment_inventory', *scopes, context=context) + if card is None: + text = self._render('equipment_inventory_empty', *scopes, context=context) + else: + unit_symbol = '"' + card.board_name + '"' + context['unit_symbol'] = unit_symbol + context['spacer_1'] = self.create_spacers((67,), (unit_symbol,))[0] * ' ' + unit_short_text = '"' + card.short_text + '"' + context['unit_short_text'] = unit_short_text + context['spacer_2'] = self.create_spacers((67,), (unit_short_text,))[0] * ' ' + unit_board_id = card.board_id + context['unit_board_id'] = unit_board_id + context['spacer_3'] = self.create_spacers((67,), (unit_board_id,))[0] * ' ' + unit_hardware_key = card.hardware_key + context['unit_hardware_key'] = unit_hardware_key + context['spacer_4'] = self.create_spacers((67,), (unit_hardware_key,))[0] * ' ' + unit_manufacturer_id = '"' + card.manufacturer_id + '"' + context['unit_manufacturer_id'] = unit_manufacturer_id + context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_id,))[0] * ' ' + unit_serial_number = '"' + card.serial_number + '"' + context['unit_serial_number'] = unit_serial_number + context['spacer_6'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' + unit_manufacturer_part_number = '"' + card.manufacturer_part_number + '"' + context['unit_manufacturer_part_number'] = unit_manufacturer_part_number + context['spacer_7'] = self.create_spacers((67,), (unit_manufacturer_part_number,))[0] * ' ' + unit_manufacturer_build_state = '"' + card.manufacturer_build_state + '"' + context['unit_manufacturer_build_state'] = unit_manufacturer_build_state + context['spacer_8'] = self.create_spacers((67,), (unit_manufacturer_build_state,))[0] * ' ' + unit_supplier_part_number = '"' + card.model_name + '"' + context['unit_supplier_part_number'] = unit_supplier_part_number + context['spacer_9'] = self.create_spacers((67,), (unit_supplier_part_number,))[0] * ' ' + unit_supplier_build_state = '"' + card.supplier_build_state + '"' + context['unit_supplier_build_state'] = unit_supplier_build_state + context['spacer_10'] = self.create_spacers((67,), (unit_supplier_build_state,))[0] * ' ' + unit_customer_id = '"' + card.customer_id + '"' + context['unit_customer_id'] = unit_customer_id + context['spacer_11'] = self.create_spacers((67,), (unit_customer_id,))[0] * ' ' + unit_customer_product_id = '"' + card.customer_product_id + '"' + context['unit_customer_product_id'] = unit_customer_product_id + context['spacer_12'] = self.create_spacers((67,), (unit_customer_product_id,))[0] * ' ' + unit_boot_loader = '"' + card.boot_loader + '"' + context['unit_boot_loader'] = unit_boot_loader + context['spacer_13'] = self.create_spacers((67,), (unit_boot_loader,))[0] * ' ' + unit_processor = '"' + card.processor + '"' + context['unit_processor'] = unit_processor + context['spacer_14'] = self.create_spacers((67,), (unit_processor,))[0] * ' ' + text = self._render('equipment_inventory', *scopes, context=context) + self._write(text) else: From 94e6616499f1d4199ddb0580449f7df3e0bf416b Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 27 Oct 2020 11:43:07 +0100 Subject: [PATCH 287/318] Added get CurrentStatus for management cards --- .../mgmt_unit/mgmtunitCommandProcessor.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py index 1a0edf5..e62b6e3 100644 --- a/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/mgmt_unit/mgmtunitCommandProcessor.py @@ -105,6 +105,28 @@ def get_property(self, command, *args, context=None): context['unit_processor'] = unit_processor context['spacer_14'] = self.create_spacers((67,), (unit_processor,))[0] * ' ' text = self._render('equipment_inventory', *scopes, context=context) + self._write(text) + elif self._validate(args, 'CurrentStatus') and context['path'].split('/')[-1] == 'main': + unit_state = card.state + context['unit_state'] = unit_state + context['spacer_1'] = self.create_spacers((67,), (unit_state,))[0] * ' ' + unit_hardware = '"' + card.board_name + ' ' + card.supplier_build_state + '"' + context['unit_hardware'] = unit_hardware + context['spacer_2'] = self.create_spacers((67,), (unit_hardware,))[0] * ' ' + unit_software = '"' + card.software[:-4] + '"' + context['unit_software'] = unit_software + context['spacer_3'] = self.create_spacers((67,), (unit_software,))[0] * ' ' + unit_serial_number = '"' + card.serial_number + '"' + context['unit_serial_number'] = unit_serial_number + context['spacer_4'] = self.create_spacers((67,), (unit_serial_number,))[0] * ' ' + unit_manufacturer_name = '"' + card.manufacturer_name + '"' + context['unit_manufacturer_name'] = unit_manufacturer_name + context['spacer_5'] = self.create_spacers((67,), (unit_manufacturer_name,))[0] * ' ' + unit_model_name = '"' + card.model_name + '"' + context['unit_model_name'] = unit_model_name + context['spacer_6'] = self.create_spacers((67,), (unit_model_name,))[0] * ' ' + text = self._render('current_status', *scopes, context=context) + self._write(text) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', From 4bf97ea94c8e696b0ad56ce9b0bacb72ac14580a Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 27 Oct 2020 12:34:45 +0100 Subject: [PATCH 288/318] Corrected template outputs for 'get IsdnPort' and get 'PstnPort' --- .../conf/bootstraps/create-keymile-MG2500.sh | 2 +- .../api/models/portgroupport_models.py | 20 +++++++++---------- .../KeyMile/login/base/get/isdnport_bottom.j2 | 6 +++--- .../KeyMile/login/base/get/isdnport_top.j2 | 2 +- .../KeyMile/login/base/get/pstnport_bottom.j2 | 4 ++-- .../KeyMile/login/base/get/pstnport_top.j2 | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index f54a548..91ee2b7 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -504,7 +504,7 @@ chan_5_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/channels) # Create a physical interface at the network device (admin operation) req='{ - "chan_id": 'chan_5_1_1' + "chan_id": '$chan_5_1_1' }' interface_5_1_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) diff --git a/nesi/softbox/api/models/portgroupport_models.py b/nesi/softbox/api/models/portgroupport_models.py index 4a1a0f9..88a86f6 100644 --- a/nesi/softbox/api/models/portgroupport_models.py +++ b/nesi/softbox/api/models/portgroupport_models.py @@ -15,15 +15,15 @@ class PortGroupPort(db.Model): #isdn enable = db.Column(db.Boolean(), default=False) - register_as_global = db.Column(db.Boolean, default=None) - register_default_number_only = db.Column(db.Boolean, default=None) - layer_1_permanently_activated = db.Column(db.Boolean, default=None) - sip_profile = db.Column(db.String(), default=None) - proxy_registrar_profile = db.Column(db.String(), default=None) - codec_sdp_profile = db.Column(db.String(), default=None) - isdnba_profile = db.Column(db.String(), default=None) + register_as_global = db.Column(db.Boolean, default=True) + register_default_number_only = db.Column(db.Boolean, default=False) + layer_1_permanently_activated = db.Column(db.Boolean, default=False) + sip_profile = db.Column(db.String(), default='none') + proxy_registrar_profile = db.Column(db.String(), default='none') + codec_sdp_profile = db.Column(db.String(), default='none') + isdnba_profile = db.Column(db.String(), default='none') #pstn - pay_phone = db.Column(db.Boolean(), default= None) - pstn_profile = db.Column(db.String(), default=None) - enterprise_profile = db.Column(db.String(), default=None) + pay_phone = db.Column(db.Boolean(), default=False) + pstn_profile = db.Column(db.String(), default='none') + enterprise_profile = db.Column(db.String(), default='none') diff --git a/templates/KeyMile/login/base/get/isdnport_bottom.j2 b/templates/KeyMile/login/base/get/isdnport_bottom.j2 index 97c6e19..a6ca59f 100644 --- a/templates/KeyMile/login/base/get/isdnport_bottom.j2 +++ b/templates/KeyMile/login/base/get/isdnport_bottom.j2 @@ -1,7 +1,7 @@ } \ -{{ context.port.register_as_global }}{{ context.spacer2 }}\ # RegisterAsGlobal -{{ context.port.register_default_number_only }}{{ context.spacer3 }}\ # RegisterDefaultNumberOnly -{{ context.port.layer_1_permanently_activated }}{{ context.spacer8 }}\ # Layer1PermanentlyActivated +{{ context.port.register_as_global | lower }}{{ context.spacer2 }}\ # RegisterAsGlobal +{{ context.port.register_default_number_only | lower }}{{ context.spacer3 }}\ # RegisterDefaultNumberOnly +{{ context.port.layer_1_permanently_activated | lower }}{{ context.spacer8 }}\ # Layer1PermanentlyActivated {{ context.port.sip_profile }}{{ context.spacer4 }}\ # SipProfile {{ context.port.proxy_registrar_profile }}{{ context.spacer5 }}\ # ProxyRegistrarProfile {{ context.port.codec_sdp_profile }}{{ context.spacer6 }}\ # CodecSdpProfile diff --git a/templates/KeyMile/login/base/get/isdnport_top.j2 b/templates/KeyMile/login/base/get/isdnport_top.j2 index 6f7ea38..96dd3bf 100644 --- a/templates/KeyMile/login/base/get/isdnport_top.j2 +++ b/templates/KeyMile/login/base/get/isdnport_top.j2 @@ -1,4 +1,4 @@ \ # IsdnPort -{{ context.port.enable }}{{ context.spacer1 }}\ # Enable +{{ context.port.enable | lower }}{{ context.spacer1 }}\ # Enable { \ # SubscriberIdentifications diff --git a/templates/KeyMile/login/base/get/pstnport_bottom.j2 b/templates/KeyMile/login/base/get/pstnport_bottom.j2 index 88b7918..adb8176 100644 --- a/templates/KeyMile/login/base/get/pstnport_bottom.j2 +++ b/templates/KeyMile/login/base/get/pstnport_bottom.j2 @@ -1,6 +1,6 @@ } \ -{{ context.port.register_as_global }}{{ context.spacer2 }}\ # RegisterAsGlobal -{{ context.port.pay_phone }}{{ context.spacer3 }}\ # PayPhone +{{ context.port.register_as_global | lower }}{{ context.spacer2 }}\ # RegisterAsGlobal +{{ context.port.pay_phone | lower }}{{ context.spacer3 }}\ # PayPhone {{ context.port.sip_profile }}{{ context.spacer4 }}\ # SipProfile {{ context.port.proxy_registrar_profile }}{{ context.spacer5 }}\ # ProxyRegistrarProfile {{ context.port.codec_sdp_profile }}{{ context.spacer6 }}\ # CodecSdpProfile diff --git a/templates/KeyMile/login/base/get/pstnport_top.j2 b/templates/KeyMile/login/base/get/pstnport_top.j2 index 9aab7aa..f470f1b 100644 --- a/templates/KeyMile/login/base/get/pstnport_top.j2 +++ b/templates/KeyMile/login/base/get/pstnport_top.j2 @@ -1,4 +1,4 @@ \ # PstnPort -{{ context.port.enable }}{{ context.spacer1 }}\ # Enable +{{ context.port.enable | lower }}{{ context.spacer1 }}\ # Enable { \ # SubscriberIdentifications From 5cbac4648530370bb52622e1d9b5ecb4083ed723 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 27 Oct 2020 15:05:55 +0100 Subject: [PATCH 289/318] Added new testsubscribers, relocated subscriber from card to portgroupport --- .../conf/bootstraps/create-keymile-MG2500.sh | 53 +++++++++++++++---- .../keymile_resources/keymile_subscriber.py | 1 + .../api/models/portgroupport_models.py | 14 +++++ nesi/softbox/api/models/subscriber_models.py | 8 +-- .../api/schemas/portgroupport_schemas.py | 5 +- .../softbox/api/schemas/subscriber_schemas.py | 4 +- .../KeyMile/login/base/get/isdnport_middle.j2 | 2 +- .../KeyMile/login/base/get/pstnport_middle.j2 | 2 +- .../port/portgroupportCommandProcessor.py | 10 ++-- 9 files changed, 74 insertions(+), 25 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 91ee2b7..cfa8d67 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -168,15 +168,6 @@ req='{ information_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) -# test subscriber -req='{ - "name": "tester", - "number": 9023, - "type": "unit" -}' - -subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) - ### Nto1-Service-1 ### # Create a physical port at the network device (admin operation) @@ -681,7 +672,11 @@ req='{ "manufacturer_part_number": "37900315", "manufacturer_build_state": "09", "boot_loader": "BLSU2_R1J01/CT40500", - "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB" + "processor": "CPU MPC852T/853T 50MHz, RAM 64MB, FLASH 32MB", + "gateway_ipaddress": "10.0.0.20", + "subnet_mask": "255.255.255.0", + "default_gateway": "10.0.0.1", + "country_code": "+672" }' unit_19=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) @@ -710,6 +705,18 @@ req='{ port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) +# test subscriber 1 +req='{ + "name": "tester", + "number": 9023, + "portgroupport_id": '$port_19_G1_1', + "autorisation_user_name": "Test User", + "autorisation_password": "topsecret", + "display_name": "Mr. Testuser" +}' + +subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) + ### PortGroupPort-2 ### # Create a physical port at the network device (admin operation) @@ -721,4 +728,28 @@ req='{ "type": "ISDN" }' -port_19_G1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) +port_19_G2_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/portgroupports) + +# test subscriber 3 +req='{ + "name": "tester2", + "number": 7653312, + "portgroupport_id": '$port_19_G2_1', + "autorisation_user_name": "Test User 2", + "autorisation_password": "topsecret", + "display_name": "Mrs. Testuser" +}' + +subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) + +# test subscriber 3 +req='{ + "name": "tester3", + "number": 1234567, + "portgroupport_id": '$port_19_G2_1', + "autorisation_user_name": "Test User 3", + "autorisation_password": "topsecret", + "display_name": "Mr. & Mrs. Testuser" +}' + +subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) diff --git a/nesi/keymile/keymile_resources/keymile_subscriber.py b/nesi/keymile/keymile_resources/keymile_subscriber.py index 6eaefbf..82c7231 100644 --- a/nesi/keymile/keymile_resources/keymile_subscriber.py +++ b/nesi/keymile/keymile_resources/keymile_subscriber.py @@ -30,6 +30,7 @@ class KeyMileSubscriber(base.Resource): autorisation_password = base.Field('autorisation_password') display_name = base.Field('display_name') privacy = base.Field('privacy') + portgroupport_id = base.Field('portgroupport_id') def set(self, field, value): mapping = {field: value} diff --git a/nesi/softbox/api/models/portgroupport_models.py b/nesi/softbox/api/models/portgroupport_models.py index 88a86f6..fdb9554 100644 --- a/nesi/softbox/api/models/portgroupport_models.py +++ b/nesi/softbox/api/models/portgroupport_models.py @@ -1,4 +1,17 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# - Philipp-Noah Groß +# +# License: https://github.com/inexio/NESi/LICENSE.rst from nesi.softbox.api import db +from .subscriber_models import Subscriber class PortGroupPort(db.Model): @@ -12,6 +25,7 @@ class PortGroupPort(db.Model): label2 = db.Column(db.String(), default='""') card_id = db.Column(db.Integer, db.ForeignKey('card.id')) type = db.Column(db.Enum('ISDN', 'PSTN'), default='ISDN') + subscribers = db.relationship('Subscriber', backref='PortGroupPort', lazy='dynamic') #isdn enable = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/models/subscriber_models.py b/nesi/softbox/api/models/subscriber_models.py index ec22ecf..7670311 100644 --- a/nesi/softbox/api/models/subscriber_models.py +++ b/nesi/softbox/api/models/subscriber_models.py @@ -9,7 +9,7 @@ # - Alexander Dincher # - Philipp-Noah Groß # -# License: https://github.com/inexio/NESi/LICENSE.rst +# License: https://github.com/inexio/NESi/LICENSE.rst< from nesi.softbox.api import db @@ -18,13 +18,13 @@ class Subscriber(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) + portgroupport_id = db.Column(db.Integer(), db.ForeignKey('port_group_port.id')) number = db.Column(db.Integer(), nullable=False, unique=True) - type = db.Column(db.Enum('unit', 'port'), default='port') address = db.Column(db.String(), default='') registration_state = db.Column(db.Enum('registered'), default='registered') autorisation_user_name = db.Column(db.String(), default='') - autorisation_password = db.Column(db.String(), default='""') + autorisation_password = db.Column(db.String(), default='') display_name = db.Column(db.String(), default='') - privacy = db.Column(db.String(), default=None) + privacy = db.Column(db.String(), default='None') diff --git a/nesi/softbox/api/schemas/portgroupport_schemas.py b/nesi/softbox/api/schemas/portgroupport_schemas.py index 5ef8f85..39cd17e 100644 --- a/nesi/softbox/api/schemas/portgroupport_schemas.py +++ b/nesi/softbox/api/schemas/portgroupport_schemas.py @@ -12,17 +12,20 @@ from nesi.softbox.api import ma from ..models.portgroupport_models import PortGroupPort +from .subscriber_schemas import SubscribersSchema class PortGroupPortSchema(ma.ModelSchema): class Meta: model = PortGroupPort fields = ('id', 'name', 'box_id', 'card_id', 'operational_state', 'admin_state', 'description', 'label1', - 'label2', 'type', 'enable', 'register_as_global', + 'label2', 'type', 'enable', 'register_as_global', 'subscribers', 'register_default_number_only', 'layer_1_permanently_activated', 'sip_profile', 'isdnba_profile', 'proxy_registrar_profile', 'codec_sdp_profile', 'pay_phone', 'pstn_profile', 'enterprise_profile', '_links') + subscribers = ma.Nested(SubscribersSchema.SubscriberSchema, many=True) + box = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_box', id='')}}) diff --git a/nesi/softbox/api/schemas/subscriber_schemas.py b/nesi/softbox/api/schemas/subscriber_schemas.py index 98c07b8..581acfc 100644 --- a/nesi/softbox/api/schemas/subscriber_schemas.py +++ b/nesi/softbox/api/schemas/subscriber_schemas.py @@ -17,8 +17,8 @@ class SubscriberSchema(ma.ModelSchema): class Meta: model = Subscriber - fields = ('id', 'name', 'box', 'box_id', 'number', 'type', 'address', 'registration_state', 'display_name', - 'autorisation_user_name', 'autorisation_password', 'privacy', + fields = ('id', 'name', 'box', 'box_id', 'number', 'address', 'registration_state', 'display_name', + 'autorisation_user_name', 'autorisation_password', 'privacy', 'portgroupport_id', '_links') box = ma.Hyperlinks( diff --git a/templates/KeyMile/login/base/get/isdnport_middle.j2 b/templates/KeyMile/login/base/get/isdnport_middle.j2 index 051b842..2336e11 100644 --- a/templates/KeyMile/login/base/get/isdnport_middle.j2 +++ b/templates/KeyMile/login/base/get/isdnport_middle.j2 @@ -3,7 +3,7 @@ "{{ context.subscriber.number }}"{{ context.spacer10 }}\ # SubscriberNumber "{{ context.subscriber.autorisation_user_name }}"{{ context.spacer11 }}\ # AuthorisationUserName "{{ context.subscriber.autorisation_password }}"{{ context.spacer12 }}\ # AuthorisationPassword - "{{ context.subscriber.display_name }}"{{ context.spacer13 }}\ # DisplayName + "{{ context.subscriber.display_name | safe }}"{{ context.spacer13 }}\ # DisplayName {{ context.subscriber.privacy }}{{ context.spacer14 }}\ # privacy ; \ diff --git a/templates/KeyMile/login/base/get/pstnport_middle.j2 b/templates/KeyMile/login/base/get/pstnport_middle.j2 index 051b842..2336e11 100644 --- a/templates/KeyMile/login/base/get/pstnport_middle.j2 +++ b/templates/KeyMile/login/base/get/pstnport_middle.j2 @@ -3,7 +3,7 @@ "{{ context.subscriber.number }}"{{ context.spacer10 }}\ # SubscriberNumber "{{ context.subscriber.autorisation_user_name }}"{{ context.spacer11 }}\ # AuthorisationUserName "{{ context.subscriber.autorisation_password }}"{{ context.spacer12 }}\ # AuthorisationPassword - "{{ context.subscriber.display_name }}"{{ context.spacer13 }}\ # DisplayName + "{{ context.subscriber.display_name | safe }}"{{ context.spacer13 }}\ # DisplayName {{ context.subscriber.privacy }}{{ context.spacer14 }}\ # privacy ; \ diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 2f92f60..0bcd0d0 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -33,11 +33,11 @@ def get_property(self, command, *args, context=None): super().get_property(command, *args, context=context) except exceptions.CommandExecutionError: if self._validate((args[0],), 'SubscriberList') and context['path'].split('/')[-1] == 'status' and \ - self._model.get_card('name', self._parent._parent.component_name).product == 'isdn': + self._model.get_card('name', self._parent._parent.component_name).product in ('isdn', 'analog'): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'port' and subscriber.address == self.component_name: + if subscriber.portgroupport_id == port.id: context['i'] = i context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' @@ -62,13 +62,13 @@ def get_property(self, command, *args, context=None): i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'port' and subscriber.address == self.component_name: + if subscriber.portgroupport_id == port.id: context['i'] = i context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' context['spacer11'] = self.create_spacers((63,), (subscriber.autorisation_user_name,))[0] * ' ' context['spacer12'] = self.create_spacers((63,), (subscriber.autorisation_password,))[0] * ' ' context['spacer13'] = self.create_spacers((63,), (subscriber.display_name,))[0] * ' ' - context['spacer14'] = self.create_spacers((63,), (subscriber.privacy,))[0] * ' ' + context['spacer14'] = self.create_spacers((65,), (subscriber.privacy,))[0] * ' ' i += 1 text += self._render('isdnport_middle', *scopes, context=dict(context, subscriber=subscriber)) @@ -88,7 +88,7 @@ def get_property(self, command, *args, context=None): i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'port' and subscriber.address == self.component_name: + if subscriber.portgroupport_id == port.id: context['i'] = i context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' context['spacer11'] = self.create_spacers((63,), (subscriber.autorisation_user_name,))[0] * ' ' From 91e2218124818bc959d549e38284a8bd3fd422e1 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 28 Oct 2020 10:04:00 +0100 Subject: [PATCH 290/318] Added further registration states and changed the way subscribers are loaded when executing 'get IsdnPort/PstnPort', also changed the behaviour of get SubscriberList when in unit-19 to only display subsribers with registration state 'Unregistered' --- bootup/conf/bootstraps/create-keymile-MG2500.sh | 3 ++- nesi/softbox/api/models/subscriber_models.py | 5 ++++- nesi/softbox/api/views/subscriber_views.py | 3 +++ .../unit/portgroup/port/portgroupportCommandProcessor.py | 7 +++---- .../KeyMile/accessPoints/root/unit/unitCommandProcessor.py | 2 +- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index cfa8d67..c32e56d 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -749,7 +749,8 @@ req='{ "portgroupport_id": '$port_19_G2_1', "autorisation_user_name": "Test User 3", "autorisation_password": "topsecret", - "display_name": "Mr. & Mrs. Testuser" + "display_name": "Mr. & Mrs. Testuser", + "registration_state": "Unregistered" }' subscriber_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subscribers) diff --git a/nesi/softbox/api/models/subscriber_models.py b/nesi/softbox/api/models/subscriber_models.py index 7670311..9e1f8dd 100644 --- a/nesi/softbox/api/models/subscriber_models.py +++ b/nesi/softbox/api/models/subscriber_models.py @@ -22,7 +22,10 @@ class Subscriber(db.Model): number = db.Column(db.Integer(), nullable=False, unique=True) address = db.Column(db.String(), default='') - registration_state = db.Column(db.Enum('registered'), default='registered') + registration_state = db.Column( + db.Enum('Registered', 'Registering', 'RegisteringWith-Cred', + 'DeRegInRegistering', 'DeRegistering', 'Reregistering', + 'Unregistered'), default='Registered') autorisation_user_name = db.Column(db.String(), default='') autorisation_password = db.Column(db.String(), default='') display_name = db.Column(db.String(), default='') diff --git a/nesi/softbox/api/views/subscriber_views.py b/nesi/softbox/api/views/subscriber_views.py index 4b46e43..545d218 100644 --- a/nesi/softbox/api/views/subscriber_views.py +++ b/nesi/softbox/api/views/subscriber_views.py @@ -12,6 +12,7 @@ from .base_views import * from ..schemas.subscriber_schemas import * +from ..models.portgroupport_models import PortGroupPort PREFIX = '/nesi/v1' @@ -43,6 +44,8 @@ def update_subscriber(box_id, id): @app.route(PREFIX + '/boxen//subscribers', methods=['POST']) def new_subscriber(box_id): req = flask.request.json + portgroupport = json.loads(show_component(PortGroupPort, box_id, req['portgroupport_id']).data.decode('utf-8')) + req['address'] = '/portgroup-' + portgroupport['name'].split('/')[1][1:] + '/port-' + portgroupport['name'].split('/')[2] response = new_component(SubscriberSchema(), Subscriber, req, box_id) return response, 201 diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 0bcd0d0..795e78f 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -36,8 +36,7 @@ def get_property(self, command, *args, context=None): self._model.get_card('name', self._parent._parent.component_name).product in ('isdn', 'analog'): text = self._render('subscriberList_top', *scopes, context=context) i = 0 - for subscriber in self._model.subscribers: - if subscriber.portgroupport_id == port.id: + for subscriber in self._model.get_subscribers('portgroupport_id', port.id): context['i'] = i context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' @@ -61,7 +60,7 @@ def get_property(self, command, *args, context=None): text = self._render('isdnport_top', *scopes, context=dict(context, port=port)) i = 0 - for subscriber in self._model.subscribers: + for subscriber in self._model.get_subscribers('portgroupport_id', port.id): if subscriber.portgroupport_id == port.id: context['i'] = i context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' @@ -87,7 +86,7 @@ def get_property(self, command, *args, context=None): text = self._render('pstnport_top', *scopes, context=dict(context, port=port)) i = 0 - for subscriber in self._model.subscribers: + for subscriber in self._model.get_subscribers('portgroupport_id', port.id): if subscriber.portgroupport_id == port.id: context['i'] = i context['spacer10'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 7aa21cd..856b376 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -84,7 +84,7 @@ def get_property(self, command, *args, context=None): text = self._render('subscriberList_top', *scopes, context=context) i = 0 for subscriber in self._model.subscribers: - if subscriber.type == 'unit': + if subscriber.registration_state == 'Unregistered': context['i'] = i context['spacer1'] = self.create_spacers((63,), (subscriber.number,))[0] * ' ' context['spacer2'] = self.create_spacers((63,), (subscriber.registration_state,))[0] * ' ' From 57809efc15850610036a46a9745e8a67f464a6c1 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 28 Oct 2020 10:24:52 +0100 Subject: [PATCH 291/318] Fixed a bug with 'get CurrTemperature' --- vendors/KeyMile/accessPoints/root/rootCommandProcessor.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 8f2b740..53cc66a 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -25,12 +25,6 @@ class RootCommandProcessor(BaseCommandProcessor): from .rootManagementFunctions import fm from .rootManagementFunctions import status - def get_property(self, command, *args, context=None): - if self._validate(args, "CurrTemperature"): - context['currTemperature'] = self._model.currTemperature - context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' - self._write(self._render('currTemperature', 'login', 'base', 'get', context=context)) - def _init_access_points(self, context=None): self.access_points = ('eoam', 'fan', 'multicast', 'services', 'tdmConnections') for card in self._model.cards: @@ -105,7 +99,7 @@ def do_upload(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def get_property(self, command, *args, context=None): - scopes = ('login', 'base', 'set') + scopes = ('login', 'base', 'get') if self._validate(args, "CurrTemperature"): context['currTemperature'] = self._model.currTemperature context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' From 3c952ae6e160a138fd7300cbfb52bb9849c27c0d Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 28 Oct 2020 12:04:12 +0100 Subject: [PATCH 292/318] Fixed a bug where the context was missing from init_accespoints() --- vendors/KeyMile/baseCommandProcessor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 4a6ea49..dbac8a0 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -367,7 +367,7 @@ def change_directory(self, path, context=None): if context['path'].split('/')[-1] in ('main', 'cfgm', 'fm', 'pm', 'status'): raise exceptions.CommandExecutionError(command=None, template='invalid_address_error', template_scopes=('login', 'base', 'execution_errors')) - self._init_access_points() # make sure all management_functions are loaded correctly + self._init_access_points(context=context) # make sure all management_functions are loaded correctly if components[0] not in self.management_functions: raise exceptions.CommandExecutionError(command=None, template=None, From 259ded3b5be429f5f29e007d56e19e5df283037d Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 28 Oct 2020 14:15:05 +0100 Subject: [PATCH 293/318] Refactored args_in_quotes_joiner function and fixed a bug on 'set Labels' --- .../root/unit/port/portCommandProcessor.py | 8 ++++---- vendors/KeyMile/baseCommandProcessor.py | 12 ++++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index ae27fe7..ca398cd 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -364,8 +364,8 @@ def set(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': - label1, label2, description = self._dissect(args, 'Labels', str, str, str) + elif self._validate(self.args_in_quotes_joiner(args=args), 'Labels', str, str, str) and context['path'].split('/')[-1] == 'main': + label1, label2, description = self._dissect(self.args_in_quotes_joiner(args=args), 'Labels', str, str, str) try: port = self.get_component() port.set_label(label1, label2, description) @@ -376,7 +376,7 @@ def set(self, command, *args, context=None): elif self._validate(args, 'Mode', str) and context['path'].split('/')[-1] == 'cfgm' and "SUE" in \ card.board_name and self.__name__ == 'port' and card.product == 'ftth': if '"' in args[1]: - mode = self.args_in_quotes_joiner((args[1],)) + _, mode = self.args_in_quotes_joiner(args=args) else: mode, = self._dissect(args, 'Mode', str) try: @@ -389,7 +389,7 @@ def set(self, command, *args, context=None): elif self._validate(args, 'Mode', str, str, str) and context['path'].split('/')[-1] == 'cfgm' and "SUE" in \ card.board_name and self.__name__ == 'port' and card.product == 'ftth': if '"' in args[1]: - mode = self.args_in_quotes_joiner(args[1:]) + _, mode = self.args_in_quotes_joiner(args=args) else: mode, = self._dissect(args, 'Mode', str) try: diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index dbac8a0..b155631 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -569,15 +569,19 @@ def _init_context(self, context=None): context['ls_EquipmentState'] = '' def args_in_quotes_joiner(self, args): - saved_args = [] + quoted_args = [] + new_args = [] save = False for i in range(len(args)): if args[i].startswith("\""): save = True if save: - saved_args.append(args[i]) + quoted_args.append(args[i]) + else: + new_args.append(args[i]) if args[i].endswith("\""): save = False - name = ' '.join(saved_args).replace("\"", "") + new_args.append(' '.join(quoted_args).replace("\"", "")) + quoted_args = [] - return name + return new_args From 4ca8c26a2050df63ea7a82dd9530578b00c9e532 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 29 Oct 2020 14:36:39 +0100 Subject: [PATCH 294/318] Fixed a bug with CreateInterface on logports --- .../root/unit/logport/port/logportCommandProcessor.py | 6 +++--- .../root/unit/port/chan/chanCommandProcessor.py | 6 +++--- .../accessPoints/root/unit/port/portCommandProcessor.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index c4a9a61..87cc57b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -109,10 +109,10 @@ def do_createinterface(self, command, *args, context=None): new_id = int(interface.name[-1]) + 1 id = new_id if new_id > id else id try: - self._model.get_interface('name', self.component_name) + self._model.get_interface('name', self.component_name + '/' + str(id)) assert False - except exceptions.SoftboxenError as exe: - vcc = self._model.add_interface(name=self.component_name, logport_id=logport.id, vlan_profile=vlan_prof) + except exceptions.SoftboxenError: + self._model.add_interface(logport_id=logport.id, vlan_profile=vlan_prof) context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' context['id'] = str(id) # TODO: Template is unknown diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 27e1e46..6f3771c 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -102,7 +102,7 @@ def do_createinterface(self, command, *args, context=None): self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: - interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof) + interf = self._model.add_interface(chan_id=chan.id, vlan_profile=vlan_prof) context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' context['id'] = str(id) # TODO: Template is unknown @@ -129,7 +129,7 @@ def do_createinterface(self, command, *args, context=None): self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: - interf = self._model.add_interface(name=name, chan_id=chan.id, vlan_profile=vlan_prof, + interf = self._model.add_interface(chan_id=chan.id, vlan_profile=vlan_prof, vcc_profile=vcc_prof) context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' context['id'] = str(id) @@ -163,7 +163,7 @@ def do_createvcc(self, command, *args, context=None): self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: - vcc = self._model.add_interface(name=name, chan_id=chan.id, vcc_profile=vcc_prof, + vcc = self._model.add_interface(chan_id=chan.id, vcc_profile=vcc_prof, vlan_profile=vlan_prof) context['spacer1'] = self.create_spacers((63,), (str(id),))[0] * ' ' context['id'] = str(id) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index ca398cd..68c914b 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -291,7 +291,7 @@ def do_createinterface(self, command, *args, context=None): self._model.get_interface('name', name) assert False except exceptions.SoftboxenError as exe: - interf = self._model.add_interface(name=name, port_id=port.id, vlan_profile=vlan_prof) + interf = self._model.add_interface(port_id=port.id, vlan_profile=vlan_prof) context['spacer1'] = self.create_spacers((57,), (str(id),))[0] * ' ' context['id'] = str(id) # TODO: unknown Template From 72f3c8ff7286ba6c9786dd57141e041f60893574 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 30 Oct 2020 11:48:26 +0100 Subject: [PATCH 295/318] Implemented get IP_Address for root/cfgm and fixed a bug with prompt_end_pos --- nesi/softbox/api/models/box_models.py | 2 ++ nesi/softbox/api/schemas/box_schemas.py | 13 +++++++------ nesi/softbox/base_resources/box.py | 18 ++++++++++++++++++ templates/KeyMile/login/base/get/ip_address.j2 | 5 +++++ .../accessPoints/root/rootCommandProcessor.py | 16 ++++++++++++++++ vendors/KeyMile/baseCommandProcessor.py | 6 ++++++ 6 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 templates/KeyMile/login/base/get/ip_address.j2 diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 9ed22a9..ed49b65 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -53,6 +53,8 @@ class Box(db.Model): description = db.Column(db.String()) hostname = db.Column(db.String(64)) mgmt_address = db.Column(db.String(32)) + default_gateway = db.Column(db.String(32), default='0.0.0.0') + net_mask = db.Column(db.String(32), default='255.255.255.0') contact_person = db.Column(db.String(), default=None, nullable=True) isam_id = db.Column(db.String(), default=None, nullable=True) isam_location = db.Column(db.String(), default=None, nullable=True) diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index bb78496..2d5f6e9 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -31,12 +31,13 @@ class BoxSchema(ma.ModelSchema): class Meta: model = Box fields = ('id', 'vendor', 'model', 'version', 'software_version', 'network_protocol', 'network_address', - 'network_port', 'uuid', 'description', 'interfaces', 'logports', - 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', - 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'currTemperature', 'srvcs', - 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', 'ont_ports', 'cpes', - 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'mgmt_cards', 'mgmt_ports', - 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', '_links') + 'network_port', 'uuid', 'description', 'interfaces', 'logports', 'ont_ports', 'cpes', 'srvcs', + 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', 'mgmt_ports', + 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'currTemperature', + 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', + 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'mgmt_cards', + 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', + 'net_mask', 'default_gateway', '_links') credentials = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/base_resources/box.py b/nesi/softbox/base_resources/box.py index b050b5c..006e1a5 100644 --- a/nesi/softbox/base_resources/box.py +++ b/nesi/softbox/base_resources/box.py @@ -56,6 +56,12 @@ class Box(base.Resource): mgmt_address = base.Field('mgmt_address') """Management IP address""" + net_mask = base.Field('net_mask') + """Network Mask of the device""" + + default_gateway = base.Field('default_gateway') + """Default network gateway of the device""" + software_version = base.Field('software_version') """Software Version""" @@ -75,6 +81,18 @@ def set_hostname(self, name): """Change the hostname value.""" self.update(hostname=name) + def set_mgmt_address(self, ip): + """Change the mgmt_address value.""" + self.update(mgmt_address=ip) + + def set_net_mask(self, mask): + """Change the net_mask value.""" + self.update(net_mask=mask) + + def set_default_gateway(self, gateway): + """Change the default_gateway value.""" + self.update(default_gateway=gateway) + def set_last_login(self, time): """Change last_login value.""" self.update(last_login=time) diff --git a/templates/KeyMile/login/base/get/ip_address.j2 b/templates/KeyMile/login/base/get/ip_address.j2 new file mode 100644 index 0000000..4baceff --- /dev/null +++ b/templates/KeyMile/login/base/get/ip_address.j2 @@ -0,0 +1,5 @@ + \ # ManagementInterface +{{ context.ip_address }}{{ context.spacer1 }}\ # IpAddress +{{ context.net_mask }}{{ context.spacer2 }}\ # NetworkMask +{{ context.default_gateway }}{{ context.spacer3 }}\ # DefaultGateway + diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 53cc66a..b7fe8b4 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -64,6 +64,12 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc + elif self._validate(args, 'IP_Address', str, str, str): + new_ip, net_mask, gateway = self._dissect(args, 'IP_Address', str, str, str) + + self._model.set_mgmt_address(new_ip) + self._model.set_net_mask(net_mask) + self._model.set_default_gateway(gateway) elif self._validate(args, 'test', str): ip, = self._dissect(args, 'test', str) #TODO test case @@ -104,6 +110,16 @@ def get_property(self, command, *args, context=None): context['currTemperature'] = self._model.currTemperature context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' self._write(self._render('currTemperature', *scopes, context=context)) + elif self._validate(args, 'IP_Address'): + context['ip_address'] = self._model.mgmt_address + context['spacer1'] = self.create_spacers((67,), (self._model.mgmt_address,))[0] * ' ' + + context['net_mask'] = self._model.net_mask + context['spacer2'] = self.create_spacers((67,), (self._model.net_mask,))[0] * ' ' + + context['default_gateway'] = self._model.default_gateway + context['spacer3'] = self.create_spacers((67,), (self._model.default_gateway,))[0] * ' ' + self._write(self._render('ip_address', *scopes, context=context)) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index b155631..660457a 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -220,11 +220,13 @@ def do_ls(self, command, *args, context=None): tmp_cmdproc.ls(context=context) except exceptions.CommandExecutionError: context['path'] = current_path + self.set_prompt_end_pos(context=context) raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) context['path'] = current_path + self.set_prompt_end_pos(context=context) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), @@ -490,10 +492,12 @@ def do_get(self, command, *args, context=None): tmp_cmdproc.get_property(command, prop, context=context) except exceptions.SoftboxenError: context['path'] = current_path + self.set_prompt_end_pos(context=context) raise exceptions.CommandExecutionError(template='invalid_property', template_scopes=('login', 'base', 'syntax_errors'), command=None) context['path'] = current_path + self.set_prompt_end_pos(context=context) else: try: self.get_property(command, args[0], context=context) @@ -525,10 +529,12 @@ def do_set(self, command, *args, context=None): proc.set(command, *res, context=context) except exceptions.CommandExecutionError: context['path'] = current_path + self.set_prompt_end_pos(context=context) raise exceptions.CommandExecutionError(template='syntax_error', template_scopes=('login', 'base', 'syntax_errors'), command=None) context['path'] = current_path + self.set_prompt_end_pos(context=context) elif args[0].count('/') == 0: self.set(command, *args, context=context) From 59ea9384796d788676c376fb89389e61dba0ccbe Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 30 Oct 2020 12:25:28 +0100 Subject: [PATCH 296/318] Fixed an issue with creating interfaces on non VDSL cards --- .../accessPoints/root/unit/port/chan/chanCommandProcessor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py index 6f3771c..bcfc07d 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/chan/chanCommandProcessor.py @@ -113,7 +113,7 @@ def do_createinterface(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm' and 'SUV' in card.board_name: + elif self._validate(args, str, str) and context['path'].split('/')[-1] == 'cfgm': # vcc profile and vlan profile vlan_prof, vcc_prof = self._dissect(args, str, str) # TODO: Check if profiles := default or profile names From d17f57e81fb568a691b3b10be40138467387f599 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 30 Oct 2020 13:06:41 +0100 Subject: [PATCH 297/318] Fixed a bug with get digitmap --- vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py index 856b376..5f4cdc3 100644 --- a/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/unitCommandProcessor.py @@ -295,7 +295,7 @@ def set(self, command, *args, context=None): card.set_sip(gw, hd, int(spn), cc, ac, int(rt), int(mri), se, aim, os, int(ot), uac, uas, int(sessione)) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - elif self._validate(args[0], 'Digitmap') and \ + elif self._validate((args[0],), 'Digitmap') and \ context['path'].split('/')[-1] == 'cfgm' and (card.product == 'isdn' or card.product == 'analog'): pass elif self._validate(args, 'Registrar', str, str, str, str) and \ From 4c1569f26a83f12c81d3222b42cfb2e1d92b9a69 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 4 Nov 2020 15:25:24 +0100 Subject: [PATCH 298/318] Fixed line and melt-test templates according to real device output --- .../keymile_portgroupport.py | 2 +- .../login/base/get/line_results_device.j2 | 63 ++++++++++++++++ ...{line__results.j2 => line_results_docu.j2} | 0 .../login/base/get/melt_results_device.j2 | 71 +++++++++++++++++++ .../{melt_results.j2 => melt_results_docu.j2} | 0 .../root/unit/port/portCommandProcessor.py | 8 +-- 6 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 templates/KeyMile/login/base/get/line_results_device.j2 rename templates/KeyMile/login/base/get/{line__results.j2 => line_results_docu.j2} (100%) create mode 100644 templates/KeyMile/login/base/get/melt_results_device.j2 rename templates/KeyMile/login/base/get/{melt_results.j2 => melt_results_docu.j2} (100%) diff --git a/nesi/keymile/keymile_resources/keymile_portgroupport.py b/nesi/keymile/keymile_resources/keymile_portgroupport.py index ce52bb6..7cbf510 100644 --- a/nesi/keymile/keymile_resources/keymile_portgroupport.py +++ b/nesi/keymile/keymile_resources/keymile_portgroupport.py @@ -73,7 +73,7 @@ def set_pstnport(self, enable, registerglobal, phone, sip, proxy, codec, pstn, e self.update(enterprise_profile=enterprise) def set_isdnport(self, enable, registerglobal, regdefault, layer1, sip, proxy, codec, isdn): - """Set the pstnport""" + """Set the isdnport""" self.update(enable=enable) self.update(register_as_global=registerglobal) self.update(register_default_number_only=regdefault) diff --git a/templates/KeyMile/login/base/get/line_results_device.j2 b/templates/KeyMile/login/base/get/line_results_device.j2 new file mode 100644 index 0000000..86eceee --- /dev/null +++ b/templates/KeyMile/login/base/get/line_results_device.j2 @@ -0,0 +1,63 @@ + \ # LineTestStatus +1970-01-01T00:00:00 \ # TimeStamp +{{ context.test_state }}{{ context.spacer }}\ # State +{ \ # Results + \ # [0] # + "Foreign DC Voltage a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [1] # + "Foreign DC Voltage b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [2] # + "Foreign DC Voltage a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [3] # + "Foreign AC Voltage a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [4] # + "Foreign AC Voltage b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [5] # + "Foreign AC Voltage a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [6] # + "Isolation a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [7] # + "Isolation b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [8] # + "Resistance b-a" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [9] # + "Resistance a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [10] # + "Capacitance a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [11] # + "Capacitance b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [12] # + "Capacitance a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [13] # + "Noise" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ +} \ + diff --git a/templates/KeyMile/login/base/get/line__results.j2 b/templates/KeyMile/login/base/get/line_results_docu.j2 similarity index 100% rename from templates/KeyMile/login/base/get/line__results.j2 rename to templates/KeyMile/login/base/get/line_results_docu.j2 diff --git a/templates/KeyMile/login/base/get/melt_results_device.j2 b/templates/KeyMile/login/base/get/melt_results_device.j2 new file mode 100644 index 0000000..6eeceff --- /dev/null +++ b/templates/KeyMile/login/base/get/melt_results_device.j2 @@ -0,0 +1,71 @@ + \ # MeasurementStatus +1970-01-01T00:00:27 \ # TimeStamp +{{ context.test_state }}{{ context.spacer }}\ # State +{ \ # Results + \ # [0] # + "Foreign DC Voltage a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [1] # + "Foreign DC Voltage a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [2] # + "Foreign DC Voltage b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [3] # + "Foreign AC Voltage a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [4] # + "Foreign AC Voltage a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [5] # + "Foreign AC Voltage b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [6] # + "Resistance a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [7] # + "Resistance a-b (pos)" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [8] # + "Resistance a-b (neg)" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [9] # + "Isolation a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [10] # + "Isolation b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [11] # + "Capacitance a-b" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [12] # + "Capacitance a-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [13] # + "Capacitance b-GND" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [14] # + "PPA detected" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ # [15] # + "PPA Resistance" \ # TestDescription + NotTested \ # Status + "" \ # MeasuredValue +; \ +} \ + diff --git a/templates/KeyMile/login/base/get/melt_results.j2 b/templates/KeyMile/login/base/get/melt_results_docu.j2 similarity index 100% rename from templates/KeyMile/login/base/get/melt_results.j2 rename to templates/KeyMile/login/base/get/melt_results_docu.j2 diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 68c914b..5fd42bf 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -101,15 +101,15 @@ def get_property(self, command, *args, context=None): self._write(text) elif self._validate((args[0],), 'LineTestResults') and context['path'].split('/')[-1] == 'status'\ and 'SUP' in card.board_name and self.__name__ == 'port': - context['spacer1'] = self.create_spacers((67,), (port.linetest_state,))[0] * ' ' + context['spacer'] = self.create_spacers((67,), (port.linetest_state,))[0] * ' ' context['test_state'] = port.linetest_state - text = self._render('line_results', *scopes, context=context) + text = self._render('line_results_device', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'MeltResults') and context['path'].split('/')[-1] == 'status'\ and card.product != 'isdn' and self.__name__ == 'port': - context['spacer1'] = self.create_spacers((67,), (port.melttest_state,))[0] * ' ' + context['spacer'] = self.create_spacers((67,), (port.melttest_state,))[0] * ' ' context['test_state'] = port.melttest_state - text = self._render('melt_results', *scopes, context=context) + text = self._render('melt_results_device', *scopes, context=context) self._write(text) elif self._validate((args[0],), 'AdministrativeStatus') and context['path'].split('/')[-1] == 'main': self.map_states(port, 'port') From ddd2ec4b533b820e8f551484218decfbecf46ada Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 4 Nov 2020 15:57:57 +0100 Subject: [PATCH 299/318] Fixed access to lock and unlock functions --- templates/KeyMile/login/base/get/quickloopbacktest.j2 | 2 +- .../accessPoints/root/unit/port/portCommandProcessor.py | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/templates/KeyMile/login/base/get/quickloopbacktest.j2 b/templates/KeyMile/login/base/get/quickloopbacktest.j2 index 38b4f82..126938e 100644 --- a/templates/KeyMile/login/base/get/quickloopbacktest.j2 +++ b/templates/KeyMile/login/base/get/quickloopbacktest.j2 @@ -1,3 +1,3 @@ \ # QuickLoopbackTest -{{ context.loopbacktest_state }}{{ context.spacer1 }}\ # State +{{ context.loopbacktest_state }}{{ context.spacer }}\ # State diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index 5fd42bf..eb97fa2 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -95,7 +95,7 @@ def get_property(self, command, *args, context=None): self._write(text) elif self._validate((args[0],), 'QuickLoopbackTest') and context['path'].split('/')[-1] == 'status'\ and (card.product == 'isdn' or 'SUI' in card.board_name) and self.__name__ == 'port': - context['spacer1'] = self.create_spacers((67,), (port.loopbacktest_state,))[0] * ' ' + context['spacer'] = self.create_spacers((67,), (port.loopbacktest_state,))[0] * ' ' context['loopbacktest_state'] = port.loopbacktest_state text = self._render('quickloopbacktest', *scopes, context=context) self._write(text) @@ -187,8 +187,7 @@ def _init_context(self, context=None): def do_lock(self, command, *args, context=None): card = self._model.get_card('name', self.component_name.split('/')[0]) - if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ - and self.__name__ == 'port': + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and (card.board_name.startswith('SUP') or card.board_name.startswith('SUI')) and self.__name__ == 'port': try: port = self.get_component() port.lock_admin() @@ -241,8 +240,7 @@ def do_startmeltmeasurement(self, command, *args, context=None): def do_unlock(self, command, *args, context=None): card = self._model.get_card('name', self.component_name.split('/')[0]) - if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ - and self.__name__ == 'port': + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and (card.board_name.startswith('SUP') or card.board_name.startswith('SUI')) and self.__name__ == 'port': try: port = self.get_component() port.unlock_admin() From 4a10e51f9d4eb45c9b477d8c1cb5d21f2d8aac2e Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 4 Nov 2020 16:00:29 +0100 Subject: [PATCH 300/318] Only allowing quickloopbacktest on cards of type SUIxx --- .../KeyMile/accessPoints/root/unit/port/portCommandProcessor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py index eb97fa2..7449412 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/portCommandProcessor.py @@ -198,7 +198,7 @@ def do_lock(self, command, *args, context=None): def do_startquickloopbacktest(self, command, *args, context=None): card = self._model.get_card('name', self.component_name.split('/')[0]) - if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.product == 'isdn' \ + if len(args) == 0 and context['path'].split('/')[-1] == 'status' and card.board_name.startswith('SUI') \ and self.__name__ == 'port': try: port = self.get_component() From 636ddd7f5379f390ab37b97054be997d56004a88 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Tue, 10 Nov 2020 14:41:03 +0100 Subject: [PATCH 301/318] Minor changes on ftpserver and upload command structures --- .../api/schemas/keymile_box_schemas.py | 4 ++-- nesi/keymile/keymile_resources/keymile_box.py | 20 ++++++++----------- nesi/softbox/api/models/box_models.py | 7 +++---- .../accessPoints/root/rootCommandProcessor.py | 20 ------------------- vendors/KeyMile/baseCommandProcessor.py | 20 +++++++++++++++++++ 5 files changed, 33 insertions(+), 38 deletions(-) diff --git a/nesi/keymile/api/schemas/keymile_box_schemas.py b/nesi/keymile/api/schemas/keymile_box_schemas.py index de66bed..303bd0c 100644 --- a/nesi/keymile/api/schemas/keymile_box_schemas.py +++ b/nesi/keymile/api/schemas/keymile_box_schemas.py @@ -17,8 +17,8 @@ class KeyMileBoxSchema(BoxSchema): class Meta: model = Box - fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature', 'logports', 'backup_ip', 'login', - 'password', 'backup_path') + fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature', 'logports', 'ftp_server_ip', 'ftp_login', + 'ftp_password') interfaces = ma.Hyperlinks( {'_links': { diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index 33da588..d311bd7 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -28,18 +28,14 @@ class KeyMileBox(Box): """ currTemperature = base.Field("currTemperature") - backup_ip = base.Field("backup_ip") - login = base.Field("login") - password = base.Field("password") - backup_path = base.Field("backup_path") - - def set_backup(self, backup_ip, login, password): - self.update(backup_ip=backup_ip) - self.update(login=login) - self.update(password=password) - - def set_path(self, path): - self.update(backup_path=path) + ftp_server_ip = base.Field("backup_ip") + ftp_login = base.Field("login") + ftp_password = base.Field("password") + + def set_ftp_data(self, ftp_server_ip, login, password): + self.update(ftp_server_ip=ftp_server_ip) + self.update(ftp_login=login) + self.update(ftp_password=password) @property def channels(self): diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index ed49b65..14c60df 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -130,7 +130,6 @@ class Box(db.Model): dsl_mode = db.Column(db.Enum('tr165', 'tr129'), default='tr165') currTemperature = db.Column(db.Integer(), default=15) - backup_ip = db.Column(db.String(), default='') - login = db.Column(db.String(), default='') - password = db.Column(db.String(), default='') - backup_path = db.Column(db.String(), default='') + ftp_server_ip = db.Column(db.String(), default='') + ftp_login = db.Column(db.String(), default='') + ftp_password = db.Column(db.String(), default='') diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index b7fe8b4..6461133 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -84,26 +84,6 @@ def do_save(self, command, *args, context=None): else: raise exceptions.CommandSyntaxError(command=command) - def do_ftpserver(self, command, *args, context=None): - if self._validate(args, str, str, str) and context['path'].split('/')[-1] != 'cfgm': - ip, login, pw = self._dissect(args, str, str, str) - try: - self._model.set_backup(ip, login, pw) - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError(command=command) - else: - raise exceptions.CommandSyntaxError(command=command) - - def do_upload(self, command, *args, context=None): - if self._validate(args, '/cfgm/configuration', str) and context['path'].split('/')[-1] != 'cfgm': - path, = self._dissect(args, '/cfgm/configuration', str) - try: - self._model.set_path(path) - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError(command=command) - else: - raise exceptions.CommandSyntaxError(command=command) - def get_property(self, command, *args, context=None): scopes = ('login', 'base', 'get') if self._validate(args, "CurrTemperature"): diff --git a/vendors/KeyMile/baseCommandProcessor.py b/vendors/KeyMile/baseCommandProcessor.py index 660457a..071caed 100644 --- a/vendors/KeyMile/baseCommandProcessor.py +++ b/vendors/KeyMile/baseCommandProcessor.py @@ -10,6 +10,7 @@ # # License: https://github.com/inexio/NESi/LICENSE.rst +from time import sleep from nesi import exceptions from nesi.softbox.cli import base import re @@ -52,10 +53,12 @@ def on_unknown_command(self, command, *args, context=None): command_proc._parse_and_execute_command(command, context=context) except exceptions.SoftboxenError: context['path'] = current_path + self.set_prompt_end_pos(context=context) raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), command=None) context['path'] = current_path + self.set_prompt_end_pos(context=context) else: raise exceptions.CommandExecutionError(template='invalid_management_function_error', template_scopes=('login', 'base', 'execution_errors'), @@ -65,6 +68,23 @@ def on_unknown_command(self, command, *args, context=None): template_scopes=('login', 'base', 'execution_errors'), command=None) + def do_ftpserver(self, command, *args, context=None): + if self._validate(args, str, str, str): + ip, login, pw = self._dissect(args, str, str, str) + try: + self._model.set_ftp_data(ip, login, pw) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_upload(self, command, *args, context=None): + if self._validate(args, '/cfgm/configuration', str) and context['path'].split('/')[-1] != 'cfgm': + path, = self._dissect(args, '/cfgm/configuration', str) + sleep(10) # NOTE: as of now there is no ftp server mocking + # mechanism so the only way to simulate an upload is by doing a sleep + else: + raise exceptions.CommandSyntaxError(command=command) def map_states(self, object, type): if object.admin_state == '0': From 75f0836d8d6b95fe9c5b80af24dca5b2ecb0815b Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 12 Nov 2020 14:45:22 +0100 Subject: [PATCH 302/318] Restructured code of set pstnport/isdnport --- .../port/portgroupportCommandProcessor.py | 124 +++++++----------- 1 file changed, 51 insertions(+), 73 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index 795e78f..ddfc0a7 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -127,82 +127,60 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'pstnport', str, str, str, str, str, str, str, str, str) and \ - context['path'].split('/')[-1] == 'cfgm': - enable, subident, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', - str, str, str, str, str, str, str, str, str) - try: - port = self.get_component() - enable = True if enable.lower() == 'true' else False - register = True if register.lower() == 'true' else False - phone = True if phone.lower() == 'true' else False - port.set_pstnport(enable, register, phone, sip, proxy, codec, pstn, enterprise) - except exceptions.SoftboxenError: - raise exceptions.CommandExecutionError(command=command, template='invalid_property', - template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'pstnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, - str) and context['path'].split('/')[-1] == 'cfgm': - enable, number, username, password, displayname, privacy, register, phone, sip, proxy, codec, pstn, enterprise = self._dissect(args, 'pstnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) - try: - port = self.get_component() - try: - subscriber = self._model.get_subscriber('number', int(number)) - subscriber.set('autorisation_user_name', username) - subscriber.set('autorisation_password', password) - subscriber.set('display_name', displayname) - subscriber.set('privacy', privacy) - except exceptions.SoftboxenError: - address = self.component_name - subscriber = self._model.add_subscriber(number=int(number), autorisation_user_name=username, - address=address, privacy=privacy, type='port', - display_name=displayname, autorisation_password=password) - pass - enable = True if enable.lower() == 'true' else False - register = True if register.lower() == 'true' else False - phone = True if phone.lower() == 'true' else False - port.set_pstnport(enable, register, phone, sip, proxy, codec, pstn, enterprise) - except exceptions.SoftboxenError as exe: - raise exceptions.CommandExecutionError(command=command, template='invalid_property', - template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'isdnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, - str) and context['path'].split('/')[-1] == 'cfgm': - enable, number, username, password, displayname, privacy, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', str, '{', str, str, str, str, str, '}', str, str, str, str, str, str, str) + elif args[0] in ('pstnport', 'isdnport') and context['path'].split('/')[-1] == 'cfgm': + enable = True if args[1].lower() == 'true' else False + number = None + username = '' + password = '' + displayname = '' + privacy = 'None' + index_end = 2 + if args[2] != '{}': + index_start = args.index('{') + index_end = args.index('}') + number = args[index_start + 1] if index_start + 1 < index_end else None + username = args[index_start + 2] if index_start + 2 < index_end else '' + password = args[index_start + 3] if index_start + 3 < index_end else '' + displayname = args[index_start + 4] if index_start + 4 < index_end else '' + privacy = args[index_start + 5] if index_start + 5 < index_end else 'None' + + register = True if args[index_end + 1].lower() == 'true' else False + try: port = self.get_component() - try: - subscriber = self._model.get_subscriber('number', int(number)) - assert subscriber.address == self.component_name - subscriber.set('autorisation_user_name', username) - subscriber.set('autorisation_password', password) - subscriber.set('display_name', displayname) - subscriber.set('privacy', privacy) - except exceptions.SoftboxenError: - address = self.component_name - subscriber = self._model.add_subscriber(number=int(number), autorisation_user_name=username, - address=address, privacy=privacy, type='port', - display_name=displayname, autorisation_password=password) + if number is not None: + try: + subscriber = self._model.get_subscriber('number', int(number)) + if username is not None: + subscriber.set('autorisation_user_name', username) + if password is not None: + subscriber.set('autorisation_password', password) + if displayname is not None: + subscriber.set('display_name', displayname) + if privacy is not None: + subscriber.set('privacy', privacy) + except exceptions.SoftboxenError: + address = self.component_name + self._model.add_subscriber(number=int(number), autorisation_user_name=username, + address=address, privacy=privacy, display_name=displayname, + autorisation_password=password, portgroupport_id=port.id) pass - except AssertionError: - raise exceptions.SoftboxenError() - enable = True if enable.lower() == 'true' else False - register = True if register.lower() == 'true' else False - regdefault = True if regdefault.lower() == 'true' else False - layer1 = True if layer1.lower() == 'true' else False - port.set_isdnport(enable, register, regdefault, layer1, sip, proxy, codec, isdnba) - except exceptions.SoftboxenError as exe: - raise exceptions.CommandExecutionError(command=command, template='invalid_property', - template_scopes=('login', 'base', 'execution_errors')) - elif self._validate(args, 'isdnport', str, str, str, str, str, str, str, str, str) and \ - context['path'].split('/')[-1] == 'cfgm': - enable, subident, register, regdefault, layer1, sip, proxy, codec, isdnba = self._dissect(args, 'isdnport', - str, str, str, str, str, str, str, str, str) - try: - port = self.get_component() - enable = True if enable.lower() == 'true' else False - register = True if register.lower() == 'true' else False - regdefault = True if regdefault.lower() == 'true' else False - layer1 = True if layer1.lower() == 'true' else False - port.set_isdnport(enable, register, regdefault, layer1, sip, proxy, codec, isdnba) + if args[0] == 'isdnport': + regdefault = True if args[index_end + 2].lower().lower() == 'true' else False + layer1 = True if args[index_end + 3].lower() == 'true' else False + sip = args[index_end + 4] + proxy = args[index_end + 5] + codec = args[index_end + 6] + isdnba = args[index_end + 7] + port.set_isdnport(enable, register, regdefault, layer1, sip, proxy, codec, isdnba) + elif args[0] == 'pstnport': + phone = True if args[index_end + 2].lower() == 'true' else False + sip = args[index_end + 3] + proxy = args[index_end + 4] + codec = args[index_end + 5] + pstn = args[index_end + 6] + enterprise = args[index_end + 7] + port.set_pstnport(enable, register, phone, sip, proxy, codec, pstn, enterprise) except exceptions.SoftboxenError: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) From d1fe41ac55e52da621b84feb2da431d035ac0bf2 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 12 Nov 2020 15:15:08 +0100 Subject: [PATCH 303/318] Changed the accepted command structure for set pstnport/isdnport --- .../port/portgroupportCommandProcessor.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py index ddfc0a7..126721d 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/port/portgroupportCommandProcessor.py @@ -136,13 +136,16 @@ def set(self, command, *args, context=None): privacy = 'None' index_end = 2 if args[2] != '{}': - index_start = args.index('{') - index_end = args.index('}') - number = args[index_start + 1] if index_start + 1 < index_end else None - username = args[index_start + 2] if index_start + 2 < index_end else '' - password = args[index_start + 3] if index_start + 3 < index_end else '' - displayname = args[index_start + 4] if index_start + 4 < index_end else '' - privacy = args[index_start + 5] if index_start + 5 < index_end else 'None' + if args[2].startswith('{') and args[2].endswith('}'): + number = args[2][1:-1] + else: + index_start = args.index('{') + index_end = args.index('}') + number = args[index_start + 1] if index_start + 1 < index_end else None + username = args[index_start + 2] if index_start + 2 < index_end else '' + password = args[index_start + 3] if index_start + 3 < index_end else '' + displayname = args[index_start + 4] if index_start + 4 < index_end else '' + privacy = args[index_start + 5] if index_start + 5 < index_end else 'None' register = True if args[index_end + 1].lower() == 'true' else False From 307b5fe8cb6c198897baa2f507254ad686a84fc8 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 12 Nov 2020 15:39:26 +0100 Subject: [PATCH 304/318] Removed cases from set functions --- vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py | 4 ---- .../KeyMile/accessPoints/root/multicastCommandProcessor.py | 4 ---- vendors/KeyMile/accessPoints/root/rootCommandProcessor.py | 4 ---- .../root/services/macaccessctrlCommandProcessor.py | 4 ---- .../accessPoints/root/services/packetCommandProcessor.py | 4 ---- .../accessPoints/root/services/servicesCommandProcessor.py | 4 ---- .../accessPoints/root/tdmconnectionsCommandProcessor.py | 4 ---- .../root/unit/logport/logportsCommandProcessor.py | 4 ---- .../root/unit/logport/port/logportCommandProcessor.py | 4 ---- .../root/unit/port/interface/interfaceCommandProcessor.py | 4 ---- .../root/unit/portgroup/portgroupCommandProcessor.py | 4 ---- 11 files changed, 44 deletions(-) diff --git a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py index b93f9c8..5c9dd85 100644 --- a/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/eoamCommandProcessor.py @@ -29,9 +29,5 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py index f431b36..940da1d 100644 --- a/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/multicastCommandProcessor.py @@ -31,9 +31,5 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index 6461133..a28f43d 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -70,10 +70,6 @@ def set(self, command, *args, context=None): self._model.set_mgmt_address(new_ip) self._model.set_net_mask(net_mask) self._model.set_default_gateway(gateway) - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py index 62a9227..995a39c 100644 --- a/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/macaccessctrlCommandProcessor.py @@ -34,10 +34,6 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - # TODO test case - return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py index 68d1d83..51173c3 100644 --- a/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/packetCommandProcessor.py @@ -31,10 +31,6 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - # TODO test case - return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py index 522103d..c2ff987 100644 --- a/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/services/servicesCommandProcessor.py @@ -33,10 +33,6 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - # TODO test case - return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py index 2c3ff28..0cd0f2e 100644 --- a/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/tdmconnectionsCommandProcessor.py @@ -28,9 +28,5 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return else: raise exceptions.CommandSyntaxError(command=command) \ No newline at end of file diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py index 9b16d08..acae680 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/logportsCommandProcessor.py @@ -97,9 +97,5 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - name, = self._dissect(args, 'test', str) - #todo testcase - return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py index 87cc57b..524347e 100644 --- a/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/logport/port/logportCommandProcessor.py @@ -136,10 +136,6 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - # TODO test case - return else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) diff --git a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py index 09b833f..012f532 100644 --- a/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/port/interface/interfaceCommandProcessor.py @@ -30,10 +30,6 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return else: raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py index 96d132c..74fc2e6 100644 --- a/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/unit/portgroup/portgroupCommandProcessor.py @@ -44,9 +44,5 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'test', str): - ip, = self._dissect(args, 'test', str) - #TODO test case - return else: raise exceptions.CommandSyntaxError(command=command) From 20e3047dda9e1dedf357249aa0bb592d23809bce Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 12 Nov 2020 16:21:37 +0100 Subject: [PATCH 305/318] Added set/get VlanId command options and functionalities --- .../api/schemas/keymile_box_schemas.py | 2 +- nesi/keymile/keymile_resources/keymile_box.py | 5 +++++ nesi/softbox/api/models/box_models.py | 1 + templates/KeyMile/login/base/get/vlan_id.j2 | 3 +++ .../accessPoints/root/rootCommandProcessor.py | 19 ++++++++++++++++--- 5 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 templates/KeyMile/login/base/get/vlan_id.j2 diff --git a/nesi/keymile/api/schemas/keymile_box_schemas.py b/nesi/keymile/api/schemas/keymile_box_schemas.py index 303bd0c..55234d1 100644 --- a/nesi/keymile/api/schemas/keymile_box_schemas.py +++ b/nesi/keymile/api/schemas/keymile_box_schemas.py @@ -18,7 +18,7 @@ class KeyMileBoxSchema(BoxSchema): class Meta: model = Box fields = BoxSchema.Meta.fields + ('channels', 'interfaces', 'currTemperature', 'logports', 'ftp_server_ip', 'ftp_login', - 'ftp_password') + 'ftp_password', 'network_element_management_vlan_id') interfaces = ma.Hyperlinks( {'_links': { diff --git a/nesi/keymile/keymile_resources/keymile_box.py b/nesi/keymile/keymile_resources/keymile_box.py index d311bd7..c049149 100644 --- a/nesi/keymile/keymile_resources/keymile_box.py +++ b/nesi/keymile/keymile_resources/keymile_box.py @@ -31,6 +31,7 @@ class KeyMileBox(Box): ftp_server_ip = base.Field("backup_ip") ftp_login = base.Field("login") ftp_password = base.Field("password") + network_element_management_vlan_id = base.Field('network_element_management_vlan_id') def set_ftp_data(self, ftp_server_ip, login, password): self.update(ftp_server_ip=ftp_server_ip) @@ -241,6 +242,10 @@ def add_srvc(self, **fields): os.path.join(self.path, 'srvcs'), **fields) + def set_vlan_id(self, vlan_id): + """Change the network element management vlan.""" + self.update(network_element_management_vlan_id=vlan_id) + class KeyMileBoxCollection(BoxCollection): """Represent a collection of boxen. diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 14c60df..ffd91c9 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -133,3 +133,4 @@ class Box(db.Model): ftp_server_ip = db.Column(db.String(), default='') ftp_login = db.Column(db.String(), default='') ftp_password = db.Column(db.String(), default='') + network_element_management_vlan_id = db.Column(db.Integer(), default=None) diff --git a/templates/KeyMile/login/base/get/vlan_id.j2 b/templates/KeyMile/login/base/get/vlan_id.j2 new file mode 100644 index 0000000..0d643c3 --- /dev/null +++ b/templates/KeyMile/login/base/get/vlan_id.j2 @@ -0,0 +1,3 @@ + \ # ManagementVlan +{{ context.vlan_id }}{{ context.spacer }}\ # VlanId + diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py index a28f43d..091b9aa 100644 --- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py +++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py @@ -64,7 +64,16 @@ def set(self, command, *args, context=None): exc.template = 'syntax_error' exc.template_scopes = ('login', 'base', 'syntax_errors') raise exc - elif self._validate(args, 'IP_Address', str, str, str): + elif self._validate(args, 'VlanId', str) and context['path'].split('/')[-1] == 'cfgm': + vlan_id, = self._dissect(args, 'VlanId', str) + vlan_id = int(vlan_id) + if not 1 < vlan_id < 4089: + raise exceptions.CommandExecutionError(template='syntax_error', + template_scopes=('login', 'base', 'syntax_errors'), + command=None) + + self._model.set_vlan_id(vlan_id) + elif self._validate(args, 'IP_Address', str, str, str) and context['path'].split('/')[-1] == 'cfgm': new_ip, net_mask, gateway = self._dissect(args, 'IP_Address', str, str, str) self._model.set_mgmt_address(new_ip) @@ -82,11 +91,11 @@ def do_save(self, command, *args, context=None): def get_property(self, command, *args, context=None): scopes = ('login', 'base', 'get') - if self._validate(args, "CurrTemperature"): + if self._validate(args, "CurrTemperature") and context['path'].split('/')[-1] == 'status': context['currTemperature'] = self._model.currTemperature context['spacer'] = self.create_spacers((67,), (context['currTemperature'],))[0] * ' ' self._write(self._render('currTemperature', *scopes, context=context)) - elif self._validate(args, 'IP_Address'): + elif self._validate(args, 'IP_Address') and context['path'].split('/')[-1] == 'cfgm': context['ip_address'] = self._model.mgmt_address context['spacer1'] = self.create_spacers((67,), (self._model.mgmt_address,))[0] * ' ' @@ -96,6 +105,10 @@ def get_property(self, command, *args, context=None): context['default_gateway'] = self._model.default_gateway context['spacer3'] = self.create_spacers((67,), (self._model.default_gateway,))[0] * ' ' self._write(self._render('ip_address', *scopes, context=context)) + elif self._validate(args, 'VlanId') and context['path'].split('/')[-1] == 'cfgm': + context['vlan_id'] = self._model.network_element_management_vlan_id + context['spacer'] = self.create_spacers((67,), (context['vlan_id'],))[0] * ' ' + self._write(self._render('vlan_id', *scopes, context=context)) else: raise exceptions.CommandExecutionError(command=command, template='invalid_property', template_scopes=('login', 'base', 'execution_errors')) From b2db921f22e2c397a6231292e850b5454e0a4e5c Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 13 Nov 2020 09:02:28 +0100 Subject: [PATCH 306/318] Removed obsolete numbers from test case filenames --- .../integration_tests/keymile/{getDslam4.txt => getDslam.txt} | 0 .../keymile/{getInventory2.txt => getInventory.txt} | 0 .../integration_tests/keymile/{getIpsx7.txt => getIpsx.txt} | 0 .../keymile/{getMonitoring3.txt => getMonitoring.txt} | 0 .../integration_tests/keymile/{getState1.txt => getState.txt} | 0 .../keymile/{getSubscriber6.txt => getSubscriber.txt} | 0 .../integration_tests/keymile/{getVoice5.txt => getVoice.txt} | 0 .../keymile/{setChannelProfile14.txt => setChannelProfile.txt} | 1 - .../keymile/{setDslProfile8.txt => setDslProfile.txt} | 0 .../keymile/{setInterface16.txt => setInterface.txt} | 0 .../integration_tests/keymile/{setIpAddr6.txt => setIpAddr.txt} | 0 .../keymile/{setportaktiv4.txt => setPortActive.txt} | 0 .../keymile/{setportdeactiv5.txt => setPortDeactive.txt} | 0 .../keymile/{setPortProfile13.txt => setPortProfile.txt} | 0 .../keymile/{setSIPDomain12.txt => setSIPDomain.txt} | 0 .../keymile/{setTraffic1.txt => setTraffic.txt} | 0 .../integration_tests/keymile/{setVCC15.txt => setVCC.txt} | 0 .../keymile/{setconfDsl2.txt => setconfDsl.txt} | 0 .../keymile/{setconfVoice9.txt => setconfVoice.txt} | 0 .../keymile/{setdeconfVoicePort11.txt => setdeconfVoicePort.txt} | 0 .../{setdeconfVoicePort17.txt => setdeconfVoicePortIsdn.txt} | 0 .../keymile/{setunconfDsl3.txt => setunconfDsl.txt} | 0 .../keymile/{testLoopback3.txt => testLoopback.txt} | 0 .../keymile/{testVoicePort2.txt => testVoicePort.txt} | 0 .../keymile/{testmelting4.txt => testmelting.txt} | 0 25 files changed, 1 deletion(-) rename test_cases/integration_tests/keymile/{getDslam4.txt => getDslam.txt} (100%) rename test_cases/integration_tests/keymile/{getInventory2.txt => getInventory.txt} (100%) rename test_cases/integration_tests/keymile/{getIpsx7.txt => getIpsx.txt} (100%) rename test_cases/integration_tests/keymile/{getMonitoring3.txt => getMonitoring.txt} (100%) rename test_cases/integration_tests/keymile/{getState1.txt => getState.txt} (100%) rename test_cases/integration_tests/keymile/{getSubscriber6.txt => getSubscriber.txt} (100%) rename test_cases/integration_tests/keymile/{getVoice5.txt => getVoice.txt} (100%) rename test_cases/integration_tests/keymile/{setChannelProfile14.txt => setChannelProfile.txt} (96%) rename test_cases/integration_tests/keymile/{setDslProfile8.txt => setDslProfile.txt} (100%) rename test_cases/integration_tests/keymile/{setInterface16.txt => setInterface.txt} (100%) rename test_cases/integration_tests/keymile/{setIpAddr6.txt => setIpAddr.txt} (100%) rename test_cases/integration_tests/keymile/{setportaktiv4.txt => setPortActive.txt} (100%) rename test_cases/integration_tests/keymile/{setportdeactiv5.txt => setPortDeactive.txt} (100%) rename test_cases/integration_tests/keymile/{setPortProfile13.txt => setPortProfile.txt} (100%) rename test_cases/integration_tests/keymile/{setSIPDomain12.txt => setSIPDomain.txt} (100%) rename test_cases/integration_tests/keymile/{setTraffic1.txt => setTraffic.txt} (100%) rename test_cases/integration_tests/keymile/{setVCC15.txt => setVCC.txt} (100%) rename test_cases/integration_tests/keymile/{setconfDsl2.txt => setconfDsl.txt} (100%) rename test_cases/integration_tests/keymile/{setconfVoice9.txt => setconfVoice.txt} (100%) rename test_cases/integration_tests/keymile/{setdeconfVoicePort11.txt => setdeconfVoicePort.txt} (100%) rename test_cases/integration_tests/keymile/{setdeconfVoicePort17.txt => setdeconfVoicePortIsdn.txt} (100%) rename test_cases/integration_tests/keymile/{setunconfDsl3.txt => setunconfDsl.txt} (100%) rename test_cases/integration_tests/keymile/{testLoopback3.txt => testLoopback.txt} (100%) rename test_cases/integration_tests/keymile/{testVoicePort2.txt => testVoicePort.txt} (100%) rename test_cases/integration_tests/keymile/{testmelting4.txt => testmelting.txt} (100%) diff --git a/test_cases/integration_tests/keymile/getDslam4.txt b/test_cases/integration_tests/keymile/getDslam.txt similarity index 100% rename from test_cases/integration_tests/keymile/getDslam4.txt rename to test_cases/integration_tests/keymile/getDslam.txt diff --git a/test_cases/integration_tests/keymile/getInventory2.txt b/test_cases/integration_tests/keymile/getInventory.txt similarity index 100% rename from test_cases/integration_tests/keymile/getInventory2.txt rename to test_cases/integration_tests/keymile/getInventory.txt diff --git a/test_cases/integration_tests/keymile/getIpsx7.txt b/test_cases/integration_tests/keymile/getIpsx.txt similarity index 100% rename from test_cases/integration_tests/keymile/getIpsx7.txt rename to test_cases/integration_tests/keymile/getIpsx.txt diff --git a/test_cases/integration_tests/keymile/getMonitoring3.txt b/test_cases/integration_tests/keymile/getMonitoring.txt similarity index 100% rename from test_cases/integration_tests/keymile/getMonitoring3.txt rename to test_cases/integration_tests/keymile/getMonitoring.txt diff --git a/test_cases/integration_tests/keymile/getState1.txt b/test_cases/integration_tests/keymile/getState.txt similarity index 100% rename from test_cases/integration_tests/keymile/getState1.txt rename to test_cases/integration_tests/keymile/getState.txt diff --git a/test_cases/integration_tests/keymile/getSubscriber6.txt b/test_cases/integration_tests/keymile/getSubscriber.txt similarity index 100% rename from test_cases/integration_tests/keymile/getSubscriber6.txt rename to test_cases/integration_tests/keymile/getSubscriber.txt diff --git a/test_cases/integration_tests/keymile/getVoice5.txt b/test_cases/integration_tests/keymile/getVoice.txt similarity index 100% rename from test_cases/integration_tests/keymile/getVoice5.txt rename to test_cases/integration_tests/keymile/getVoice.txt diff --git a/test_cases/integration_tests/keymile/setChannelProfile14.txt b/test_cases/integration_tests/keymile/setChannelProfile.txt similarity index 96% rename from test_cases/integration_tests/keymile/setChannelProfile14.txt rename to test_cases/integration_tests/keymile/setChannelProfile.txt index 52f2a2d..1697bff 100644 --- a/test_cases/integration_tests/keymile/setChannelProfile14.txt +++ b/test_cases/integration_tests/keymile/setChannelProfile.txt @@ -3,7 +3,6 @@ secret cd /unit-5/port-1/chan-1/cfgm set chanprofile profile set chanprofile default -#else cd /unit-5/port-1/chan-1/cfgm set ProfileName $profile set ProfileName default diff --git a/test_cases/integration_tests/keymile/setDslProfile8.txt b/test_cases/integration_tests/keymile/setDslProfile.txt similarity index 100% rename from test_cases/integration_tests/keymile/setDslProfile8.txt rename to test_cases/integration_tests/keymile/setDslProfile.txt diff --git a/test_cases/integration_tests/keymile/setInterface16.txt b/test_cases/integration_tests/keymile/setInterface.txt similarity index 100% rename from test_cases/integration_tests/keymile/setInterface16.txt rename to test_cases/integration_tests/keymile/setInterface.txt diff --git a/test_cases/integration_tests/keymile/setIpAddr6.txt b/test_cases/integration_tests/keymile/setIpAddr.txt similarity index 100% rename from test_cases/integration_tests/keymile/setIpAddr6.txt rename to test_cases/integration_tests/keymile/setIpAddr.txt diff --git a/test_cases/integration_tests/keymile/setportaktiv4.txt b/test_cases/integration_tests/keymile/setPortActive.txt similarity index 100% rename from test_cases/integration_tests/keymile/setportaktiv4.txt rename to test_cases/integration_tests/keymile/setPortActive.txt diff --git a/test_cases/integration_tests/keymile/setportdeactiv5.txt b/test_cases/integration_tests/keymile/setPortDeactive.txt similarity index 100% rename from test_cases/integration_tests/keymile/setportdeactiv5.txt rename to test_cases/integration_tests/keymile/setPortDeactive.txt diff --git a/test_cases/integration_tests/keymile/setPortProfile13.txt b/test_cases/integration_tests/keymile/setPortProfile.txt similarity index 100% rename from test_cases/integration_tests/keymile/setPortProfile13.txt rename to test_cases/integration_tests/keymile/setPortProfile.txt diff --git a/test_cases/integration_tests/keymile/setSIPDomain12.txt b/test_cases/integration_tests/keymile/setSIPDomain.txt similarity index 100% rename from test_cases/integration_tests/keymile/setSIPDomain12.txt rename to test_cases/integration_tests/keymile/setSIPDomain.txt diff --git a/test_cases/integration_tests/keymile/setTraffic1.txt b/test_cases/integration_tests/keymile/setTraffic.txt similarity index 100% rename from test_cases/integration_tests/keymile/setTraffic1.txt rename to test_cases/integration_tests/keymile/setTraffic.txt diff --git a/test_cases/integration_tests/keymile/setVCC15.txt b/test_cases/integration_tests/keymile/setVCC.txt similarity index 100% rename from test_cases/integration_tests/keymile/setVCC15.txt rename to test_cases/integration_tests/keymile/setVCC.txt diff --git a/test_cases/integration_tests/keymile/setconfDsl2.txt b/test_cases/integration_tests/keymile/setconfDsl.txt similarity index 100% rename from test_cases/integration_tests/keymile/setconfDsl2.txt rename to test_cases/integration_tests/keymile/setconfDsl.txt diff --git a/test_cases/integration_tests/keymile/setconfVoice9.txt b/test_cases/integration_tests/keymile/setconfVoice.txt similarity index 100% rename from test_cases/integration_tests/keymile/setconfVoice9.txt rename to test_cases/integration_tests/keymile/setconfVoice.txt diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort11.txt b/test_cases/integration_tests/keymile/setdeconfVoicePort.txt similarity index 100% rename from test_cases/integration_tests/keymile/setdeconfVoicePort11.txt rename to test_cases/integration_tests/keymile/setdeconfVoicePort.txt diff --git a/test_cases/integration_tests/keymile/setdeconfVoicePort17.txt b/test_cases/integration_tests/keymile/setdeconfVoicePortIsdn.txt similarity index 100% rename from test_cases/integration_tests/keymile/setdeconfVoicePort17.txt rename to test_cases/integration_tests/keymile/setdeconfVoicePortIsdn.txt diff --git a/test_cases/integration_tests/keymile/setunconfDsl3.txt b/test_cases/integration_tests/keymile/setunconfDsl.txt similarity index 100% rename from test_cases/integration_tests/keymile/setunconfDsl3.txt rename to test_cases/integration_tests/keymile/setunconfDsl.txt diff --git a/test_cases/integration_tests/keymile/testLoopback3.txt b/test_cases/integration_tests/keymile/testLoopback.txt similarity index 100% rename from test_cases/integration_tests/keymile/testLoopback3.txt rename to test_cases/integration_tests/keymile/testLoopback.txt diff --git a/test_cases/integration_tests/keymile/testVoicePort2.txt b/test_cases/integration_tests/keymile/testVoicePort.txt similarity index 100% rename from test_cases/integration_tests/keymile/testVoicePort2.txt rename to test_cases/integration_tests/keymile/testVoicePort.txt diff --git a/test_cases/integration_tests/keymile/testmelting4.txt b/test_cases/integration_tests/keymile/testmelting.txt similarity index 100% rename from test_cases/integration_tests/keymile/testmelting4.txt rename to test_cases/integration_tests/keymile/testmelting.txt From 5c64311764fbdb619e061ea76648248ee1c14c1b Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 13 Nov 2020 09:14:43 +0100 Subject: [PATCH 307/318] Fixed some integration tests --- test_cases/integration_tests/keymile/backup.txt | 4 ++++ test_cases/integration_tests/keymile/setDslProfile.txt | 3 --- test_cases/integration_tests/keymile/setconfVoice.txt | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) delete mode 100644 test_cases/integration_tests/keymile/setDslProfile.txt diff --git a/test_cases/integration_tests/keymile/backup.txt b/test_cases/integration_tests/keymile/backup.txt index 5db5c11..df2a0c5 100644 --- a/test_cases/integration_tests/keymile/backup.txt +++ b/test_cases/integration_tests/keymile/backup.txt @@ -1,3 +1,7 @@ manager secret +ftpserver 128.0.0.2 testuser testpass +cd /cfgm +save +upload /cfgm/configuration /testtftp/backups/keymilebackup.conf exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setDslProfile.txt b/test_cases/integration_tests/keymile/setDslProfile.txt deleted file mode 100644 index 5db5c11..0000000 --- a/test_cases/integration_tests/keymile/setDslProfile.txt +++ /dev/null @@ -1,3 +0,0 @@ -manager -secret -exit \ No newline at end of file diff --git a/test_cases/integration_tests/keymile/setconfVoice.txt b/test_cases/integration_tests/keymile/setconfVoice.txt index c25801f..66632b0 100644 --- a/test_cases/integration_tests/keymile/setconfVoice.txt +++ b/test_cases/integration_tests/keymile/setconfVoice.txt @@ -1,14 +1,14 @@ manager secret cd /unit-19/portgroup-1/port-1/cfgm -set pstnport true 11 true false none none none none none +set pstnport true { 11 } true false none none none none none cd /unit-19/portgroup-1/port-1/main Set Labels "ssdd" "sssd" "" cd /unit-19/port-1/main set AdministrativeStatus up Set Labels www "carrierLineId" "" cd /unit-19/portgroup-2/port-1/cfgm -set isdnport true 112 true false none none none none none +set isdnport true {112} true false none none none none none cd /unit-19/portgroup-2/port-1/main Set Labels dada "test" "" cd /unit-19/port-1/main From 1c8c9308d665a841d80e56adf4cacc5cfa04901f Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 18 Nov 2020 18:03:50 +0100 Subject: [PATCH 308/318] Removed credential_id from user and added user_id to credentials, several changes regarding this topic --- bootup/conf/bootstraps/create-alcatel-7360.sh | 16 ++--- bootup/conf/bootstraps/create-huawei-5623.sh | 20 +++---- .../conf/bootstraps/create-keymile-MG2500.sh | 58 +++++++++---------- nesi/softbox/api/models/box_models.py | 2 +- nesi/softbox/api/models/credential_models.py | 1 + nesi/softbox/api/models/mgmt_port_models.py | 1 + nesi/softbox/api/models/user_models.py | 3 +- nesi/softbox/api/schemas/box_schemas.py | 3 + .../softbox/api/schemas/credential_schemas.py | 2 +- nesi/softbox/api/schemas/mgmt_card_schemas.py | 4 +- nesi/softbox/api/schemas/user_schemas.py | 7 ++- nesi/softbox/base_resources/credentials.py | 1 + nesi/softbox/base_resources/user.py | 1 - test_cases/unit_tests/huawei/test_huawei.py | 2 +- vendors/Huawei/configCommandProcessor.py | 10 +--- vendors/Huawei/main.py | 2 +- 16 files changed, 70 insertions(+), 63 deletions(-) diff --git a/bootup/conf/bootstraps/create-alcatel-7360.sh b/bootup/conf/bootstraps/create-alcatel-7360.sh index a1b2009..fbad234 100755 --- a/bootup/conf/bootstraps/create-alcatel-7360.sh +++ b/bootup/conf/bootstraps/create-alcatel-7360.sh @@ -101,21 +101,21 @@ req='{ box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 -# Create login credentials at the switch (admin operation) +# Admin user req='{ - "username": "admin", - "password": "secret" + "name": "Admin" }' -admin_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) +admin_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) -# Admin user +# Create login credentials at the switch (admin operation) req='{ - "name": "admin", - "credentials_id": '$admin_credential_id' + "username": "admin", + "password": "secret", + "user_id": '$admin_id' }' -admin_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) +admin_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) # PortProfile 1 req='{ diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index fe9b521..0e8b9dc 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -123,18 +123,9 @@ req='{ box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 -# Super Admin credentials -req='{ - "username": "root", - "password": "secret" -}' - -root_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) - # Super Admin user req='{ - "name": "root", - "credentials_id": '$root_credential_id', + "name": "Root", "level": "Super", "profile": "root", "append_info": "Super Admin", @@ -145,6 +136,15 @@ req='{ root_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) +# Super Admin credentials +req='{ + "username": "root", + "password": "secret", + "user_id": '$root_id' +}' + +root_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + # Service Profile req='{ "name": "line_spectrum_1", diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index c32e56d..9a1c66a 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -79,7 +79,7 @@ req='{ "hostname": "KeyMileMG2500", "mgmt_address": "10.0.0.12", "software_version": "MG2500V800R016C00", - "network_protocol": "telnet", + "network_protocol": "ssh", "network_address": "127.0.0.1", "network_port": 9023, "uuid": "2500", @@ -88,18 +88,9 @@ req='{ box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 -# Sessionmanager credentials -req='{ - "username": "sessionmanager", - "password": "secret" -}' - -sessionmanager_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) - # Sessionmanager user req='{ - "name": "sessionmanager", - "credentials_id": '$sessionmanager_credential_id', + "name": "Session Manager", "level": "Super", "profile": "root", "append_info": "Sessionmanager", @@ -108,18 +99,18 @@ req='{ sessionmanager_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) -# Manager credentials +# Sessionmanager credentials req='{ - "username": "manager", - "password": "secret" + "username": "sessionmanager", + "password": "secret", + "user_id": '$sessionmanager_id' }' -manager_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) +sessionmanager_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) # Manager user req='{ - "name": "manager", - "credentials_id": '$manager_credential_id', + "name": "Manager", "level": "Admin", "profile": "admin", "append_info": "Manager", @@ -128,18 +119,18 @@ req='{ manager_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) -# Maintenance credentials +# Manager credentials req='{ - "username": "maintenance", - "password": "secret" + "username": "manager", + "password": "secret", + "user_id": '$manager_id' }' -maintenance_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) +manager_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) # Manager user req='{ - "name": "maintenance", - "credentials_id": '$maintenance_credential_id', + "name": "Maintenance", "level": "Operator", "profile": "operator", "append_info": "Maintenance", @@ -148,18 +139,18 @@ req='{ maintenance_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) -# Information credentials +# Maintenance credentials req='{ - "username": "information", - "password": "secret" + "username": "maintenance", + "password": "secret", + "user_id": '$maintenance_id' }' -information_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) +maintenance_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) # Manager user req='{ - "name": "information", - "credentials_id": '$information_credential_id', + "name": "Information", "level": "User", "profile": "commonuser", "append_info": "Information", @@ -168,6 +159,15 @@ req='{ information_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) +# Information credentials +req='{ + "username": "information", + "password": "secret", + "user_id": '$information_id' +}' + +information_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + ### Nto1-Service-1 ### # Create a physical port at the network device (admin operation) diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index ffd91c9..4e39385 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -63,7 +63,7 @@ class Box(db.Model): credentials = db.relationship('Credential', backref='Box', lazy='dynamic') credential_details = db.relationship('Credential', backref='credentials', lazy='dynamic') users = db.relationship('User', backref='Box', lazy='dynamic') - + user_details = db.relationship('User', backref='users', lazy='dynamic') subracks = db.relationship('Subrack', backref='Box', lazy='dynamic') subrack_details = db.relationship('Subrack', backref='subracks', lazy='dynamic') cards = db.relationship('Card', backref='Box', lazy='dynamic') diff --git a/nesi/softbox/api/models/credential_models.py b/nesi/softbox/api/models/credential_models.py index 7271d64..242d925 100644 --- a/nesi/softbox/api/models/credential_models.py +++ b/nesi/softbox/api/models/credential_models.py @@ -17,6 +17,7 @@ class Credential(db.Model): id = db.Column(db.Integer(), primary_key=True) protocol = db.Column( db.Enum('password'), nullable=False, default='password') + user_id = db.Column(db.Integer, db.ForeignKey('user.id')) username = db.Column(db.String(64), nullable=True) password = db.Column(db.String(32), nullable=True) box_id = db.Column(db.Integer, db.ForeignKey('box.id')) diff --git a/nesi/softbox/api/models/mgmt_port_models.py b/nesi/softbox/api/models/mgmt_port_models.py index eb1b56e..85ca3ca 100644 --- a/nesi/softbox/api/models/mgmt_port_models.py +++ b/nesi/softbox/api/models/mgmt_port_models.py @@ -12,6 +12,7 @@ # License: https://github.com/inexio/NESi/LICENSE.rst from nesi.softbox.api import db + class MgmtPort(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(64)) diff --git a/nesi/softbox/api/models/user_models.py b/nesi/softbox/api/models/user_models.py index 2add0be..860ed31 100644 --- a/nesi/softbox/api/models/user_models.py +++ b/nesi/softbox/api/models/user_models.py @@ -9,6 +9,7 @@ # - Alexander Dincher # # License: https://github.com/inexio/NESi/LICENSE.rst +from .credential_models import Credential from nesi.softbox.api import db @@ -17,7 +18,7 @@ class User(db.Model): id = db.Column(db.Integer(), primary_key=True) box_id = db.Column(db.Integer(), db.ForeignKey('box.id')) - credentials_id = db.Column(db.Integer(), db.ForeignKey('credential.id')) + credential_details = db.relationship('Credential', backref='User', lazy='dynamic') name = db.Column(db.String(), default='user') level = db.Column(db.Enum('Super', 'Admin', 'Operator', 'User'), default='User') status = db.Column(db.Enum('Online', 'Offline'), default='Offline') diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index 2d5f6e9..62f6fe3 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -17,6 +17,7 @@ from ..schemas.credential_schemas import CredentialsSchema from ..schemas.vlan_schemas import VlansSchema from ..schemas.portprofile_schemas import PortProfilesSchema +from ..schemas.user_schemas import UsersSchema class RootSchema(ma.ModelSchema): @@ -49,6 +50,8 @@ class Meta: {'_links': { 'self': ma.URLFor('show_users', box_id='')}}) + user_details = ma.Nested(UsersSchema.UserSchema, many=True) + subracks = ma.Hyperlinks( {'_links': { 'self': ma.URLFor('show_subracks', box_id='')}}) diff --git a/nesi/softbox/api/schemas/credential_schemas.py b/nesi/softbox/api/schemas/credential_schemas.py index 7259d53..c81a5a7 100644 --- a/nesi/softbox/api/schemas/credential_schemas.py +++ b/nesi/softbox/api/schemas/credential_schemas.py @@ -18,7 +18,7 @@ class CredentialSchema(ma.ModelSchema): class Meta: model = Credential fields = ('id', 'protocol', 'credential', 'username', 'password', - 'box', 'box_id', '_links') + 'box', 'box_id', 'user_id', '_links') box = ma.Hyperlinks( {'_links': { diff --git a/nesi/softbox/api/schemas/mgmt_card_schemas.py b/nesi/softbox/api/schemas/mgmt_card_schemas.py index c03f1c5..e455a6f 100644 --- a/nesi/softbox/api/schemas/mgmt_card_schemas.py +++ b/nesi/softbox/api/schemas/mgmt_card_schemas.py @@ -40,7 +40,9 @@ class Meta: class MgmtCardSchema(ma.ModelSchema): class Meta: model = MgmtCard - fields = ('id', 'name', '_links') + fields = ('id', 'name', 'operational_state', 'mgmt_ports', '_links') + + mgmt_ports = ma.Nested(MgmtPortsSchema.MgmtPortSchema, many=True) _links = ma.Hyperlinks( {'self': ma.URLFor( diff --git a/nesi/softbox/api/schemas/user_schemas.py b/nesi/softbox/api/schemas/user_schemas.py index 6341cd0..b574ef6 100644 --- a/nesi/softbox/api/schemas/user_schemas.py +++ b/nesi/softbox/api/schemas/user_schemas.py @@ -12,12 +12,15 @@ from nesi.softbox.api import ma from ..models.user_models import User +from ..schemas.credential_schemas import CredentialsSchema class UserSchema(ma.ModelSchema): class Meta: model = User - fields = ('id', 'box', 'box_id', 'credentials_id', 'name', '_links') + fields = ('id', 'box', 'box_id', 'credential_details', 'name', '_links') + + credential_details = ma.Nested(CredentialsSchema.CredentialSchema, many=True) box = ma.Hyperlinks( {'_links': { @@ -35,7 +38,7 @@ class Meta: class UserSchema(ma.ModelSchema): class Meta: model = User - fields = ('id', 'name', '_links') + fields = ('id', 'name', 'status', '_links') _links = ma.Hyperlinks( {'self': ma.URLFor( diff --git a/nesi/softbox/base_resources/credentials.py b/nesi/softbox/base_resources/credentials.py index dc48bd6..271f97d 100644 --- a/nesi/softbox/base_resources/credentials.py +++ b/nesi/softbox/base_resources/credentials.py @@ -21,6 +21,7 @@ class Credentials(base.Resource): """Represent user credentials.""" id = base.Field('id') + user_id = base.Field('user_id') protocol = base.Field('protocol') username = base.Field('username') password = base.Field('password') diff --git a/nesi/softbox/base_resources/user.py b/nesi/softbox/base_resources/user.py index a82a0eb..a8368a2 100644 --- a/nesi/softbox/base_resources/user.py +++ b/nesi/softbox/base_resources/user.py @@ -20,7 +20,6 @@ class User(base.Resource): """Represents a logical User resource""" id = base.Field('id') - credentials_id = base.Field('credentials_id') name = base.Field('name') diff --git a/test_cases/unit_tests/huawei/test_huawei.py b/test_cases/unit_tests/huawei/test_huawei.py index dc2d5e9..41989b7 100644 --- a/test_cases/unit_tests/huawei/test_huawei.py +++ b/test_cases/unit_tests/huawei/test_huawei.py @@ -192,7 +192,7 @@ def test_service_vlan(self): assert True def test_user(self): - user = self.model.get_user("name", 'root') + user = self.model.get_user("name", 'Root') assert user.lock_status == 'Unlocked' user.lock() assert user.lock_status == 'Locked' diff --git a/vendors/Huawei/configCommandProcessor.py b/vendors/Huawei/configCommandProcessor.py index b948005..bc4fb7b 100644 --- a/vendors/Huawei/configCommandProcessor.py +++ b/vendors/Huawei/configCommandProcessor.py @@ -962,19 +962,15 @@ def do_terminal(self, command, *args, context=None): info = self.user_input(" User's Appended Info(<=30 chars):", False, 30) box = self._model - box.add_credentials(username=login, password=password) - try: - creds = self._model.get_credentials('username', login) - except exceptions.SoftboxenError: - raise exceptions.CommandSyntaxError(command=command) - - box.add_user(name=login, credentials_id=creds.id, level=lvl, profile=profile, reenter_num=reenter_num, + box.add_user(name=login, level=lvl, profile=profile, reenter_num=reenter_num, reenter_num_temp=reenter_num, append_info=info, lock_status='Unlocked') try: user = self._model.get_user('name', login) except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) + box.add_credentials(username=login, password=password, user_id=user.id) + text = self._render('user_created', context=context) self._write(text) diff --git a/vendors/Huawei/main.py b/vendors/Huawei/main.py index a93ce3f..ae00fd4 100644 --- a/vendors/Huawei/main.py +++ b/vendors/Huawei/main.py @@ -43,7 +43,7 @@ def on_unknown_command(self, command, *args, context=None): for creds in self._model.credentials: if creds.username == username and creds.password == password: - user = self._model.get_user('credentials_id', creds.id) + user = self._model.get_user('id', creds.user_id) if user.lock_status == 'Locked': text = self._render('user_locked', context=context) self._write(text) From ec335c7bce7b239bb6927eeb6b7f51ff0545fb03 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 19 Nov 2020 08:57:29 +0100 Subject: [PATCH 309/318] Added user_details to box fields --- nesi/softbox/api/schemas/box_schemas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py index 62f6fe3..eb5b802 100644 --- a/nesi/softbox/api/schemas/box_schemas.py +++ b/nesi/softbox/api/schemas/box_schemas.py @@ -36,7 +36,7 @@ class Meta: 'hostname', 'mgmt_address', 'credentials', 'credential_details', 'port_profiles', 'mgmt_ports', 'port_profile_details', 'vlans', 'service_vlans', 'vlan_details', 'subscribers', 'currTemperature', 'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts', - 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'portgroupports', 'mgmt_cards', + 'cpe_ports', 'routes', 'login_banner', 'vlan_interfaces', 'users', 'user_details', 'portgroupports', 'mgmt_cards', 'welcome_banner', 'last_login', 'last_logout', 'sntp_server_ip_address', 'timezone_offset', 'net_mask', 'default_gateway', '_links') From bc94cff0be45294c3ad7745bf25746c09fddc8ee Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 20 Nov 2020 10:01:16 +0100 Subject: [PATCH 310/318] Changes according to UI --- bootup/conf/bootstraps/create-huawei-5623.sh | 2 +- bootup/conf/bootstraps/create-keymile-MG2500.sh | 10 +++++----- nesi/huawei/api/schemas/huawei_user_schemas.py | 4 ++-- nesi/huawei/huawei_resources/huawei_user.py | 10 ++++------ nesi/softbox/api/models/user_models.py | 4 ++-- nesi/softbox/api/schemas/user_schemas.py | 2 +- nesi/softbox/base_resources/user.py | 2 ++ test_cases/unit_tests/huawei/test_huawei.py | 12 ++++++------ vendors/Huawei/baseMixIn.py | 2 +- vendors/Huawei/configCommandProcessor.py | 8 ++++---- vendors/Huawei/diagnoseCommandProcessor.py | 4 ++-- vendors/Huawei/enableCommandProcessor.py | 6 +++--- vendors/Huawei/huaweiBaseCommandProcessor.py | 3 ++- vendors/Huawei/main.py | 2 +- vendors/Huawei/userViewCommandProcessor.py | 2 +- 15 files changed, 37 insertions(+), 36 deletions(-) diff --git a/bootup/conf/bootstraps/create-huawei-5623.sh b/bootup/conf/bootstraps/create-huawei-5623.sh index 0e8b9dc..a95a429 100644 --- a/bootup/conf/bootstraps/create-huawei-5623.sh +++ b/bootup/conf/bootstraps/create-huawei-5623.sh @@ -131,7 +131,7 @@ req='{ "append_info": "Super Admin", "reenter_num": 3, "reenter_num_temp": 3, - "lock_status": "Unlocked" + "lock_status": "unlocked" }' root_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) diff --git a/bootup/conf/bootstraps/create-keymile-MG2500.sh b/bootup/conf/bootstraps/create-keymile-MG2500.sh index 9a1c66a..f87a252 100644 --- a/bootup/conf/bootstraps/create-keymile-MG2500.sh +++ b/bootup/conf/bootstraps/create-keymile-MG2500.sh @@ -79,7 +79,7 @@ req='{ "hostname": "KeyMileMG2500", "mgmt_address": "10.0.0.12", "software_version": "MG2500V800R016C00", - "network_protocol": "ssh", + "network_protocol": "telnet", "network_address": "127.0.0.1", "network_port": 9023, "uuid": "2500", @@ -94,7 +94,7 @@ req='{ "level": "Super", "profile": "root", "append_info": "Sessionmanager", - "lock_status": "Unlocked" + "lock_status": "unlocked" }' sessionmanager_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) @@ -114,7 +114,7 @@ req='{ "level": "Admin", "profile": "admin", "append_info": "Manager", - "lock_status": "Unlocked" + "lock_status": "unlocked" }' manager_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) @@ -134,7 +134,7 @@ req='{ "level": "Operator", "profile": "operator", "append_info": "Maintenance", - "lock_status": "Unlocked" + "lock_status": "unlocked" }' maintenance_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) @@ -154,7 +154,7 @@ req='{ "level": "User", "profile": "commonuser", "append_info": "Information", - "lock_status": "Unlocked" + "lock_status": "unlocked" }' information_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) diff --git a/nesi/huawei/api/schemas/huawei_user_schemas.py b/nesi/huawei/api/schemas/huawei_user_schemas.py index 2ab3e86..4264e1a 100644 --- a/nesi/huawei/api/schemas/huawei_user_schemas.py +++ b/nesi/huawei/api/schemas/huawei_user_schemas.py @@ -4,5 +4,5 @@ class HuaweiUserSchema(UserSchema): class Meta: model = User - fields = UserSchema.Meta.fields + ('level', 'status', 'profile', 'append_info', 'reenter_num', - 'reenter_num_temp', 'lock_status') + fields = UserSchema.Meta.fields + ('level', 'profile', 'append_info', 'reenter_num', + 'reenter_num_temp') diff --git a/nesi/huawei/huawei_resources/huawei_user.py b/nesi/huawei/huawei_resources/huawei_user.py index 090f2cf..d3acc6b 100644 --- a/nesi/huawei/huawei_resources/huawei_user.py +++ b/nesi/huawei/huawei_resources/huawei_user.py @@ -20,24 +20,22 @@ class HuaweiUser(User): """Represents a logical User resource""" level = base.Field('level') - status = base.Field('status') profile = base.Field('profile') append_info = base.Field('append_info') reenter_num = base.Field('reenter_num') reenter_num_temp = base.Field('reenter_num_temp') - lock_status = base.Field('lock_status') def set_online(self): - self.update(status='Online') + self.update(status='online') def set_offline(self): - self.update(status='Offline') + self.update(status='offline') def lock(self): - self.update(lock_status='Locked') + self.update(lock_status='locked') def unlock(self): - self.update(lock_status='Unlocked') + self.update(lock_status='unlocked') def set_reenter_num_temp(self, num): self.update(reenter_num_temp=num) diff --git a/nesi/softbox/api/models/user_models.py b/nesi/softbox/api/models/user_models.py index 860ed31..aef11d0 100644 --- a/nesi/softbox/api/models/user_models.py +++ b/nesi/softbox/api/models/user_models.py @@ -21,9 +21,9 @@ class User(db.Model): credential_details = db.relationship('Credential', backref='User', lazy='dynamic') name = db.Column(db.String(), default='user') level = db.Column(db.Enum('Super', 'Admin', 'Operator', 'User'), default='User') - status = db.Column(db.Enum('Online', 'Offline'), default='Offline') + status = db.Column(db.Enum('online', 'offline'), default='offline') profile = db.Column(db.Enum('root', 'admin', 'operator', 'commonuser'), default='commonuser') append_info = db.Column(db.String(), default='-----') reenter_num = db.Column(db.Integer(), default=3) reenter_num_temp = db.Column(db.Integer(), default=3) - lock_status = db.Column(db.Enum('Locked', 'Unlocked'), default='Unlocked') + lock_status = db.Column(db.Enum('locked', 'unlocked'), default='unlocked') diff --git a/nesi/softbox/api/schemas/user_schemas.py b/nesi/softbox/api/schemas/user_schemas.py index b574ef6..6bd71c0 100644 --- a/nesi/softbox/api/schemas/user_schemas.py +++ b/nesi/softbox/api/schemas/user_schemas.py @@ -18,7 +18,7 @@ class UserSchema(ma.ModelSchema): class Meta: model = User - fields = ('id', 'box', 'box_id', 'credential_details', 'name', '_links') + fields = ('id', 'box', 'box_id', 'credential_details', 'name', 'status', 'lock_status', '_links') credential_details = ma.Nested(CredentialsSchema.CredentialSchema, many=True) diff --git a/nesi/softbox/base_resources/user.py b/nesi/softbox/base_resources/user.py index a8368a2..9e13703 100644 --- a/nesi/softbox/base_resources/user.py +++ b/nesi/softbox/base_resources/user.py @@ -21,6 +21,8 @@ class User(base.Resource): id = base.Field('id') name = base.Field('name') + status = base.Field('status') + lock_status = base.Field('lock_status') class UserCollection(base.ResourceCollection): diff --git a/test_cases/unit_tests/huawei/test_huawei.py b/test_cases/unit_tests/huawei/test_huawei.py index 41989b7..e836525 100644 --- a/test_cases/unit_tests/huawei/test_huawei.py +++ b/test_cases/unit_tests/huawei/test_huawei.py @@ -193,11 +193,11 @@ def test_service_vlan(self): def test_user(self): user = self.model.get_user("name", 'Root') - assert user.lock_status == 'Unlocked' + assert user.lock_status == 'unlocked' user.lock() - assert user.lock_status == 'Locked' + assert user.lock_status == 'locked' user.unlock() - assert user.lock_status == 'Unlocked' + assert user.lock_status == 'unlocked' assert user.reenter_num_temp == 3 user.set_reenter_num_temp(1) @@ -208,11 +208,11 @@ def test_user(self): except exceptions.SoftboxenError: assert True - assert user.status == 'Offline' + assert user.status == 'offline' user.set_online() - assert user.status == 'Online' + assert user.status == 'online' user.set_offline() - assert user.status == 'Offline' + assert user.status == 'offline' def test_vlan(self): vlan = self.model.get_vlan('number', 2620) diff --git a/vendors/Huawei/baseMixIn.py b/vendors/Huawei/baseMixIn.py index 2c80975..b1a8035 100644 --- a/vendors/Huawei/baseMixIn.py +++ b/vendors/Huawei/baseMixIn.py @@ -34,7 +34,7 @@ def do_config(self, command, *args, context=None): try: - admin = self._model.get_user('status', 'Online') + admin = self._model.get_user('status', 'online') assert admin.level != 'User' except (exceptions.SoftboxenError, AssertionError): raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/Huawei/configCommandProcessor.py b/vendors/Huawei/configCommandProcessor.py index bc4fb7b..bf18286 100644 --- a/vendors/Huawei/configCommandProcessor.py +++ b/vendors/Huawei/configCommandProcessor.py @@ -888,7 +888,7 @@ def do_system(self, command, *args, context=None): raise exceptions.CommandSyntaxError(command=command) def do_terminal(self, command, *args, context=None): - creating_user = self._model.get_user('status', 'Online') + creating_user = self._model.get_user('status', 'online') if creating_user.level != 'Super' and creating_user.level != 'Admin': raise exceptions.CommandSyntaxError(command=command) if self._validate(args, 'user', 'name'): @@ -963,7 +963,7 @@ def do_terminal(self, command, *args, context=None): box = self._model box.add_user(name=login, level=lvl, profile=profile, reenter_num=reenter_num, - reenter_num_temp=reenter_num, append_info=info, lock_status='Unlocked') + reenter_num_temp=reenter_num, append_info=info, lock_status='unlocked') try: user = self._model.get_user('name', login) except exceptions.SoftboxenError: @@ -991,11 +991,11 @@ def do_terminal(self, command, *args, context=None): except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) - if locked_user.lock_status == 'Locked': + if locked_user.lock_status == 'locked': locked_user.set_reenter_num_temp(locked_user.reenter_num) locked_user.unlock() return - elif locked_user.lock_status == 'Unlocked': + elif locked_user.lock_status == 'unlocked': text = self._render('user_already_unlocked', context=context) self._write(text) else: diff --git a/vendors/Huawei/diagnoseCommandProcessor.py b/vendors/Huawei/diagnoseCommandProcessor.py index 911369a..8df1c24 100644 --- a/vendors/Huawei/diagnoseCommandProcessor.py +++ b/vendors/Huawei/diagnoseCommandProcessor.py @@ -108,7 +108,7 @@ def on_unknown_command(self, command, *args, context=None): def do_switch(self, command, *args, context=None): if self._validate(args, 'vdsl', 'mode', 'to', str): - user = self._model.get_user('status', 'Online') + user = self._model.get_user('status', 'online') if user.level != 'Super': raise exceptions.CommandSyntaxError(command=command) @@ -166,7 +166,7 @@ def do_switch(self, command, *args, context=None): self.on_cycle(context=context) time.sleep(10) self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) - user = self._model.get_user('status', 'Online') + user = self._model.get_user('status', 'online') user.set_offline() exc = exceptions.TerminalExitError() exc.return_to = 'sysreboot' diff --git a/vendors/Huawei/enableCommandProcessor.py b/vendors/Huawei/enableCommandProcessor.py index e7d93b4..bbca42d 100644 --- a/vendors/Huawei/enableCommandProcessor.py +++ b/vendors/Huawei/enableCommandProcessor.py @@ -33,7 +33,7 @@ def do_quit(self, command, *args, context=None): answer = self.user_input("Are you sure to log out? (y/n)[n]:", False, 1) if answer == "y": self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) - user = self._model.get_user('status', 'Online') + user = self._model.get_user('status', 'online') user.set_offline() self._model.enable_smart() self._model.enable_interactive() @@ -54,7 +54,7 @@ def do_config(self, command, *args, context=None): from .configCommandProcessor import ConfigCommandProcessor try: - admin = self._model.get_user('status', 'Online') + admin = self._model.get_user('status', 'online') assert admin.level != 'User' except (exceptions.SoftboxenError, AssertionError): raise exceptions.CommandSyntaxError(command=command) @@ -250,7 +250,7 @@ def do_reboot(self, command, *args, context=None): self.on_cycle(context=context) time.sleep(10) self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) - user = self._model.get_user('status', 'Online') + user = self._model.get_user('status', 'online') user.set_offline() exc = exceptions.TerminalExitError() exc.return_to = 'sysreboot' diff --git a/vendors/Huawei/huaweiBaseCommandProcessor.py b/vendors/Huawei/huaweiBaseCommandProcessor.py index 572ebe0..b09a18d 100644 --- a/vendors/Huawei/huaweiBaseCommandProcessor.py +++ b/vendors/Huawei/huaweiBaseCommandProcessor.py @@ -587,7 +587,7 @@ def display_terminal_user(self, command, context): user_counter = 0 try: - exec_user = self._model.get_user('status', 'Online') + exec_user = self._model.get_user('status', 'online') except exceptions.SoftboxenError: raise exceptions.CommandSyntaxError(command=command) @@ -610,6 +610,7 @@ def display_terminal_user(self, command, context): context['spacer4'] = self.create_spacers((1,), ('',))[0] * ' ' context['spacer5'] = self.create_spacers((16,), (user.profile,))[0] * ' ' + user.status = user.status.capitalize() text += self._render('display_terminal_user_all_middle', context=dict(context, user=user)) user_counter += 1 diff --git a/vendors/Huawei/main.py b/vendors/Huawei/main.py index ae00fd4..e7dda0f 100644 --- a/vendors/Huawei/main.py +++ b/vendors/Huawei/main.py @@ -44,7 +44,7 @@ def on_unknown_command(self, command, *args, context=None): for creds in self._model.credentials: if creds.username == username and creds.password == password: user = self._model.get_user('id', creds.user_id) - if user.lock_status == 'Locked': + if user.lock_status == 'locked': text = self._render('user_locked', context=context) self._write(text) raise exceptions.TerminalExitError() diff --git a/vendors/Huawei/userViewCommandProcessor.py b/vendors/Huawei/userViewCommandProcessor.py index ac1a067..e1c3c95 100644 --- a/vendors/Huawei/userViewCommandProcessor.py +++ b/vendors/Huawei/userViewCommandProcessor.py @@ -42,7 +42,7 @@ def do_quit(self, command, *args, context=None): answer = self.user_input("Are you sure to log out? (y/n)[n]:", False, 1) if answer == "y": self._model.set_last_logout(datetime.now().strftime("%m/%d/%Y %H:%M:%S")) - user = self._model.get_user('status', 'Online') + user = self._model.get_user('status', 'online') user.set_offline() self._model.enable_smart() self._model.enable_interactive() From aabf0ed77fe996bd661b18d5bd82f49594ea2566 Mon Sep 17 00:00:00 2001 From: Connyko65 Date: Fri, 20 Nov 2020 15:15:24 +0100 Subject: [PATCH 311/318] Bugfix related to card name generation --- nesi/softbox/api/views/card_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nesi/softbox/api/views/card_views.py b/nesi/softbox/api/views/card_views.py index 9852947..1d96791 100644 --- a/nesi/softbox/api/views/card_views.py +++ b/nesi/softbox/api/views/card_views.py @@ -78,7 +78,7 @@ def new_card(box_id): else: if vendor == 'Huawei': req['name'] = "0" - if vendor == 'KeyMile': + elif vendor == 'KeyMile': if box['version'] == '2500': req['name'] = "1" elif box['version'] == '2300': From d8b5905234358c1317fa4a0dd65e0d4f3f9379e5 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Wed, 25 Nov 2020 13:48:58 +0100 Subject: [PATCH 312/318] Updated delete and clone box functions and limited credentials so user_id can't have multiple entries --- nesi/softbox/api/models/box_models.py | 4 ++++ nesi/softbox/api/views/box_views.py | 26 +++++++++------------- nesi/softbox/api/views/credential_views.py | 4 ++++ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index 4e39385..f4d3f9c 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -34,6 +34,8 @@ from .logport_models import LogPort from .interface_models import Interface from .srvc_models import Srvc +from .service_vlan_models import ServiceVlan +from .service_port_models import ServicePort from .mgmt_card_models import MgmtCard from .mgmt_port_models import MgmtPort @@ -87,6 +89,8 @@ class Box(db.Model): portgroupports = db.relationship('PortGroupPort', backref='Box', lazy='dynamic') logports = db.relationship('LogPort', backref='Box', lazy='dynamic') srvcs = db.relationship('Srvc', backref='Box', lazy='dynamic') + service_vlans = db.relationship('ServiceVlan', backref='Box', lazy='dynamic') + service_ports = db.relationship('ServicePort', backref='Box', lazy='dynamic') board_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_instl_missing_reporting_logging = db.Column(db.Boolean(), default=False) board_init_reporting_logging = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/views/box_views.py b/nesi/softbox/api/views/box_views.py index ba6c867..2c3a01b 100644 --- a/nesi/softbox/api/views/box_views.py +++ b/nesi/softbox/api/views/box_views.py @@ -25,6 +25,7 @@ from ..models.vlan_models import Vlan from ..models.portprofile_models import PortProfile from ..models.route_models import Route +from ..models.user_models import User from ..schemas.box_schemas import * # KNAUP @@ -185,7 +186,7 @@ def clone_components(components, component_model, reference_field=None, referenc component_mapping[component.id] = component_new.id return component_mapping - _ = clone_components(box.credentials, Credential) + clone_components(box.credentials, Credential) subrack_mapping = clone_components(box.subracks, Subrack) card_mapping = clone_components(box.cards, Card, 'subrack_id', subrack_mapping) port_mapping = clone_components(box.ports, Port, 'card_id', card_mapping) @@ -194,6 +195,8 @@ def clone_components(components, component_model, reference_field=None, referenc cpe_mapping = clone_components(box.cpes, Cpe, 'port_id', port_mapping, 'ont_port_id', ont_port_mapping) clone_components(box.cpe_ports, CpePort, 'cpe_id', cpe_mapping) clone_components(box.vlans, Vlan) + user_mapping = clone_components(box.users, User) + clone_components(box.credentials, Credential, 'user_id', user_mapping) clone_components(box.port_profiles, PortProfile) clone_components(box.routes, Route) @@ -237,21 +240,12 @@ def del_sub_components(component_collection): for component in component_collection: db.session.delete(component) - del_sub_components(box.credentials) - del_sub_components(box.subracks) - del_sub_components(box.cards) - del_sub_components(box.ports) - del_sub_components(box.cpes) - del_sub_components(box.cpe_ports) - del_sub_components(box.onts) - del_sub_components(box.ont_ports) - del_sub_components(box.vlans) - del_sub_components(box.port_profiles) - del_sub_components(box.routes) - del_sub_components(box.vlan_interfaces) - del_sub_components(box.emus) - del_sub_components(box.qos_interfaces) - del_sub_components(box.users) + for element in (box.credentials, box.subracks, box.cards, box.ports, box.cpes, box.cpe_ports, + box.onts, box.ont_ports, box.vlans, box.port_profiles, box.routes, box.vlan_interfaces, + box.emus, box.users, box.channels, box.interfaces, box.logports, box.mgmt_cards, + box.mgmt_ports, box.portgroupports, box.srvcs, box.service_ports, box.service_vlans + ): + del_sub_components(element) db.session.delete(box) db.session.commit() diff --git a/nesi/softbox/api/views/credential_views.py b/nesi/softbox/api/views/credential_views.py index 9021636..7491df6 100644 --- a/nesi/softbox/api/views/credential_views.py +++ b/nesi/softbox/api/views/credential_views.py @@ -36,6 +36,10 @@ def show_credential(box_id, id): @app.route(PREFIX + '/boxen//credentials', methods=['POST']) def new_credential(box_id): req = flask.request.json + credentials = json.loads(show_components(CredentialsSchema(), Credential, {'user_id': req['user_id']}, box_id).data.decode('utf-8'))['members'] + if len(credentials) >= 1: + return flask.Response(status=500) + response = new_component(CredentialSchema(), Credential, req, box_id) return response, 201 From af3dfda19facfad278f40c52c57bb62109df5510 Mon Sep 17 00:00:00 2001 From: Dinker1996 Date: Thu, 26 Nov 2020 17:36:26 +0100 Subject: [PATCH 313/318] Implemented Vendor Edgecore --- README.md | 7 +- .../conf/bootstraps/create-edgecore-xxxx.sh | 154 +++++++++++++ bootup/restapi.sh | 5 +- nesi/edgecore/api/__init__.py | 0 nesi/edgecore/api/schemas/__init__.py | 17 ++ .../api/schemas/edgecore_box_schemas.py | 24 ++ .../api/schemas/edgecore_card_schemas.py | 19 ++ .../api/schemas/edgecore_interface_schemas.py | 21 ++ .../api/schemas/edgecore_port_schemas.py | 19 ++ .../api/schemas/edgecore_user_schemas.py | 7 + .../api/schemas/edgecore_vlan_schemas.py | 19 ++ nesi/edgecore/edgecore_resources/__init__.py | 2 +- .../edgecore_resources/edgecore_box.py | 119 +++++++++- .../edgecore_resources/edgecore_card.py | 36 +++ .../edgecore_resources/edgecore_interface.py | 42 ++++ .../edgecore_resources/edgecore_port.py | 34 +++ .../edgecore_resources/edgecore_user.py | 30 +++ .../edgecore_resources/edgecore_vlan.py | 32 +++ nesi/softbox/api/models/box_models.py | 14 ++ nesi/softbox/api/models/card_models.py | 3 + nesi/softbox/api/models/interface_models.py | 10 +- nesi/softbox/api/models/port_models.py | 3 + nesi/softbox/api/models/user_models.py | 2 +- nesi/softbox/api/models/vlan_models.py | 2 +- nesi/softbox/api/schemas/user_schemas.py | 2 +- nesi/softbox/api/schemas/vlan_schemas.py | 2 +- nesi/softbox/api/views/base_views.py | 3 + nesi/softbox/api/views/interface_views.py | 26 ++- nesi/softbox/cli/base.py | 4 +- templates/EdgeCore/login/mainloop/?.j2 | 14 ++ templates/EdgeCore/login/mainloop/enable/?.j2 | 43 ++++ .../enable/config/interface/on_cycle.j2 | 1 + .../enable/config/interface/on_error.j2 | 3 + .../login/mainloop/enable/config/on_cycle.j2 | 1 + .../login/mainloop/enable/config/on_error.j2 | 3 + .../mainloop/enable/config/vlan/on_cycle.j2 | 1 + .../mainloop/enable/config/vlan/on_error.j2 | 3 + .../enable/copy_startup_config_ftp_failure.j2 | 3 + .../enable/copy_startup_config_ftp_success.j2 | 4 + .../EdgeCore/login/mainloop/enable/help.j2 | 12 + .../login/mainloop/enable/on_cycle.j2 | 1 + .../login/mainloop/enable/on_error.j2 | 3 + .../EdgeCore/login/mainloop/enable/show_?.j2 | 92 ++++++++ .../mainloop/enable/show_interface_status.j2 | 29 +++ .../enable/show_interface_switchport.j2 | 22 ++ .../enable/show_interface_transceiver.j2 | 26 +++ .../mainloop/enable/show_mac_address_table.j2 | 3 + .../enable/show_mac_address_table_entry.j2 | 2 + .../enable/show_mac_address_table_unit.j2 | 3 + .../login/mainloop/enable/show_memory.j2 | 10 + .../login/mainloop/enable/show_process_cpu.j2 | 16 ++ .../login/mainloop/enable/show_system.j2 | 28 +++ .../login/mainloop/enable_password.j2 | 2 + templates/EdgeCore/login/mainloop/help.j2 | 12 + templates/EdgeCore/login/mainloop/on_cycle.j2 | 1 + templates/EdgeCore/login/mainloop/on_enter.j2 | 24 ++ templates/EdgeCore/login/mainloop/on_error.j2 | 3 + templates/EdgeCore/login/mainloop/show_?.j2 | 17 ++ templates/EdgeCore/login/on_cycle.j2 | 0 templates/EdgeCore/login/on_enter.j2 | 1 + templates/EdgeCore/login/password.j2 | 2 + templates/EdgeCore/on_cycle.j2 | 1 + templates/EdgeCore/on_enter.j2 | 0 templates/EdgeCore/on_exit.j2 | 4 + .../integration_tests/edgecore/backup.txt | 10 + .../edgecore/configureBox7.txt | 9 + .../edgecore/configureBoxName10.txt | 8 + .../edgecore/configureClock9.txt | 10 + .../edgecore/configureInternet2.txt | 12 + .../edgecore/configureLog11.txt | 8 + .../edgecore/configureMVlan12.txt | 13 ++ .../edgecore/configurePort4.txt | 8 + .../edgecore/configureRelay13.txt | 7 + .../edgecore/configureRelayOnPort14.txt | 13 ++ .../edgecore/configureTVlan8.txt | 8 + .../edgecore/configureTVlanPort1.txt | 8 + .../edgecore/configureUVlan15.txt | 9 + .../edgecore/display_data2.txt | 8 + .../edgecore/display_information4.txt | 6 + .../edgecore/display_model3.txt | 6 + .../edgecore/display_state1.txt | 8 + .../edgecore/unconfigureInternet3.txt | 20 ++ .../edgecore/unconfigurePort5.txt | 8 + .../unit_tests/edgecore/test_edgecore.py | 91 ++++++-- vendors/EdgeCore/__init__.py | 0 vendors/EdgeCore/baseCommandProcessor.py | 74 ++++++ vendors/EdgeCore/configCommandProcessor.py | 182 +++++++++++++++ vendors/EdgeCore/enableCommandProcessor.py | 155 +++++++++++++ vendors/EdgeCore/interfaceCommandProcessor.py | 212 ++++++++++++++++++ vendors/EdgeCore/main.py | 63 ++++++ vendors/EdgeCore/userViewCommandProcessor.py | 71 ++++++ vendors/EdgeCore/vlanCommandProcessor.py | 32 +++ 92 files changed, 2067 insertions(+), 40 deletions(-) create mode 100644 bootup/conf/bootstraps/create-edgecore-xxxx.sh create mode 100644 nesi/edgecore/api/__init__.py create mode 100644 nesi/edgecore/api/schemas/__init__.py create mode 100644 nesi/edgecore/api/schemas/edgecore_box_schemas.py create mode 100644 nesi/edgecore/api/schemas/edgecore_card_schemas.py create mode 100644 nesi/edgecore/api/schemas/edgecore_interface_schemas.py create mode 100644 nesi/edgecore/api/schemas/edgecore_port_schemas.py create mode 100644 nesi/edgecore/api/schemas/edgecore_user_schemas.py create mode 100644 nesi/edgecore/api/schemas/edgecore_vlan_schemas.py create mode 100644 nesi/edgecore/edgecore_resources/edgecore_card.py create mode 100644 nesi/edgecore/edgecore_resources/edgecore_interface.py create mode 100644 nesi/edgecore/edgecore_resources/edgecore_port.py create mode 100644 nesi/edgecore/edgecore_resources/edgecore_user.py create mode 100644 nesi/edgecore/edgecore_resources/edgecore_vlan.py create mode 100644 templates/EdgeCore/login/mainloop/?.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/?.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/config/interface/on_cycle.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/config/interface/on_error.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/config/on_cycle.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/config/on_error.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/config/vlan/on_cycle.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/config/vlan/on_error.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_failure.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_success.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/help.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/on_cycle.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/on_error.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_?.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_interface_status.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_interface_switchport.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_interface_transceiver.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_mac_address_table.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_mac_address_table_entry.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_mac_address_table_unit.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_memory.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_process_cpu.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable/show_system.j2 create mode 100644 templates/EdgeCore/login/mainloop/enable_password.j2 create mode 100644 templates/EdgeCore/login/mainloop/help.j2 create mode 100644 templates/EdgeCore/login/mainloop/on_cycle.j2 create mode 100644 templates/EdgeCore/login/mainloop/on_enter.j2 create mode 100644 templates/EdgeCore/login/mainloop/on_error.j2 create mode 100644 templates/EdgeCore/login/mainloop/show_?.j2 create mode 100644 templates/EdgeCore/login/on_cycle.j2 create mode 100644 templates/EdgeCore/login/on_enter.j2 create mode 100644 templates/EdgeCore/login/password.j2 create mode 100644 templates/EdgeCore/on_cycle.j2 create mode 100644 templates/EdgeCore/on_enter.j2 create mode 100644 templates/EdgeCore/on_exit.j2 create mode 100644 test_cases/integration_tests/edgecore/backup.txt create mode 100644 test_cases/integration_tests/edgecore/configureBox7.txt create mode 100644 test_cases/integration_tests/edgecore/configureBoxName10.txt create mode 100644 test_cases/integration_tests/edgecore/configureClock9.txt create mode 100644 test_cases/integration_tests/edgecore/configureInternet2.txt create mode 100644 test_cases/integration_tests/edgecore/configureLog11.txt create mode 100644 test_cases/integration_tests/edgecore/configureMVlan12.txt create mode 100644 test_cases/integration_tests/edgecore/configurePort4.txt create mode 100644 test_cases/integration_tests/edgecore/configureRelay13.txt create mode 100644 test_cases/integration_tests/edgecore/configureRelayOnPort14.txt create mode 100644 test_cases/integration_tests/edgecore/configureTVlan8.txt create mode 100644 test_cases/integration_tests/edgecore/configureTVlanPort1.txt create mode 100644 test_cases/integration_tests/edgecore/configureUVlan15.txt create mode 100644 test_cases/integration_tests/edgecore/display_data2.txt create mode 100644 test_cases/integration_tests/edgecore/display_information4.txt create mode 100644 test_cases/integration_tests/edgecore/display_model3.txt create mode 100644 test_cases/integration_tests/edgecore/display_state1.txt create mode 100644 test_cases/integration_tests/edgecore/unconfigureInternet3.txt create mode 100644 test_cases/integration_tests/edgecore/unconfigurePort5.txt create mode 100644 vendors/EdgeCore/__init__.py create mode 100644 vendors/EdgeCore/baseCommandProcessor.py create mode 100644 vendors/EdgeCore/configCommandProcessor.py create mode 100644 vendors/EdgeCore/enableCommandProcessor.py create mode 100644 vendors/EdgeCore/interfaceCommandProcessor.py create mode 100644 vendors/EdgeCore/main.py create mode 100644 vendors/EdgeCore/userViewCommandProcessor.py create mode 100644 vendors/EdgeCore/vlanCommandProcessor.py diff --git a/README.md b/README.md index 9edd2fc..f470dbe 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,10 @@ Click [here](https://thola.io/posts/thola-fosdem/) for more information ### Supported Vendors - Alcatel (nearly feature complete) - Huawei (nearly feature complete) - - Edgecore (not implemented yet) - - Keymile (work in progress) + - Edgecore (nearly feature complete) + - Keymile (nearly feature complete) - Pbn (not implemented yet) - - Zhone (not implemented yet) + - Zhone (work in progress) ### Supported network components @@ -51,6 +51,7 @@ Click [here](https://thola.io/posts/thola-fosdem/) for more information - ONTs - CPEs - Vlans +- Interfaces ## Download diff --git a/bootup/conf/bootstraps/create-edgecore-xxxx.sh b/bootup/conf/bootstraps/create-edgecore-xxxx.sh new file mode 100644 index 0000000..847ef39 --- /dev/null +++ b/bootup/conf/bootstraps/create-edgecore-xxxx.sh @@ -0,0 +1,154 @@ +#!/bin/bash +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst +# +# Example NESi REST API server bootstrapping +# +ENDPOINT=http://localhost:5000/nesi/v1 + +path="`dirname \"$0\"`" + +. $path/functions.sh + +#--------------------------------------------------------# +# # +# Subrack 0 # +# |---> Card 1 # +# | |-> Port 1/1 # +# | | |-> Interface 1/1 # +# # +#--------------------------------------------------------# +# # +# default Vlan 1 # +# Enable Credentials # +# Backup Credentials # +# # +#--------------------------------------------------------# + +# Create a network device (admin operation) +req='{ + "vendor": "EdgeCore", + "model": "ECS4120-28Fv2-I", + "version": "A", + "description": "EdgeCore ECS4120-28Fv2-I box", + "hostname": "ed-ge-co-re-1", + "mgmt_address": "10.0.0.12", + "software_version": "MA5623V800R016C00", + "network_protocol": "telnet", + "network_address": "127.0.0.1", + "network_port": 9023, + "dsl_mode": "tr165", + "uuid": "1111" +}' + +box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1 + +# Admin user +req='{ + "name": "Admin", + "profile": "root" +}' + +admin_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) + +# Admin credentials +req='{ + "username": "admin", + "password": "secret", + "user_id": '$admin_id' +}' + +admin_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# enable user +req='{ + "name": "Enable", + "profile": "enable" +}' + +enable_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) + +# Super enable credentials +req='{ + "username": "enable", + "password": "enable", + "user_id": '$enable_id' +}' + +enable_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +# backup user +req='{ + "name": "Backuo", + "profile": "backup" +}' + +backup_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users) + +# Super backup credentials +req='{ + "username": "backup", + "password": "backup", + "user_id": '$backup_id' +}' + +backup_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials) + +### Subrack 0 ### + +# Create a physical subrack at the network device (admin operation) +req='{ + "name": "", + "description": "Pseudo Subrack" +}' + +subrack_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks) + +### Unit-1 ### + +# Create a physical card at the network device (admin operation) +req='{ + "subrack_id": '$subrack_id', + "name": "1", + "product": "adsl" +}' + +unit_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards) + +### Port-1 ### + +# Create a physical port at the network device (admin operation) +req='{ + "card_id": '$unit_1', + "admin_state": "1", + "operational_state": "1" +}' + +port_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports) + +### Interface-1 ### + +# Create a physical interface at the network device (admin operation) +req='{ + "port_id": '$port_1_1' +}' + +interface_3_1_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/interfaces) + +# default Vlan +req='{ + "number": 1, + "name": "default", + "description": "The standard Vlan" +}' + +vlan_pppoe=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlans) \ No newline at end of file diff --git a/bootup/restapi.sh b/bootup/restapi.sh index 6d8dd93..aea0175 100755 --- a/bootup/restapi.sh +++ b/bootup/restapi.sh @@ -181,7 +181,8 @@ if [ $recreate_db = "yes" ]; then #bash bootup/conf/bootstraps/create-box-port-vlan.sh #bash bootup/conf/bootstraps/create-alcatel-7360.sh #bash bootup/conf/bootstraps/create-huawei-5623.sh - bash bootup/conf/bootstraps/create-keymile-MG2500.sh + #bash bootup/conf/bootstraps/create-keymile-MG2500.sh + bash bootup/conf/bootstraps/create-edgecore-xxxx.sh fi if [ $alcatel_api = "yes" ]; then @@ -194,7 +195,7 @@ if [ $keymile_api = "yes" ]; then bash bootup/conf/bootstraps/create-keymile-MG2500.sh fi if [ $edgecore_api = "yes" ]; then - bash bootup/conf/bootstraps/create-alcatel-7360.sh #work_in_progress + bash bootup/conf/bootstraps/create-edgecore-xxxx.sh fi if [ $pbn_api = "yes" ]; then bash bootup/conf/bootstraps/create-alcatel-7360.sh #work_in_progress diff --git a/nesi/edgecore/api/__init__.py b/nesi/edgecore/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nesi/edgecore/api/schemas/__init__.py b/nesi/edgecore/api/schemas/__init__.py new file mode 100644 index 0000000..04e408d --- /dev/null +++ b/nesi/edgecore/api/schemas/__init__.py @@ -0,0 +1,17 @@ +from inspect import isclass +from pkgutil import iter_modules +from pathlib import Path +from importlib import import_module + +# iterate through the modules in the current package +package_dir = Path(__file__).resolve().parent +for (_, module_name, _) in iter_modules([package_dir]): + + # import the module and iterate through its attributes + module = import_module(f"{__name__}.{module_name}") + for attribute_name in dir(module): + attribute = getattr(module, attribute_name) + + if isclass(attribute): + # Add the class to this package's variables + globals()[attribute_name] = attribute \ No newline at end of file diff --git a/nesi/edgecore/api/schemas/edgecore_box_schemas.py b/nesi/edgecore/api/schemas/edgecore_box_schemas.py new file mode 100644 index 0000000..85d2896 --- /dev/null +++ b/nesi/edgecore/api/schemas/edgecore_box_schemas.py @@ -0,0 +1,24 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.box_schemas import * + + +class EdgeCoreBoxSchema(BoxSchema): + class Meta: + model = Box + fields = BoxSchema.Meta.fields + ('management_start_address', 'management_end_address', 'logging_host', + 'loopback_detection_action', 'logging_port', 'logging_level', + 'sntp_server_ip', 'sntp_client', 'timezone_name', 'timezone_time', + 'summer_time_name', 'summer_time_region') + + diff --git a/nesi/edgecore/api/schemas/edgecore_card_schemas.py b/nesi/edgecore/api/schemas/edgecore_card_schemas.py new file mode 100644 index 0000000..5f3b4bf --- /dev/null +++ b/nesi/edgecore/api/schemas/edgecore_card_schemas.py @@ -0,0 +1,19 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.card_schemas import * + + +class EdgeCoreCardSchema(CardSchema): + class Meta: + model = Card + fields = CardSchema.Meta.fields + ('mac_address', 'admin_state', 'operational_state') diff --git a/nesi/edgecore/api/schemas/edgecore_interface_schemas.py b/nesi/edgecore/api/schemas/edgecore_interface_schemas.py new file mode 100644 index 0000000..da8e696 --- /dev/null +++ b/nesi/edgecore/api/schemas/edgecore_interface_schemas.py @@ -0,0 +1,21 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.interface_schemas import * + + +class EdgeCoreInterfaceSchema(InterfaceSchema): + class Meta: + model = Interface + fields = InterfaceSchema.Meta.fields + ('port_id', 'ingress_state', 'ingress_rate', 'egress_state', + 'egress_rate', 'vlan_membership_mode', 'native_vlan', 'allowed_vlan', + 'mac_address') diff --git a/nesi/edgecore/api/schemas/edgecore_port_schemas.py b/nesi/edgecore/api/schemas/edgecore_port_schemas.py new file mode 100644 index 0000000..b5cfe93 --- /dev/null +++ b/nesi/edgecore/api/schemas/edgecore_port_schemas.py @@ -0,0 +1,19 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.port_schemas import * + + +class EdgeCorePortSchema(PortSchema): + class Meta: + model = Port + fields = PortSchema.Meta.fields + ('mac_address', ) diff --git a/nesi/edgecore/api/schemas/edgecore_user_schemas.py b/nesi/edgecore/api/schemas/edgecore_user_schemas.py new file mode 100644 index 0000000..30f905c --- /dev/null +++ b/nesi/edgecore/api/schemas/edgecore_user_schemas.py @@ -0,0 +1,7 @@ +from nesi.softbox.api.schemas.user_schemas import * + + +class EdgecoreUserSchema(UserSchema): + class Meta: + model = User + fields = UserSchema.Meta.fields + ('profile',) diff --git a/nesi/edgecore/api/schemas/edgecore_vlan_schemas.py b/nesi/edgecore/api/schemas/edgecore_vlan_schemas.py new file mode 100644 index 0000000..fcba3da --- /dev/null +++ b/nesi/edgecore/api/schemas/edgecore_vlan_schemas.py @@ -0,0 +1,19 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.api.schemas.vlan_schemas import * + + +class EdgeCoreVlanSchema(VlanSchema): + class Meta: + model = Vlan + fields = VlanSchema.Meta.fields diff --git a/nesi/edgecore/edgecore_resources/__init__.py b/nesi/edgecore/edgecore_resources/__init__.py index a9a2c5b..2cc22c0 100644 --- a/nesi/edgecore/edgecore_resources/__init__.py +++ b/nesi/edgecore/edgecore_resources/__init__.py @@ -1 +1 @@ -__all__ = [] +__all__ = ["edgecore_card", "edgecore_interface", "edgecore_port", "edgecore_vlan", "edgecore_user"] diff --git a/nesi/edgecore/edgecore_resources/edgecore_box.py b/nesi/edgecore/edgecore_resources/edgecore_box.py index 47b29b7..ea2c8ce 100644 --- a/nesi/edgecore/edgecore_resources/edgecore_box.py +++ b/nesi/edgecore/edgecore_resources/edgecore_box.py @@ -9,10 +9,9 @@ # - Alexander Dincher # # License: https://github.com/inexio/NESi/LICENSE.rst -from nesi.huawei.huawei_resources import * +from nesi.edgecore.edgecore_resources import * from nesi.softbox.base_resources import credentials -from nesi.softbox.base_resources import route from nesi.softbox.base_resources.box import * LOG = logging.getLogger(__name__) @@ -25,6 +24,122 @@ class EdgeCoreBox(Box): :param identity: The identity of the System resource """ # Define Edgecore Properties + management_start_address = base.Field('management_start_address') + management_end_address = base.Field('management_end_address') + logging_host = base.Field('logging_host') + logging_port = base.Field('logging_port') + logging_level = base.Field('logging_level') + loopback_detection_action = base.Field('loopback_detection_action') + sntp_server_ip = base.Field('sntp_server_ip') + sntp_client = base.Field('sntp_client') + timezone_name = base.Field('timezone_name') + timezone_time = base.Field('timezone_time') + summer_time_name = base.Field('summer_time_name') + summer_time_region = base.Field('summer_time_region') + + @property + def credentials(self): + """Return `CredentialsCollection` object.""" + return credentials.CredentialsCollection( + self._conn, base.get_sub_resource_path_by( + self, 'credentials')) + + @property + def users(self): + """Return `UserCollection` object.""" + return edgecore_user.UserCollection( + self._conn, base.get_sub_resource_path_by( + self, 'users')) + + def get_user(self, field, value): + """Get specific user object.""" + return edgecore_user.EdgecoreUserCollection( + self._conn, base.get_sub_resource_path_by(self, 'users'), + params={field: value}).find_by_field_value(field, value) + + @property + def cards(self): + """Return `CardCollection` object.""" + return edgecore_card.EdgeCoreCardCollection( + self._conn, base.get_sub_resource_path_by(self, 'cards')) + + def get_card(self, field, value): + """Get specific card object.""" + return edgecore_card.EdgeCoreCardCollection( + self._conn, base.get_sub_resource_path_by(self, 'cards'), + params={field: value}).find_by_field_value(field, value) + + def get_cards(self, field, value): + """Get all cards.""" + return edgecore_card.EdgeCoreCardCollection( + self._conn, base.get_sub_resource_path_by(self, 'cards'), + params={field: value}) + + @property + def ports(self): + """Return `PortCollection` object.""" + return edgecore_port.EdgeCorePortCollection( + self._conn, base.get_sub_resource_path_by(self, 'ports')) + + def get_port(self, field, value): + """Get specific port object.""" + return edgecore_port.EdgeCorePortCollection( + self._conn, base.get_sub_resource_path_by(self, 'ports'), + params={field: value}).find_by_field_value(field, value) + + def get_ports(self, field, value): + """Get specific port object.""" + return edgecore_port.EdgeCorePortCollection( + self._conn, base.get_sub_resource_path_by(self, 'ports'), + params={field: value}) + + @property + def interfaces(self): + """Return `InterfaceCollection` object.""" + return edgecore_interface.EdgeCoreInterfaceCollection( + self._conn, base.get_sub_resource_path_by(self, 'interfaces')) + + def get_interface(self, field, value): + """Get specific interface object.""" + return edgecore_interface.EdgeCoreInterfaceCollection( + self._conn, base.get_sub_resource_path_by(self, 'interfaces'), + params={field: value}).find_by_field_value(field, value) + + def get_interfaces(self, field, value): + """Get specific interface object.""" + return edgecore_interface.EdgeCoreInterfaceCollection( + self._conn, base.get_sub_resource_path_by(self, 'interfaces'), + params={field: value}) + + @property + def vlans(self): + """Return `VlanCollection` object.""" + return edgecore_vlan.EdgeCoreVlanCollection( + self._conn, base.get_sub_resource_path_by(self, 'vlans')) + + def get_vlan(self, field, value): + """Get specific vlan object.""" + return edgecore_vlan.EdgeCoreVlanCollection( + self._conn, base.get_sub_resource_path_by(self, 'vlans'), + params={field: value}).find_by_field_value(field, value) + + def get_vlans(self, field, value): + """Get specific vlan object.""" + return edgecore_vlan.EdgeCoreVlanCollection( + self._conn, base.get_sub_resource_path_by(self, 'vlans'), + params={field: value}) + + def add_vlan(self, **fields): + """Add new vlan.""" + edgecore_vlan.EdgeCoreVlan.create( + self._conn, + os.path.join(self.path, 'vlans'), + **fields + ) + + def set(self, field, value): + mapping = {field: value} + self.update(**mapping) class EdgeCoreBoxCollection(BoxCollection): diff --git a/nesi/edgecore/edgecore_resources/edgecore_card.py b/nesi/edgecore/edgecore_resources/edgecore_card.py new file mode 100644 index 0000000..e431f77 --- /dev/null +++ b/nesi/edgecore/edgecore_resources/edgecore_card.py @@ -0,0 +1,36 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.card import Card, CardCollection, logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class EdgeCoreCard(Card): + """Represent physical shelf resource.""" + + mac_address = base.Field('mac_address') + admin_state = base.Field('admin_state') + operational_state = base.Field('operational_state') + + def set(self, field, value): + mapping = {field: value} + self.update(**mapping) + + +class EdgeCoreCardCollection(CardCollection): + """Represent a collection of cards.""" + + @property + def _resource_type(self): + return EdgeCoreCard diff --git a/nesi/edgecore/edgecore_resources/edgecore_interface.py b/nesi/edgecore/edgecore_resources/edgecore_interface.py new file mode 100644 index 0000000..9571240 --- /dev/null +++ b/nesi/edgecore/edgecore_resources/edgecore_interface.py @@ -0,0 +1,42 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.interface import Interface, InterfaceCollection, logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class EdgeCoreInterface(Interface): + """Represent a VlanInterface resource.""" + + port_id = base.Field('port_id') + ingress_state = base.Field('ingress_state') + ingress_rate = base.Field('ingress_rate') + egress_state = base.Field('egress_state') + egress_rate = base.Field('egress_rate') + vlan_membership_mode = base.Field('vlan_membership_mode') + native_vlan = base.Field('native_vlan') + allowed_vlan = base.Field('allowed_vlan') + mac_address = base.Field('mac_address') + + def set(self, field, value): + mapping = {field: value} + self.update(**mapping) + + +class EdgeCoreInterfaceCollection(InterfaceCollection): + """Represent the collection of VlanInterfaces.""" + + @property + def _resource_type(self): + return EdgeCoreInterface diff --git a/nesi/edgecore/edgecore_resources/edgecore_port.py b/nesi/edgecore/edgecore_resources/edgecore_port.py new file mode 100644 index 0000000..f49f4b2 --- /dev/null +++ b/nesi/edgecore/edgecore_resources/edgecore_port.py @@ -0,0 +1,34 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.port import Port, PortCollection, logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class EdgeCorePort(Port): + """Represent physical port resource.""" + + mac_address = base.Field('mac_address') + + def set(self, field, value): + mapping = {field: value} + self.update(**mapping) + + +class EdgeCorePortCollection(PortCollection): + """Represent a collection of ports.""" + + @property + def _resource_type(self): + return EdgeCorePort diff --git a/nesi/edgecore/edgecore_resources/edgecore_user.py b/nesi/edgecore/edgecore_resources/edgecore_user.py new file mode 100644 index 0000000..fb56e38 --- /dev/null +++ b/nesi/edgecore/edgecore_resources/edgecore_user.py @@ -0,0 +1,30 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.user import User, UserCollection, logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class EdgecoreUser(User): + """Represents a logical User resource""" + + profile = base.Field('profile') + + +class EdgecoreUserCollection(UserCollection): + """Represent the collection of Users.""" + + @property + def _resource_type(self): + return EdgecoreUser diff --git a/nesi/edgecore/edgecore_resources/edgecore_vlan.py b/nesi/edgecore/edgecore_resources/edgecore_vlan.py new file mode 100644 index 0000000..16b90ab --- /dev/null +++ b/nesi/edgecore/edgecore_resources/edgecore_vlan.py @@ -0,0 +1,32 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.base_resources.vlan import Vlan, VlanCollection, logging +from nesi.softbox.base_resources import base + +LOG = logging.getLogger(__name__) + + +class EdgeCoreVlan(Vlan): + """Represent a VLAN resource.""" + + def set(self, field, value): + mapping = {field: value} + self.update(**mapping) + + +class EdgeCoreVlanCollection(VlanCollection): + """Represent the collection of VLANs.""" + + @property + def _resource_type(self): + return EdgeCoreVlan diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py index f4d3f9c..223b94e 100644 --- a/nesi/softbox/api/models/box_models.py +++ b/nesi/softbox/api/models/box_models.py @@ -138,3 +138,17 @@ class Box(db.Model): ftp_login = db.Column(db.String(), default='') ftp_password = db.Column(db.String(), default='') network_element_management_vlan_id = db.Column(db.Integer(), default=None) + + #EdgeCore + management_start_address = db.Column(db.String(), default='') + management_end_address = db.Column(db.String(), default='') + logging_host = db.Column(db.String(), default='') + logging_port = db.Column(db.String(), default='') + logging_level = db.Column(db.Integer(), default=7) + loopback_detection_action = db.Column(db.String(), default='shutdown') + sntp_server_ip = db.Column(db.String(), default='None') + sntp_client = db.Column(db.Enum('Disabled', 'Enabled'), default='Disabled') + timezone_name = db.Column(db.String(), default='None') + timezone_time = db.Column(db.String(), default='None') + summer_time_name = db.Column(db.String(), default='') + summer_time_region = db.Column(db.String(), default='') diff --git a/nesi/softbox/api/models/card_models.py b/nesi/softbox/api/models/card_models.py index efbadfd..4d26ffb 100644 --- a/nesi/softbox/api/models/card_models.py +++ b/nesi/softbox/api/models/card_models.py @@ -144,3 +144,6 @@ class Card(db.Model): #digimap_domain_phone_context = db.Column(db.String(), default='') #digimap_prestrip = db.Column(db.Integer(), default=0) #digimap_prepend = db.Column(db.String(), default='') + + #Edgecore + mac_address = db.Column(db.String(), default='A8-2B-B5-7F-E3-C0') diff --git a/nesi/softbox/api/models/interface_models.py b/nesi/softbox/api/models/interface_models.py index cd68d95..e73d2f7 100644 --- a/nesi/softbox/api/models/interface_models.py +++ b/nesi/softbox/api/models/interface_models.py @@ -30,4 +30,12 @@ class Interface(db.Model): reconfiguration_allowed = db.Column(db.Enum('true', 'false'), default='true') services_connected = db.Column(db.String(), default='') - + #EdgeCore + ingress_state = db.Column(db.Enum('Disabled', 'Enabled'), default='Disabled') + ingress_rate = db.Column(db.Integer(), default=1000000) + egress_state = db.Column(db.Enum('Disabled', 'Enabled'), default='Disabled') + egress_rate = db.Column(db.Integer(), default=1000000) + vlan_membership_mode = db.Column(db.Enum('Hybrid', 'Access', 'Trunk'), default='Hybrid') + native_vlan = db.Column(db.Integer(), default=1) + allowed_vlan = db.Column(db.String(), default='1(u)') + mac_address = db.Column(db.String(), default='A8-2B-B5-7F-E3-C0') diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py index 6ed09a0..3136913 100644 --- a/nesi/softbox/api/models/port_models.py +++ b/nesi/softbox/api/models/port_models.py @@ -331,3 +331,6 @@ class Port(db.Model): profile4_enable = db.Column(db.Boolean(), default=False) profile4_name = db.Column(db.String(), default='') profile_mode = db.Column(db.Enum('Priority', 'ElectricalLoopLength'), default=None) + + #Edgecore + mac_address = db.Column(db.String(), default='A8-2B-B5-7F-E3-C0') \ No newline at end of file diff --git a/nesi/softbox/api/models/user_models.py b/nesi/softbox/api/models/user_models.py index aef11d0..74805e5 100644 --- a/nesi/softbox/api/models/user_models.py +++ b/nesi/softbox/api/models/user_models.py @@ -22,7 +22,7 @@ class User(db.Model): name = db.Column(db.String(), default='user') level = db.Column(db.Enum('Super', 'Admin', 'Operator', 'User'), default='User') status = db.Column(db.Enum('online', 'offline'), default='offline') - profile = db.Column(db.Enum('root', 'admin', 'operator', 'commonuser'), default='commonuser') + profile = db.Column(db.Enum('root', 'admin', 'operator', 'commonuser', 'enable', 'backup'), default='commonuser') append_info = db.Column(db.String(), default='-----') reenter_num = db.Column(db.Integer(), default=3) reenter_num_temp = db.Column(db.Integer(), default=3) diff --git a/nesi/softbox/api/models/vlan_models.py b/nesi/softbox/api/models/vlan_models.py index 13a4bc9..e9f5fd6 100644 --- a/nesi/softbox/api/models/vlan_models.py +++ b/nesi/softbox/api/models/vlan_models.py @@ -19,6 +19,7 @@ class Vlan(db.Model): name = db.Column(db.String(64), nullable=False) number = db.Column(db.Integer(), nullable=False) description = db.Column(db.String()) + mtu = db.Column(db.Integer(), default=1500) role = db.Column( db.Enum('access', 'trunk', 'native'), nullable=False, default='access') @@ -29,7 +30,6 @@ class Vlan(db.Model): egress_port = db.Column(db.String(), default='') fdb_id = db.Column(db.Integer, default=2620) shutdown = db.Column(db.Boolean(), default=False) - mtu = db.Column(db.Integer(), default=1500) access_group_in = db.Column(db.String(64), default='') access_group_out = db.Column(db.String(64), default='') ip_redirect = db.Column(db.Boolean(), default=False) diff --git a/nesi/softbox/api/schemas/user_schemas.py b/nesi/softbox/api/schemas/user_schemas.py index 6bd71c0..fadd4e8 100644 --- a/nesi/softbox/api/schemas/user_schemas.py +++ b/nesi/softbox/api/schemas/user_schemas.py @@ -18,7 +18,7 @@ class UserSchema(ma.ModelSchema): class Meta: model = User - fields = ('id', 'box', 'box_id', 'credential_details', 'name', 'status', 'lock_status', '_links') + fields = ('id', 'box', 'box_id', 'credential_details', 'name', 'status', 'lock_status', 'profile', '_links') credential_details = ma.Nested(CredentialsSchema.CredentialSchema, many=True) diff --git a/nesi/softbox/api/schemas/vlan_schemas.py b/nesi/softbox/api/schemas/vlan_schemas.py index 49ca8d7..1620b34 100644 --- a/nesi/softbox/api/schemas/vlan_schemas.py +++ b/nesi/softbox/api/schemas/vlan_schemas.py @@ -17,7 +17,7 @@ class VlanSchema(ma.ModelSchema): class Meta: model = Vlan - fields = ('id', 'box_id', 'number', 'mtu', 'box' + fields = ('id', 'box_id', 'number', 'mtu', 'box', 'description', 'name', '_links') box = ma.Hyperlinks( diff --git a/nesi/softbox/api/views/base_views.py b/nesi/softbox/api/views/base_views.py index 4259e94..47b60df 100644 --- a/nesi/softbox/api/views/base_views.py +++ b/nesi/softbox/api/views/base_views.py @@ -21,6 +21,9 @@ from nesi.alcatel.api.schemas import * from nesi.huawei.api.schemas import * from nesi.keymile.api.schemas import * +from nesi.edgecore.api.schemas import * +from nesi.pbn.api.schemas import * +from nesi.zhone.api.schemas import * # important for other view classes from nesi.softbox.api import db diff --git a/nesi/softbox/api/views/interface_views.py b/nesi/softbox/api/views/interface_views.py index 74159f2..8d140c3 100644 --- a/nesi/softbox/api/views/interface_views.py +++ b/nesi/softbox/api/views/interface_views.py @@ -11,6 +11,7 @@ # License: https://github.com/inexio/NESi/LICENSE.rst from .base_views import * +from .box_views import show_box from ..models.port_models import Port from ..models.channel_models import Channel from ..models.logport_models import LogPort @@ -39,19 +40,24 @@ def show_interface(box_id, id): @app.route(PREFIX + '/boxen//interfaces', methods=['POST']) def new_interface(box_id): req = flask.request.json + box = json.loads(show_box(box_id)[0].data.decode('utf-8')) if 'name' not in req or req['name'] == "": - if 'port_id' in req: + if box['vendor'] == 'KeyMile': + if 'port_id' in req: + port = json.loads(show_component(Port, box_id, req['port_id']).data.decode('utf-8')) + req['name'] = port['name'] + "/" + str(len(port['interfaces']) + 1) + elif 'chan_id' in req: + channel = json.loads(show_component(Channel, box_id, req['chan_id']).data.decode('utf-8')) + req['name'] = channel['name'] + "/" + str(len(channel['interfaces']) + 1) + elif 'logport_id' in req: + logport = json.loads(show_component(LogPort, box_id, req['logport_id']).data.decode('utf-8')) + req['name'] = logport['name'] + "/" + str(len(logport['interfaces']) + 1) + else: + raise exceptions.Forbidden('can not have port and channel as parent') + elif box['vendor'] == 'EdgeCore': port = json.loads(show_component(Port, box_id, req['port_id']).data.decode('utf-8')) - req['name'] = port['name'] + "/" + str(len(port['interfaces']) + 1) - elif 'chan_id' in req: - channel = json.loads(show_component(Channel, box_id, req['chan_id']).data.decode('utf-8')) - req['name'] = channel['name'] + "/" + str(len(channel['interfaces']) + 1) - elif 'logport_id' in req: - logport = json.loads(show_component(LogPort, box_id, req['logport_id']).data.decode('utf-8')) - req['name'] = logport['name'] + "/" + str(len(logport['interfaces']) + 1) - else: - raise exceptions.Forbidden('can not have port and channel as parent') + req['name'] = port['name'] response = new_component(InterfaceSchema(), Interface, req, box_id) return response, 201 diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 1632d66..9a4566b 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -284,8 +284,8 @@ def _get_command_func(self, line): if self.case_sensitive is False: command = command.lower() - if command == self.negation: - command += "_" + args.pop(0) + #if command == self.negation: + #command += "_" + args.pop(0) command = command.replace('-', '_') diff --git a/templates/EdgeCore/login/mainloop/?.j2 b/templates/EdgeCore/login/mainloop/?.j2 new file mode 100644 index 0000000..a184270 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/?.j2 @@ -0,0 +1,14 @@ +EXEC commands: + disable Returns to normal mode from privileged mode + disconnect Terminates an SSH, Telnet, or a console connection + enable Turns on privileged commands + exit Exits from privileged EXEC mode + help Description of the interactive help system + ping Sends ICMP echo request packets to another host + ping6 Sends ICMPv6 echo request packets to another host + quit Exits a CLI session + show Shows information + terminal Terminal setting + traceroute Traces routing path + traceroute6 Traces routing path + diff --git a/templates/EdgeCore/login/mainloop/enable/?.j2 b/templates/EdgeCore/login/mainloop/enable/?.j2 new file mode 100644 index 0000000..4b455cf --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/?.j2 @@ -0,0 +1,43 @@ +EXEC commands: + auto-traffic-control Auto traffic control configuration + calendar Date and time information + clear Resets functions + configure Enters configuration mode + copy Copies from one file to another + debug Debugging functions + delete Deletes a file + dir Lists files on the file system + disable Returns to normal mode from privileged mode + disconnect Terminates an SSH, Telnet, or a console connection + dot1x Configures 802.1X port-based access control + efm Ethernet First Mile feature + enable Turns on privileged commands + erps Ethernet Ring Protection Switching + ethernet Metro Ethernet + exit Exits from privileged EXEC mode + hardware Hardware ralated functions + help Description of the interactive help system + ip Internet protocol + ipv6 IPv6 configuration commands + loopback-detection Performs loopback detection privileged operations + no Negates a command or sets its defaults + ping Sends ICMP echo request packets to another host + ping6 Sends ICMPv6 echo request packets to another host + port Configures the characteristics of the port + quit Exits a CLI session + rcommand telnet to member + reload Halts and performs a warm restart + sflow Configures sFlow + show Shows information + smart-pair Specifies a smart pair + spanning-tree Specifies spanning-tree configuration + telnet Telnet to a specified host + terminal Terminal setting + test Tests subsystem + traceroute Traces routing path + traceroute6 Traces routing path + transceiver-eeprom Access transceiver EEPROM data + watchdog Configures watchdog setting + web-auth Configures web authentication parameters + whichboot Shows which files booted on system power up + diff --git a/templates/EdgeCore/login/mainloop/enable/config/interface/on_cycle.j2 b/templates/EdgeCore/login/mainloop/enable/config/interface/on_cycle.j2 new file mode 100644 index 0000000..7496ed2 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/config/interface/on_cycle.j2 @@ -0,0 +1 @@ +{{ model.hostname }}(config-if)# diff --git a/templates/EdgeCore/login/mainloop/enable/config/interface/on_error.j2 b/templates/EdgeCore/login/mainloop/enable/config/interface/on_error.j2 new file mode 100644 index 0000000..d965dc6 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/config/interface/on_error.j2 @@ -0,0 +1,3 @@ + ^ +% Invalid input detected at '^' marker. + diff --git a/templates/EdgeCore/login/mainloop/enable/config/on_cycle.j2 b/templates/EdgeCore/login/mainloop/enable/config/on_cycle.j2 new file mode 100644 index 0000000..ece1f7f --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/config/on_cycle.j2 @@ -0,0 +1 @@ +{{ model.hostname }}(config)# diff --git a/templates/EdgeCore/login/mainloop/enable/config/on_error.j2 b/templates/EdgeCore/login/mainloop/enable/config/on_error.j2 new file mode 100644 index 0000000..d965dc6 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/config/on_error.j2 @@ -0,0 +1,3 @@ + ^ +% Invalid input detected at '^' marker. + diff --git a/templates/EdgeCore/login/mainloop/enable/config/vlan/on_cycle.j2 b/templates/EdgeCore/login/mainloop/enable/config/vlan/on_cycle.j2 new file mode 100644 index 0000000..7c17cd7 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/config/vlan/on_cycle.j2 @@ -0,0 +1 @@ +{{ model.hostname }}(config-vlan)# diff --git a/templates/EdgeCore/login/mainloop/enable/config/vlan/on_error.j2 b/templates/EdgeCore/login/mainloop/enable/config/vlan/on_error.j2 new file mode 100644 index 0000000..e13e225 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/config/vlan/on_error.j2 @@ -0,0 +1,3 @@ + ^ +% Invalid input detected at '^' marker. + diff --git a/templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_failure.j2 b/templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_failure.j2 new file mode 100644 index 0000000..639e9d9 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_failure.j2 @@ -0,0 +1,3 @@ +Failed to connect to server. +Error. + diff --git a/templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_success.j2 b/templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_success.j2 new file mode 100644 index 0000000..ff46f1d --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/copy_startup_config_ftp_success.j2 @@ -0,0 +1,4 @@ +Flash Programming started. +Flash Programming completed. +Success. + diff --git a/templates/EdgeCore/login/mainloop/enable/help.j2 b/templates/EdgeCore/login/mainloop/enable/help.j2 new file mode 100644 index 0000000..800b1a8 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/help.j2 @@ -0,0 +1,12 @@ +Help may be requested at any point in a command by entering +a question mark '?'. If nothing matches, the help list will +be empty and you must backup until entering a '?' shows the +available options. +Two styles of help are provided: +1. Full help is available when you are ready to enter a + command argument (e.g. 'show ?') and describes each possible + argument. +2. Partial help is provided when an abbreviated argument is entered + and you want to know what arguments match the input + (e.g. 'show br?'.) + diff --git a/templates/EdgeCore/login/mainloop/enable/on_cycle.j2 b/templates/EdgeCore/login/mainloop/enable/on_cycle.j2 new file mode 100644 index 0000000..d8fe528 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/on_cycle.j2 @@ -0,0 +1 @@ +{{ model.hostname }}# \ No newline at end of file diff --git a/templates/EdgeCore/login/mainloop/enable/on_error.j2 b/templates/EdgeCore/login/mainloop/enable/on_error.j2 new file mode 100644 index 0000000..d965dc6 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/on_error.j2 @@ -0,0 +1,3 @@ + ^ +% Invalid input detected at '^' marker. + diff --git a/templates/EdgeCore/login/mainloop/enable/show_?.j2 b/templates/EdgeCore/login/mainloop/enable/show_?.j2 new file mode 100644 index 0000000..036b300 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_?.j2 @@ -0,0 +1,92 @@ + access-group Access groups + access-list Access lists + accounting Uses the specified accounting list + arp Information of ARP cache + authorization Authorization configurations + auto-traffic-control Auto traffic control information + banner Banner info + bridge-ext Bridge extension information + cable-diagnostics Shows the information of cable diagnostics + calendar Date and time information + class-map Displays class maps + cluster Display cluster + debug State of each debugging option + discard Discard packet + dns DNS information + dos-protection Shows the system dos-protection summary information + dot1q-tunnel 802.1Q tunnel + dot1x 802.1X content + dying-gasp Dying gasp information + efm Ethernet First Mile feature + erps Displays ERPS configuration + ethernet Shows Metro Ethernet information + garp GARP properties + gvrp GVRP interface information + hardware Hardware ralated functions + history Shows history information + hosts Host information + interfaces Shows interface information + ip IP information + ipv6 IPv6 information + l2protocol-tunnel Layer 2 protocol tunneling configuration + lacp LACP statistics + line TTY line information + lldp LLDP + log Log records + logging Logging setting + loop Shows the information of loopback + loopback-detection Shows loopback detection information + mac MAC access list + mac-address-table Configuration of the address table + mac-vlan MAC-based VLAN information + management Shows management information + memory Memory utilization + mvr multicast VLAN registration + mvr6 IPv6 Multicast VLAN registration + network-access Shows the entries of the secure port + nlm Show notification log + ntp Network Time Protocol configuration + policy-map Displays policy maps + port Port characteristics + port-channel Port channel information + power Shows power + power-save Shows the power saving information + pppoe Displays PPPoE configuration + privilege Shows current privilege level + process Device process + protocol-vlan Protocol-VLAN information + public-key Public key information + qos Quality of Service + queue Priority queue information + radius-server RADIUS server information + reload Shows the reload settings + rmon Remote monitoring information + rspan Display status of the current RSPAN configuration + running-config Information on the running configuration + sflow Shows the sflow information + smart-pair Displays backup port information + snmp Simple Network Management Protocol configuration and + statistics + snmp-server Displays SNMP server configuration + sntp Simple Network Time Protocol configuration + spanning-tree Spanning-tree configuration + ssh Secure shell server connections + startup-config Startup system configuration + subnet-vlan IP subnet-based VLAN information + system System information + tacacs-server TACACS server information + tech-support Technical information + time-range Time range + traffic-segmentation Traffic segmentation information + transceiver-eeprom Access transceiver EEPROM data configuration + twamp TWAMP configuration, statistics and session information + udld Displays UDLD information + upgrade Shows upgrade information + users Information about users logged in + version System hardware and software versions + vlan Shows virtual LAN settings + vlan-translation VLAN translation information + voice Shows the voice VLAN information + watchdog Displays watchdog status + web-auth Shows web authentication configuration + diff --git a/templates/EdgeCore/login/mainloop/enable/show_interface_status.j2 b/templates/EdgeCore/login/mainloop/enable/show_interface_status.j2 new file mode 100644 index 0000000..456249d --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_interface_status.j2 @@ -0,0 +1,29 @@ +Information of Eth {{ context.port.name }} + Basic Information: + Port Type : 1000BASE SFP + MAC Address : {{ context.port.mac_address }} +Configuration: + Name : {{ context.port.description }} + Port Admin : {{ context.port.admin_state }} + Speed-duplex : Auto + Capabilities : 1000full + Broadcast Storm : Disabled + Broadcast Storm Limit : 500 packets/second + Multicast Storm : Disabled + Multicast Storm Limit : 262143 packets/second + Unknown Unicast Storm : Disabled + Unknown Unicast Storm Limit : 262143 packets/second + Flow Control : Disabled + VLAN Trunking : Disabled + LACP : Disabled + MAC Learning : Enabled + Link-up-down Trap : Enabled + Media Type : None + MTU : 1518 +Current Status: + Link Status : {{ context.port.operational_state }} + Operation Speed-duplex : 1000full + Flow Control Type : None + Max Frame Size : 1518 bytes (1522 bytes for tagged frames) + MAC Learning Status : Enabled + diff --git a/templates/EdgeCore/login/mainloop/enable/show_interface_switchport.j2 b/templates/EdgeCore/login/mainloop/enable/show_interface_switchport.j2 new file mode 100644 index 0000000..ccf7204 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_interface_switchport.j2 @@ -0,0 +1,22 @@ +Information of Eth {{ context.interface.name }} + Broadcast Threshold : Enabled, 500 packets/second + Multicast Threshold : Disabled + Unknown Unicast Threshold : Disabled + LACP Status : Disabled + Ingress Rate Limit : {{ context.interface.ingress_state }}, {{ context.interface.ingress_rate }} kbits/second + Egress Rate Limit : {{ context.interface.egress_state }}, {{ context.interface.egress_rate }} kbits/second + VLAN Membership Mode : {{ context.interface.vlan_membership_mode }} + Ingress Rule : Disabled + Acceptable Frame Type : All frames + Native VLAN : {{ context.interface.native_vlan }} + Priority for Untagged Traffic : 0 + GVRP Status : Disabled + Allowed VLAN : {{ context.interface.allowed_vlan }} + Forbidden VLAN : + 802.1Q Tunnel Status : Disabled + 802.1Q Tunnel Mode : Normal + 802.1Q Tunnel TPID : 8100 (Hex) + Broadcast Block : Disabled + Unknown Multicast Block : Disabled + Unknown Unicast Block : Disabled + diff --git a/templates/EdgeCore/login/mainloop/enable/show_interface_transceiver.j2 b/templates/EdgeCore/login/mainloop/enable/show_interface_transceiver.j2 new file mode 100644 index 0000000..271b17d --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_interface_transceiver.j2 @@ -0,0 +1,26 @@ +Information of Eth {{ context.port.name }} + Connector Type : LC + Fiber Type : Multimode 50um (M5), Multimode 62.5um (M6) + Eth Compliance Codes : 1000BASE-SX + Baud Rate : 2100 MBd + Vendor OUI : 00-90-65 + Vendor Name : FINISAR CORP. + Vendor PN : FTLF8519P2BNL + Vendor Rev : A + Vendor SN : PFS4U5F + Date Code : 09-07-02 +DDM Information + Temperature : 31.36 degree C + Vcc : 3.32 V + Bias Current : 25.61 mA + TX Power : -3.11 dBm + RX Power : -40.00 dBm +DDM Thresholds + Low Alarm Low Warning High Warning High Alarm + ----------- ------------ ------------ ------------ ------------ + Temperature(Celsius) -25.00 -20.00 90.00 95.00 + Voltage(Volts) 2.80 2.90 3.70 3.80 + Current(mA) 2.00 3.00 80.00 90.00 + TxPower(dBm) -7.96 -6.99 1.00 2.01 + RxPower(dBm) -20.00 -19.00 0.00 1.00 + diff --git a/templates/EdgeCore/login/mainloop/enable/show_mac_address_table.j2 b/templates/EdgeCore/login/mainloop/enable/show_mac_address_table.j2 new file mode 100644 index 0000000..82e2ff6 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_mac_address_table.j2 @@ -0,0 +1,3 @@ + Interface MAC Address VLAN Type Life Time + --------- ----------------- ---- -------- ----------------- + diff --git a/templates/EdgeCore/login/mainloop/enable/show_mac_address_table_entry.j2 b/templates/EdgeCore/login/mainloop/enable/show_mac_address_table_entry.j2 new file mode 100644 index 0000000..413ac00 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_mac_address_table_entry.j2 @@ -0,0 +1,2 @@ + Eth {{ context.interface.name }} {{ context.interface.mac_address }} {{ context.interface.native_vlan }} Learn Delete on Timeout + diff --git a/templates/EdgeCore/login/mainloop/enable/show_mac_address_table_unit.j2 b/templates/EdgeCore/login/mainloop/enable/show_mac_address_table_unit.j2 new file mode 100644 index 0000000..769a7e1 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_mac_address_table_unit.j2 @@ -0,0 +1,3 @@ + CPU {{ context.card.mac_address }} 1 CPU Delete on Reset + + diff --git a/templates/EdgeCore/login/mainloop/enable/show_memory.j2 b/templates/EdgeCore/login/mainloop/enable/show_memory.j2 new file mode 100644 index 0000000..a082ecb --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_memory.j2 @@ -0,0 +1,10 @@ + Status Bytes % + ------ ---------- --- + Free 236236800 44 + Used 300634112 56 + Total 536870912 + +Alarm Configuration + Rising Threshold : 90% + Falling Threshold : 70% + diff --git a/templates/EdgeCore/login/mainloop/enable/show_process_cpu.j2 b/templates/EdgeCore/login/mainloop/enable/show_process_cpu.j2 new file mode 100644 index 0000000..fe6c2bb --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_process_cpu.j2 @@ -0,0 +1,16 @@ + CPU Utilization in the past 5 seconds : 7% + + CPU Utilization in the past 60 seconds + Average Utilization : 8% + Maximum Utilization : 9% + + Alarm Status + Current Alarm Status : Off + Last Alarm Start Time : Jun 9 15:10:09 2011 + Last Alarm Duration Time : 10 seconds + + Alarm Configuration + Rising Threshold : 90% + Falling Threshold : 70% + + diff --git a/templates/EdgeCore/login/mainloop/enable/show_system.j2 b/templates/EdgeCore/login/mainloop/enable/show_system.j2 new file mode 100644 index 0000000..e9c9f14 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable/show_system.j2 @@ -0,0 +1,28 @@ +System Description : {{ context.box.model }} +System OID String : 1.3.6.1.4.1.259.10.1.45.108 +System Information + System Up Time : 0 days, 5 hours, 44 minutes, and 42.28 seconds + System Name : + System Location : + System Contact : + MAC Address (Unit 1) : {{ context.card.mac_address }} + Web Server : Enabled + Web Server Port : 80 + Web Secure Server : Enabled + Web Secure Server Port : 443 + Telnet Server : Enabled + Telnet Server Port : 23 + Jumbo Frame : Disabled + +System Fan: + Force Fan Speed Full : Disabled +Unit 1 + Fan 1: Ok Fan 2: Ok + +System Temperature: +Unit 1 + Temperature 1: 35 degrees + +Unit 1 + Main Power Status : {{ context.card.admin_state }} + diff --git a/templates/EdgeCore/login/mainloop/enable_password.j2 b/templates/EdgeCore/login/mainloop/enable_password.j2 new file mode 100644 index 0000000..417a449 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/enable_password.j2 @@ -0,0 +1,2 @@ +% Bad passwords + diff --git a/templates/EdgeCore/login/mainloop/help.j2 b/templates/EdgeCore/login/mainloop/help.j2 new file mode 100644 index 0000000..800b1a8 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/help.j2 @@ -0,0 +1,12 @@ +Help may be requested at any point in a command by entering +a question mark '?'. If nothing matches, the help list will +be empty and you must backup until entering a '?' shows the +available options. +Two styles of help are provided: +1. Full help is available when you are ready to enter a + command argument (e.g. 'show ?') and describes each possible + argument. +2. Partial help is provided when an abbreviated argument is entered + and you want to know what arguments match the input + (e.g. 'show br?'.) + diff --git a/templates/EdgeCore/login/mainloop/on_cycle.j2 b/templates/EdgeCore/login/mainloop/on_cycle.j2 new file mode 100644 index 0000000..d9f093f --- /dev/null +++ b/templates/EdgeCore/login/mainloop/on_cycle.j2 @@ -0,0 +1 @@ +{{ model.hostname }}> \ No newline at end of file diff --git a/templates/EdgeCore/login/mainloop/on_enter.j2 b/templates/EdgeCore/login/mainloop/on_enter.j2 new file mode 100644 index 0000000..c148098 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/on_enter.j2 @@ -0,0 +1,24 @@ +*************************************************************** +WARNING - MONITORED ACTIONS AND ACCESSES +FNT + + +Station's information: + + +Floor / Row / Rack / Sub-Rack + / / / +DC power supply: +Power Source A: Floor / Row / Rack / Electrical circuit + / / / + +Number of LP: +Position MUX: +IP LAN: {{ context.ip }} +Note: {{ context.name }} +MOTD: +*************************************************************** + + CLI session with the ECS4120-28Fv2-I is opened. + To end the CLI session, enter [Exit]. + diff --git a/templates/EdgeCore/login/mainloop/on_error.j2 b/templates/EdgeCore/login/mainloop/on_error.j2 new file mode 100644 index 0000000..d965dc6 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/on_error.j2 @@ -0,0 +1,3 @@ + ^ +% Invalid input detected at '^' marker. + diff --git a/templates/EdgeCore/login/mainloop/show_?.j2 b/templates/EdgeCore/login/mainloop/show_?.j2 new file mode 100644 index 0000000..73ca696 --- /dev/null +++ b/templates/EdgeCore/login/mainloop/show_?.j2 @@ -0,0 +1,17 @@ + banner Banner info + calendar Date and time information + history Shows history information + interfaces Shows interface information + ip IP information + lacp LACP statistics + line TTY line information + memory Memory utilization + privilege Shows current privilege level + process Device process + public-key Public key information + snmp Simple Network Management Protocol configuration and statistics + system System information + users Information about users logged in + version System hardware and software versions + vlan Shows virtual LAN settings + diff --git a/templates/EdgeCore/login/on_cycle.j2 b/templates/EdgeCore/login/on_cycle.j2 new file mode 100644 index 0000000..e69de29 diff --git a/templates/EdgeCore/login/on_enter.j2 b/templates/EdgeCore/login/on_enter.j2 new file mode 100644 index 0000000..3adfb18 --- /dev/null +++ b/templates/EdgeCore/login/on_enter.j2 @@ -0,0 +1 @@ +>>User password: \ No newline at end of file diff --git a/templates/EdgeCore/login/password.j2 b/templates/EdgeCore/login/password.j2 new file mode 100644 index 0000000..a64789f --- /dev/null +++ b/templates/EdgeCore/login/password.j2 @@ -0,0 +1,2 @@ +Bad username or password + diff --git a/templates/EdgeCore/on_cycle.j2 b/templates/EdgeCore/on_cycle.j2 new file mode 100644 index 0000000..b24a03e --- /dev/null +++ b/templates/EdgeCore/on_cycle.j2 @@ -0,0 +1 @@ +>>User name: \ No newline at end of file diff --git a/templates/EdgeCore/on_enter.j2 b/templates/EdgeCore/on_enter.j2 new file mode 100644 index 0000000..e69de29 diff --git a/templates/EdgeCore/on_exit.j2 b/templates/EdgeCore/on_exit.j2 new file mode 100644 index 0000000..b900707 --- /dev/null +++ b/templates/EdgeCore/on_exit.j2 @@ -0,0 +1,4 @@ +% CLI exit session +Connection to {{ context.ip }} closed by remote host. +Connection to {{ context.ip }} closed. + diff --git a/test_cases/integration_tests/edgecore/backup.txt b/test_cases/integration_tests/edgecore/backup.txt new file mode 100644 index 0000000..9b5d380 --- /dev/null +++ b/test_cases/integration_tests/edgecore/backup.txt @@ -0,0 +1,10 @@ +admin +secret +enable +enable +copy startup-config ftp +1.1.1.1 +backup +backup +/example.txt +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureBox7.txt b/test_cases/integration_tests/edgecore/configureBox7.txt new file mode 100644 index 0000000..1cc3455 --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureBox7.txt @@ -0,0 +1,9 @@ +admin +secret +enable +enable +configure +management all-client 10.218.20.21 10.218.20.22 +no logging host 10.10.103.254 +loopback-detection action shutdown +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureBoxName10.txt b/test_cases/integration_tests/edgecore/configureBoxName10.txt new file mode 100644 index 0000000..82f10c4 --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureBoxName10.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +configure +prompt name_prompt +hostname test_device +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureClock9.txt b/test_cases/integration_tests/edgecore/configureClock9.txt new file mode 100644 index 0000000..db1aa8b --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureClock9.txt @@ -0,0 +1,10 @@ +admin +secret +enable +enable +configure +sntp server 77.244.98.1 +sntp client +clock timezone gmt hours 1 minute 0 +clock summer-time MESZ predefined europe +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureInternet2.txt b/test_cases/integration_tests/edgecore/configureInternet2.txt new file mode 100644 index 0000000..445095c --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureInternet2.txt @@ -0,0 +1,12 @@ +admin +secret +enable +enable +configure +interface ethernet 1/1 +description test_description +switchport mode hybrid +no shutdown +rate-limit input 1 +rate-limit output 1 +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureLog11.txt b/test_cases/integration_tests/edgecore/configureLog11.txt new file mode 100644 index 0000000..af21cba --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureLog11.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +configure +logging host 10.218.23.2 port 514 +logging trap +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureMVlan12.txt b/test_cases/integration_tests/edgecore/configureMVlan12.txt new file mode 100644 index 0000000..3707bf4 --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureMVlan12.txt @@ -0,0 +1,13 @@ +admin +secret +enable +enable +configure +vlan database +vlan 22 name scription media ethernet +exit +ip dhcp snooping +ip dhcp snooping vlan 1 +ip dhcp snooping information option encode no-subtype +ip dhcp snooping information option remote-id string test sub-option port-description +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configurePort4.txt b/test_cases/integration_tests/edgecore/configurePort4.txt new file mode 100644 index 0000000..677408c --- /dev/null +++ b/test_cases/integration_tests/edgecore/configurePort4.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +configure +interface ethernet 1/1 +no shutdown +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureRelay13.txt b/test_cases/integration_tests/edgecore/configureRelay13.txt new file mode 100644 index 0000000..a074bb3 --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureRelay13.txt @@ -0,0 +1,7 @@ +admin +secret +enable +enable +configure +pppoe intermediate-agent +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureRelayOnPort14.txt b/test_cases/integration_tests/edgecore/configureRelayOnPort14.txt new file mode 100644 index 0000000..a30b7c1 --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureRelayOnPort14.txt @@ -0,0 +1,13 @@ +admin +secret +enable +enable +configure +interface ethernet 1/1 +pppoe intermediate-agent port-enable +pppoe intermediate-agent trust +ip dhcp snooping trust +pppoe intermediate-agent port-format-type circuit-id 1/1 +ip dhcp snooping information option circuit-id tr101 node-identifier ip +ip dhcp snooping information option circuit-id tr101 no-vlan-field +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureTVlan8.txt b/test_cases/integration_tests/edgecore/configureTVlan8.txt new file mode 100644 index 0000000..97c1a4b --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureTVlan8.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +configure +vlan database +vlan 1111 name scription media ethernet +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureTVlanPort1.txt b/test_cases/integration_tests/edgecore/configureTVlanPort1.txt new file mode 100644 index 0000000..fd6e597 --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureTVlanPort1.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +configure +interface ethernet 1/1 +switchport allowed vlan add 1 tagged +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/configureUVlan15.txt b/test_cases/integration_tests/edgecore/configureUVlan15.txt new file mode 100644 index 0000000..f08985c --- /dev/null +++ b/test_cases/integration_tests/edgecore/configureUVlan15.txt @@ -0,0 +1,9 @@ +admin +secret +enable +enable +configure +interface ethernet 1/1 +switchport allowed vlan add 1 untagged +switchport native vlan 1 +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/display_data2.txt b/test_cases/integration_tests/edgecore/display_data2.txt new file mode 100644 index 0000000..ef5c230 --- /dev/null +++ b/test_cases/integration_tests/edgecore/display_data2.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +show system +show process cpu +show memory +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/display_information4.txt b/test_cases/integration_tests/edgecore/display_information4.txt new file mode 100644 index 0000000..7e24d3c --- /dev/null +++ b/test_cases/integration_tests/edgecore/display_information4.txt @@ -0,0 +1,6 @@ +admin +secret +enable +enable +show mac-address-table +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/display_model3.txt b/test_cases/integration_tests/edgecore/display_model3.txt new file mode 100644 index 0000000..461ab56 --- /dev/null +++ b/test_cases/integration_tests/edgecore/display_model3.txt @@ -0,0 +1,6 @@ +admin +secret +enable +enable +show system +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/display_state1.txt b/test_cases/integration_tests/edgecore/display_state1.txt new file mode 100644 index 0000000..a9897db --- /dev/null +++ b/test_cases/integration_tests/edgecore/display_state1.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +show interfaces status ethernet 1/1 +show interfaces switchport ethernet 1/1 +show interfaces transceiver ethernet 1/1 +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/unconfigureInternet3.txt b/test_cases/integration_tests/edgecore/unconfigureInternet3.txt new file mode 100644 index 0000000..0b8e7c5 --- /dev/null +++ b/test_cases/integration_tests/edgecore/unconfigureInternet3.txt @@ -0,0 +1,20 @@ +admin +secret +enable +enable +configure +interface ethernet 1/1 +rate-limit input 1000000 +rate-limit output 1000000 +no rate-limit input +no rate-limit output +shutdown +no description +no switchport mode +no switchport native vlan +no switchport allowed vlan +no pppoe intermediate-agent port-enable +no pppoe intermediate-agent port-format-type circuit-id +no ip dhcp snooping information option circuit-id tr101 no-vlan-field +no ip dhcp snooping information option circuit-id +quit \ No newline at end of file diff --git a/test_cases/integration_tests/edgecore/unconfigurePort5.txt b/test_cases/integration_tests/edgecore/unconfigurePort5.txt new file mode 100644 index 0000000..0e66ce9 --- /dev/null +++ b/test_cases/integration_tests/edgecore/unconfigurePort5.txt @@ -0,0 +1,8 @@ +admin +secret +enable +enable +configure +interface ethernet 1/1 +shutdown +quit \ No newline at end of file diff --git a/test_cases/unit_tests/edgecore/test_edgecore.py b/test_cases/unit_tests/edgecore/test_edgecore.py index 2bc31a7..1885d33 100644 --- a/test_cases/unit_tests/edgecore/test_edgecore.py +++ b/test_cases/unit_tests/edgecore/test_edgecore.py @@ -11,23 +11,84 @@ # License: https://github.com/inexio/NESi/LICENSE.rst from test_cases.unit_tests.test_core import TestCore +import pytest +from os import listdir +from os.path import isfile, join class TestEdgecore(TestCore): + PATH = 'test_cases/integration_tests/edgecore/' + DATA = [f for f in listdir('test_cases/integration_tests/edgecore/') if + isfile(join('test_cases/integration_tests/edgecore/', f)) and f != 'output.txt'] - def test_portup_portdown(self): - port = self.model.get_port("name", '1/1/1/1') - assert(self.model.get_port("name", '1/1/1/1').admin_state == '0') - port.admin_up() - assert(self.model.get_port("name", '1/1/1/1').admin_state == '1') - port.admin_down() - assert(self.model.get_port("name", '1/1/1/1').admin_state == '0') - - def test_ontportup_portdown(self): - port = self.model.get_ont_port("name", '1/1/4/1/1/1/1') - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '0') - port.admin_up() - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '1') - port.admin_down() - assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == '0') + def test_box(self): + box = self.model + box.set('management_start_address', 'test') + box.set('management_end_address', 'test') + box.set('logging_host', 'test') + box.set('logging_port', 'test') + box.set('logging_level', 8) + box.set('loopback_detection_action', 'shutdown') + box.set('sntp_server_ip', '') + box.set('sntp_client', 'Enabled') + box.set('timezone_name', '') + box.set('timezone_time', '') + box.set('summer_time_name', 'test') + box.set('summer_time_region', 'test') + assert box.management_start_address == 'test' + assert box.management_end_address == 'test' + assert box.logging_host == 'test' + assert box.logging_port == 'test' + assert box.logging_level == 8 + assert box.loopback_detection_action == 'shutdown' + assert box.sntp_server_ip == '' + assert box.sntp_client == 'Enabled' + assert box.timezone_name == '' + assert box.timezone_time == '' + assert box.summer_time_name == 'test' + assert box.summer_time_region == 'test' + + def test_card(self): + card = self.model.get_card("name", '1') + card.set('mac_address', '11-11-11-11') + card.set('admin_state', '1') + card.set('operational_state', '1') + + assert card.mac_address == '11-11-11-11' + assert card.admin_state == '1' + assert card.operational_state == '1' + + def test_port(self): + port = self.model.get_port("name", '1/1') + port.set('mac_address', '11-11-11-11') + port.set('admin_state', '1') + port.set('operational_state', '1') + + assert port.mac_address == '11-11-11-11' + assert port.admin_state == '1' + assert port.operational_state == '1' + + def test_interface(self): + interface = self.model.get_interface("name", '1/1') + interface.set('ingress_state', 'Enabled') + interface.set('ingress_rate', 1) + interface.set('egress_state', 'Enabled') + interface.set('egress_rate', 1) + interface.set('vlan_membership_mode', 'Access') + interface.set('native_vlan', 1010) + interface.set('mac_address', '11-11-11-11') + interface.set('allowed_vlan', '1,1010(u)') + + assert interface.ingress_state == 'Enabled' + assert interface.ingress_rate == 1 + assert interface.egress_state == 'Enabled' + assert interface.egress_rate == 1 + assert interface.vlan_membership_mode == 'Access' + assert interface.native_vlan == 1010 + assert interface.mac_address == '11-11-11-11' + assert interface.allowed_vlan == '1,1010(u)' + + @pytest.mark.parametrize("path", DATA) + def test_integration(self, path): + self.run(self.PATH + path, self.PATH + 'output.txt') diff --git a/vendors/EdgeCore/__init__.py b/vendors/EdgeCore/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/vendors/EdgeCore/baseCommandProcessor.py b/vendors/EdgeCore/baseCommandProcessor.py new file mode 100644 index 0000000..9dc0d3c --- /dev/null +++ b/vendors/EdgeCore/baseCommandProcessor.py @@ -0,0 +1,74 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi import exceptions +from nesi.softbox.cli import base + + +class BaseCommandProcessor(base.CommandProcessor): + """Create CLI REPR loop for example switch.""" + + def map_states(self, object, type): + if object.admin_state == '0': + if type in ('port', 'card'): + object.admin_state = 'Down' + elif object.admin_state == '1': + if type in ('port', 'card'): + object.admin_state = 'Up' + + if object.operational_state == '0': + if type in 'port': + object.operational_state = 'Down' + + elif object.operational_state == '1': + if type in 'port': + object.operational_state = 'Up' + + def do_exit(self, command, *args, context=None): + exc = exceptions.TerminalExitError() + raise exc + + def do_quit(self, command, *args, context=None): + exc = exceptions.TerminalExitError() + exc.return_to = 'sysexit' + raise exc + + def on_unknown_command(self, command, *args, context=None): + raise exceptions.CommandSyntaxError(command=command) + + def create_spacers(self, positions, args): + spacers = [] + previous_pos = 0 + i = 0 + for position in positions: + spacer = position - (previous_pos + len(str(args[i]))) + spacers.append(spacer) + previous_pos = position + i += 1 + + return spacers + + def user_input(self, prompt, allow_history=True, tmp_boundary=None): + self._write(prompt) + prompt_end_pos = self.prompt_end_pos + self.prompt_end_pos = len(prompt) - 1 + if not allow_history: + self.history_enabled = False + + if len(self.line_buffer) != 0: + input = self.line_buffer.pop(0) + else: + input = self._read(tmp_boundary).strip() + if not allow_history: + self.history_enabled = True + self.prompt_end_pos = prompt_end_pos + return input diff --git a/vendors/EdgeCore/configCommandProcessor.py b/vendors/EdgeCore/configCommandProcessor.py new file mode 100644 index 0000000..34f17c3 --- /dev/null +++ b/vendors/EdgeCore/configCommandProcessor.py @@ -0,0 +1,182 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst +import random +import datetime +import re +import time + +from nesi import exceptions +from .baseCommandProcessor import BaseCommandProcessor + + +class ConfigCommandProcessor(BaseCommandProcessor): + + def on_unknown_command(self, command, *args, context=None): + if self._validate(command, '?'): + text = self._render( + '?', + context=context) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_interface(self, command, *args, context=None): + if self._validate(args, 'ethernet', str): + interface_name, = self._dissect(args, 'ethernet', str) + + try: + _ = self._model.get_interface('name', interface_name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + from .interfaceCommandProcessor import InterfaceCommandProcessor + + subprocessor = self._create_subprocessor(InterfaceCommandProcessor, 'login', 'mainloop', 'enable', 'config', + 'interface') + subprocessor.set_interface_name(interface_name) + subprocessor.loop(return_to=ConfigCommandProcessor, context=dict(context)) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_vlan(self, command, *args, context=None): + if self._validate(args, 'database'): + from .vlanCommandProcessor import VlanCommandProcessor + + subprocessor = self._create_subprocessor(VlanCommandProcessor, 'login', 'mainloop', 'enable', 'config', + 'vlan') + subprocessor.loop(return_to=ConfigCommandProcessor, context=dict(context)) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_no(self, command, *args, context=None): + if self._validate(args, 'logging', 'host', str): + host, = self._dissect(args, 'logging', 'host', str) + box = self._model + if host in box.logging_host: + addresss = box.logging_host.split(', ') + ports = box.logging_port.split(', ') + index = 0 + for address in addresss: + if address == host: + break + index += 1 + addresss.remove(host) + ports.pop(index) + address_list = ', '.join(addresss) + port_list = ', '.join(ports) + box.set('logging_host', address_list) + box.set('logging_port', port_list) + else: + pass + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_management(self, command, *args, context=None): + if self._validate(args, 'all-client', str, str): + start, end = self._dissect(args, 'all-client', str, str) + box = self._model + box.set('management_start_address', start) + box.set('management_end_address', end) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_loopback_detection(self, command, *args, context=None): + if self._validate(args, 'action', str): + prop, = self._dissect(args, 'action', str) + box = self._model + box.set('loopback_detection_action', prop) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_sntp(self, command, *args, context=None): + if self._validate(args, 'server', str): + ip, = self._dissect(args, 'server', str) + box = self._model + box.set('sntp_server_ip', ip) + elif self._validate(args, 'client'): + box = self._model + box.set('sntp_client', 'Enabled') + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_clock(self, command, *args, context=None): + if self._validate(args, 'timezone', str, 'hours', str, 'minute', str): + name, h, m = self._dissect(args, 'timezone', str, 'hours', str, 'minute', str) + box = self._model + box.set('timezone_name', name) + box.set('timezone_time', (h + ',' + m)) + elif self._validate(args, 'summer-time', str, 'predefined', str): + name, region = self._dissect(args, 'summer-time', str, 'predefined', str) + box = self._model + box.set('summer_time_name', name) + box.set('summer_time_region', region) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_prompt(self, command, *args, context=None): + if self._validate(args, str): + name, = self._dissect(args, str) + box = self._model + box.set('hostname', name) + self.set_prompt_end_pos(context) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_hostname(self, command, *args, context=None): + if self._validate(args, str): + name, = self._dissect(args, str) + box = self._model + box.set('hostname', name) + self.set_prompt_end_pos(context) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_logging(self, command, *args, context=None): + if self._validate(args, 'host', str, 'port', str): + host, port = self._dissect(args, 'host', str, 'port', str) + box = self._model + if host not in box.logging_host: + address_list = box.logging_host + ', ' + host + port_list = box.logging_port + ', ' + port + box.set('logging_host', address_list) + box.set('logging_port', port_list) + + elif self._validate(args, 'trap'): + box = self._model + box.set('logging_level', 7) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_ip(self, command, *args, context=None): + if self._validate(args, 'dhcp', 'snooping'): + pass # No visible changes + + elif self._validate(args, 'dhcp', 'snooping', 'vlan', str): + pass # No visible changes + + elif self._validate(args, 'dhcp', 'snooping', 'information', 'option', 'encode', 'no-subtype'): + pass # No visible changes + + elif self._validate(args, 'dhcp', 'snooping', 'information', 'option', 'remote-id', 'string', str, 'sub-option', + 'port-description'): + pass # No visible changes + + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_pppoe(self, command, *args, context=None): + if self._validate(args, 'intermediate-agent'): + pass # No visible changes + + else: + raise exceptions.CommandSyntaxError(command=command) + diff --git a/vendors/EdgeCore/enableCommandProcessor.py b/vendors/EdgeCore/enableCommandProcessor.py new file mode 100644 index 0000000..e78bb09 --- /dev/null +++ b/vendors/EdgeCore/enableCommandProcessor.py @@ -0,0 +1,155 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst +from datetime import datetime + +from nesi import exceptions +from .baseCommandProcessor import BaseCommandProcessor +import time + + +class EnableCommandProcessor(BaseCommandProcessor): + + def do_disable(self, command, *args, context=None): + + from .userViewCommandProcessor import UserViewCommandProcessor + + exc = exceptions.TerminalExitError() + exc.return_to = UserViewCommandProcessor + raise exc + + def do_exit(self, command, *args, context=None): + exc = exceptions.TerminalExitError() + exc.return_to = 'sysexit' + raise exc + + def on_unknown_command(self, command, *args, context=None): + if command == '?' and args == (): + text = self._render('?', context=context) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_configure(self, command, *args, context=None): + + from .configCommandProcessor import ConfigCommandProcessor + + subprocessor = self._create_subprocessor( + ConfigCommandProcessor, 'login', 'mainloop', 'enable', 'config') + + subprocessor.loop(context=context, return_to=EnableCommandProcessor) + + def do_config(self, command, *args, context=None): + + from .configCommandProcessor import ConfigCommandProcessor + + subprocessor = self._create_subprocessor( + ConfigCommandProcessor, 'login', 'mainloop', 'enable', 'config') + + subprocessor.loop(context=context, return_to=EnableCommandProcessor) + + def do_show(self, command, *args, context=None): + if command == '?' and args == (): + text = self._render('show_?', context=context) + self._write(text) + elif self._validate(args, 'interfaces', 'status', 'ethernet', str): + port_name, = self._dissect(args, 'interfaces', 'status', 'ethernet', str) + try: + port = self._model.get_port('name', port_name) + self.map_states(port, 'port') + interface = self._model.get_interface('name', port_name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + # TODO: Information of Interface + text = self._render('show_interface_status', context=dict(context, port=port, interface=interface)) + self._write(text) + elif self._validate(args, 'interfaces', 'switchport', 'ethernet', str): + port_name, = self._dissect(args, 'interfaces', 'switchport', 'ethernet', str) + try: + port = self._model.get_port('name', port_name) + self.map_states(port, 'port') + interface = self._model.get_interface('name', port_name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + # TODO: Information of Interface + text = self._render('show_interface_switchport', context=dict(context, port=port, interface=interface)) + self._write(text) + elif self._validate(args, 'interfaces', 'transceiver', 'ethernet', str): + port_name, = self._dissect(args, 'interfaces', 'transceiver', 'ethernet', str) + try: + port = self._model.get_port('name', port_name) + self.map_states(port, 'port') + interface = self._model.get_interface('name', port_name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + # TODO: Information of Interface + # erst ab port 25-28 + text = self._render('show_interface_transceiver', context=dict(context, port=port, interface=interface)) + self._write(text) + elif self._validate(args, 'system'): + try: + card = self._model.get_card('name', "1") + self.map_states(card, 'card') + box = self._model + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + text = self._render('show_system', context=dict(context, card=card, box=box)) + self._write(text) + elif self._validate(args, 'process', 'cpu'): + text = self._render('show_process_cpu', context=context) + self._write(text) + elif self._validate(args, 'memory'): + text = self._render('show_memory', context=context) + self._write(text) + elif self._validate(args, 'mac-address-table'): + text = self._render('show_mac_address_table', context=context) + for interface in self._model.interfaces: + text += self._render('show_mac_address_table_entry', context=dict(context, interface=interface)) + card = self._model.get_card('name', "1") + self.map_states(card, 'card') + text += self._render('show_mac_address_table_unit', context=dict(context, card=card)) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_copy(self, command, *args, context=None): + if self._validate(args, 'startup-config', 'ftp'): # Work in progess + ip = self.user_input("FTP server IP address: ", False, None) + user = self.user_input("User[anonymous]: ", False, None) + self.hide_input = True + pw = self.user_input("Password: ", False, None) + self.hide_input = False + dest = self.user_input("Destination file name: ", False, None) + + for creds in self._model.credentials: + if creds.username == user: + user = self._model.get_user('id', creds.user_id) + if user.profile == 'backup': + break + + if creds.password != pw or '/' not in dest or ip.count('.') != 3: + text = self._render('copy_startup_config_ftp_failure', context=context) + self._write(text) + else: + text = self._render('copy_startup_config_ftp_success', context=context) + self._write(text) + + else: + raise exceptions.CommandSyntaxError(command=command) + + def on_help(self, command, *args, context=None): + if args == (): + text = self._render( + 'help', + context=context) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/EdgeCore/interfaceCommandProcessor.py b/vendors/EdgeCore/interfaceCommandProcessor.py new file mode 100644 index 0000000..3003971 --- /dev/null +++ b/vendors/EdgeCore/interfaceCommandProcessor.py @@ -0,0 +1,212 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +import random +import re +from datetime import datetime, date +from ipaddress import IPv4Network +from nesi import exceptions +from .baseCommandProcessor import BaseCommandProcessor + + +class InterfaceCommandProcessor(BaseCommandProcessor): + + component_name = None + + def set_interface_name(self, name): + self.component_name = name + + def get_actual_interface(self, command): + if self.component_name is None: + raise exceptions.CommandExecutionError(command='Component name is None') + try: + return self._model.get_interface('name', self.component_name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + def get_actual_port(self, command): + if self.component_name is None: + raise exceptions.CommandExecutionError(command='Component name is None') + try: + return self._model.get_port('name', self.component_name) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + + def do_shutdown(self, command, *args, context=None): + if len(args) == 0: + port = self.get_actual_port(command) + port.admin_down() + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_no(self, command, *args, context=None): + if self._validate(args, 'shutdown'): + port = self.get_actual_port(command) + port.admin_up() + + elif self._validate(args, 'rate-limit', 'input'): + interface = self.get_actual_interface(command) + interface.set('ingress_state', 'Disabled') + + elif self._validate(args, 'rate-limit', 'output'): + interface = self.get_actual_interface(command) + interface.set('egress_state', 'Disabled') + + elif self._validate(args, 'description'): + port = self.get_actual_port(command) + port.set('description', '') + + elif self._validate(args, 'switchport', 'mode'): + interface = self.get_actual_interface(command) + interface.set('vlan_membership_mode', 'Hybrid') + interface.set('native_vlan', 1) + + elif self._validate(args, 'switchport', 'native', 'vlan'): + interface = self.get_actual_interface(command) + interface.set('native_vlan', 1) + + elif self._validate(args, 'switchport', 'allowed', 'vlan'): + interface = self.get_actual_interface(command) + interface.set('allowed_vlan', '1(u)') + + elif self._validate(args, 'pppoe', 'intermediate-agent', 'port-enable'): + pass # No visible changes + + elif self._validate(args, 'pppoe', 'intermediate-agent', 'port-format-type', 'circuit-id'): + pass # No visible changes + + elif self._validate(args, 'ip', 'dhcp', 'snooping', 'information', 'option', 'circuit-id', 'tr101', + 'no-vlan-field'): + pass # No visible changes + + elif self._validate(args, 'ip', 'dhcp', 'snooping', 'information', 'option', 'circuit-id'): + pass # No visible changes + + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_rate_limit(self, command, *args, context=None): + if self._validate(args, 'input', str): + rate, = self._dissect(args, 'input', str) + interface = self.get_actual_interface(command) + interface.set('ingress_state', 'Enabled') + interface.set('ingress_rate', int(rate)) + elif self._validate(args, 'output', str): + rate, = self._dissect(args, 'output', str) + interface = self.get_actual_interface(command) + interface.set('egress_state', 'Enabled') + interface.set('egress_rate', int(rate)) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_description(self, command, *args, context=None): + if self._validate(args, str): + descr, = self._dissect(args, str) + port = self.get_actual_port(command) + port.set('description', descr) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_switchport(self, command, *args, context=None): + if self._validate(args, 'mode', 'hybrid'): + interface = self.get_actual_interface(command) + interface.set('vlan_membership_mode', 'Hybrid') + + elif self._validate(args, 'mode', 'access'): + interface = self.get_actual_interface(command) + interface.set('vlan_membership_mode', 'Access') + + elif self._validate(args, 'mode', 'trunk'): + interface = self.get_actual_interface(command) + interface.set('vlan_membership_mode', 'Trunk') + + elif self._validate(args, 'allowed', 'vlan', 'add', str, 'tagged'): + interface = self.get_actual_interface(command) + id_list, = self._dissect(args, 'allowed', 'vlan', 'add', str, 'tagged') + if ',' in id_list: + ids = id_list.split(',') + for id in ids: + try: + id = int(id) + _ = self._model.get_vlan('number', id) + except Exception: + raise exceptions.CommandSyntaxError(command=command) + else: + try: + id = int(id_list) + _ = self._model.get_vlan('number', id) + except Exception: + raise exceptions.CommandSyntaxError(command=command) + id_list = id_list + '(t)' + interface.set('allowed_vlan', id_list) + + elif self._validate(args, 'allowed', 'vlan', 'add', str, 'untagged'): + interface = self.get_actual_interface(command) + id_list, = self._dissect(args, 'allowed', 'vlan', 'add', str, 'untagged') + if ',' in id_list: + ids = id_list.split(',') + for id in ids: + try: + id = int(id) + _ = self._model.get_vlan('number', id) + except Exception: + raise exceptions.CommandSyntaxError(command=command) + else: + try: + id = int(id_list) + _ = self._model.get_vlan('number', id) + except Exception: + raise exceptions.CommandSyntaxError(command=command) + id_list = id_list + '(u)' + interface.set('allowed_vlan', id_list) + + elif self._validate(args, 'native', 'vlan', str): #untagged + vlan_id, = self._dissect(args, 'native', 'vlan', str) + interface = self.get_actual_interface(command) + try: + vlan = self._model.get_vlan('number', int(vlan_id)) + except exceptions.SoftboxenError: + raise exceptions.CommandSyntaxError(command=command) + interface.set('native_vlan', int(vlan_id)) + + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_pppoe(self, command, *args, context=None): + if self._validate(args, 'intermediate-agent', 'port-enable'): + pass # No visible changes + + elif self._validate(args, 'intermediate-agent', 'trust'): + pass # No visible changes + + elif self._validate(args, 'intermediate-agent', 'port-format-type', 'circuit-id', str): + pass # No visible changes + + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_ip(self, command, *args, context=None): + if self._validate(args, 'dhcp', 'snooping'): + pass # No visible changes + + elif self._validate(args, 'dhcp', 'snooping', 'trust'): + pass # No visible changes + + elif self._validate(args, 'dhcp', 'snooping', 'information', 'option', 'circuit-id', 'tr101', 'node-identifier', + 'ip'): + pass # No visible changes + + elif self._validate(args, 'dhcp', 'snooping', 'information', 'option', 'circuit-id', 'tr101', 'no-vlan-field'): + pass # No visible changes + + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/EdgeCore/main.py b/vendors/EdgeCore/main.py new file mode 100644 index 0000000..b11b23e --- /dev/null +++ b/vendors/EdgeCore/main.py @@ -0,0 +1,63 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + +from nesi.softbox.cli import base +from vendors.EdgeCore.userViewCommandProcessor import * +from nesi import exceptions + + +class PreLoginCommandProcessor(base.CommandProcessor): + + def on_unknown_command(self, command, *args, context=None): + subprocessor = self._create_subprocessor( + LoginCommandProcessor, 'login') + + context['username'] = context['raw_line'].replace('\r', '').replace('\n', '') + + try: + subprocessor.history_enabled = False + subprocessor.hide_input = True + context['ip'] = self._model.network_address + context['name'] = self._model.hostname + subprocessor.loop(context=context) + except exceptions.TerminalExitError as exc: + if exc.return_to is not None and exc.return_to != 'sysexit': + raise exc + else: + context['ip'] = self._model.network_address + self.on_exit(context) + raise exc + + +class LoginCommandProcessor(base.CommandProcessor): + + def on_unknown_command(self, command, *args, context=None): + username = context.pop('username') + password = command + + for creds in self._model.credentials: + if creds.username == username and creds.password == password: + user = self._model.get_user('id', creds.user_id) + if user.profile == 'root': + break + else: + text = self._render('password', context=context) + self._write(text) + raise exceptions.TerminalExitError() + + self._output.write(bytes(False)) + self._output.write(bytes(False)) + + subprocessor = self._create_subprocessor( + UserViewCommandProcessor, 'login', 'mainloop') + + subprocessor.loop(context=context) diff --git a/vendors/EdgeCore/userViewCommandProcessor.py b/vendors/EdgeCore/userViewCommandProcessor.py new file mode 100644 index 0000000..4f61cae --- /dev/null +++ b/vendors/EdgeCore/userViewCommandProcessor.py @@ -0,0 +1,71 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst +from datetime import datetime + +from nesi import exceptions +from .baseCommandProcessor import BaseCommandProcessor + + +class UserViewCommandProcessor(BaseCommandProcessor): + + def do_enable(self, command, *args, context=None): + + for i in range(0, 3): + self.hide_input = True + enable_pw = self.user_input("Password:", False, None) + self.hide_input = False + + for creds in self._model.credentials: + if creds.username == 'enable': + user = self._model.get_user('id', creds.user_id) + if user.profile == 'enable': + break + + if creds.password == enable_pw: + break + else: + text = self._render('enable_password', context=context) + self._write(text) + return + + from .enableCommandProcessor import EnableCommandProcessor + + subprocessor = self._create_subprocessor( + EnableCommandProcessor, 'login', 'mainloop', 'enable') + + subprocessor.loop(context=context) + + def do_disable(self, command, *args, context=None): + return + + def on_unknown_command(self, command, *args, context=None): + if self._validate(command, '?'): + text = self._render( + '?', + context=context) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) + + def do_exit(self, command, *args, context=None): + exc = exceptions.TerminalExitError() + exc.return_to = 'sysexit' + raise exc + + def on_help(self, command, *args, context=None): + if args == (): + text = self._render( + 'help', + context=context) + self._write(text) + else: + raise exceptions.CommandSyntaxError(command=command) diff --git a/vendors/EdgeCore/vlanCommandProcessor.py b/vendors/EdgeCore/vlanCommandProcessor.py new file mode 100644 index 0000000..b7f7f5b --- /dev/null +++ b/vendors/EdgeCore/vlanCommandProcessor.py @@ -0,0 +1,32 @@ +# This file is part of the NESi software. +# +# Copyright (c) 2020 +# Original Software Design by Ilya Etingof . +# +# Software adapted by inexio . +# - Janis Groß +# - Philip Konrath +# - Alexander Dincher +# +# License: https://github.com/inexio/NESi/LICENSE.rst + + +from .baseCommandProcessor import BaseCommandProcessor +from nesi import exceptions + + +class VlanCommandProcessor(BaseCommandProcessor): + + def do_vlan(self, command, *args, context=None): + # vlan $trafficVlan name $description media ethernet + # vlan $cpe_management_vlan name $description media ethernet + if self._validate(args, str, 'name', str, 'media', 'ethernet'): + number, name = self._dissect(args, str, 'name', str, 'media', 'ethernet') + try: + vlan = self._model.get_vlan('number', int(number)) + vlan.set('name', name) + except exceptions.SoftboxenError: + _ = self._model.add_vlan(number=int(number), name=name) + vlan = self._model.get_vlan('number', int(number)) + else: + raise exceptions.CommandSyntaxError(command=command) From 7e4576daacdf1aa6b5cb1d0645d43a6279e8dedc Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 3 Dec 2020 15:53:44 +0100 Subject: [PATCH 314/318] Added ssh socket class and implementation, changes to NESi backend according to ssh socket --- bootup/sockets/ssh.py | 137 +++++++++++++++++++++++++++++++++++++++ cli.py | 6 +- nesi/softbox/cli/base.py | 32 ++++++--- requirements.txt | 1 + 4 files changed, 166 insertions(+), 10 deletions(-) create mode 100644 bootup/sockets/ssh.py diff --git a/bootup/sockets/ssh.py b/bootup/sockets/ssh.py new file mode 100644 index 0000000..4f52202 --- /dev/null +++ b/bootup/sockets/ssh.py @@ -0,0 +1,137 @@ +from twisted.cred.portal import Portal +from twisted.cred import portal +from twisted.conch.ssh import factory, userauth, connection, keys, session +from twisted.conch.ssh.transport import SSHServerTransport +from twisted.conch import avatar +from twisted.cred.checkers import InMemoryUsernamePasswordDatabaseDontUse +from twisted.internet import reactor, protocol +from twisted.python import components +from zope.interface import implementer +import threading + +SERVER_RSA_PUBLIC = '~/.ssh/id_rsa.pub' +SERVER_RSA_PRIVATE = '~/.ssh/id_rsa' + +PRIMES = { + 2048: [(2, 24265446577633846575813468889658944748236936003103970778683933705240497295505367703330163384138799145013634794444597785054574812547990300691956176233759905976222978197624337271745471021764463536913188381724789737057413943758936963945487690939921001501857793275011598975080236860899147312097967655185795176036941141834185923290769258512343298744828216530595090471970401506268976911907264143910697166165795972459622410274890288999065530463691697692913935201628660686422182978481412651196163930383232742547281180277809475129220288755541335335798837173315854931040199943445285443708240639743407396610839820418936574217939)], + 4096: [(2, 889633836007296066695655481732069270550615298858522362356462966213994239650370532015908457586090329628589149803446849742862797136176274424808060302038380613106889959709419621954145635974564549892775660764058259799708313210328185716628794220535928019146593583870799700485371067763221569331286080322409646297706526831155237865417316423347898948704639476720848300063714856669054591377356454148165856508207919637875509861384449885655015865507939009502778968273879766962650318328175030623861285062331536562421699321671967257712201155508206384317725827233614202768771922547552398179887571989441353862786163421248709273143039795776049771538894478454203924099450796009937772259125621285287516787494652132525370682385152735699722849980820612370907638783461523042813880757771177423192559299945620284730833939896871200164312605489165789501830061187517738930123242873304901483476323853308396428713114053429620808491032573674192385488925866607192870249619437027459456991431298313382204980988971292641217854130156830941801474940667736066881036980286520892090232096545650051755799297658390763820738295370567143697617670291263734710392873823956589171067167839738896249891955689437111486748587887718882564384870583135509339695096218451174112035938859)], + } + + +class Avatar(avatar.ConchUser): + def __init__(self, username, cli, model, template_root): + avatar.ConchUser.__init__(self) + self.username = username + self.cli = cli + self.model = model + self.template_root = template_root + self.channelLookup.update({b'session': session.SSHSession}) + + +@implementer(portal.IRealm) +class Realm(object): + def __init__(self, cli, model, template_root): + self.cli = cli + self.model = model + self.template_root = template_root + + def requestAvatar(self, avatarId, mind, *interfaces): + return interfaces[0], Avatar(avatarId, self.cli, self.model, self.template_root), lambda: None + + +class SSHProtocol(protocol.Protocol): + char = b'' + + def connectionMade(self): + connection = self.transport.getPeer().address + print('%s:%s connected.' % (connection.host, connection.port)) + + def connectionLost(self, reason=None): + connection = self.transport.getPeer().address + print('%s:%s disconnected.' % (connection.host, connection.port)) + + def receiveData(self): + while self.char == b'': + pass + + return_val = self.char + self.char = b'' + return return_val + + def dataReceived(self, data): + if data == b'\r': + data = b'\r\n' + elif data == b'\x03': # ^C + self.transport.loseConnection() + return + self.char = data + + +class ExampleSession(object): + def __init__(self, avatar): + self.avatar = avatar + + def getPty(self, term, windowSize, attrs): + pass + + def execCommand(self, proto, cmd): + raise Exception("not executing commands") + + def openShell(self, transport): + protocol = SSHProtocol() + protocol.makeConnection(transport) + transport.makeConnection(session.wrapProtocol(protocol)) + + command_processor = self.avatar.cli( + self.avatar.model, protocol, transport, (), template_root=self.avatar.template_root, daemon=True) + command_processor.skipLogin = True + thread = threading.Thread(target=command_processor.loop, args=()) + thread.start() + + def eofReceived(self): + pass + + def closed(self): + pass + + +class Factory(factory.SSHFactory): + protocol = SSHServerTransport + publicKeys = { + b'ssh-rsa': keys.Key.fromFile(SERVER_RSA_PUBLIC) + } + privateKeys = { + b'ssh-rsa': keys.Key.fromFile(SERVER_RSA_PRIVATE) + } + services = { + b'ssh-userauth': userauth.SSHUserAuthServer, + b'ssh-connection': connection.SSHConnection + } + + def getPrimes(self): + return PRIMES + + +class SshSocket: + def __init__(self, cli, model, template_root, hostaddress, port): + self.hostaddress = hostaddress + self.port = port + self.cli = cli + self.model = model + self.template_root = template_root + + def start(self): + components.registerAdapter(ExampleSession, Avatar, session.ISession) + + portal = Portal(Realm(self.cli, self.model, self.template_root)) + passwdDB = InMemoryUsernamePasswordDatabaseDontUse() + + for credential in self.model.credentials: + passwdDB.addUser(credential.username.encode('utf-8'), credential.password.encode('utf-8')) + + portal.registerChecker(passwdDB) + Factory.portal = portal + + print("Starting ssh socket on " + self.hostaddress + ":" + str(self.port)) + reactor.listenTCP(self.port, Factory()) + reactor.run() diff --git a/cli.py b/cli.py index a64a13a..13526d2 100644 --- a/cli.py +++ b/cli.py @@ -23,6 +23,7 @@ from nesi.softbox.cli import rest_client from nesi.softbox.base_resources import root, base from bootup.sockets.telnet import TelnetSocket +from bootup.sockets.ssh import SshSocket import pytest import subprocess @@ -184,8 +185,9 @@ def main(): telnet = TelnetSocket(cli, model, template_root, ip_address, int(port)) telnet.start() elif model.network_protocol == 'ssh': - ssh = None - # TODO: add ssh-socket daemon + cli = main.PostLoginCommandProcessor + ssh = SshSocket(cli, model, template_root, ip_address, int(port)) + ssh.start() else: stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 9a4566b..535e944 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -18,6 +18,7 @@ import jinja2 from nesi import exceptions +from twisted.internet import reactor LOG = logging.getLogger(__name__) @@ -62,6 +63,7 @@ def __init__(self, model, input_stream, output_stream, history, self.daemon = daemon # CLI specific attributes + self.skipLogin = False self.case_sensitive = case_sensitive self.line_buffer = [] self.history_enabled = True @@ -116,10 +118,18 @@ def move_right(self): self.cursor_pos += 1 def get(self): - inkey = self._Getch() + inkey = None + if not self.daemon: + inkey = self._Getch() while (1): - k = inkey(self._input).decode('utf-8') - if k != '': break + if self.daemon: + k = self._input.receiveData().decode('utf-8') + if k == '\r\n': + k = '\r' + else: + k = inkey(self._input).decode('utf-8') + if k != '': + break if k == '\x1b[A': # up-arrow if self.history_enabled: return 'history', self.history_up() @@ -141,7 +151,7 @@ def get(self): return 'backspace', '' else: return None, None - elif k == '[3': # del-key + elif k == '[3' or k == '[3~': # del-key return 'del', '' elif k == '': # ctrl-v return 'paste', pyperclip.paste() @@ -263,15 +273,17 @@ def _default_command_handler(self, command, *args, context=None): self._write(text) def _read(self, tmp_boundary=None): - if self.daemon: + if self.daemon and self._model.network_protocol == 'telnet': line = self._input.readline().decode('utf-8') else: line = self.getline(tmp_boundary) - return line def _write(self, text): + text = text.replace('\n', '\r\n') self._output.write(text.encode('utf-8')) + if self.daemon and self._model.network_protocol == 'ssh': + reactor.iterate() def _get_command_func(self, line): if line.startswith(self.comment): @@ -349,8 +361,8 @@ def loop(self, context=None, return_to=None, command=None): continue context['raw_line'] = line - if self.daemon: - self._write(line) # write line to stdout if box is in daemon mode + #if self.daemon: + # self._write(line) # write line to stdout if box is in daemon mode else: line = command command = None @@ -368,6 +380,10 @@ def loop(self, context=None, return_to=None, command=None): exc.return_to = return_to if not exc.return_to or exc.return_to == 'sysexit' or exc.return_to == 'sysreboot' or not isinstance(self, exc.return_to): + if self.daemon and self._model.network_protocol == 'ssh': + self._output.loseConnection() + reactor.iterate() + return raise exc # set prompt_len anew in case of prompt_len change in command-processor beneath self.set_prompt_end_pos(context) diff --git a/requirements.txt b/requirements.txt index 5038a59..ed20d47 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,3 +9,4 @@ pydevd-pycharm~=201.7846.77 psutil pytest pyperclip +twisted From b7e813484b07980d4f6ca28cdf4bc856c47d0b68 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 3 Dec 2020 16:12:23 +0100 Subject: [PATCH 315/318] Changes to get ssh-server running with EdgeCore simulated box --- bootup/conf/bootstraps/create-edgecore-xxxx.sh | 2 +- nesi/softbox/api/views/base_views.py | 2 -- vendors/EdgeCore/main.py | 9 +++++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/bootup/conf/bootstraps/create-edgecore-xxxx.sh b/bootup/conf/bootstraps/create-edgecore-xxxx.sh index 847ef39..970e776 100644 --- a/bootup/conf/bootstraps/create-edgecore-xxxx.sh +++ b/bootup/conf/bootstraps/create-edgecore-xxxx.sh @@ -43,7 +43,7 @@ req='{ "hostname": "ed-ge-co-re-1", "mgmt_address": "10.0.0.12", "software_version": "MA5623V800R016C00", - "network_protocol": "telnet", + "network_protocol": "ssh", "network_address": "127.0.0.1", "network_port": 9023, "dsl_mode": "tr165", diff --git a/nesi/softbox/api/views/base_views.py b/nesi/softbox/api/views/base_views.py index 47b60df..cd8d2b2 100644 --- a/nesi/softbox/api/views/base_views.py +++ b/nesi/softbox/api/views/base_views.py @@ -22,8 +22,6 @@ from nesi.huawei.api.schemas import * from nesi.keymile.api.schemas import * from nesi.edgecore.api.schemas import * -from nesi.pbn.api.schemas import * -from nesi.zhone.api.schemas import * # important for other view classes from nesi.softbox.api import db diff --git a/vendors/EdgeCore/main.py b/vendors/EdgeCore/main.py index b11b23e..77f1e67 100644 --- a/vendors/EdgeCore/main.py +++ b/vendors/EdgeCore/main.py @@ -61,3 +61,12 @@ def on_unknown_command(self, command, *args, context=None): UserViewCommandProcessor, 'login', 'mainloop') subprocessor.loop(context=context) + + +class PostLoginCommandProcessor(base.CommandProcessor): + + def loop(self, context=None, return_to=None, command=None): + subprocessor = self._create_subprocessor( + UserViewCommandProcessor, 'login', 'mainloop') + + subprocessor.loop(context=context) From 84e324e63d8da8b6ff4721a646f18315d2f5af94 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Thu, 17 Dec 2020 15:38:16 +0100 Subject: [PATCH 316/318] Fixed a bug where entering exit in ssh terminal would terminate box completely. --- bootup/conf/bootstraps/create-edgecore-xxxx.sh | 4 ++-- nesi/softbox/cli/base.py | 11 ++++++----- requirements.txt | 3 +++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/bootup/conf/bootstraps/create-edgecore-xxxx.sh b/bootup/conf/bootstraps/create-edgecore-xxxx.sh index 970e776..5d5699e 100644 --- a/bootup/conf/bootstraps/create-edgecore-xxxx.sh +++ b/bootup/conf/bootstraps/create-edgecore-xxxx.sh @@ -88,7 +88,7 @@ enable_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credential # backup user req='{ - "name": "Backuo", + "name": "Backup", "profile": "backup" }' @@ -151,4 +151,4 @@ req='{ "description": "The standard Vlan" }' -vlan_pppoe=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlans) \ No newline at end of file +vlan_pppoe=$(create_resource "$req" $ENDPOINT/boxen/$box_id/vlans) diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 535e944..86426bb 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -177,15 +177,16 @@ def updateline(self, line): self._write('\033[' + str(self.cursor_pos) + 'C') # move cursor to correct position def getline(self, tmp_boundary=None): - char = None + char = '' line = '' self.history_pos = len(self.history) self.cursor_pos = self.prompt_end_pos + 1 self.cursor_boundary = self.prompt_end_pos + 1 - while char != '\r': + while '\r' not in char: option, char = self.get() if char is None: + char = '' continue elif char == '\r': continue @@ -282,8 +283,8 @@ def _read(self, tmp_boundary=None): def _write(self, text): text = text.replace('\n', '\r\n') self._output.write(text.encode('utf-8')) - if self.daemon and self._model.network_protocol == 'ssh': - reactor.iterate() + #if self.daemon and self._model.network_protocol == 'ssh': + # reactor.iterate() def _get_command_func(self, line): if line.startswith(self.comment): @@ -380,7 +381,7 @@ def loop(self, context=None, return_to=None, command=None): exc.return_to = return_to if not exc.return_to or exc.return_to == 'sysexit' or exc.return_to == 'sysreboot' or not isinstance(self, exc.return_to): - if self.daemon and self._model.network_protocol == 'ssh': + if self.daemon and self._model.network_protocol == 'ssh' and exc.return_to in ('sysexit', 'sysreboot'): self._output.loseConnection() reactor.iterate() return diff --git a/requirements.txt b/requirements.txt index ed20d47..ba89e83 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,3 +10,6 @@ psutil pytest pyperclip twisted +cryptography +bcrypt +pyasn1 From 9276e4e47577fd13e744e2b85571a98a16958e56 Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 18 Dec 2020 11:59:23 +0100 Subject: [PATCH 317/318] Fixed an issue with line-ending special characters not being recognized correctly --- bootup/sockets/ssh.py | 16 ++++++++-------- nesi/softbox/cli/base.py | 6 +++++- vendors/EdgeCore/enableCommandProcessor.py | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/bootup/sockets/ssh.py b/bootup/sockets/ssh.py index 4f52202..55ba080 100644 --- a/bootup/sockets/ssh.py +++ b/bootup/sockets/ssh.py @@ -8,14 +8,19 @@ from twisted.python import components from zope.interface import implementer import threading +import os +from pathlib import Path -SERVER_RSA_PUBLIC = '~/.ssh/id_rsa.pub' -SERVER_RSA_PRIVATE = '~/.ssh/id_rsa' +full_path = os.path.dirname(os.path.abspath(__file__)) +path = str(Path(full_path).parents[0]) + +SERVER_RSA_PUBLIC = path + '/conf/ssh/id_rsa.pub' +SERVER_RSA_PRIVATE = path + '/conf/ssh/id_rsa' PRIMES = { 2048: [(2, 24265446577633846575813468889658944748236936003103970778683933705240497295505367703330163384138799145013634794444597785054574812547990300691956176233759905976222978197624337271745471021764463536913188381724789737057413943758936963945487690939921001501857793275011598975080236860899147312097967655185795176036941141834185923290769258512343298744828216530595090471970401506268976911907264143910697166165795972459622410274890288999065530463691697692913935201628660686422182978481412651196163930383232742547281180277809475129220288755541335335798837173315854931040199943445285443708240639743407396610839820418936574217939)], 4096: [(2, 889633836007296066695655481732069270550615298858522362356462966213994239650370532015908457586090329628589149803446849742862797136176274424808060302038380613106889959709419621954145635974564549892775660764058259799708313210328185716628794220535928019146593583870799700485371067763221569331286080322409646297706526831155237865417316423347898948704639476720848300063714856669054591377356454148165856508207919637875509861384449885655015865507939009502778968273879766962650318328175030623861285062331536562421699321671967257712201155508206384317725827233614202768771922547552398179887571989441353862786163421248709273143039795776049771538894478454203924099450796009937772259125621285287516787494652132525370682385152735699722849980820612370907638783461523042813880757771177423192559299945620284730833939896871200164312605489165789501830061187517738930123242873304901483476323853308396428713114053429620808491032573674192385488925866607192870249619437027459456991431298313382204980988971292641217854130156830941801474940667736066881036980286520892090232096545650051755799297658390763820738295370567143697617670291263734710392873823956589171067167839738896249891955689437111486748587887718882564384870583135509339695096218451174112035938859)], - } +} class Avatar(avatar.ConchUser): @@ -59,11 +64,6 @@ def receiveData(self): return return_val def dataReceived(self, data): - if data == b'\r': - data = b'\r\n' - elif data == b'\x03': # ^C - self.transport.loseConnection() - return self.char = data diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py index 86426bb..f39c52e 100644 --- a/nesi/softbox/cli/base.py +++ b/nesi/softbox/cli/base.py @@ -124,8 +124,12 @@ def get(self): while (1): if self.daemon: k = self._input.receiveData().decode('utf-8') - if k == '\r\n': + if k == '\r\n' or k == '\n\r': k = '\r' + if '\r\n' in k or '\n\r' in k: + k = k.replace('\n', '') + elif '\n' in k: + k = k.replace('\n', '\r') else: k = inkey(self._input).decode('utf-8') if k != '': diff --git a/vendors/EdgeCore/enableCommandProcessor.py b/vendors/EdgeCore/enableCommandProcessor.py index e78bb09..d3f392e 100644 --- a/vendors/EdgeCore/enableCommandProcessor.py +++ b/vendors/EdgeCore/enableCommandProcessor.py @@ -123,7 +123,7 @@ def do_show(self, command, *args, context=None): def do_copy(self, command, *args, context=None): if self._validate(args, 'startup-config', 'ftp'): # Work in progess ip = self.user_input("FTP server IP address: ", False, None) - user = self.user_input("User[anonymous]: ", False, None) + user = self.user_input("User [Anonymous]: ", False, None) self.hide_input = True pw = self.user_input("Password: ", False, None) self.hide_input = False From 607111d1558bb7c4fdf6c63088a8b5eb3506ce8a Mon Sep 17 00:00:00 2001 From: unkn0wn-user Date: Fri, 18 Dec 2020 12:00:19 +0100 Subject: [PATCH 318/318] Added public and private key for ssh-daemon --- bootup/conf/ssh/id_rsa | 28 ++++++++++++++++++++++++++++ bootup/conf/ssh/id_rsa.pub | 1 + 2 files changed, 29 insertions(+) create mode 100644 bootup/conf/ssh/id_rsa create mode 100644 bootup/conf/ssh/id_rsa.pub diff --git a/bootup/conf/ssh/id_rsa b/bootup/conf/ssh/id_rsa new file mode 100644 index 0000000..5c272a8 --- /dev/null +++ b/bootup/conf/ssh/id_rsa @@ -0,0 +1,28 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn +NhAAAAAwEAAQAAAQEA2m6f+W9xnt0mHvvJqzasFmIP1/z8gaDTYcgzwYhE4UItZeUXLUzx +3PGSiFd8GkRIjEhaPL9omFbL5E5q/SLNzu6AAg9eNOMKthy+EwyUYAC/Z36XSsjt89hXkv +SwzqIT7APl5hE4ZZIub3mA9q9YmLlo9bAi90UF11z7U3/jg0vlV45iDUj02Ont/QsvaxWr +EQG3XF4DWs5iid7RFqoHYdwEAMafi3nTZZKB8RGvsx9vpZkjLy5h+9Svgx1mFJZz2G4yJ0 +sEGOL/6QGCc6fp0L58+2rkVLGUZ0VT1o3WCp9ij8PKh24h1nuYXr1xHkG+ojVv1sXCnMxY +ww7g9BX3HwAAA+Ai4SmvIuEprwAAAAdzc2gtcnNhAAABAQDabp/5b3Ge3SYe+8mrNqwWYg +/X/PyBoNNhyDPBiEThQi1l5RctTPHc8ZKIV3waREiMSFo8v2iYVsvkTmr9Is3O7oACD140 +4wq2HL4TDJRgAL9nfpdKyO3z2FeS9LDOohPsA+XmEThlki5veYD2r1iYuWj1sCL3RQXXXP +tTf+ODS+VXjmINSPTY6e39Cy9rFasRAbdcXgNazmKJ3tEWqgdh3AQAxp+LedNlkoHxEa+z +H2+lmSMvLmH71K+DHWYUlnPYbjInSwQY4v/pAYJzp+nQvnz7auRUsZRnRVPWjdYKn2KPw8 +qHbiHWe5hevXEeQb6iNW/WxcKczFjDDuD0FfcfAAAAAwEAAQAAAQEA0i7ctJIuDKXURsAV +oDBtiuQ1Rqpi9wEgJdkVJEbRsMeTE5dLpAWEPgwd6h/0hPnrrUD5w7aTGPN8ImXqwUW6ME +KC3niXN+C4r+AcbgwOwgo2I4pGXmnVvmwQaJIXh92hudtOXwF2+RWepRmPpM+5Osw+WRtx +qem64y7Pj9thuzWGyKGuFmQ8ujb7zh6ovWwNlyTB64rM9zq+YFPh8QWiXocRwN7egOChtZ +fF+amgn/wkMi1Ja11PTIzVON/ajg0vnpPYOZ56boerPU3YhRHnzHXkSa34qvzd7XofiNee +2ybfFO7QxaEhDfcIXqztItPp6t1RvIUb89lUyCT4WkG3cQAAAIEAtiMJt2nkKL8UWbY6PT +wgEZ9D4RRuZzEk4SMnonXxGaFAXtnL2+sKlQiyJhGJEKQrWAyEBIXQtZNo2rZwLIvOOq7T +uXk9OjwCGPXT50jLrhD09yBNeWAR4fZsCqAYEq1cjLZgaXJxBGiBWfvk0vHADnz6PKPxfi +q7PJKn7WAIT/4AAACBAPrlmB0HOvFL0QAN4HnvLe3QMy7HuDVoYaQ9jz9uB9T7VTE+N7R9 +CxwDD8AUufU8gc88tw1FBUaWN1l6K8gSC0KIIKgIVtT+lttblKY1qJIakox2V/+qbtPU0T +DTSaC85znNkUJ4eqavRCitjPVnKke6v5JSePQO6Rag5/8Ww9KjAAAAgQDe3/0ca5btlE7n +iDEWQxfpzBYyED19VVb0HVM82BMYDb9rbgdmAu5vEWmIhtOyNTjkvOR5ZvZ5alsFY+FbcV +QVDWu5AqHGp+iUm1pfxCNB7UbJN664O+raL6UyHDQLZfjPT/rUCL2PX4ePsLaV4Cc8lQ5D +thL7QOgFiQ2Sx9JNVQAAACRqYW5pc19ncm9zc0BKYW5pc3MtTWFjQm9vay1Qcm8ubG9jYW +wBAgMEBQ== +-----END OPENSSH PRIVATE KEY----- diff --git a/bootup/conf/ssh/id_rsa.pub b/bootup/conf/ssh/id_rsa.pub new file mode 100644 index 0000000..3eb0b1b --- /dev/null +++ b/bootup/conf/ssh/id_rsa.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDabp/5b3Ge3SYe+8mrNqwWYg/X/PyBoNNhyDPBiEThQi1l5RctTPHc8ZKIV3waREiMSFo8v2iYVsvkTmr9Is3O7oACD1404wq2HL4TDJRgAL9nfpdKyO3z2FeS9LDOohPsA+XmEThlki5veYD2r1iYuWj1sCL3RQXXXPtTf+ODS+VXjmINSPTY6e39Cy9rFasRAbdcXgNazmKJ3tEWqgdh3AQAxp+LedNlkoHxEa+zH2+lmSMvLmH71K+DHWYUlnPYbjInSwQY4v/pAYJzp+nQvnz7auRUsZRnRVPWjdYKn2KPw8qHbiHWe5hevXEeQb6iNW/WxcKczFjDDuD0Ffcf janis_gross@Janiss-MacBook-Pro.local