Browse Source

Make telnet script for ZTE-C320. And maked snmp field validate in dynamic device types

devel
bashmak 8 years ago
parent
commit
d5eeeec38f
  1. 11
      agent/mod_mikrotik.py
  2. 15
      devapp/base_intr.py
  3. 24
      devapp/dev_types.py
  4. 18
      devapp/forms.py
  5. 433
      devapp/locale/ru/LC_MESSAGES/django.po
  6. 9
      devapp/models.py
  7. 2
      devapp/templates/devapp/devices.html
  8. 15
      djing/lib/__init__.py
  9. 4
      djing/lib/tln/__init__.py
  10. 266
      djing/lib/tln/tln.py

11
agent/mod_mikrotik.py

@ -6,7 +6,7 @@ from abc import ABCMeta
from hashlib import md5
from typing import Iterable, Optional, Tuple
from .core import BaseTransmitter, NasFailedResult, NasNetworkError
from djing.lib import singleton
from djing.lib import Singleton
from .structs import TariffStruct, AbonStruct, IpStruct, VectorAbon, VectorTariff
from . import settings as local_settings
from django.conf import settings
@ -18,8 +18,7 @@ LIST_USERS_ALLOWED = 'DjingUsersAllowed'
LIST_USERS_BLOCKED = 'DjingUsersBlocked'
@singleton
class ApiRos:
class ApiRos(metaclass=Singleton):
"""Routeros api"""
sk = None
is_login = False
@ -223,8 +222,8 @@ class TransmitterManager(BaseTransmitter, metaclass=ABCMeta):
speeds = info['=max-limit'].split('/')
t = TariffStruct(
speedIn=parse_speed(speeds[1]),
speedOut=parse_speed(speeds[0])
speed_in=parse_speed(speeds[1]),
speed_out=parse_speed(speeds[0])
)
try:
a = AbonStruct(
@ -480,7 +479,7 @@ class MikrotikTransmitter(QueueManager, IpAddressListManager):
interface = r[0]['=interface']
r = self._exec_cmd((
'/ping', '=address=%s' % host, '=arp-ping=yes', '=interval=100ms', '=count=%d' % count,
'=interface=%s' % interface
'=interface=%s' % interface
))
received, sent = int(r[-2:][0]['=received']), int(r[-2:][0]['=sent'])
return received, sent

15
devapp/base_intr.py

@ -1,10 +1,10 @@
from abc import ABCMeta, abstractmethod
from datetime import timedelta
from django.utils.translation import gettext
from typing import Union, Iterable, AnyStr, Generator, Optional
from easysnmp import Session
from django.utils.translation import gettext
ListOrError = Union[
Iterable,
Union[Exception, Iterable]
@ -15,7 +15,7 @@ class DeviceImplementationError(Exception):
pass
class DevBase(object, metaclass=ABCMeta):
class DevBase(object):
def __init__(self, dev_instance=None):
self.db_instance = dev_instance
@ -53,6 +53,15 @@ class DevBase(object, metaclass=ABCMeta):
def is_use_device_port() -> bool:
"""True if used device port while opt82 authorization"""
@abstractmethod
def validate_extra_snmp_info(self, v: str) -> None:
"""
Validate extra snmp field for each device.
If validation failed then raise en exception from djing.lib.tln.ValidationError
with description of error.
:param v: String value for validate
"""
class BasePort(object, metaclass=ABCMeta):
def __init__(self, num, name, status, mac, speed):

24
devapp/dev_types.py

@ -4,6 +4,7 @@ from easysnmp import EasySNMPTimeoutError
from django.utils.translation import gettext_lazy as _, gettext
from djing.lib import RuTimedelta, safe_int
from djing.lib.tln.tln import ValidationError as TlnValidationError
from .base_intr import DevBase, SNMPBaseWorker, BasePort, DeviceImplementationError, ListOrError
@ -77,6 +78,10 @@ class DLinkDevice(DevBase, SNMPBaseWorker):
def is_use_device_port():
return True
def validate_extra_snmp_info(self, v: str) -> None:
# Dlink has no require snmp info
pass
class ONUdev(BasePort):
def __init__(self, num, name, status, mac, speed, signal, snmp_worker):
@ -150,6 +155,10 @@ class OLTDevice(DevBase, SNMPBaseWorker):
def is_use_device_port():
return False
def validate_extra_snmp_info(self, v: str) -> None:
# Olt has no require snmp info
pass
class OnuDevice(DevBase, SNMPBaseWorker):
def __init__(self, dev_instance):
@ -216,6 +225,13 @@ class OnuDevice(DevBase, SNMPBaseWorker):
except EasySNMPTimeoutError as e:
return {'err': "%s: %s" % (_('ONU not connected'), e)}
def validate_extra_snmp_info(self, v: str) -> None:
# DBCOM Onu have en integer snmp port
try:
int(v)
except ValueError:
raise TlnValidationError(_('Onu snmp field must be en integer'))
class EltexPort(BasePort):
def __init__(self, snmp_worker, *args, **kwargs):
@ -360,3 +376,11 @@ class ZteOnuDevice(OnuDevice):
def get_template_name(self):
return 'onu_for_zte.html'
def validate_extra_snmp_info(self, v: str) -> None:
# for example 268501760.5
try:
fiber_num, onu_port = v.split('.')
int(fiber_num), int(onu_port)
except ValueError:
raise TlnValidationError(_('Zte onu snmp field must be two dot separated integers'))

18
devapp/forms.py

@ -1,7 +1,9 @@
from django import forms
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from django.db import IntegrityError
from djing.lib.tln.tln import ValidationError as TlnValidationError
from . import models
from djing import MAC_ADDR_REGEX, IP_ADDR_REGEX
@ -15,9 +17,23 @@ class DeviceForm(forms.ModelForm):
'unique': _('Device with that mac is already exist')
})
def clean_snmp_extra(self):
snmp_extra = self.cleaned_data.get('snmp_extra')
if snmp_extra is None:
return
device = self.instance
manager = device.get_manager_object()
try:
manager.validate_extra_snmp_info(snmp_extra)
except TlnValidationError as e:
raise ValidationError(
e, code='invalid'
)
return snmp_extra
class Meta:
model = models.Device
exclude = ['map_dot', 'status']
exclude = ('map_dot', 'status')
widgets = {
'ip_address': forms.TextInput(attrs={
'pattern': IP_ADDR_REGEX,

433
devapp/locale/ru/LC_MESSAGES/django.po

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-24 23:27+0300\n"
"POT-Creation-Date: 2018-06-02 16:39+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Dmitry Novikov nerosketch@gmail.com\n"
"Language: ru\n"
@ -18,377 +18,456 @@ msgstr ""
"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
"%100>=11 && n%100<=14)? 2 : 3);\n"
#: devapp/base_intr.py:82
#: base_intr.py:92
msgid "Ip address is required"
msgstr "Ip адрес необходим"
#: devapp/dev_types.py:35
#: dev_types.py:37
msgid "DLink switch"
msgstr "Свич D'Link"
#: devapp/dev_types.py:54
#: dev_types.py:56
msgid "does not fetch the mac"
msgstr "не нашёл мак"
#: devapp/dev_types.py:106
#: dev_types.py:112
msgid "PON OLT"
msgstr ""
#: devapp/dev_types.py:131 devapp/views.py:268 devapp/views.py:413
#: dev_types.py:136 views.py:275 views.py:433
msgid "wait for a reply from the SNMP Timeout"
msgstr "Время ожидания ответа от SNMP истекло"
#: devapp/dev_types.py:171
#: dev_types.py:176
msgid "Ip address or parent device with ip address required for ONU device"
msgstr ""
"Необходим ip адрес. Или родительское устройство с назначенным ip адресом "
"необходимо."
#: dev_types.py:182
msgid "PON ONU"
msgstr ""
#: devapp/dev_types.py:216
#: dev_types.py:227
msgid "ONU not connected"
msgstr "ONU не в сети"
#: devapp/dev_types.py:242
#: dev_types.py:234
msgid "Onu snmp field must be en integer"
msgstr "Поле для snmp информации об ONU должно быть числом"
#: dev_types.py:260
msgid "Eltex switch"
msgstr "Элтекс свич"
#: devapp/forms.py:14
#: dev_types.py:305
msgid "OLT ZTE C320"
msgstr ""
#: dev_types.py:354
msgid "ZTE PON ONU"
msgstr ""
#: dev_types.py:387
msgid "Zte onu snmp field must be two dot separated integers"
msgstr ""
"Поле snmp информации для ZTE ONU должно быть двумя целыми числами, "
"разделенными точкой"
#: forms.py:16
msgid "Mac address is required for fill"
msgstr "MAC-адрес необходим для заполнения"
#: devapp/forms.py:15
#: forms.py:17
msgid "Device with that mac is already exist"
msgstr "Устройство с этим мак-адресом уже есть"
#: devapp/forms.py:48
#: forms.py:63
msgid "Port number on device must be unique"
msgstr "Номер порта на устройстве должен быть уникальным"
#: devapp/models.py:21 devapp/templates/devapp/custom_dev_page/onu.html:18
#: devapp/templates/devapp/devices.html:22
#: devapp/templates/devapp/devices_null_group.html:20
#: models.py:25 templates/devapp/custom_dev_page/onu.html:18
#: templates/devapp/custom_dev_page/onu_for_zte.html:18
#: templates/devapp/devices.html:22 templates/devapp/devices_null_group.html:20
msgid "Ip address"
msgstr "Ip адрес"
#: devapp/models.py:22 devapp/templates/devapp/devices.html:32
#: models.py:26 templates/devapp/devices.html:32
msgid "Mac address"
msgstr "Мак адрес"
#: devapp/models.py:23 devapp/templates/devapp/devices.html:28
#: devapp/templates/devapp/devices_null_group.html:26
#: models.py:27 templates/devapp/devices.html:28
#: templates/devapp/devices_null_group.html:26
msgid "Comment"
msgstr "Комментарий"
#: devapp/models.py:30 devapp/templates/devapp/devices.html:36
#: devapp/templates/devapp/devices_null_group.html:32
#: models.py:36 templates/devapp/devices.html:36
#: templates/devapp/devices_null_group.html:32
msgid "Device type"
msgstr "Тип устройства"
#: devapp/models.py:32
#: models.py:38
msgid "SNMP password"
msgstr "Пароль SNMP"
#: devapp/models.py:33
#: models.py:39
msgid "Device group"
msgstr "Группа устройства"
#: devapp/models.py:34 devapp/templates/devapp/add_dev.html:46
#: devapp/templates/devapp/custom_dev_page/onu.html:34
#: devapp/templates/devapp/custom_dev_page/ports.html:59
#: devapp/templates/devapp/dev.html:33
#: devapp/templates/devapp/fix_dev_group.html:42
#: models.py:40 templates/devapp/add_dev.html:46
#: templates/devapp/custom_dev_page/onu.html:34
#: templates/devapp/custom_dev_page/onu_for_zte.html:34
#: templates/devapp/custom_dev_page/ports.html:59 templates/devapp/dev.html:33
#: templates/devapp/fix_dev_group.html:42
msgid "Parent device"
msgstr "Родительское устройство"
#: devapp/models.py:37
msgid "SNMP Number"
msgstr "SNMP Ном."
#: models.py:43
msgid "SNMP extra info"
msgstr "Доп. инфо для snmp"
#: devapp/models.py:40
#: models.py:46
msgid "Undefined"
msgstr "Не определено"
#: devapp/models.py:41
#: models.py:47
msgid "Up"
msgstr "В сети"
#: devapp/models.py:42
#: models.py:48
msgid "Unreachable"
msgstr "Не доступно"
#: devapp/models.py:43
#: models.py:49
msgid "Down"
msgstr "Не в сети"
#: devapp/models.py:45
#: models.py:51
msgid "Status"
msgstr "Состояние"
#: devapp/models.py:47
#: models.py:53
msgid "Send notify when monitoring state changed"
msgstr "Отправлять уведомления при событиях мониторинга"
#: devapp/models.py:52
#: models.py:58
msgid "Can view device"
msgstr "Может видеть устройство"
#: devapp/models.py:54 devapp/models.py:126
#: models.py:60 models.py:108
msgid "Device"
msgstr "Устройство"
#: devapp/models.py:55 devapp/templates/devapp/devices.html:14
#: devapp/templates/devapp/devices_null_group.html:8
#: models.py:61 templates/devapp/devices.html:14
#: templates/devapp/devices_null_group.html:8
msgid "Devices"
msgstr "Устройства"
#: devapp/models.py:127 devapp/templates/devapp/manage_ports/list.html:11
#: models.py:96 views.py:175 views.py:237
msgid "Device does not have a group, please fix that"
msgstr "У устройства нет группы, пожалуйста, исправьте это"
#: models.py:109 templates/devapp/manage_ports/list.html:11
msgid "Number"
msgstr "Номер"
#: devapp/models.py:128 devapp/templates/devapp/custom_dev_page/onu.html:20
#: devapp/templates/devapp/custom_dev_page/ports.html:88
#: devapp/templates/devapp/manage_ports/add_ports.html:33
#: devapp/templates/devapp/manage_ports/list.html:12
#: models.py:110 templates/devapp/custom_dev_page/onu.html:20
#: templates/devapp/custom_dev_page/onu_for_zte.html:20
#: templates/devapp/custom_dev_page/ports.html:88
#: templates/devapp/manage_ports/add_ports.html:33
#: templates/devapp/manage_ports/list.html:12
msgid "Description"
msgstr "Описание"
#: devapp/models.py:137
#: models.py:119
msgid "Can toggle ports"
msgstr "Может переключать порты"
#: devapp/models.py:139 devapp/templates/devapp/custom_dev_page/ports.html:110
#: devapp/templates/devapp/manage_ports/fix_abon_device.html:24
#: models.py:121 templates/devapp/custom_dev_page/ports.html:110
#: templates/devapp/manage_ports/fix_abon_device.html:24
msgid "Port"
msgstr "Порт"
#: devapp/models.py:140
#: models.py:122
msgid "Ports"
msgstr "Порты"
#: devapp/templates/devapp/add_dev.html:8
#: devapp/templates/devapp/devices.html:8
#: devapp/templates/devapp/devices_null_group.html:7
#: devapp/templates/devapp/fix_dev_group.html:9
#: devapp/templates/devapp/group_list.html:7
#: devapp/templates/devapp/manage_ports/add_ports.html:7
#: devapp/templates/devapp/manage_ports/fix_abon_device.html:7
#: templates/devapp/add_dev.html:8
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:7
#: templates/devapp/devices.html:8 templates/devapp/devices_null_group.html:7
#: templates/devapp/fix_dev_group.html:9 templates/devapp/group_list.html:7
#: templates/devapp/manage_ports/add_ports.html:7
#: templates/devapp/manage_ports/fix_abon_device.html:7
msgid "Groups"
msgstr "Группы"
#: devapp/templates/devapp/add_dev.html:10
#: templates/devapp/add_dev.html:10
msgid "Add new device"
msgstr "Добавить устройство"
#: devapp/templates/devapp/add_dev.html:16
#: devapp/templates/devapp/custom_dev_page/ports.html:68
#: devapp/templates/devapp/devices.html:63
#: devapp/templates/devapp/manage_ports/add_ports.html:16
#: templates/devapp/add_dev.html:16
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:12
#: templates/devapp/custom_dev_page/ports.html:68
#: templates/devapp/devices.html:63
#: templates/devapp/manage_ports/add_ports.html:16
msgid "Not assigned"
msgstr "&lt;Не назначено&gt;"
#: devapp/templates/devapp/add_dev.html:21 devapp/templates/devapp/dev.html:8
#: templates/devapp/add_dev.html:21 templates/devapp/dev.html:8
msgid "Device info"
msgstr "Инфа о железке"
#: devapp/templates/devapp/add_dev.html:60 devapp/templates/devapp/dev.html:43
#: devapp/templates/devapp/dev.html:47
#: devapp/templates/devapp/fix_dev_group.html:51
#: devapp/templates/devapp/fix_dev_group.html:55
#: templates/devapp/add_dev.html:60 templates/devapp/dev.html:43
#: templates/devapp/dev.html:47 templates/devapp/fix_dev_group.html:51
#: templates/devapp/fix_dev_group.html:55
msgid "Find the device"
msgstr "Найти устройство"
#: devapp/templates/devapp/add_dev.html:72 devapp/templates/devapp/dev.html:61
#: devapp/templates/devapp/fix_dev_group.html:64
#: devapp/templates/devapp/manage_ports/add_ports.html:75
#: devapp/templates/devapp/manage_ports/add_ports.html:79
#: devapp/templates/devapp/manage_ports/modal_add_edit_port.html:21
#: templates/devapp/add_dev.html:72 templates/devapp/dev.html:61
#: templates/devapp/fix_dev_group.html:64
#: templates/devapp/manage_ports/add_ports.html:75
#: templates/devapp/manage_ports/add_ports.html:79
#: templates/devapp/manage_ports/modal_add_edit_port.html:21
msgid "Save"
msgstr "Сохранить"
#: devapp/templates/devapp/add_dev.html:75 devapp/templates/devapp/dev.html:73
#: devapp/templates/devapp/fix_dev_group.html:67
#: templates/devapp/add_dev.html:75 templates/devapp/dev.html:73
#: templates/devapp/fix_dev_group.html:67
msgid "Reset"
msgstr "Сбросить"
#: devapp/templates/devapp/custom_dev_page/olt.html:10
#: devapp/templates/devapp/custom_dev_page/onu.html:12
#: devapp/templates/devapp/custom_dev_page/ports.html:12
#: templates/devapp/custom_dev_page/olt.html:10
#: templates/devapp/custom_dev_page/olt_ztec320.html:11
#: templates/devapp/custom_dev_page/onu.html:12
#: templates/devapp/custom_dev_page/onu_for_zte.html:12
#: templates/devapp/custom_dev_page/ports.html:12
msgid "Uptime"
msgstr "Без перезагрузки"
#: devapp/templates/devapp/custom_dev_page/olt.html:17
#: templates/devapp/custom_dev_page/olt.html:17
msgid "SNMP Num"
msgstr "SNMP Ном."
#: devapp/templates/devapp/custom_dev_page/olt.html:18
#: templates/devapp/custom_dev_page/olt.html:18
msgid "Name"
msgstr "Имя"
#: devapp/templates/devapp/custom_dev_page/olt.html:19
#: devapp/templates/devapp/custom_dev_page/onu.html:19
#: templates/devapp/custom_dev_page/olt.html:19
#: templates/devapp/custom_dev_page/onu.html:19
#: templates/devapp/custom_dev_page/onu_for_zte.html:19
msgid "Mac"
msgstr "Мак"
#: devapp/templates/devapp/custom_dev_page/olt.html:20
#: devapp/templates/devapp/custom_dev_page/onu.html:73
#: templates/devapp/custom_dev_page/olt.html:20
#: templates/devapp/custom_dev_page/onu.html:74
#: templates/devapp/custom_dev_page/onu_for_zte.html:77
msgid "Signal"
msgstr "Ур. сигнала"
#: devapp/templates/devapp/custom_dev_page/olt.html:38
#: templates/devapp/custom_dev_page/olt.html:38
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:45
msgid "Create device"
msgstr "Создать устройство"
#: devapp/templates/devapp/custom_dev_page/olt.html:45
#: devapp/templates/devapp/manage_ports/list.html:48
#: templates/devapp/custom_dev_page/olt.html:45
#: templates/devapp/manage_ports/list.html:48
msgid "Ports not found"
msgstr "Порты не найдены"
#: devapp/templates/devapp/custom_dev_page/onu.html:10
#: devapp/templates/devapp/custom_dev_page/ports.html:10
#: templates/devapp/custom_dev_page/olt_ztec320.html:31
#: templates/devapp/custom_dev_page/ports.html:54
msgid "We have not received info, please check options :("
msgstr "Инфа не получена, проверьте настройки :("
#: templates/devapp/custom_dev_page/olt_ztec320.html:36
msgid "Long description"
msgstr "Длинное описание"
#: templates/devapp/custom_dev_page/olt_ztec320.html:37
msgid "Hostname"
msgstr "Имя хоста"
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:15
msgid "OLT Scan"
msgstr "Скан OLT"
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:27
msgid "Onu type"
msgstr "Тип ONU"
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:28
msgid "Onu port"
msgstr "Порт ONU"
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:29
msgid "Onu signal"
msgstr "Сигнала ONU"
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:30
msgid "Serial"
msgstr "Серийный номер"
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:52
msgid "ONU not found"
msgstr "ONU не найдена"
#: templates/devapp/custom_dev_page/onu.html:10
#: templates/devapp/custom_dev_page/onu_for_zte.html:10
#: templates/devapp/custom_dev_page/ports.html:10
msgid "Title of the type of switch"
msgstr "Название типа свича"
#: devapp/templates/devapp/custom_dev_page/onu.html:22
#: templates/devapp/custom_dev_page/onu.html:22
#: templates/devapp/custom_dev_page/onu_for_zte.html:22
msgid "Attached user"
msgstr "Прикрепленный абонент"
#: devapp/templates/devapp/custom_dev_page/onu.html:47
#: templates/devapp/custom_dev_page/onu.html:48
#: templates/devapp/custom_dev_page/onu_for_zte.html:50
msgid "ONU Status"
msgstr "Состояние ONU"
#: devapp/templates/devapp/custom_dev_page/onu.html:57
#: templates/devapp/custom_dev_page/onu.html:58
#: templates/devapp/custom_dev_page/onu_for_zte.html:60
msgid "ONU error"
msgstr "ONU ошибка"
#: devapp/templates/devapp/custom_dev_page/onu.html:71
#: templates/devapp/custom_dev_page/onu.html:72
#: templates/devapp/custom_dev_page/onu_for_zte.html:75
msgid "Name on OLT"
msgstr "Имя на OLT"
#: devapp/templates/devapp/custom_dev_page/onu.html:72
#: templates/devapp/custom_dev_page/onu.html:73
#: templates/devapp/custom_dev_page/onu_for_zte.html:76
msgid "Distance(m)"
msgstr "Расстояние (м)"
#: devapp/templates/devapp/custom_dev_page/onu.html:77
#: devapp/templates/devapp/custom_dev_page/onu.html:85
#: templates/devapp/custom_dev_page/onu.html:78
#: templates/devapp/custom_dev_page/onu.html:86
msgid "Mac on OLT"
msgstr "MAC адрес на OLT"
#: devapp/templates/devapp/custom_dev_page/onu.html:78
#: templates/devapp/custom_dev_page/onu.html:79
msgid "Mac-addresses does not match"
msgstr "MAC адреса не совпадают"
#: devapp/templates/devapp/custom_dev_page/onu.html:79
#: devapp/templates/devapp/custom_dev_page/onu.html:81
#: templates/devapp/custom_dev_page/onu.html:80
#: templates/devapp/custom_dev_page/onu.html:82
msgid "Fix it"
msgstr "Исправить"
#: devapp/templates/devapp/custom_dev_page/onu.html:92
#: templates/devapp/custom_dev_page/onu.html:93
#: templates/devapp/custom_dev_page/onu_for_zte.html:83
msgid "Info does not fetch"
msgstr "Информация не получена"
#: devapp/templates/devapp/custom_dev_page/ports.html:44
#: templates/devapp/custom_dev_page/ports.html:44
msgid "Disable port"
msgstr "Выключить порт"
#: devapp/templates/devapp/custom_dev_page/ports.html:48
#: templates/devapp/custom_dev_page/ports.html:48
msgid "Enable port"
msgstr "Включить порт"
#: devapp/templates/devapp/custom_dev_page/ports.html:54
msgid "We have not received info, please check options :("
msgstr "Инфа не получена, проверьте настройки :("
#: devapp/templates/devapp/custom_dev_page/ports.html:80
#: templates/devapp/custom_dev_page/ports.html:80
msgid "Device log"
msgstr "Лог устройства"
#: devapp/templates/devapp/custom_dev_page/ports.html:87
#: templates/devapp/custom_dev_page/ports.html:87
msgid "Level"
msgstr "Уровень"
#: devapp/templates/devapp/custom_dev_page/ports.html:89
#: templates/devapp/custom_dev_page/ports.html:89
msgid "Date"
msgstr "Дата"
#: devapp/templates/devapp/custom_dev_page/ports.html:104
#: templates/devapp/custom_dev_page/ports.html:104
msgid "Ports comment"
msgstr "Комментарии портов"
#: devapp/templates/devapp/custom_dev_page/ports.html:111
#: templates/devapp/custom_dev_page/ports.html:111
msgid "Title"
msgstr "Название"
#: devapp/templates/devapp/custom_dev_page/ports.html:122
#: templates/devapp/custom_dev_page/ports.html:122
msgid "We have not received info for ports"
msgstr "Инфа о портах не получена"
#: devapp/templates/devapp/dev.html:65 devapp/templates/devapp/dev.html:69
#: devapp/templates/devapp/manage_ports/add_ports.html:53
#: devapp/templates/devapp/manage_ports/add_ports.html:55
#: devapp/templates/devapp/manage_ports/list.html:35
#: devapp/templates/devapp/manage_ports/modal_del_port.html:14
#: templates/devapp/dev.html:65 templates/devapp/dev.html:69
#: templates/devapp/manage_ports/add_ports.html:53
#: templates/devapp/manage_ports/add_ports.html:55
#: templates/devapp/manage_ports/list.html:35
#: templates/devapp/manage_ports/modal_del_port.html:14
msgid "Delete"
msgstr "Удалить"
#: devapp/templates/devapp/dev.html:68
#: templates/devapp/dev.html:68
msgid "Permission denied"
msgstr "Доступ запрещён"
#: devapp/templates/devapp/devices.html:81
#: devapp/templates/devapp/devices_null_group.html:62
#: templates/devapp/device_confirm_delete.html:9
msgid "Remove device"
msgstr "Удалить устройство"
#: templates/devapp/device_confirm_delete.html:13
msgid "Are you sure you want to delete device?"
msgstr "Вы уверены что хотите удалить устройство?"
#: templates/devapp/devices.html:81 templates/devapp/devices_null_group.html:62
msgid "Devices does not found"
msgstr "Нет созданных устройств"
#: devapp/templates/devapp/devices.html:81
#: devapp/templates/devapp/devices.html:91
#: devapp/templates/devapp/devices_null_group.html:62
#: devapp/templates/devapp/devices_null_group.html:72
#: templates/devapp/devices.html:81 templates/devapp/devices.html:91
#: templates/devapp/devices_null_group.html:62
#: templates/devapp/devices_null_group.html:72
msgid "Create"
msgstr "Cоздать"
#: devapp/templates/devapp/devices_null_group.html:13
#: devapp/templates/devapp/group_list.html:32
#: templates/devapp/devices_null_group.html:13
#: templates/devapp/group_list.html:32
msgid "Devices without group"
msgstr "Устройства без группы"
#: devapp/templates/devapp/fix_dev_group.html:17
#: templates/devapp/fix_dev_group.html:17
msgid "Fix device group"
msgstr "Поправить группу устройства"
#: devapp/templates/devapp/group_list.html:14
#: templates/devapp/group_list.html:14
msgid "Group title"
msgstr "Название"
#: devapp/templates/devapp/group_list.html:24
#: templates/devapp/group_list.html:24
msgid "Groups was not found"
msgstr "Эта группа не найдена"
#: devapp/templates/devapp/group_list.html:35
#: templates/devapp/group_list.html:35
msgid "Export to nagios objects"
msgstr "Экспортировать конфиг для nagios"
#: devapp/templates/devapp/manage_ports/add_ports.html:10
#: devapp/templates/devapp/manage_ports/list.html:58
#: templates/devapp/manage_ports/add_ports.html:10
#: templates/devapp/manage_ports/list.html:58
msgid "Add ports"
msgstr "Добавить порты"
#: devapp/templates/devapp/manage_ports/add_ports.html:32
#: templates/devapp/manage_ports/add_ports.html:32
msgid "Mode"
msgstr "Режим"
#: devapp/templates/devapp/manage_ports/add_ports.html:60
#: devapp/templates/devapp/manage_ports/list.html:57
#: templates/devapp/manage_ports/add_ports.html:60
#: templates/devapp/manage_ports/list.html:57
msgid "Add"
msgstr "Добавить"
#: devapp/templates/devapp/manage_ports/fix_abon_device.html:10
#: devapp/templates/devapp/manage_ports/fix_abon_device.html:16
#: templates/devapp/manage_ports/fix_abon_device.html:10
#: templates/devapp/manage_ports/fix_abon_device.html:16
msgid "Fix subscriber ports conflict"
msgstr "Исправить конфликт абонентов на порту"
#: devapp/templates/devapp/manage_ports/fix_abon_device.html:21
#: templates/devapp/manage_ports/fix_abon_device.html:21
msgid "Subscribers list on port"
msgstr "Список абонентов на порту"
#: devapp/templates/devapp/manage_ports/fix_abon_device.html:25
#: templates/devapp/manage_ports/fix_abon_device.html:25
msgid ""
"You may choose the subscriber who correctly attached to device port. When "
"you have found right subscriber, remove the port from the other person"
@ -397,15 +476,15 @@ msgstr ""
"найдёте нужного абонента удалите этот порт у другого абонента чтоб исправить "
"конфликт"
#: devapp/templates/devapp/manage_ports/fix_abon_device.html:31
#: templates/devapp/manage_ports/fix_abon_device.html:31
msgid "Abons not found"
msgstr "Абоненты не найдены"
#: devapp/templates/devapp/manage_ports/list.html:13
#: templates/devapp/manage_ports/list.html:13
msgid "Count of subscribers"
msgstr "Сколько абонов"
#: devapp/templates/devapp/manage_ports/list.html:26
#: templates/devapp/manage_ports/list.html:26
#, python-format
msgid ""
"Port should not have more than one subscriber, <a href='%(furl)s'>fix that</"
@ -414,113 +493,105 @@ msgstr ""
"Порт не должен иметь больше одного назначенного абонента, <a "
"href='%(furl)s'>исправить</a>"
#: devapp/templates/devapp/manage_ports/list.html:31
#: templates/devapp/manage_ports/list.html:31
msgid "Show subscriber on port"
msgstr "Показать абонента на порту"
#: devapp/templates/devapp/manage_ports/list.html:40
#: devapp/templates/devapp/manage_ports/modal_add_edit_port.html:14
#: templates/devapp/manage_ports/list.html:40
#: templates/devapp/manage_ports/modal_add_edit_port.html:14
msgid "Edit"
msgstr "Редактировать"
#: devapp/templates/devapp/manage_ports/modal_del_port.html:7
#: templates/devapp/manage_ports/modal_del_port.html:7
msgid "Are you sure?"
msgstr "Вы уверены?"
#: devapp/templates/devapp/manage_ports/modal_del_port.html:11
#: templates/devapp/manage_ports/modal_del_port.html:11
msgid "Are you sure that you want to delete switch port from db?"
msgstr "Вы уверены что хотите удалить порт свича из бд?"
#: devapp/templates/devapp/manage_ports/modal_show_subscriber_on_port.html:5
#: templates/devapp/manage_ports/modal_show_subscriber_on_port.html:5
msgid "Subscriber on port"
msgstr "Абонент на порту"
#: devapp/views.py:80
msgid "Delete failed"
msgstr "Неизвестная ошибка при удалении :("
#: views.py:87
msgid "Device successfully deleted"
msgstr "Устройство успешно удалено"
#: devapp/views.py:109
#: views.py:115
msgid "You have redirected to existing device"
msgstr "Вы были переадресованы на существующее устройство"
#: devapp/views.py:112 devapp/views.py:361 devapp/views.py:457
#: views.py:118 views.py:368 views.py:481
msgid "Please attach group for device"
msgstr "Пожалуйста назначте устройству группу в настройках"
#: devapp/views.py:121
#: views.py:127
msgid "Device info has been saved"
msgstr "Инфа о точке сохранена"
#: devapp/views.py:124 devapp/views.py:307 devapp/views.py:336
#: devapp/views.py:459
#: views.py:130 views.py:314 views.py:343 views.py:483
msgid "Form is invalid, check fields and try again"
msgstr "Ошибка в данных, проверте их ещё раз"
#: devapp/views.py:127
#: views.py:133
#, python-format
msgid "Duplicate user and port: %s"
msgstr "Пользователь с таким портом и устройством уже есть: %s"
#: devapp/views.py:168 devapp/views.py:230
msgid "Device does not have a group, please fix that"
msgstr "У устройства нет группы, пожалуйста, исправьте это"
#: devapp/views.py:173 devapp/views.py:263 devapp/views.py:348
#: views.py:180 views.py:270 views.py:355
msgid "Device does not exist"
msgstr "Устойство не найдено"
#: devapp/views.py:194
#: views.py:201
msgid "Subscribers on port does not exist"
msgstr "Абоненты на порту не найдены"
#: devapp/views.py:196
#: views.py:203
msgid "More than one subscriber on device port"
msgstr "Больше одного абонента на порту устройства"
#: devapp/views.py:282
#: views.py:289
msgid "Port successfully removed"
msgstr "Порт успешно удалён"
#: devapp/views.py:290 devapp/views.py:318
#: views.py:297 views.py:325
msgid "Port does not exist"
msgstr "Порт не найден"
#: devapp/views.py:305 devapp/views.py:333
#: views.py:312 views.py:340
msgid "Port successfully saved"
msgstr "Порт успешно сохранён"
#: devapp/views.py:368 devapp/views.py:411
#: views.py:375 views.py:431
msgid "Dot was not pinged"
msgstr "Эта точка не пингуется"
#: devapp/views.py:377 devapp/views.py:409
#: views.py:384 views.py:429
msgid "Not Set snmp device password"
msgstr "Не указан snmp пароль для устройства"
#: devapp/views.py:385
#: views.py:392
msgid "SNMP error on device"
msgstr "Ошибка SNMP на устройстве"
#: devapp/views.py:454
#: views.py:478
msgid "Device fixed"
msgstr "Устройство исправлено"
#: devapp/views.py:483
#: views.py:508
#, python-format
msgid "Device with mac address %(mac)s does not exist"
msgstr "Устройство мак адресом %(mac)s не найдено"
#: devapp/views.py:491
#: views.py:516
msgid "Fixed"
msgstr "Исправлено, обновите страницу"
#: devapp/views.py:494
#: views.py:519
msgid "Parent device not found"
msgstr "Вышестоящее устройство не найдено"
#~ msgid "Plugin output"
#~ msgstr "Вывод мониторинга"
msgid "Device %(device_name)s is up"
msgstr "%(device_name)s в сети"
@ -532,15 +603,3 @@ msgstr "%(device_name)s недостижим"
msgid "Device %(device_name)s getting undefined status code"
msgstr "Устройство %(device_name)s получило не определённый код состояния"
msgid "Ip address or parent device with ip address required for ONU device"
msgstr "Необходим ip адрес. Или родительское устройство с назначенным ip адресом необходимо."
msgid "Are you sure you want to delete device?"
msgstr "Вы уверены что хотите удалить устройство?"
msgid "Remove device"
msgstr "Удалить устройство"
msgid "Device successfully deleted"
msgstr "Устройство успешно удалено"

9
devapp/models.py

@ -20,6 +20,8 @@ class DeviceMonitoringException(Exception):
class Device(models.Model):
_cached_manager = None
ip_address = MyGenericIPAddressField(verbose_name=_('Ip address'), null=True, blank=True)
mac_addr = MACAddressField(verbose_name=_('Mac address'), null=True, blank=True, unique=True)
comment = models.CharField(_('Comment'), max_length=256)
@ -71,11 +73,14 @@ class Device(models.Model):
res = klasses[0][1]
if issubclass(res, DevBase):
return res
return
raise TypeError('one of types is not subclass of DevBase. '
'Or implementation of that device type is not found')
def get_manager_object(self) -> DevBase:
man_klass = self.get_manager_klass()
return man_klass(self)
if self._cached_manager is None:
self._cached_manager = man_klass(self)
return self._cached_manager
# Can attach device to subscriber in subscriber page
def has_attachable_to_subscriber(self):

2
devapp/templates/devapp/devices.html

@ -30,7 +30,6 @@
{% if order_by == 'comment' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th class="col-md-3">{% trans 'Mac address' %}</th>
{# <th class="col-md-3 hidden-xs hidden-sm">{% trans 'Plugin output' %}</th> #}
<th class="col-md-1">
<a href="{% url 'devapp:devs' group.pk %}?{% url_replace request order_by='devtype' dir=dir|default:'down' %}">
{% trans 'Device type' %}
@ -61,7 +60,6 @@
<td><a href="{% url 'devapp:view' grpid dev.pk %}">{{ dev.ip_address }}</a></td>
<td>{{ dev.comment }}</td>
<td>{{ dev.mac_addr|default:_('Not assigned') }}</td>
{# <td class="hidden-xs hidden-sm">{{ dev.mon.plugin_output|default:'&ndash;' }}</td> #}
<td>{{ dev.get_devtype_display }}</td>
<td class="btn-group btn-group-xs btn-group-justified">
{% if can_del_dev %}

15
djing/lib/__init__.py

@ -1,5 +1,6 @@
import socket
import struct
from abc import ABCMeta
from datetime import timedelta
from collections import Iterator
from django.db import models
@ -125,12 +126,10 @@ class LogicError(Exception):
pass
def singleton(class_):
instances = {}
class Singleton(type):
_instances = {}
def getinstance(*args, **kwargs):
if class_ not in instances:
instances[class_] = class_(*args, **kwargs)
return instances[class_]
return getinstance
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]

4
djing/lib/tln/__init__.py

@ -0,0 +1,4 @@
from .tln import *
__all__ = ('TelnetApi', 'ValidationError', 'ZTEFiberNumberNotFound', 'ZTEFiberIsFull',
'OnuZteRegisterError', 'ZteOltConsoleError', 'register_onu_ZTE_F660')

266
djing/lib/tln/tln.py

@ -0,0 +1,266 @@
#!/usr/bin/env python3
import re
import struct
from telnetlib import Telnet
from time import sleep
from typing import Generator, Dict, Optional, Tuple
class ZteOltConsoleError(Exception):
pass
class OnuZteRegisterError(ZteOltConsoleError):
pass
class ZTEFiberIsFull(ZteOltConsoleError):
pass
class ZTEFiberNumberNotFound(ZteOltConsoleError):
pass
class ValidationError(ValueError):
pass
MAC_ADDR_REGEX = b'^([0-9A-Fa-f]{1,2}[:-]){5}([0-9A-Fa-f]{1,2})$'
IP_ADDR_REGEX = '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
ONU_SN_REGEX = b'^ZTEG[A-F\d]{8}$'
class TelnetApi(Telnet):
config_level = []
def __init__(self, *args, **kwargs):
timeout = kwargs.get('timeout')
if timeout:
self._timeout = timeout
self._prompt_string = b'ZTE-C320-PKP#'
super().__init__(*args, **kwargs)
def write(self, buffer: bytes) -> None:
buffer = buffer + b'\n'
print('>>', buffer)
super().write(buffer)
def resize_screen(self, width: int, height: int):
naws_cmd = struct.pack('>BBBHHBB',
255, 250, 31, # IAC SB NAWS
width, height,
255, 240 # IAC SE
)
sock = self.get_socket()
sock.send(naws_cmd)
def enter(self, username: bytes, passw: bytes) -> None:
self.read_until(b'Username:')
self.write(username)
self.read_until(b'Password:')
self.write(passw)
def read_lines(self) -> Generator:
while True:
line = self.read_until(b'\r\n', timeout=self._timeout)
line = line.replace(b'\r\n', b'')
if self._prompt_string == line:
break
if line == b'':
continue
yield line
def command_to(self, cmd: bytes) -> Generator:
self.write(cmd)
return self.read_lines()
def set_prompt_string(self, prompt_string: bytes) -> None:
self.config_level.append(prompt_string)
self._prompt_string = prompt_string
def level_exit(self) -> Optional[Tuple]:
if len(self.config_level) < 2:
print('We are in root')
return
self.config_level.pop()
self.set_prompt_string(self.config_level[-1])
return tuple(self.command_to(b'exit'))
def __del__(self):
if self.sock:
self.write(b'exit')
super().__del__()
def parse_onu_name(onu_name: bytes, name_regexp=re.compile(b'[/:_]')) -> Dict[str, bytes]:
gpon_onu, stack_num, rack_num, fiber_num, onu_num = name_regexp.split(onu_name)
return {
'stack_num': stack_num,
'rack_num': rack_num,
'fiber_num': fiber_num,
'onu_num': onu_num
}
class OltZTERegister(TelnetApi):
def __init__(self, screen_size: Tuple[int, int], *args, **kwargs):
super().__init__(*args, **kwargs)
self.resize_screen(*screen_size)
def get_unregistered_onu(self, sn: bytes) -> Optional[Dict]:
lines = tuple(self.command_to(b'show gpon onu uncfg'))
if len(lines) > 3:
# devices available
# find onu by sn
line = tuple(ln for ln in lines if sn.lower() in ln.lower())
if len(line) > 0:
line = line[0]
onu_name, onu_sn, onu_state = line.split()
onu_numbers = parse_onu_name(onu_name)
onu_numbers.update({
'onu_name': onu_name,
'onu_sn': onu_sn,
'onu_state': onu_state
})
return onu_numbers
def get_last_registered_onu_number(self, stack_num: int, rack_num: int, fiber_num: int) -> int:
registered_lines = self.command_to(b'show run int gpon-olt_%d/%d/%d' % (
stack_num,
rack_num,
fiber_num
))
onu_type_regexp = re.compile(b'^\s{2}onu \d{1,3} type [-\w\d]{4,64} sn \w{4,64}$')
last_onu = 0
for rl in registered_lines:
if rl == b' --More--':
self.write(b' ')
if onu_type_regexp.match(rl):
_onu, num, _type, onu_type, _sn, onu_sn = rl.split()
last_onu = int(num)
return last_onu
def enter_to_config_mode(self) -> bool:
prompt = b'ZTE-C320-PKP(config)#'
self.set_prompt_string(prompt)
res = tuple(self.command_to(b'config terminal'))
if res[1].startswith(b'Enter configuration commands'):
# ok, we in the config mode
return True
return False
def go_to_olt_interface(self, stack_num: int, rack_num: int, fiber_num: int) -> Tuple:
self.set_prompt_string(b'ZTE-C320-PKP(config-if)#')
return tuple(self.command_to(b'interface gpon-olt_%d/%d/%d' % (
stack_num,
rack_num,
fiber_num
)))
def go_to_onu_interface(self, stack_num: int, rack_num: int, fiber_num: int, onu_port_num: int) -> Tuple:
self.set_prompt_string(b'ZTE-C320-PKP(config-if)#')
return tuple(self.command_to(b'interface gpon-onu_%d/%d/%d:%d' % (
stack_num,
rack_num,
fiber_num,
onu_port_num
)))
def apply_conf_to_onu(self, mac_addr: bytes, vlan_id: int) -> None:
tmpl = (
b'switchport vlan %d tag vport 1' % vlan_id,
b'port-location format flexible-syntax vport 1',
b'port-location sub-option remote-id enable vport 1',
b'port-location sub-option remote-id name %s vport 1' % mac_addr,
b'dhcp-option82 enable vport 1',
b'dhcp-option82 trust true replace vport 1',
b'ip dhcp snooping enable vport 1'
)
for conf_line in tmpl:
self.write(conf_line)
def register_onu_on_olt_fiber(self, onu_type: bytes, new_onu_num: int, onu_sn: bytes, line_profile: bytes,
remote_profile: bytes) -> Tuple:
# ok, we in interface
tpl = b'onu %d type %s sn %s' % (new_onu_num, onu_type, onu_sn)
r = tuple(self.command_to(tpl))
return tuple(self.command_to(b'onu %d profile line %s remote %s' % (
new_onu_num,
line_profile,
remote_profile
))) + r
def register_onu_ZTE_F660(olt_ip: str, onu_sn: bytes, login_passwd: Tuple[bytes, bytes], onu_mac: bytes):
onu_type = b'ZTE-F660'
line_profile = b'ZTE-F660-LINE'
remote_profile = b'ZTE-F660-ROUTER'
if not re.match(MAC_ADDR_REGEX, onu_mac):
raise ValidationError
if not re.match(IP_ADDR_REGEX, olt_ip):
raise ValidationError
if not re.match(ONU_SN_REGEX, onu_sn):
raise ValidationError
tn = OltZTERegister(host=olt_ip, timeout=2, screen_size=(120, 128))
tn.enter(*login_passwd)
unregistered_onu = tn.get_unregistered_onu(onu_sn)
if unregistered_onu is None:
raise OnuZteRegisterError('unregistered onu not found, sn=%s' % onu_sn.decode('utf-8'))
stack_num = int(unregistered_onu['stack_num'])
rack_num = int(unregistered_onu['rack_num'])
fiber_num = int(unregistered_onu['fiber_num'])
last_onu_number = tn.get_last_registered_onu_number(
stack_num, rack_num, fiber_num
)
if last_onu_number < 1:
raise ZTEFiberNumberNotFound
elif last_onu_number > 126:
raise ZTEFiberIsFull('olt fiber %d is full' % fiber_num)
# enter to config
if not tn.enter_to_config_mode():
raise ZteOltConsoleError('Failed to enter to config mode')
# go to olt interface
if not tn.go_to_olt_interface(stack_num, rack_num, fiber_num):
raise ZteOltConsoleError('Failed to enter in olt fiber port')
# new onu port number
new_onu_port_num = last_onu_number + 1
# register onu on olt interface
r = tn.register_onu_on_olt_fiber(onu_type, new_onu_port_num, onu_sn, line_profile, remote_profile)
print(r)
# exit from olt interface
tn.level_exit()
r = tn.go_to_onu_interface(stack_num, rack_num, fiber_num, new_onu_port_num)
print(r)
tn.apply_conf_to_onu(onu_mac, 145)
sleep(1)
return
if __name__ == '__main__':
ip = '10.40.1.10'
try:
register_onu_ZTE_F660(
olt_ip=ip, onu_sn=b'ZTEGC0458DCE', login_passwd=(b'admin', b'2ekc3'),
onu_mac=b'cc:7b:35:8b:7:0'
)
except ZteOltConsoleError as e:
print(e)
except ConnectionRefusedError:
print('ERROR: connection refused', ip)
Loading…
Cancel
Save