Browse Source

Make extra data field for store custom data

devel
bashmak 8 years ago
parent
commit
75536ecec1
  1. 8
      devapp/base_intr.py
  2. 29
      devapp/dev_types.py
  3. 8
      devapp/forms.py
  4. 219
      devapp/locale/ru/LC_MESSAGES/django.po
  5. 21
      devapp/migrations/0004_device_extra_data.py
  6. 6
      devapp/models.py
  7. 18
      devapp/templates/devapp/dev.html
  8. 25
      devapp/templates/devapp/modal_device_extra_edit.html
  9. 3
      devapp/urls.py
  10. 38
      devapp/views.py
  11. 2
      djing/lib/tln/__init__.py
  12. 23
      djing/lib/tln/tln.py

8
devapp/base_intr.py

@ -1,6 +1,6 @@
from abc import ABCMeta, abstractmethod
from datetime import timedelta
from typing import Union, Iterable, AnyStr, Generator, Optional
from typing import Union, Iterable, AnyStr, Generator, Optional, Dict
from easysnmp import Session
from django.utils.translation import gettext
@ -17,6 +17,10 @@ class DeviceImplementationError(Exception):
pass
class DeviceConfigurationError(DeviceImplementationError):
pass
class DevBase(object, metaclass=ABCMeta):
def __init__(self, dev_instance=None):
self.db_instance = dev_instance
@ -64,7 +68,7 @@ class DevBase(object, metaclass=ABCMeta):
"""
@abstractmethod
def register_device(self):
def register_device(self, extra_data: Dict):
pass
@abstractmethod

29
devapp/dev_types.py

@ -7,7 +7,10 @@ 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, register_onu_ZTE_F660
from .base_intr import DevBase, SNMPBaseWorker, BasePort, DeviceImplementationError, ListOrError
from .base_intr import (
DevBase, SNMPBaseWorker, BasePort, DeviceImplementationError,
ListOrError, DeviceConfigurationError
)
def _norm_name(name: str, replreg=None):
@ -116,7 +119,7 @@ class DLinkDevice(DevBase, SNMPBaseWorker):
device = self.db_instance
return plain_ip_device_mon_template(device, *args, **kwargs)
def register_device(self):
def register_device(self, extra_data: Dict):
pass
@ -200,7 +203,7 @@ class OLTDevice(DevBase, SNMPBaseWorker):
device = self.db_instance
return plain_ip_device_mon_template(device)
def register_device(self):
def register_device(self, extra_data: Dict):
pass
@ -302,7 +305,7 @@ class OnuDevice(DevBase, SNMPBaseWorker):
)
return '\n'.join(i for i in r if i)
def register_device(self):
def register_device(self, extra_data: Dict):
pass
@ -439,9 +442,6 @@ class Olt_ZTE_C320(OLTDevice):
def get_template_name(self):
return 'olt_ztec320.html'
def register_device(self):
pass
class ZteOnuDevice(OnuDevice):
@staticmethod
@ -506,7 +506,9 @@ class ZteOnuDevice(OnuDevice):
)
return '\n'.join(i for i in r if i)
def register_device(self):
def register_device(self, extra_data: Dict):
if extra_data is None:
raise DeviceConfigurationError('You have not info in extra_data field, please fill it in JSON')
device = self.db_instance
ip = None
if device.ip_address:
@ -516,8 +518,15 @@ class ZteOnuDevice(OnuDevice):
if ip:
mac = str(device.mac_addr).encode()
sn = b"ZTEG%s" % b''.join(mac.split(b':')[-4:]).upper()
# FIXME: Store login & password for device somewhere
telnet = extra_data.get('telnet')
if telnet is None:
raise DeviceConfigurationError('For ZTE configuration needed "telnet" section in extra_data')
login = telnet.get('login')
password = telnet.get('password')
if login is None or password is None:
raise DeviceConfigurationError('For ZTE configuration needed login and'
' password for telnet access in extra_data')
register_onu_ZTE_F660(
olt_ip=ip, onu_sn=sn, login_passwd=(b'admin', device.man_passw.encode()),
olt_ip=ip, onu_sn=sn, login_passwd=(login.encode(), password.encode()),
onu_mac=mac
)

8
devapp/forms.py

@ -35,7 +35,7 @@ class DeviceForm(forms.ModelForm):
class Meta:
model = models.Device
exclude = ('map_dot', 'status')
exclude = ('map_dot', 'status', 'extra_data')
widgets = {
'ip_address': forms.TextInput(attrs={
'pattern': IP_ADDR_REGEX,
@ -47,6 +47,12 @@ class DeviceForm(forms.ModelForm):
}
class DeviceExtraDataForm(forms.ModelForm):
class Meta:
model = models.Device
fields = ('extra_data',)
class PortForm(forms.ModelForm):
class Meta:
model = models.Port

219
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-06-02 16:39+0300\n"
"POT-Creation-Date: 2018-06-07 13:20+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Dmitry Novikov nerosketch@gmail.com\n"
"Language: ru\n"
@ -18,57 +18,57 @@ 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"
#: base_intr.py:92
#: base_intr.py:103
msgid "Ip address is required"
msgstr "Ip адрес необходим"
#: dev_types.py:37
#: dev_types.py:66
msgid "DLink switch"
msgstr "Свич D'Link"
#: dev_types.py:56
#: dev_types.py:85
msgid "does not fetch the mac"
msgstr "не нашёл мак"
#: dev_types.py:112
#: dev_types.py:148
msgid "PON OLT"
msgstr ""
#: dev_types.py:136 views.py:275 views.py:433
#: dev_types.py:172 views.py:354 views.py:512
msgid "wait for a reply from the SNMP Timeout"
msgstr "Время ожидания ответа от SNMP истекло"
#: dev_types.py:176
#: dev_types.py:219
msgid "Ip address or parent device with ip address required for ONU device"
msgstr ""
"Необходим ip адрес. Или родительское устройство с назначенным ip адресом "
"необходимо."
#: dev_types.py:182
#: dev_types.py:225
msgid "PON ONU"
msgstr ""
#: dev_types.py:227
#: dev_types.py:271
msgid "ONU not connected"
msgstr "ONU не в сети"
#: dev_types.py:234
#: dev_types.py:279
msgid "Onu snmp field must be en integer"
msgstr "Поле для snmp информации об ONU должно быть числом"
#: dev_types.py:260
#: dev_types.py:332
msgid "Eltex switch"
msgstr "Элтекс свич"
#: dev_types.py:305
#: dev_types.py:380
msgid "OLT ZTE C320"
msgstr ""
#: dev_types.py:354
#: dev_types.py:449
msgid "ZTE PON ONU"
msgstr ""
#: dev_types.py:387
#: dev_types.py:483
msgid "Zte onu snmp field must be two dot separated integers"
msgstr ""
"Поле snmp информации для ZTE ONU должно быть двумя целыми числами, "
@ -82,39 +82,39 @@ msgstr "MAC-адрес необходим для заполнения"
msgid "Device with that mac is already exist"
msgstr "Устройство с этим мак-адресом уже есть"
#: forms.py:63
#: forms.py:71
msgid "Port number on device must be unique"
msgstr "Номер порта на устройстве должен быть уникальным"
#: models.py:25 templates/devapp/custom_dev_page/onu.html:18
#: models.py:27 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 адрес"
#: models.py:26 templates/devapp/devices.html:32
#: models.py:28 templates/devapp/devices.html:32
msgid "Mac address"
msgstr "Мак адрес"
#: models.py:27 templates/devapp/devices.html:28
#: models.py:29 templates/devapp/devices.html:28
#: templates/devapp/devices_null_group.html:26
msgid "Comment"
msgstr "Комментарий"
#: models.py:36 templates/devapp/devices.html:36
#: models.py:38 templates/devapp/devices.html:35
#: templates/devapp/devices_null_group.html:32
msgid "Device type"
msgstr "Тип устройства"
#: models.py:38
#: models.py:40
msgid "SNMP password"
msgstr "Пароль SNMP"
#: models.py:39
#: models.py:41
msgid "Device group"
msgstr "Группа устройства"
#: models.py:40 templates/devapp/add_dev.html:46
#: models.py:42 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
@ -122,56 +122,66 @@ msgstr "Группа устройства"
msgid "Parent device"
msgstr "Родительское устройство"
#: models.py:43
#: models.py:45
msgid "SNMP extra info"
msgstr "Доп. инфо для snmp"
#: models.py:46
msgid "Extra data"
msgstr "Дополнительные данные"
#: models.py:47
msgid "Extra data in JSON format. You may use it for your custom data"
msgstr ""
"Дополнительные данные в формате JSON. Вы можете хранить там собственные "
"данные"
#: models.py:51
msgid "Undefined"
msgstr "Не определено"
#: models.py:47
#: models.py:52
msgid "Up"
msgstr "В сети"
#: models.py:48
#: models.py:53
msgid "Unreachable"
msgstr "Не доступно"
#: models.py:49
#: models.py:54
msgid "Down"
msgstr "Не в сети"
#: models.py:51
#: models.py:56
msgid "Status"
msgstr "Состояние"
#: models.py:53
#: models.py:58
msgid "Send notify when monitoring state changed"
msgstr "Отправлять уведомления при событиях мониторинга"
#: models.py:58
#: models.py:63
msgid "Can view device"
msgstr "Может видеть устройство"
#: models.py:60 models.py:108
#: models.py:65 models.py:123
msgid "Device"
msgstr "Устройство"
#: models.py:61 templates/devapp/devices.html:14
#: models.py:66 templates/devapp/devices.html:14
#: templates/devapp/devices_null_group.html:8
msgid "Devices"
msgstr "Устройства"
#: models.py:96 views.py:175 views.py:237
#: models.py:102 views.py:254 views.py:316
msgid "Device does not have a group, please fix that"
msgstr "У устройства нет группы, пожалуйста, исправьте это"
#: models.py:109 templates/devapp/manage_ports/list.html:11
#: models.py:124 templates/devapp/manage_ports/list.html:11
msgid "Number"
msgstr "Номер"
#: models.py:110 templates/devapp/custom_dev_page/onu.html:20
#: models.py:125 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
@ -179,21 +189,21 @@ msgstr "Номер"
msgid "Description"
msgstr "Описание"
#: models.py:119
#: models.py:134
msgid "Can toggle ports"
msgstr "Может переключать порты"
#: models.py:121 templates/devapp/custom_dev_page/ports.html:110
#: models.py:136 templates/devapp/custom_dev_page/ports.html:110
#: templates/devapp/manage_ports/fix_abon_device.html:24
msgid "Port"
msgstr "Порт"
#: models.py:122
#: models.py:137
msgid "Ports"
msgstr "Порты"
#: templates/devapp/add_dev.html:8
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:7
#: templates/devapp/custom_dev_page/olt_ztec320_units_uncfg.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
@ -206,9 +216,10 @@ msgid "Add new device"
msgstr "Добавить устройство"
#: templates/devapp/add_dev.html:16
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:12
#: templates/devapp/custom_dev_page/olt_ztec320_units_uncfg.html:12
#: templates/devapp/custom_dev_page/olt_ztec320_units_uncfg.html:20
#: templates/devapp/custom_dev_page/ports.html:68
#: templates/devapp/devices.html:63
#: templates/devapp/devices.html:64
#: templates/devapp/manage_ports/add_ports.html:16
msgid "Not assigned"
msgstr "&lt;Не назначено&gt;"
@ -223,16 +234,16 @@ msgstr "Инфа о железке"
msgid "Find the device"
msgstr "Найти устройство"
#: templates/devapp/add_dev.html:72 templates/devapp/dev.html:61
#: templates/devapp/add_dev.html:72 templates/devapp/dev.html:62
#: 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
#: templates/devapp/modal_device_extra_edit.html:14
msgid "Save"
msgstr "Сохранить"
#: templates/devapp/add_dev.html:75 templates/devapp/dev.html:73
#: templates/devapp/fix_dev_group.html:67
#: templates/devapp/add_dev.html:75 templates/devapp/fix_dev_group.html:67
msgid "Reset"
msgstr "Сбросить форму"
@ -253,6 +264,7 @@ msgid "Name"
msgstr "Имя"
#: templates/devapp/custom_dev_page/olt.html:19
#: templates/devapp/custom_dev_page/olt_ztec320_units_uncfg.html:31
#: templates/devapp/custom_dev_page/onu.html:19
#: templates/devapp/custom_dev_page/onu_for_zte.html:19
msgid "Mac"
@ -265,7 +277,7 @@ msgid "Signal"
msgstr "Ур. сигнала"
#: templates/devapp/custom_dev_page/olt.html:38
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:45
#: templates/devapp/custom_dev_page/olt_ztec320_units_uncfg.html:48
msgid "Create device"
msgstr "Создать устройство"
@ -287,27 +299,27 @@ msgstr "Длинное описание"
msgid "Hostname"
msgstr "Имя хоста"
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:15
#: templates/devapp/custom_dev_page/olt_ztec320_units_uncfg.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_units_uncfg.html:20
msgid "Unregistered units"
msgstr "Незарегистрированные юниты"
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:28
msgid "Onu port"
msgstr "Порт ONU"
#: templates/devapp/custom_dev_page/olt_ztec320_units_uncfg.html:32
msgid "Firmware version"
msgstr "Версия прошивки"
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:29
msgid "Onu signal"
msgstr "Сигнала ONU"
#: templates/devapp/custom_dev_page/olt_ztec320_units_uncfg.html:33
msgid "LOID password"
msgstr "LOID пароль"
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:30
msgid "Serial"
msgstr "Серийный номер"
#: templates/devapp/custom_dev_page/olt_ztec320_units_uncfg.html:34
msgid "LOID"
msgstr ""
#: templates/devapp/custom_dev_page/olt_ztec320_ports.html:52
#: templates/devapp/custom_dev_page/olt_ztec320_units_uncfg.html:55
msgid "ONU not found"
msgstr "ONU не найдена"
@ -393,7 +405,7 @@ msgstr "Название"
msgid "We have not received info for ports"
msgstr "Инфа о портах не получена"
#: templates/devapp/dev.html:65 templates/devapp/dev.html:69
#: templates/devapp/dev.html:66 templates/devapp/dev.html:70
#: templates/devapp/manage_ports/add_ports.html:53
#: templates/devapp/manage_ports/add_ports.html:55
#: templates/devapp/manage_ports/list.html:35
@ -401,10 +413,18 @@ msgstr "Инфа о портах не получена"
msgid "Delete"
msgstr "Удалить"
#: templates/devapp/dev.html:68
#: templates/devapp/dev.html:69
msgid "Permission denied"
msgstr "Доступ запрещён"
#: templates/devapp/dev.html:74
msgid "Register device"
msgstr "Зарегистрировать устройство"
#: templates/devapp/dev.html:81
msgid "Tech date"
msgstr "Техническая информация"
#: templates/devapp/device_confirm_delete.html:9
msgid "Remove device"
msgstr "Удалить устройство"
@ -514,84 +534,108 @@ msgstr "Вы уверены что хотите удалить порт свич
msgid "Subscriber on port"
msgstr "Абонент на порту"
#: templates/devapp/modal_device_extra_edit.html:8
msgid "Change extra data for device"
msgstr "Изменить дополнительные данные для устройства"
#: templates/devapp/modal_device_extra_edit.html:18
msgid "Back"
msgstr "Назад"
#: views.py:87
msgid "Device successfully deleted"
msgstr "Устройство успешно удалено"
#: views.py:115
#: views.py:109
#, python-format
msgid "Duplicate user and port: %s"
msgstr "Пользователь с таким портом и устройством уже есть: %s"
#: views.py:121 views.py:178
msgid "You have redirected to existing device"
msgstr "Вы были переадресованы на существующее устройство"
#: views.py:118 views.py:368 views.py:481
#: views.py:124 views.py:181 views.py:447 views.py:560
msgid "Please attach group for device"
msgstr "Пожалуйста назначте устройству группу в настройках"
#: views.py:127
#: views.py:131 views.py:188
msgid "Device info has been saved"
msgstr "Инфа о точке сохранена"
#: views.py:130 views.py:314 views.py:343 views.py:483
#: views.py:146 views.py:393 views.py:422 views.py:562
msgid "Form is invalid, check fields and try again"
msgstr "Ошибка в данных, проверте их ещё раз"
#: views.py:133
#, python-format
msgid "Duplicate user and port: %s"
msgstr "Пользователь с таким портом и устройством уже есть: %s"
#: views.py:238
msgid "Device extra data has successfully updated"
msgstr "Дополнительная информация об устройстве успешно обновлена"
#: views.py:180 views.py:270 views.py:355
#: views.py:259 views.py:349 views.py:434
msgid "Device does not exist"
msgstr "Устойство не найдено"
#: views.py:201
#: views.py:280
msgid "Subscribers on port does not exist"
msgstr "Абоненты на порту не найдены"
#: views.py:203
#: views.py:282
msgid "More than one subscriber on device port"
msgstr "Больше одного абонента на порту устройства"
#: views.py:289
#: views.py:368
msgid "Port successfully removed"
msgstr "Порт успешно удалён"
#: views.py:297 views.py:325
#: views.py:376 views.py:404
msgid "Port does not exist"
msgstr "Порт не найден"
#: views.py:312 views.py:340
#: views.py:391 views.py:419
msgid "Port successfully saved"
msgstr "Порт успешно сохранён"
#: views.py:375 views.py:431
#: views.py:454 views.py:510
msgid "Dot was not pinged"
msgstr "Эта точка не пингуется"
#: views.py:384 views.py:429
#: views.py:463 views.py:508
msgid "Not Set snmp device password"
msgstr "Не указан snmp пароль для устройства"
#: views.py:392
#: views.py:471
msgid "SNMP error on device"
msgstr "Ошибка SNMP на устройстве"
#: views.py:478
#: views.py:557
msgid "Device fixed"
msgstr "Устройство исправлено"
#: views.py:508
#: views.py:587
#, python-format
msgid "Device with mac address %(mac)s does not exist"
msgstr "Устройство мак адресом %(mac)s не найдено"
#: views.py:516
#: views.py:595
msgid "Fixed"
msgstr "Исправлено, обновите страницу"
#: views.py:519
#: views.py:598
msgid "Parent device not found"
msgstr "Вышестоящее устройство не найдено"
#: views.py:737
msgid "Unregistered onu not found"
msgstr "Незарегистрированные ONU не найдены"
#: views.py:739
msgid "Wrong login or password for telnet access"
msgstr "Не правильный логин или пароль для доступа по telnet"
#: views.py:743
msgid "Process locked by another process"
msgstr "Процесс занят другой задачей, подождите чуть и попробуйте ещё"
msgid "Device %(device_name)s is up"
msgstr "%(device_name)s в сети"
@ -607,14 +651,5 @@ msgstr "Устройство %(device_name)s получило не опреде
msgid "View"
msgstr "Посмотреть"
msgid "Unregistered units"
msgstr "Незарегистрированные юниты"
msgid "Register device"
msgstr "Зарегистрировать устройство"
msgid "Unregistered onu not found"
msgstr "Незарегистрированные ONU не найдены"
msgid "Process locked by another process"
msgstr "Процесс занят другой задачей, подождите чуть и попробуйте ещё"
msgid "Enter valid JSON"
msgstr "Введите данные в формате JSON"

21
devapp/migrations/0004_device_extra_data.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-06-07 10:59
from __future__ import unicode_literals
from django.db import migrations
import jsonfield.fields
class Migration(migrations.Migration):
dependencies = [
('devapp', '0003_auto_20180529_1311'),
]
operations = [
migrations.AddField(
model_name='device',
name='extra_data',
field=jsonfield.fields.JSONField(blank=True, help_text='Extra data in JSON format. You may use it for your custom data', null=True, verbose_name='Extra data'),
),
]

6
devapp/models.py

@ -4,6 +4,7 @@ from subprocess import run
from django.db import models
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from jsonfield import JSONField
from djing.fields import MACAddressField, MyGenericIPAddressField
from djing.lib import MyChoicesAdapter
@ -42,6 +43,9 @@ class Device(models.Model):
on_delete=models.SET_NULL)
snmp_extra = models.CharField(_('SNMP extra info'), max_length=256, null=True, blank=True)
extra_data = JSONField(verbose_name=_('Extra data'),
help_text=_('Extra data in JSON format. You may use it for your custom data'),
blank=True, null=True)
NETWORK_STATES = (
('und', _('Undefined')),
@ -112,7 +116,7 @@ class Device(models.Model):
def register_device(self):
mng = self.get_manager_object()
# if hasattr(mng, 'register_device') and callable(mng.register_device):
mng.register_device()
mng.register_device(self.extra_data)
class Port(models.Model):

18
devapp/templates/devapp/dev.html

@ -56,12 +56,13 @@
{% bootstrap_field form.is_noticeable %}
{% with grp_id=group.pk|default:0 %}
<div class="btn-group btn-group-sm">
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-save"></span> {% trans 'Save' %}
</button>
{% if perms.devapp.delete_device %}
<a href="{% url 'devapp:del' group.pk|default:0 dev.pk %}" class="btn btn-danger btn-modal">
<a href="{% url 'devapp:del' grp_id dev.pk %}" class="btn btn-danger btn-modal">
<span class="glyphicon glyphicon-remove"></span> {% trans 'Delete' %}
</a>
{% else %}
@ -69,13 +70,16 @@
<span class="glyphicon glyphicon-remove"></span> {% trans 'Delete' %}
</a>
{% endif %}
<a href="{% url 'devapp:dev_register' group.pk|default:0 dev.pk %}" class="btn btn-default btn-cmd">
<span class="glyphicon glyphicon-fire"></span> <span class="hidden-xs">{% trans 'Register device' %}</span>
</a>
<button type="reset" class="btn btn-default">
<span class="glyphicon glyphicon-remove-circle"></span> {% trans 'Reset' %}
</button>
{% if perms.devapp.change_device %}
<a href="{% url 'devapp:dev_register' grp_id dev.pk %}" class="btn btn-default btn-cmd">
<span class="glyphicon glyphicon-fire"></span> <span class="hidden-xs">{% trans 'Register device' %}</span>
</a>
<a href="{% url 'devapp:extra_data_edit' grp_id dev.pk %}" class="btn btn-default btn-modal">
<span class="glyphicon glyphicon-cog"></span> <span class="hidden-xs">{% trans 'Tech date' %}</span>
</a>
{% endif %}
</div>
{% endwith %}
</form>
</div>

25
devapp/templates/devapp/modal_device_extra_edit.html

@ -0,0 +1,25 @@
{% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% load i18n %}
{% load bootstrap3 %}
{% block main %}
<form action="{% url 'devapp:extra_data_edit' group_id object.pk %}" method="post">{% csrf_token %}
<div class="modal-header primary">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title"><span class="glyphicon glyphicon-exclamation-sign"></span>{% trans 'Change extra data for device' %}</h4>
</div>
<div class="modal-body">
{% bootstrap_form form %}
<div class="btn-group btn-group-sm">
{% trans 'Save' as btntxt %}
{% bootstrap_button btntxt button_type="submit" button_class="btn-primary" icon="save" %}
{% if not request.is_ajax %}
{% trans 'Back' as btntxt %}
{% url 'devapp:edit' group_id object.pk as backurl %}
{% bootstrap_button btntxt button_type="link" href=backurl icon="fast-backward" %}
{% endif %}
</div>
</div>
</form>
{% endblock %}

3
devapp/urls.py

@ -10,9 +10,10 @@ urlpatterns = [
url(r'^(?P<group_id>\d+)$', views.DevicesListView.as_view(), name='devs'),
url(r'^(?P<group_id>\d+)/add$', views.DeviceCreateView.as_view(), name='add'),
url(r'^(\d+)/(?P<device_id>\d+)$', views.devview, name='view'),
url(r'^(\d+)/(?P<device_id>\d+)/del$', views.DeviceVeleteView.as_view(), name='del'),
url(r'^(\d+)/(?P<device_id>\d+)/del$', views.DeviceDeleteView.as_view(), name='del'),
url(r'^(?P<group_id>\d+)/(?P<device_id>\d+)/add$', views.add_single_port, name='add_port'),
url(r'^(?P<group_id>\d+)/(?P<device_id>\d+)/edit$', views.DeviceUpdate.as_view(), name='edit'),
url(r'^(?P<group_id>\d+)/(?P<device_id>\d+)/edit_extra$', views.DeviceUpdateExtra.as_view(), name='extra_data_edit'),
url(r'^(\d+)/(?P<device_id>\d+)/ports$', views.manage_ports, name='manage_ports'),
url(r'^(?P<group_id>\d+)/(?P<device_id>\d+)/ports/(?P<port_id>\d+)/fix_port_conflict$', views.fix_port_conflict,
name='fix_port_conflict'),

38
devapp/views.py

@ -16,7 +16,7 @@ from devapp.base_intr import DeviceImplementationError
from djing.lib.decorators import only_admins, hash_auth_view
from djing.lib import safe_int, ProcessLocked
from abonapp.models import Abon
from djing.lib.tln import ZteOltConsoleError, OnuZteRegisterError
from djing.lib.tln import ZteOltConsoleError, OnuZteRegisterError, ZteOltLoginFailed
from group_app.models import Group
from accounts_app.models import UserProfile
from django.conf import settings
@ -27,7 +27,7 @@ from chatbot.models import ChatException
from jsonview.decorators import json_view
from djing import global_base_views, MAC_ADDR_REGEX, ping, get_object_or_None
from .models import Device, Port, DeviceDBException, DeviceMonitoringException
from .forms import DeviceForm, PortForm
from .forms import DeviceForm, PortForm, DeviceExtraDataForm
class BaseDeviceListView(global_base_views.BaseListWithFiltering):
@ -71,7 +71,7 @@ class DevicesWithoutGroupsListView(global_base_views.OrderingMixin, BaseDeviceLi
@method_decorator(login_required, name='dispatch')
@method_decorator(permission_required('devapp.delete_device'), name='dispatch')
class DeviceVeleteView(DeleteView):
class DeviceDeleteView(DeleteView):
model = Device
pk_url_kwarg = 'device_id'
@ -220,6 +220,30 @@ class DeviceCreateView(CreateView):
return context
@method_decorator(login_required, name='dispatch')
@method_decorator(permission_required('devapp.change_device'), name='dispatch')
class DeviceUpdateExtra(UpdateView):
template_name = 'devapp/modal_device_extra_edit.html'
model = Device
form_class = DeviceExtraDataForm
pk_url_kwarg = 'device_id'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['group_id'] = self.kwargs.get('group_id')
return context
def form_valid(self, form):
r = super().form_valid(form)
messages.success(self.request, _('Device extra data has successfully updated'))
return r
def get_success_url(self):
return resolve_url('devapp:edit',
self.kwargs.get('group_id'),
self.kwargs.get('device_id'))
@login_required
@permission_required('devapp.change_device')
def manage_ports(request, device_id):
@ -612,7 +636,7 @@ class OnDeviceMonitoringEvent(global_base_views.SecureApiView):
if not re.match(MAC_ADDR_REGEX, dev_mac):
return {'text': 'mac address %s is not valid' % dev_mac}
device_down = Device.objects.filter(mac_addr=dev_mac).first()
device_down = Device.objects.filter(mac_addr=dev_mac).defer('extra_data').first()
if device_down is None:
return {'text': 'Devices with mac %s does not exist' % dev_mac}
@ -689,7 +713,7 @@ class DevicesGetListView(global_base_views.SecureApiView):
devs = Device.objects.all()
else:
devs = Device.objects.filter(devtype=device_type)
res = devs.defer('man_passw', 'group', 'parent_dev').values()
res = devs.defer('man_passw', 'group', 'parent_dev', 'extra_data').values()
for r in res:
if isinstance(r['mac_addr'], EUI):
r['mac_addr'] = int(r['mac_addr'])
@ -711,8 +735,12 @@ def regster_device(request, device_id: str):
status = 0
except OnuZteRegisterError:
text = format_msg(gettext('Unregistered onu not found'), 'eye-close')
except ZteOltLoginFailed:
text = format_msg(gettext('Wrong login or password for telnet access'), 'lock')
except (ConnectionRefusedError, ZteOltConsoleError) as e:
text = format_msg(e, 'exclamation-sign')
except DeviceImplementationError as e:
text = format_msg(e, 'wrench')
except ProcessLocked:
text = format_msg(gettext('Process locked by another process'), 'time')
else:

2
djing/lib/tln/__init__.py

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

23
djing/lib/tln/tln.py

@ -20,6 +20,10 @@ class ZTEFiberIsFull(ZteOltConsoleError):
pass
class ZteOltLoginFailed(ZteOltConsoleError):
pass
class ValidationError(ValueError):
pass
@ -56,12 +60,6 @@ class TelnetApi(Telnet):
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)
@ -110,6 +108,15 @@ class OltZTERegister(TelnetApi):
super().__init__(*args, **kwargs)
self.resize_screen(*screen_size)
def enter(self, username: bytes, passw: bytes) -> None:
self.read_until(b'Username:')
self.write(username)
self.read_until(b'Password:')
self.write(passw)
for l in self.read_lines():
if b'bad password' in l:
raise ZteOltLoginFailed
def get_unregistered_onu(self, sn: bytes) -> Optional[Dict]:
lines = tuple(self.command_to(b'show gpon onu uncfg'))
if len(lines) > 3:
@ -251,10 +258,10 @@ def register_onu_ZTE_F660(olt_ip: str, onu_sn: bytes, login_passwd: Tuple[bytes,
if __name__ == '__main__':
ip = '10.40.1.10'
ip = '192.168.0.100'
try:
register_onu_ZTE_F660(
olt_ip=ip, onu_sn=b'ZTEG^#*$&@&', login_passwd=(b'admin', b'password'),
olt_ip=ip, onu_sn=b'ZTEG^#*$&@&', login_passwd=(b'login', b'password'),
onu_mac=b'MAC'
)
except ZteOltConsoleError as e:

Loading…
Cancel
Save