From 2615359fc91fa168dbf5021ffcf6ae48d3db08f0 Mon Sep 17 00:00:00 2001
From: png2000
Date: Tue, 5 Jan 2021 15:56:44 +0100
Subject: [PATCH 1/3] initial zhone commit
---
bootup/conf/bootstraps/create-zhone.sh | 81 +++++++++++++++++++
bootup/restapi.sh | 5 +-
cli.py | 7 +-
nesi/softbox/api/models/box_models.py | 2 +-
nesi/softbox/api/models/port_models.py | 6 ++
nesi/softbox/api/schemas/box_schemas.py | 2 +-
nesi/softbox/api/schemas/subrack_schemas.py | 2 +
nesi/softbox/api/views/base_views.py | 1 +
nesi/softbox/base_resources/box.py | 1 +
nesi/zhone/api/__init__.py | 7 ++
nesi/zhone/api/schemas/__init__.py | 25 ++++++
nesi/zhone/api/schemas/zhone_box_schemas.py | 14 ++++
nesi/zhone/api/schemas/zhone_card_schemas.py | 14 ++++
nesi/zhone/api/schemas/zhone_port_schemas.py | 15 ++++
.../api/schemas/zhone_subrack_schemas.py | 14 ++++
nesi/zhone/zhone_resources/__init__.py | 2 +-
nesi/zhone/zhone_resources/zhone_box.py | 15 +++-
nesi/zhone/zhone_resources/zhone_card.py | 0
nesi/zhone/zhone_resources/zhone_port.py | 35 ++++++++
nesi/zhone/zhone_resources/zhone_subrack.py | 0
templates/Zhone/login/base/dslstatEmptyArg.j2 | 2 +
.../Zhone/login/base/dslstatInvalidArg.j2 | 2 +
templates/Zhone/login/base/dslstatTemplate.j2 | 66 +++++++++++++++
templates/Zhone/login/base/on_cycle.j2 | 1 +
templates/Zhone/login/base/on_enter.j2 | 2 +
templates/Zhone/login/on_enter.j2 | 1 +
templates/Zhone/login/password.j2 | 2 +
templates/Zhone/on_cycle.j2 | 1 +
templates/Zhone/on_enter.j2 | 0
.../accessPoints/root/rootCommandProcessor.py | 7 +-
vendors/Zhone/__init__.py | 7 ++
vendors/Zhone/baseCommandProcessor.py | 29 +++++++
vendors/Zhone/main.py | 60 ++++++++++++++
vendors/Zhone/rootCommandProcessor.py | 33 ++++++++
34 files changed, 451 insertions(+), 10 deletions(-)
create mode 100644 bootup/conf/bootstraps/create-zhone.sh
create mode 100644 nesi/zhone/api/__init__.py
create mode 100644 nesi/zhone/api/schemas/__init__.py
create mode 100644 nesi/zhone/api/schemas/zhone_box_schemas.py
create mode 100644 nesi/zhone/api/schemas/zhone_card_schemas.py
create mode 100644 nesi/zhone/api/schemas/zhone_port_schemas.py
create mode 100644 nesi/zhone/api/schemas/zhone_subrack_schemas.py
create mode 100644 nesi/zhone/zhone_resources/zhone_card.py
create mode 100644 nesi/zhone/zhone_resources/zhone_port.py
create mode 100644 nesi/zhone/zhone_resources/zhone_subrack.py
create mode 100644 templates/Zhone/login/base/dslstatEmptyArg.j2
create mode 100644 templates/Zhone/login/base/dslstatInvalidArg.j2
create mode 100644 templates/Zhone/login/base/dslstatTemplate.j2
create mode 100644 templates/Zhone/login/base/on_cycle.j2
create mode 100644 templates/Zhone/login/base/on_enter.j2
create mode 100644 templates/Zhone/login/on_enter.j2
create mode 100644 templates/Zhone/login/password.j2
create mode 100644 templates/Zhone/on_cycle.j2
create mode 100644 templates/Zhone/on_enter.j2
create mode 100644 vendors/Zhone/__init__.py
create mode 100644 vendors/Zhone/baseCommandProcessor.py
create mode 100644 vendors/Zhone/main.py
create mode 100644 vendors/Zhone/rootCommandProcessor.py
diff --git a/bootup/conf/bootstraps/create-zhone.sh b/bootup/conf/bootstraps/create-zhone.sh
new file mode 100644
index 0000000..5532916
--- /dev/null
+++ b/bootup/conf/bootstraps/create-zhone.sh
@@ -0,0 +1,81 @@
+#!/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
+# - Philipp-Noah Groß
+#
+# 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": "Zhone",
+ "model": "Zhone-Gerät lol",
+ "version": "2500",
+ "description": "(Juan-)",
+ "hostname": "Zhone-Gerät lul",
+ "network_protocol": "telnet",
+ "network_address": "127.0.0.1",
+ "network_port": 9023,
+ "uuid": "7777",
+ "software_version": "juan"
+ }'
+
+box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1
+
+# Sessionmanager credentials
+req='{
+ "username": "admin",
+ "password": "secret"
+}'
+
+admin_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials)
+
+# create a Subrack
+
+req='{
+ "name": "1",
+ "description": "Juan Zhone"
+}'
+
+subrack_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks)
+
+# create a Card
+
+req='{
+ "subrack_id": '$subrack_1',
+ "name": "1/1",
+ "product": "vdsl",
+ "description": "Karte von Juan"
+}'
+
+card_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards)
+
+# create a Port
+
+req='{
+ "card_id": '$card_1',
+ "name": "1/1/1/0",
+ "description": "Port von Juan",
+ "admin_state": "1",
+ "operational_state": "1",
+ "upLineRate": 5555,
+ "downLineRate": 4444,
+ "maxUpLineRate": 3333,
+ "maxDownLineRate": 2222
+}'
+
+port_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports)
\ No newline at end of file
diff --git a/bootup/restapi.sh b/bootup/restapi.sh
index 6d8dd93..a9fa5c1 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-zhone.sh
fi
if [ $alcatel_api = "yes" ]; then
@@ -200,7 +201,7 @@ if [ $pbn_api = "yes" ]; then
bash bootup/conf/bootstraps/create-alcatel-7360.sh #work_in_progress
fi
if [ $zhone_api = "yes" ]; then
- bash bootup/conf/bootstraps/create-alcatel-7360.sh #work_in_progress
+ bash bootup/conf/bootstraps/create-zhone.sh #work_in_progress
fi
diff --git a/cli.py b/cli.py
index a64a13a..6abf6f8 100644
--- a/cli.py
+++ b/cli.py
@@ -1,9 +1,10 @@
# This file is part of the NESi software.
#
# Copyright (c) 2020, inexio
-# Janis Groß
-# Philip Konrath
-# Alexander Dincher
+# - Janis Groß
+# - Philip Konrath
+# - Alexander Dincher
+# - Philipp-Noah Groß
#
# Ilya Etingof
#
diff --git a/nesi/softbox/api/models/box_models.py b/nesi/softbox/api/models/box_models.py
index f4d3f9c..455f157 100644
--- a/nesi/softbox/api/models/box_models.py
+++ b/nesi/softbox/api/models/box_models.py
@@ -1,4 +1,4 @@
-# This file is part of the NESi software.
+ # This file is part of the NESi software.
#
# Copyright (c) 2020
# Original Software Design by Ilya Etingof .
diff --git a/nesi/softbox/api/models/port_models.py b/nesi/softbox/api/models/port_models.py
index 6ed09a0..da78916 100644
--- a/nesi/softbox/api/models/port_models.py
+++ b/nesi/softbox/api/models/port_models.py
@@ -331,3 +331,9 @@ 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)
+
+ #Zhone
+ upLineRate = db.Column(db.Integer(), default=0)
+ downLineRate = db.Column(db.Integer(), default=0)
+ maxUpLineRate = db.Column(db.Integer(), default=0)
+ maxDownLineRate = db.Column(db.Integer(), default=0)
diff --git a/nesi/softbox/api/schemas/box_schemas.py b/nesi/softbox/api/schemas/box_schemas.py
index eb5b802..41e0e6d 100644
--- a/nesi/softbox/api/schemas/box_schemas.py
+++ b/nesi/softbox/api/schemas/box_schemas.py
@@ -38,7 +38,7 @@ class Meta:
'subracks', 'subrack_details', 'cards', 'ports', 'channels', 'service_ports', 'emus', 'onts',
'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')
+ 'net_mask', 'default_gateway', '_links', 'ont_ports', 'cpes')
credentials = ma.Hyperlinks(
{'_links': {
diff --git a/nesi/softbox/api/schemas/subrack_schemas.py b/nesi/softbox/api/schemas/subrack_schemas.py
index 7a6c773..7bf1672 100644
--- a/nesi/softbox/api/schemas/subrack_schemas.py
+++ b/nesi/softbox/api/schemas/subrack_schemas.py
@@ -51,3 +51,5 @@ class Meta:
_links = ma.Hyperlinks(
{'self': ma.URLFor('show_subracks', box_id='')})
+
+
diff --git a/nesi/softbox/api/views/base_views.py b/nesi/softbox/api/views/base_views.py
index 4259e94..2ac1261 100644
--- a/nesi/softbox/api/views/base_views.py
+++ b/nesi/softbox/api/views/base_views.py
@@ -21,6 +21,7 @@
from nesi.alcatel.api.schemas import *
from nesi.huawei.api.schemas import *
from nesi.keymile.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/base_resources/box.py b/nesi/softbox/base_resources/box.py
index 006e1a5..e839600 100644
--- a/nesi/softbox/base_resources/box.py
+++ b/nesi/softbox/base_resources/box.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/zhone/api/__init__.py b/nesi/zhone/api/__init__.py
new file mode 100644
index 0000000..0342a16
--- /dev/null
+++ b/nesi/zhone/api/__init__.py
@@ -0,0 +1,7 @@
+# Software adapted by inexio .
+# - Janis Groß
+# - Philip Konrath
+# - Alexander Dincher
+# - Philipp-Noah Groß
+#
+# License: https://github.com/inexio/NESi/LICENSE.rst
\ No newline at end of file
diff --git a/nesi/zhone/api/schemas/__init__.py b/nesi/zhone/api/schemas/__init__.py
new file mode 100644
index 0000000..c168985
--- /dev/null
+++ b/nesi/zhone/api/schemas/__init__.py
@@ -0,0 +1,25 @@
+# Software adapted by inexio .
+# - Janis Groß
+# - Philip Konrath
+# - Alexander Dincher
+# - Philipp-Noah Groß
+#
+# License: https://github.com/inexio/NESi/LICENSE.rst
+
+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/zhone/api/schemas/zhone_box_schemas.py b/nesi/zhone/api/schemas/zhone_box_schemas.py
new file mode 100644
index 0000000..74dab06
--- /dev/null
+++ b/nesi/zhone/api/schemas/zhone_box_schemas.py
@@ -0,0 +1,14 @@
+# 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.schemas.box_schemas import *
+
+class ZhoneBoxSchema(BoxSchema):
+ class Meta:
+ model = Box
+ fields = BoxSchema.Meta.fields # + ('', '', '', '')
diff --git a/nesi/zhone/api/schemas/zhone_card_schemas.py b/nesi/zhone/api/schemas/zhone_card_schemas.py
new file mode 100644
index 0000000..32a66ed
--- /dev/null
+++ b/nesi/zhone/api/schemas/zhone_card_schemas.py
@@ -0,0 +1,14 @@
+# 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.schemas.card_schemas import *
+
+class ZhoneCardSchema(CardSchema):
+ class Meta:
+ model = Card
+ fields = CardSchema.Meta.fields # + ('', '', '', '')
diff --git a/nesi/zhone/api/schemas/zhone_port_schemas.py b/nesi/zhone/api/schemas/zhone_port_schemas.py
new file mode 100644
index 0000000..56f088c
--- /dev/null
+++ b/nesi/zhone/api/schemas/zhone_port_schemas.py
@@ -0,0 +1,15 @@
+# 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.schemas.port_schemas import *
+
+class ZhonePortSchema(PortSchema):
+ class Meta:
+ model = Port
+ fields = PortSchema.Meta.fields + ('upLineRate', 'downLineRate', 'maxUpLineRate', 'maxDownLineRate')
+
diff --git a/nesi/zhone/api/schemas/zhone_subrack_schemas.py b/nesi/zhone/api/schemas/zhone_subrack_schemas.py
new file mode 100644
index 0000000..64bd078
--- /dev/null
+++ b/nesi/zhone/api/schemas/zhone_subrack_schemas.py
@@ -0,0 +1,14 @@
+# 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.schemas.subrack_schemas import *
+
+class ZhoneSubrackSchema(SubrackSchema):
+ class Meta:
+ model = Subrack
+ fields = SubrackSchema.Meta.fields # + ('', '', '', '')
\ No newline at end of file
diff --git a/nesi/zhone/zhone_resources/__init__.py b/nesi/zhone/zhone_resources/__init__.py
index a9a2c5b..250684e 100644
--- a/nesi/zhone/zhone_resources/__init__.py
+++ b/nesi/zhone/zhone_resources/__init__.py
@@ -1 +1 @@
-__all__ = []
+__all__ = ["zhone_port", "zhone_card", "zhone_subrack"]
diff --git a/nesi/zhone/zhone_resources/zhone_box.py b/nesi/zhone/zhone_resources/zhone_box.py
index 744d68f..5673a11 100644
--- a/nesi/zhone/zhone_resources/zhone_box.py
+++ b/nesi/zhone/zhone_resources/zhone_box.py
@@ -7,11 +7,12 @@
# - Janis Groß
# - Philip Konrath
# - Alexander Dincher
+# - Philipp-Noah Groß
#
# License: https://github.com/inexio/NESi/LICENSE.rst
from nesi.zhone.zhone_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 *
@@ -25,6 +26,18 @@ class ZhoneBox(Box):
:param identity: The identity of the System resource
"""
# Define Zhone Properties
+ @property
+ def credentials(self):
+ return credentials.CredentialsCollection(
+ self._conn, base.get_sub_resource_path_by(
+ self, 'credentials'))
+
+ def get_port(self, field, value):
+ """Get specific port object."""
+ return zhone_port.ZhonePortCollection(
+ self._conn, base.get_sub_resource_path_by(self, 'ports'),
+ params={field: value}).find_by_field_value(field, value)
+
class ZhoneBoxCollection(BoxCollection):
diff --git a/nesi/zhone/zhone_resources/zhone_card.py b/nesi/zhone/zhone_resources/zhone_card.py
new file mode 100644
index 0000000..e69de29
diff --git a/nesi/zhone/zhone_resources/zhone_port.py b/nesi/zhone/zhone_resources/zhone_port.py
new file mode 100644
index 0000000..51c2656
--- /dev/null
+++ b/nesi/zhone/zhone_resources/zhone_port.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ß
\ No newline at end of file
diff --git a/templates/Zhone/login/base/on_enter.j2 b/templates/Zhone/login/base/on_enter.j2
new file mode 100644
index 0000000..e607b9b
--- /dev/null
+++ b/templates/Zhone/login/base/on_enter.j2
@@ -0,0 +1,2 @@
+You logged in successfully.
+
diff --git a/templates/Zhone/login/on_enter.j2 b/templates/Zhone/login/on_enter.j2
new file mode 100644
index 0000000..8d65370
--- /dev/null
+++ b/templates/Zhone/login/on_enter.j2
@@ -0,0 +1 @@
+Password:
diff --git a/templates/Zhone/login/password.j2 b/templates/Zhone/login/password.j2
new file mode 100644
index 0000000..a16fedb
--- /dev/null
+++ b/templates/Zhone/login/password.j2
@@ -0,0 +1,2 @@
+Login incorrect
+
diff --git a/templates/Zhone/on_cycle.j2 b/templates/Zhone/on_cycle.j2
new file mode 100644
index 0000000..2a6191f
--- /dev/null
+++ b/templates/Zhone/on_cycle.j2
@@ -0,0 +1 @@
+login as:
diff --git a/templates/Zhone/on_enter.j2 b/templates/Zhone/on_enter.j2
new file mode 100644
index 0000000..e69de29
diff --git a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py
index 091b9aa..b9c5fb9 100644
--- a/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py
+++ b/vendors/KeyMile/accessPoints/root/rootCommandProcessor.py
@@ -14,7 +14,6 @@
from nesi import exceptions
from vendors.KeyMile.baseCommandProcessor import BaseCommandProcessor
-
class RootCommandProcessor(BaseCommandProcessor):
__name__ = 'root'
management_functions = {'main', 'cfgm', 'fm', 'status'}
@@ -25,6 +24,12 @@ 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):
self.access_points = ('eoam', 'fan', 'multicast', 'services', 'tdmConnections')
for card in self._model.cards:
diff --git a/vendors/Zhone/__init__.py b/vendors/Zhone/__init__.py
new file mode 100644
index 0000000..0342a16
--- /dev/null
+++ b/vendors/Zhone/__init__.py
@@ -0,0 +1,7 @@
+# Software adapted by inexio .
+# - Janis Groß
+# - Philip Konrath
+# - Alexander Dincher
+# - Philipp-Noah Groß
+#
+# License: https://github.com/inexio/NESi/LICENSE.rst
\ No newline at end of file
diff --git a/vendors/Zhone/baseCommandProcessor.py b/vendors/Zhone/baseCommandProcessor.py
new file mode 100644
index 0000000..d80fd90
--- /dev/null
+++ b/vendors/Zhone/baseCommandProcessor.py
@@ -0,0 +1,29 @@
+# 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 nesi.softbox.cli import base
+import re
+
+class BaseCommandProcessor(base.CommandProcessor):
+ def do_exit(self, command, *args, context=None):
+ exc = exceptions.TerminalExitError()
+ exc.return_to = 'sysexit'
+ raise exc
+
+ 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
\ No newline at end of file
diff --git a/vendors/Zhone/main.py b/vendors/Zhone/main.py
new file mode 100644
index 0000000..67dd517
--- /dev/null
+++ b/vendors/Zhone/main.py
@@ -0,0 +1,60 @@
+# Software adapted by inexio .
+# - Janis Groß
+# - Philip Konrath
+# - Alexander Dincher
+# - Philipp-Noah Groß
+#
+# License: https://github.com/inexio/NESi/LICENSE.rst
+
+from nesi.softbox.cli import base
+from vendors.Zhone.rootCommandProcessor import RootCommandProcessor
+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.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(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:
+ break
+
+ else:
+ text = self._render('password', context=context)
+ self._write(text)
+ raise exceptions.TerminalExitError()
+
+ self.case_sensitive = False
+
+ subprocessor = self._create_subprocessor(
+ RootCommandProcessor, 'login', 'base')
+
+ context['path'] = '/'
+ context['component_path'] = '/'
+
+ subprocessor.loop(context=context, return_to=RootCommandProcessor)
+
+ self.on_exit(context)
\ No newline at end of file
diff --git a/vendors/Zhone/rootCommandProcessor.py b/vendors/Zhone/rootCommandProcessor.py
new file mode 100644
index 0000000..5e1143d
--- /dev/null
+++ b/vendors/Zhone/rootCommandProcessor.py
@@ -0,0 +1,33 @@
+# 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.Zhone.baseCommandProcessor import BaseCommandProcessor
+
+class RootCommandProcessor(BaseCommandProcessor):
+
+ 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',
+ template_scopes=('login', 'base', 'execution_errors'))
+
+ def do_dslstat(self, command, *args, context=None):
+
+ if self._validate(args, *()):
+ self._write(self._render('dslstatEmptyArg', 'login', 'base', context=context))
+ elif self._validate(args, "1/1/1/0/vdsl"):
+
+ port = self._model.get_port('name', '1/1/1/0')
+
+ context['port'] = port
+
+ self._write(self._render('dslstatTemplate', 'login', 'base', context=context))
+ else:
+ self._write(self._render('dslstatInvalidArg', 'login', 'base', context=context))
\ No newline at end of file
From 28c02ac43600eea7bf70ae00c6d53d9f9b47de25 Mon Sep 17 00:00:00 2001
From: unkn0wn-user
Date: Fri, 15 Jan 2021 10:19:38 +0100
Subject: [PATCH 2/3] Further implementation of dslstat command
---
bootup/conf/bootstraps/create-zhone.sh | 33 +++++++++--
nesi/softbox/cli/base.py | 9 ++-
.../Zhone/login/base/dslstatCyclePrompt.j2 | 2 +
templates/Zhone/login/base/dslstatEmptyArg.j2 | 2 +-
.../Zhone/login/base/dslstatInvalidArg.j2 | 3 +-
templates/Zhone/login/base/dslstatTemplate.j2 | 16 +-----
templates/Zhone/login/base/on_enter.j2 | 2 -
vendors/Zhone/baseCommandProcessor.py | 21 +++++++
vendors/Zhone/main.py | 2 +-
vendors/Zhone/rootCommandProcessor.py | 56 +++++++++++++++++--
10 files changed, 113 insertions(+), 33 deletions(-)
create mode 100644 templates/Zhone/login/base/dslstatCyclePrompt.j2
diff --git a/bootup/conf/bootstraps/create-zhone.sh b/bootup/conf/bootstraps/create-zhone.sh
index 5532916..d2f06c3 100644
--- a/bootup/conf/bootstraps/create-zhone.sh
+++ b/bootup/conf/bootstraps/create-zhone.sh
@@ -36,10 +36,18 @@ req='{
box_id=$(create_resource "$req" $ENDPOINT/boxen) || exit 1
-# Sessionmanager credentials
+# Admin user
+req='{
+ "name": "Admin"
+}'
+
+admin_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/users)
+
+# Admin credentials
req='{
"username": "admin",
- "password": "secret"
+ "password": "secret",
+ "user_id": '$admin_id'
}'
admin_credential_id=$(create_resource "$req" $ENDPOINT/boxen/$box_id/credentials)
@@ -57,7 +65,6 @@ subrack_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/subracks)
req='{
"subrack_id": '$subrack_1',
- "name": "1/1",
"product": "vdsl",
"description": "Karte von Juan"
}'
@@ -68,8 +75,7 @@ card_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/cards)
req='{
"card_id": '$card_1',
- "name": "1/1/1/0",
- "description": "Port von Juan",
+ "description": "Network Port 1",
"admin_state": "1",
"operational_state": "1",
"upLineRate": 5555,
@@ -78,4 +84,19 @@ req='{
"maxDownLineRate": 2222
}'
-port_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports)
\ No newline at end of file
+port_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports)
+
+# create a Port
+
+req='{
+ "card_id": '$card_1',
+ "description": "Network Port 2",
+ "admin_state": "0",
+ "operational_state": "0",
+ "upLineRate": 5555,
+ "downLineRate": 4444,
+ "maxUpLineRate": 3333,
+ "maxDownLineRate": 2222
+}'
+
+port_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports)
\ No newline at end of file
diff --git a/nesi/softbox/cli/base.py b/nesi/softbox/cli/base.py
index 1632d66..637e27b 100644
--- a/nesi/softbox/cli/base.py
+++ b/nesi/softbox/cli/base.py
@@ -160,11 +160,13 @@ def get(self):
def updateline(self, line):
self._write('\r') # reset cursor to start of line
- self._write('\033[' + str(self.prompt_end_pos + 1) + 'C') # move cursor to end of prompt
+ if self.prompt_end_pos != 0:
+ self._write('\033[' + str(self.prompt_end_pos + 1) + 'C') # move cursor to end of prompt
self._write('\033[K') # clear rest of line
self._write(line) # insert new line contents
self._write('\r') # reset cursor to start of line
- self._write('\033[' + str(self.cursor_pos) + 'C') # move cursor to correct position
+ if self.cursor_pos != 0:
+ self._write('\033[' + str(self.cursor_pos) + 'C') # move cursor to correct position
def getline(self, tmp_boundary=None):
char = None
@@ -348,9 +350,6 @@ 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
diff --git a/templates/Zhone/login/base/dslstatCyclePrompt.j2 b/templates/Zhone/login/base/dslstatCyclePrompt.j2
new file mode 100644
index 0000000..d353857
--- /dev/null
+++ b/templates/Zhone/login/base/dslstatCyclePrompt.j2
@@ -0,0 +1,2 @@
+ for next page, for next line, A for all, Q to quit
+
diff --git a/templates/Zhone/login/base/dslstatEmptyArg.j2 b/templates/Zhone/login/base/dslstatEmptyArg.j2
index 46fb563..63a504a 100644
--- a/templates/Zhone/login/base/dslstatEmptyArg.j2
+++ b/templates/Zhone/login/base/dslstatEmptyArg.j2
@@ -1,2 +1,2 @@
-Not enough arguments. Please specify the name of the port.
+Usage: dslstat <[ifIndex] | [name/type] | [shelf/slot/port/subport/type]> <-v>
diff --git a/templates/Zhone/login/base/dslstatInvalidArg.j2 b/templates/Zhone/login/base/dslstatInvalidArg.j2
index eb5db2f..06d92e6 100644
--- a/templates/Zhone/login/base/dslstatInvalidArg.j2
+++ b/templates/Zhone/login/base/dslstatInvalidArg.j2
@@ -1,2 +1,3 @@
-The argument is invalid.
+Unknown interface: {{ context.identifier }}
+InfoIfTranslateGetFromString failed
diff --git a/templates/Zhone/login/base/dslstatTemplate.j2 b/templates/Zhone/login/base/dslstatTemplate.j2
index fda93dc..14560a7 100644
--- a/templates/Zhone/login/base/dslstatTemplate.j2
+++ b/templates/Zhone/login/base/dslstatTemplate.j2
@@ -1,7 +1,7 @@
General Stats:
-------------
-AdminStatus..................................UP
-LineStatus...................................HANDSHAKE
+AdminStatus..................................{{ context.port.admin_state }}
+LineStatus...................................{{ context.port.operational_state }}
DslUpLineRate (bitsPerSec)...................{{ context.port.upLineRate }}
DslDownLineRate (bitsPerSec).................{{ context.port.downLineRate }}
DslMaxAttainableUpLineRate (bitsPerSec)......{{ context.port.maxUpLineRate }}
@@ -15,10 +15,6 @@ Out Pkts/Cells/Frags.........................0
Out Discards.................................0
Out Errors...................................0
-DSL Physical Stats:
-------------------
-Out Errors...................................0
-
DSL Physical Stats:
------------------
DslLineSnrMgn (tenths dB)....................0
@@ -39,11 +35,6 @@ Loss of Link Seconds.........................32170614
Severely Errored Seconds.....................32170614
Unavailable Seconds..........................32170614
-far-end statstics:
-Loss of Link Seconds.........................32170614
-Severely Errored Seconds.....................32170614
-Unavailable Seconds..........................32170614
-
far-end statstics:
-----------------
Loss of Frame Seconds........................0
@@ -62,5 +53,4 @@ Vtuc UnCorrectable Retransmitted codewords...0
Vtur PhyRActive..............................FALSE
Vtur Retransmitted codewords.................0
Vtur Corrected Retransmitted codewords.......0
-Vtur UnCorrectable Retransmitted codewords...0
-
+Vtur UnCorrectable Retransmitted codewords...0
\ No newline at end of file
diff --git a/templates/Zhone/login/base/on_enter.j2 b/templates/Zhone/login/base/on_enter.j2
index e607b9b..e69de29 100644
--- a/templates/Zhone/login/base/on_enter.j2
+++ b/templates/Zhone/login/base/on_enter.j2
@@ -1,2 +0,0 @@
-You logged in successfully.
-
diff --git a/vendors/Zhone/baseCommandProcessor.py b/vendors/Zhone/baseCommandProcessor.py
index d80fd90..2b47956 100644
--- a/vendors/Zhone/baseCommandProcessor.py
+++ b/vendors/Zhone/baseCommandProcessor.py
@@ -16,6 +16,27 @@ def do_exit(self, command, *args, context=None):
exc.return_to = 'sysexit'
raise exc
+ 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 = 'UP'
+ elif object.admin_state == '2':
+ if type == 'port':
+ object.admin_state = 'ERR'
+
+ if object.operational_state == '0':
+ if type == 'port':
+ object.operational_state = 'DOWN'
+ elif object.operational_state == '1':
+ if type == 'port':
+ object.operational_state = 'DATA'
+ elif object.operational_state == '2':
+ if type == 'port':
+ object.operational_state = 'HANDSHAKE'
+
def create_spacers(self, positions, args):
spacers = []
previous_pos = 0
diff --git a/vendors/Zhone/main.py b/vendors/Zhone/main.py
index 67dd517..5be48e3 100644
--- a/vendors/Zhone/main.py
+++ b/vendors/Zhone/main.py
@@ -21,7 +21,7 @@ def on_unknown_command(self, command, *args, context=None):
try:
subprocessor.history_enabled = False
- subprocessor.star_input = True
+ 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/Zhone/rootCommandProcessor.py b/vendors/Zhone/rootCommandProcessor.py
index 5e1143d..c1fcfbc 100644
--- a/vendors/Zhone/rootCommandProcessor.py
+++ b/vendors/Zhone/rootCommandProcessor.py
@@ -19,15 +19,63 @@ def get_property(self, command, *args, context=None):
template_scopes=('login', 'base', 'execution_errors'))
def do_dslstat(self, command, *args, context=None):
-
if self._validate(args, *()):
self._write(self._render('dslstatEmptyArg', 'login', 'base', context=context))
- elif self._validate(args, "1/1/1/0/vdsl"):
+ elif self._validate(args, str):
+ identifier, = self._dissect(args, str)
+ identifier_components = identifier.split('/')
+ if len(identifier_components) != 5 or identifier_components[3] != '0' or identifier_components[4] != 'vdsl':
+ context['identifier'] = identifier
+ self._write(self._render('dslstatInvalidArg', 'login', 'base', context=context))
+ return
+ port = self._model.get_port('name', "/".join(identifier_components[:3]))
- port = self._model.get_port('name', '1/1/1/0')
+ self.map_states(port, 'port')
context['port'] = port
- self._write(self._render('dslstatTemplate', 'login', 'base', context=context))
+ if self.daemon and self._model.network_protocol == 'ssh':
+ output = self._render('dslstatTemplate', 'login', 'base', context=context).split("\n")
+ pointer = 0
+ buff_size = 19
+ prompt_end = self.prompt_end_pos
+ while True:
+ self.cursor_pos = 0
+ self._write("\n".join(output[pointer:pointer + buff_size]))
+ self._write("\n")
+ pointer += buff_size
+
+ if pointer >= len(output):
+ break
+
+ option_string = ' for next page, for next line, A for all, Q to quit'
+ self.cursor_pos = len(option_string) + 1
+ self.prompt_end_pos = 0
+ self.updateline(option_string)
+
+ character = None
+
+ while character not in ('\r', 'a', 'q', ' '):
+ _, character = self.get()
+
+ self.cursor_pos = 0
+ self.updateline('')
+
+ if character == '\r':
+ buff_size = 1
+ continue
+ elif character == 'a':
+ buff_size = len(output) - pointer
+ continue
+ elif character == 'q':
+ break
+ elif character == ' ':
+ buff_size = 19
+ continue
+ self.cursor_pos = 0
+ self.prompt_end_pos = prompt_end
+ else:
+ output = self._render('dslstatTemplate', 'login', 'base', context=context) + "\n"
+ self._write(output)
else:
self._write(self._render('dslstatInvalidArg', 'login', 'base', context=context))
\ No newline at end of file
From b70eafb765c5eecc5cba12d51ad3bdb24df9d60d Mon Sep 17 00:00:00 2001
From: unkn0wn-user
Date: Fri, 15 Jan 2021 11:17:11 +0100
Subject: [PATCH 3/3] Fixed wrong fields in zhone / relocated up/downstream
fields into base port
---
bootup/conf/bootstraps/create-zhone.sh | 16 +++++++-------
.../alcatel/alcatel_resources/alcatel_port.py | 4 ----
.../api/schemas/alcatel_port_schemas.py | 3 +--
.../huawei/api/schemas/huawei_port_schemas.py | 3 +--
nesi/huawei/huawei_resources/huawei_port.py | 4 ----
.../keymile/keymile_resources/keymile_port.py | 2 --
nesi/softbox/api/models/port_models.py | 6 ------
nesi/softbox/api/schemas/port_schemas.py | 2 +-
nesi/softbox/base_resources/port.py | 4 ++++
nesi/zhone/api/schemas/zhone_port_schemas.py | 2 +-
nesi/zhone/zhone_resources/zhone_port.py | 6 ------
templates/Zhone/login/base/dslstatTemplate.j2 | 8 +++----
.../integration_tests/zhone/dslstat.txt | 4 ++++
test_cases/unit_tests/zhone/test_zhone.py | 21 ++++++++-----------
14 files changed, 33 insertions(+), 52 deletions(-)
create mode 100644 test_cases/integration_tests/zhone/dslstat.txt
diff --git a/bootup/conf/bootstraps/create-zhone.sh b/bootup/conf/bootstraps/create-zhone.sh
index d2f06c3..a17859b 100644
--- a/bootup/conf/bootstraps/create-zhone.sh
+++ b/bootup/conf/bootstraps/create-zhone.sh
@@ -78,10 +78,10 @@ req='{
"description": "Network Port 1",
"admin_state": "1",
"operational_state": "1",
- "upLineRate": 5555,
- "downLineRate": 4444,
- "maxUpLineRate": 3333,
- "maxDownLineRate": 2222
+ "upstream": 4023,
+ "downstream": 13232,
+ "upstream_max": 8000,
+ "downstream_max": 16000
}'
port_1=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports)
@@ -93,10 +93,10 @@ req='{
"description": "Network Port 2",
"admin_state": "0",
"operational_state": "0",
- "upLineRate": 5555,
- "downLineRate": 4444,
- "maxUpLineRate": 3333,
- "maxDownLineRate": 2222
+ "upstream": 4023,
+ "downstream": 13232,
+ "upstream_max": 8000,
+ "downstream_max": 16000
}'
port_2=$(create_resource "$req" $ENDPOINT/boxen/$box_id/ports)
\ No newline at end of file
diff --git a/nesi/alcatel/alcatel_resources/alcatel_port.py b/nesi/alcatel/alcatel_resources/alcatel_port.py
index 8864d12..c322830 100644
--- a/nesi/alcatel/alcatel_resources/alcatel_port.py
+++ b/nesi/alcatel/alcatel_resources/alcatel_port.py
@@ -22,10 +22,6 @@ class AlcatelPort(Port):
mode = base.Field('mode')
shutdown = base.Field('shutdown')
speed = base.Field('speed')
- upstream = base.Field('upstream')
- downstream = base.Field('downstream')
- upstream_max = base.Field('upstream_max')
- downstream_max = base.Field('downstream_max')
noise_margin_up = base.Field('noise_margin_up')
noise_margin_down = base.Field('noise_margin_down')
tgt_noise_margin_up = base.Field('tgt_noise_margin_up')
diff --git a/nesi/alcatel/api/schemas/alcatel_port_schemas.py b/nesi/alcatel/api/schemas/alcatel_port_schemas.py
index 36571a3..f3680e8 100644
--- a/nesi/alcatel/api/schemas/alcatel_port_schemas.py
+++ b/nesi/alcatel/api/schemas/alcatel_port_schemas.py
@@ -16,8 +16,7 @@
class AlcatelPortSchema(PortSchema):
class Meta:
model = Port
- fields = PortSchema.Meta.fields + ('shutdown', 'speed', 'upstream', 'downstream', 'upstream_max',
- 'downstream_max', 'noise_margin_up', 'noise_margin_down',
+ fields = PortSchema.Meta.fields + ('shutdown', 'speed', 'noise_margin_up', 'noise_margin_down',
'tgt_noise_margin_up', 'tgt_noise_margin_down', 'attenuation_up',
'attenuation_down', 'attained_upstream', 'attained_downstream',
'threshold_upstream', 'threshold_downstream', 'max_delay_upstream',
diff --git a/nesi/huawei/api/schemas/huawei_port_schemas.py b/nesi/huawei/api/schemas/huawei_port_schemas.py
index c56dbb4..f2ee5f8 100644
--- a/nesi/huawei/api/schemas/huawei_port_schemas.py
+++ b/nesi/huawei/api/schemas/huawei_port_schemas.py
@@ -16,8 +16,7 @@
class HuaweiPortSchema(PortSchema):
class Meta:
model = Port
- fields = PortSchema.Meta.fields + ('upstream', 'downstream', 'upstream_max', 'downstream_max',
- 'line_template', 'loopback', 'sos_profile', 'sos_profile_num',
+ fields = PortSchema.Meta.fields + ('line_template', 'loopback', 'sos_profile', 'sos_profile_num',
'alarm_template', 'dynamic_profile_index', 'dynamic_profile_name',
'hardware', 'last_up_time', 'last_down_time', 'show_time',
'nte_power_status', 'current_operational_mode', 'cpes', 'description',
diff --git a/nesi/huawei/huawei_resources/huawei_port.py b/nesi/huawei/huawei_resources/huawei_port.py
index 8f0400d..61bee77 100644
--- a/nesi/huawei/huawei_resources/huawei_port.py
+++ b/nesi/huawei/huawei_resources/huawei_port.py
@@ -21,10 +21,6 @@ class HuaweiPort(Port):
cpes = base.Field('cpes')
description = base.Field('description')
- upstream = base.Field('upstream')
- downstream = base.Field('downstream')
- upstream_max = base.Field('upstream_max')
- downstream_max = base.Field('downstream_max')
loopback = base.Field('loopback')
line_template = base.Field('line_template')
alarm_template = base.Field('alarm_template')
diff --git a/nesi/keymile/keymile_resources/keymile_port.py b/nesi/keymile/keymile_resources/keymile_port.py
index c976869..81a248d 100644
--- a/nesi/keymile/keymile_resources/keymile_port.py
+++ b/nesi/keymile/keymile_resources/keymile_port.py
@@ -36,8 +36,6 @@ 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/port_models.py b/nesi/softbox/api/models/port_models.py
index da78916..6ed09a0 100644
--- a/nesi/softbox/api/models/port_models.py
+++ b/nesi/softbox/api/models/port_models.py
@@ -331,9 +331,3 @@ 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)
-
- #Zhone
- upLineRate = db.Column(db.Integer(), default=0)
- downLineRate = db.Column(db.Integer(), default=0)
- maxUpLineRate = db.Column(db.Integer(), default=0)
- maxDownLineRate = db.Column(db.Integer(), default=0)
diff --git a/nesi/softbox/api/schemas/port_schemas.py b/nesi/softbox/api/schemas/port_schemas.py
index 83679f3..bf580fc 100644
--- a/nesi/softbox/api/schemas/port_schemas.py
+++ b/nesi/softbox/api/schemas/port_schemas.py
@@ -22,7 +22,7 @@ class PortSchema(ma.ModelSchema):
class Meta:
model = Port
fields = ('id', 'box_id', 'box', 'card_id', 'cpes', 'onts', 'channels', 'loopback', 'name', 'interfaces',
- 'description', 'admin_state', 'operational_state', '_links')
+ 'description', 'admin_state', 'operational_state', 'upstream', 'upstream_max', 'downstream', 'downstream_max', '_links')
cpes = ma.Nested(CpesSchema.CpeSchema, many=True)
diff --git a/nesi/softbox/base_resources/port.py b/nesi/softbox/base_resources/port.py
index 5b51433..c02a0df 100644
--- a/nesi/softbox/base_resources/port.py
+++ b/nesi/softbox/base_resources/port.py
@@ -27,6 +27,10 @@ class Port(base.Resource):
description = base.Field('description')
admin_state = base.Field('admin_state')
operational_state = base.Field('operational_state')
+ upstream = base.Field('upstream')
+ downstream = base.Field('downstream')
+ upstream_max = base.Field('upstream_max')
+ downstream_max = base.Field('downstream_max')
def admin_up(self):
"""Set the admin port state to up"""
diff --git a/nesi/zhone/api/schemas/zhone_port_schemas.py b/nesi/zhone/api/schemas/zhone_port_schemas.py
index 56f088c..05838e8 100644
--- a/nesi/zhone/api/schemas/zhone_port_schemas.py
+++ b/nesi/zhone/api/schemas/zhone_port_schemas.py
@@ -11,5 +11,5 @@
class ZhonePortSchema(PortSchema):
class Meta:
model = Port
- fields = PortSchema.Meta.fields + ('upLineRate', 'downLineRate', 'maxUpLineRate', 'maxDownLineRate')
+ fields = PortSchema.Meta.fields
diff --git a/nesi/zhone/zhone_resources/zhone_port.py b/nesi/zhone/zhone_resources/zhone_port.py
index 51c2656..41fc631 100644
--- a/nesi/zhone/zhone_resources/zhone_port.py
+++ b/nesi/zhone/zhone_resources/zhone_port.py
@@ -18,15 +18,9 @@
class ZhonePort(Port):
- upLineRate = base.Field("upLineRate")
- downLineRate = base.Field("downLineRate")
- maxUpLineRate = base.Field("maxUpLineRate")
- maxDownLineRate = base.Field("maxDownLineRate")
-
"""Represent physical port resource."""
-
class ZhonePortCollection(PortCollection):
"""Represent a collection of ports."""
diff --git a/templates/Zhone/login/base/dslstatTemplate.j2 b/templates/Zhone/login/base/dslstatTemplate.j2
index 14560a7..9df55fd 100644
--- a/templates/Zhone/login/base/dslstatTemplate.j2
+++ b/templates/Zhone/login/base/dslstatTemplate.j2
@@ -2,10 +2,10 @@ General Stats:
-------------
AdminStatus..................................{{ context.port.admin_state }}
LineStatus...................................{{ context.port.operational_state }}
-DslUpLineRate (bitsPerSec)...................{{ context.port.upLineRate }}
-DslDownLineRate (bitsPerSec).................{{ context.port.downLineRate }}
-DslMaxAttainableUpLineRate (bitsPerSec)......{{ context.port.maxUpLineRate }}
-DslMaxAttainableDownLineRate (bitsPerSec)....{{ context.port.maxDownLineRate }}
+DslUpLineRate (bitsPerSec)...................{{ context.port.upstream }}
+DslDownLineRate (bitsPerSec).................{{ context.port.downstream }}
+DslMaxAttainableUpLineRate (bitsPerSec)......{{ context.port.upstream_max }}
+DslMaxAttainableDownLineRate (bitsPerSec)....{{ context.port.downstream_max }}
In Octets....................................0
In Pkts/Cells/Frags..........................0
In Discards..................................0
diff --git a/test_cases/integration_tests/zhone/dslstat.txt b/test_cases/integration_tests/zhone/dslstat.txt
new file mode 100644
index 0000000..393132c
--- /dev/null
+++ b/test_cases/integration_tests/zhone/dslstat.txt
@@ -0,0 +1,4 @@
+admin
+secret
+dslstat 1/1/1/0/vdsl
+exit
\ No newline at end of file
diff --git a/test_cases/unit_tests/zhone/test_zhone.py b/test_cases/unit_tests/zhone/test_zhone.py
index ea9b941..9b11fa3 100644
--- a/test_cases/unit_tests/zhone/test_zhone.py
+++ b/test_cases/unit_tests/zhone/test_zhone.py
@@ -16,18 +16,15 @@
class TestZhone(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')
- port.admin_up()
- assert(self.model.get_port("name", '1/1/1/1').admin_state == 'up')
+ port = self.model.get_port("name", '1/1/1')
+ assert(self.model.get_port("name", '1/1/1').admin_state == '1')
port.admin_down()
- assert(self.model.get_port("name", '1/1/1/1').admin_state == 'down')
-
- 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_port("name", '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')
- port.admin_down()
- assert(self.model.get_ont_port("name", '1/1/4/1/1/1/1').admin_state == 'down')
+ assert(self.model.get_port("name", '1/1/1').admin_state == '1')
+ assert (self.model.get_port("name", '1/1/1').operational_state == '1')
+ port.down()
+ assert (self.model.get_port("name", '1/1/1').operational_state == '0')
+ port.up()
+ assert (self.model.get_port("name", '1/1/1').operational_state == '1')