Browse Source

Set ip_address in Device to null=true, because ONU device may be without

ip_address.
devel
bashmak 8 years ago
parent
commit
38663bdca8
  1. 6
      devapp/base_intr.py
  2. 23
      devapp/dev_types.py
  3. 3
      devapp/locale/ru/LC_MESSAGES/django.po
  4. 26
      devapp/migrations/0002_auto_20180409_1318.py
  5. 19
      devapp/models.py
  6. 6
      devapp/templates/devapp/custom_dev_page/olt.html
  7. 4
      devapp/templates/devapp/custom_dev_page/onu.html
  8. 2
      devapp/templates/devapp/custom_dev_page/ports.html
  9. 2
      devapp/templates/devapp/devices_null_group.html
  10. 2
      devapp/templates/devapp/manage_ports/list.html
  11. 34
      devapp/views.py

6
devapp/base_intr.py

@ -1,7 +1,7 @@
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
from datetime import timedelta from datetime import timedelta
from django.utils.translation import gettext from django.utils.translation import gettext
from typing import Union, Iterable, AnyStr, Generator
from typing import Union, Iterable, AnyStr, Generator, Optional
from easysnmp import Session from easysnmp import Session
@ -77,8 +77,8 @@ class BasePort(object, metaclass=ABCMeta):
class SNMPBaseWorker(object, metaclass=ABCMeta): class SNMPBaseWorker(object, metaclass=ABCMeta):
ses = None ses = None
def __init__(self, ip: str, community='public', ver=2):
if ip is None:
def __init__(self, ip: Optional[str], community='public', ver=2):
if ip is None or ip == '':
raise DeviceImplementationError(gettext('Ip address is required')) raise DeviceImplementationError(gettext('Ip address is required'))
self.ses = Session(hostname=ip, community=community, version=ver) self.ses = Session(hostname=ip, community=community, version=ver)

23
devapp/dev_types.py

@ -1,7 +1,9 @@
from django.utils.translation import gettext_lazy as _, gettext
from mydefs import RuTimedelta, safe_int
from typing import AnyStr
from datetime import timedelta from datetime import timedelta
from easysnmp import EasySNMPTimeoutError from easysnmp import EasySNMPTimeoutError
from django.utils.translation import gettext_lazy as _, gettext
from mydefs import RuTimedelta, safe_int
from .base_intr import DevBase, SNMPBaseWorker, BasePort, DeviceImplementationError, ListOrError from .base_intr import DevBase, SNMPBaseWorker, BasePort, DeviceImplementationError, ListOrError
@ -153,11 +155,20 @@ class OLTDevice(DevBase, SNMPBaseWorker):
class OnuDevice(DevBase, SNMPBaseWorker): class OnuDevice(DevBase, SNMPBaseWorker):
def __init__(self, dev_instance): def __init__(self, dev_instance):
DevBase.__init__(self, dev_instance) DevBase.__init__(self, dev_instance)
SNMPBaseWorker.__init__(self, dev_instance.ip_address, dev_instance.man_passw, 2)
dev_ip_addr = None
if dev_instance.ip_address:
dev_ip_addr = dev_instance.ip_address
else:
parent_device = dev_instance.parent_dev
if parent_device is not None and parent_device.ip_address:
dev_ip_addr = parent_device.ip_address
if dev_ip_addr is None:
raise DeviceImplementationError('Ip address or parent device with ip address required for ONU device')
SNMPBaseWorker.__init__(self, dev_ip_addr, dev_instance.man_passw, 2)
@staticmethod @staticmethod
def description():
return _('PON ONU')
def description() -> AnyStr:
return gettext('PON ONU')
def reboot(self): def reboot(self):
pass pass
@ -193,7 +204,7 @@ class OnuDevice(DevBase, SNMPBaseWorker):
signal = self.get_item('.1.3.6.1.4.1.3320.101.10.5.1.5.%d' % num) signal = self.get_item('.1.3.6.1.4.1.3320.101.10.5.1.5.%d' % num)
distance = self.get_item('.1.3.6.1.4.1.3320.101.10.1.1.27.%d' % num) distance = self.get_item('.1.3.6.1.4.1.3320.101.10.1.1.27.%d' % num)
mac = ':'.join(['%x' % ord(i) for i in self.get_item('.1.3.6.1.4.1.3320.101.10.1.1.3.%d' % num)]) mac = ':'.join(['%x' % ord(i) for i in self.get_item('.1.3.6.1.4.1.3320.101.10.1.1.3.%d' % num)])
uptime = self.get_item('.1.3.6.1.2.1.2.2.1.9.%d' % num)
# uptime = self.get_item('.1.3.6.1.2.1.2.2.1.9.%d' % num)
return { return {
'status': status, 'status': status,
'signal': int(signal) / 10 if signal != 'NOSUCHINSTANCE' else 0, 'signal': int(signal) / 10 if signal != 'NOSUCHINSTANCE' else 0,

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

@ -514,3 +514,6 @@ msgstr "Абоненты на порту не найдены"
msgid "Export to nagios objects" msgid "Export to nagios objects"
msgstr "Экспортировать конфиг для nagios" msgstr "Экспортировать конфиг для nagios"
msgid "Ip address or parent device with ip address required for ONU device"
msgstr "Ip-адрес или родительское устройство с ip-адресом, необходимым для устройства ONU"

26
devapp/migrations/0002_auto_20180409_1318.py

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-04-09 13:18
from __future__ import unicode_literals
from django.db import migrations
import mydefs
class Migration(migrations.Migration):
dependencies = [
('devapp', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='device',
options={'ordering': ['id'], 'permissions': (('can_view_device', 'Can view device'),),
'verbose_name': 'Device', 'verbose_name_plural': 'Devices'},
),
migrations.AlterField(
model_name='device',
name='ip_address',
field=mydefs.MyGenericIPAddressField(blank=True, max_length=8, null=True, protocol='ipv4',
verbose_name='Ip address'),
),
]

19
devapp/models.py

@ -9,7 +9,6 @@ from django.conf import settings
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from group_app.models import Group from group_app.models import Group
DEVICE_TYPES = ( DEVICE_TYPES = (
('Dl', dev_types.DLinkDevice), ('Dl', dev_types.DLinkDevice),
('Pn', dev_types.OLTDevice), ('Pn', dev_types.OLTDevice),
@ -27,13 +26,15 @@ class DeviceMonitoringException(Exception):
class Device(models.Model): class Device(models.Model):
ip_address = MyGenericIPAddressField(verbose_name=_('Ip address'))
ip_address = MyGenericIPAddressField(verbose_name=_('Ip address'), null=True, blank=True)
mac_addr = MACAddressField(verbose_name=_('Mac address'), null=True, blank=True, unique=True) mac_addr = MACAddressField(verbose_name=_('Mac address'), null=True, blank=True, unique=True)
comment = models.CharField(_('Comment'), max_length=256) comment = models.CharField(_('Comment'), max_length=256)
devtype = models.CharField(_('Device type'), max_length=2, default=DEVICE_TYPES[0][0], choices=MyChoicesAdapter(DEVICE_TYPES))
devtype = models.CharField(_('Device type'), max_length=2, default=DEVICE_TYPES[0][0],
choices=MyChoicesAdapter(DEVICE_TYPES))
man_passw = models.CharField(_('SNMP password'), max_length=16, null=True, blank=True) man_passw = models.CharField(_('SNMP password'), max_length=16, null=True, blank=True)
group = models.ForeignKey(Group, on_delete=models.SET_NULL, null=True, blank=True, verbose_name=_('Device group')) group = models.ForeignKey(Group, on_delete=models.SET_NULL, null=True, blank=True, verbose_name=_('Device group'))
parent_dev = models.ForeignKey('self', verbose_name=_('Parent device'), blank=True, null=True, on_delete=models.SET_NULL)
parent_dev = models.ForeignKey('self', verbose_name=_('Parent device'), blank=True, null=True,
on_delete=models.SET_NULL)
snmp_item_num = models.PositiveSmallIntegerField(_('SNMP Number'), default=0, blank=True) snmp_item_num = models.PositiveSmallIntegerField(_('SNMP Number'), default=0, blank=True)
@ -70,22 +71,22 @@ class Device(models.Model):
return res return res
return return
def get_manager_object(self):
def get_manager_object(self) -> DevBase:
man_klass = self.get_manager_klass() man_klass = self.get_manager_klass()
return man_klass(self) return man_klass(self)
# Можно-ли подключать устройство к абоненту
# Can attach device to subscriber in subscriber page
def has_attachable_to_subscriber(self): def has_attachable_to_subscriber(self):
mngr_class = self.get_manager_klass() mngr_class = self.get_manager_klass()
return mngr_class.has_attachable_to_subscriber() return mngr_class.has_attachable_to_subscriber()
def __str__(self): def __str__(self):
return "%s: (%s) %s %s" % (self.comment, self.get_devtype_display(), self.ip_address, self.mac_addr or '')
return "%s: (%s) %s %s" % (self.comment, self.get_devtype_display(), self.ip_address or '', self.mac_addr or '')
def update_dhcp(self): def update_dhcp(self):
if self.devtype not in ('On','Dl'):
if self.devtype not in ('On', 'Dl'):
return return
#raise ProgrammingError('переделать это безобразие')
# raise ProgrammingError('переделать это безобразие')
# FIXME: переделать это безобразие # FIXME: переделать это безобразие
grp = self.group.id grp = self.group.id
code = '' code = ''

6
devapp/templates/devapp/custom_dev_page/olt.html

@ -23,19 +23,19 @@
</thead> </thead>
<tbody> <tbody>
{% with dip=dev.ip_address grp=dev.group.pk %}
{% with grp=dev.group.pk %}
{% for port in ports %} {% for port in ports %}
<tr> <tr>
<td>{% if port.st %}<span class="glyphicon glyphicon-ok text-success"></span> <td>{% if port.st %}<span class="glyphicon glyphicon-ok text-success"></span>
{% else %}<span class="glyphicon glyphicon-warning-sign text-danger"></span> {% else %}<span class="glyphicon glyphicon-warning-sign text-danger"></span>
{% endif %} {% endif %}
</td> </td>
<td>{{ port.num }}</td>
<td>{{ port.num }}</td>
<td>{{ port.nm }}</td> <td>{{ port.nm }}</td>
<td>{{ port.mac }}</td> <td>{{ port.mac }}</td>
<td>{{ port.signal }}</td> <td>{{ port.signal }}</td>
<td> <td>
<a href="{% url 'devapp:add' grp %}?mac={{ port.mac }}&t=On&c={{ port.nm }}&ip={{ dip }}&n={{ port.num }}" title="{% trans 'Create device' %}">
<a href="{% url 'devapp:add' grp %}?mac={{ port.mac }}&t=On&c={{ port.nm }}{% if dev.ip_address %}&ip={{ dev.ip_address }}{% endif %}&n={{ port.num }}" title="{% trans 'Create device' %}">
<span class="glyphicon glyphicon-plus"></span> <span class="glyphicon glyphicon-plus"></span>
</a> </a>
</td> </td>

4
devapp/templates/devapp/custom_dev_page/onu.html

@ -15,7 +15,7 @@
</div> </div>
<div class="panel-body"> <div class="panel-body">
<ul class="list-group"> <ul class="list-group">
<li class="list-group-item">{% trans 'Ip address' %}: {{ dev.ip_address }}</li>
<li class="list-group-item">{% trans 'Ip address' %}: {{ dev.ip_address|default:'-' }}</li>
<li class="list-group-item">{% trans 'Mac' %}: {{ dev.mac_addr }}</li> <li class="list-group-item">{% trans 'Mac' %}: {{ dev.mac_addr }}</li>
<li class="list-group-item">{% trans 'Description' %}: {{ dev.comment }}</li> <li class="list-group-item">{% trans 'Description' %}: {{ dev.comment }}</li>
{% for da in dev_accs %} {% for da in dev_accs %}
@ -33,7 +33,7 @@
{% with pdev=dev.parent_dev pdgrp=dev.parent_dev.group %} {% with pdev=dev.parent_dev pdgrp=dev.parent_dev.group %}
{% trans 'Parent device' %}:<a href="{% url 'devapp:view' pdgrp.pk pdev.pk %}" {% trans 'Parent device' %}:<a href="{% url 'devapp:view' pdgrp.pk pdev.pk %}"
title="{{ pdev.mac_addr|default:'' }}" title="{{ pdev.mac_addr|default:'' }}"
target="_blank">{{ pdev.ip_address }} {{ pdev.comment }}</a>
target="_blank">{{ pdev.ip_address|default:'-' }} {{ pdev.comment }}</a>
{% endwith %} {% endwith %}
</li> </li>
{% endif %} {% endif %}

2
devapp/templates/devapp/custom_dev_page/ports.html

@ -59,7 +59,7 @@
{% trans 'Parent device' %} {% trans 'Parent device' %}
{% with pdev=dev.parent_dev %} {% with pdev=dev.parent_dev %}
{% if pdev %} {% if pdev %}
<a href="{% url 'devapp:view' pdev.group.pk pdev.pk %}" title="{{ pdev.ip_address }}" data-toggle="tooltip">{{ pdev.comment }}</a>
<a href="{% url 'devapp:view' pdev.group.pk pdev.pk %}" title="{{ pdev.ip_address|default:'-' }}" data-toggle="tooltip">{{ pdev.comment }}</a>
{% else %} {% else %}
{% trans 'Not assigned' %} {% trans 'Not assigned' %}
{% endif %} {% endif %}

2
devapp/templates/devapp/devices_null_group.html

@ -41,7 +41,7 @@
{% with can_del_dev=perms.devapp.delete_device can_change_dev=perms.devapp.change_device %} {% with can_del_dev=perms.devapp.delete_device can_change_dev=perms.devapp.change_device %}
{% for dev in devices %} {% for dev in devices %}
<tr> <tr>
<td><a href="{% url 'devapp:view' 0 dev.pk %}">{{ dev.ip_address }}</a></td>
<td><a href="{% url 'devapp:view' 0 dev.pk %}">{{ dev.ip_address|default:'-' }}</a></td>
<td>{{ dev.comment }}</td> <td>{{ dev.comment }}</td>
<td>{{ dev.get_devtype_display }}</td> <td>{{ dev.get_devtype_display }}</td>
<td class="btn-group btn-group-sm"> <td class="btn-group btn-group-sm">

2
devapp/templates/devapp/manage_ports/list.html

@ -20,7 +20,7 @@
{% for port in ports %} {% for port in ports %}
<tr> <tr>
<td>{{ port.num }}</td> <td>{{ port.num }}</td>
<td>{{ port.descr }}</td>
<td>{{ port.descr|default:'-' }}</td>
{% if port.num_abons > 1 %} {% if port.num_abons > 1 %}
{% url 'devapp:fix_port_conflict' gid did port.id as fixurl %} {% url 'devapp:fix_port_conflict' gid did port.id as fixurl %}
<td class="text-danger"><b>{{ port.num_abons }}</b>. {% blocktrans with furl=fixurl %}Port should not have more than one subscriber, <a href='{{ furl }}'>fix that</a>{% endblocktrans %}</td> <td class="text-danger"><b>{{ port.num_abons }}</b>. {% blocktrans with furl=fixurl %}Port should not have more than one subscriber, <a href='{{ furl }}'>fix that</a>{% endblocktrans %}</td>

34
devapp/views.py

@ -14,7 +14,7 @@ from easysnmp import EasySNMPTimeoutError, EasySNMPError
from django.views.generic import DetailView from django.views.generic import DetailView
from devapp.base_intr import DeviceImplementationError from devapp.base_intr import DeviceImplementationError
from mydefs import res_success, res_error, only_admins, ping
from mydefs import res_success, res_error, only_admins, safe_int
from abonapp.models import Abon from abonapp.models import Abon
from group_app.models import Group from group_app.models import Group
from accounts_app.models import UserProfile from accounts_app.models import UserProfile
@ -24,10 +24,9 @@ from guardian.shortcuts import get_objects_for_user
from chatbot.telebot import send_notify from chatbot.telebot import send_notify
from chatbot.models import ChatException from chatbot.models import ChatException
from jsonview.decorators import json_view from jsonview.decorators import json_view
from djing import global_base_views, IP_ADDR_REGEX
from djing import global_base_views, IP_ADDR_REGEX, ping
from .models import Device, Port, DeviceDBException, DeviceMonitoringException from .models import Device, Port, DeviceDBException, DeviceMonitoringException
from .forms import DeviceForm, PortForm from .forms import DeviceForm, PortForm
from mydefs import safe_int
class BaseDeviceListView(global_base_views.BaseListWithFiltering): class BaseDeviceListView(global_base_views.BaseListWithFiltering):
@ -124,7 +123,7 @@ def dev(request, group_id, device_id=0):
else: else:
messages.error(request, _('Form is invalid, check fields and try again')) messages.error(request, _('Form is invalid, check fields and try again'))
except IntegrityError as e: except IntegrityError as e:
if 'unique constraint' in e.message:
if 'unique constraint' in str(e):
messages.error(request, _('Duplicate user and port: %s') % e) messages.error(request, _('Duplicate user and port: %s') % e)
else: else:
messages.error(request, e) messages.error(request, e)
@ -362,18 +361,18 @@ def devview(request, device_id):
template_name = 'ports.html' template_name = 'ports.html'
try: try:
if ping(dev.ip_address):
if dev.man_passw:
manager = dev.get_manager_object()
ports = manager.get_ports()
if len(ports) > 0 and isinstance(ports[0], Exception):
messages.error(request, ports[0])
ports = ports[1]
template_name = manager.get_template_name()
else:
messages.warning(request, _('Not Set snmp device password'))
if dev.ip_address:
if not ping(dev.ip_address):
messages.error(request, _('Dot was not pinged'))
if dev.man_passw:
manager = dev.get_manager_object()
ports = manager.get_ports()
if len(ports) > 0 and isinstance(ports[0], Exception):
messages.error(request, ports[0])
ports = ports[1]
template_name = manager.get_template_name()
else: else:
messages.error(request, _('Dot was not pinged'))
messages.warning(request, _('Not Set snmp device password'))
return render(request, 'devapp/custom_dev_page/' + template_name, { return render(request, 'devapp/custom_dev_page/' + template_name, {
'dev': dev, 'dev': dev,
'ports': ports, 'ports': ports,
@ -437,7 +436,7 @@ def search_dev(request):
results = Device.objects.filter( results = Device.objects.filter(
Q(comment__icontains=word) | Q(ip_address=word) Q(comment__icontains=word) | Q(ip_address=word)
).only('pk', 'ip_address', 'comment')[:16] ).only('pk', 'ip_address', 'comment')[:16]
results = [{'id': dev.pk, 'text': "%s: %s" % (dev.ip_address, dev.comment)} for dev in results]
results = [{'id': dev.pk, 'text': "%s: %s" % (dev.ip_address or '', dev.comment)} for dev in results]
return JsonResponse(results, json_dumps_params={'ensure_ascii': False}, safe=False) return JsonResponse(results, json_dumps_params={'ensure_ascii': False}, safe=False)
@ -594,7 +593,8 @@ def nagios_objects_conf(request):
def norm_name(name: str, replreg=re.compile(r'\W{1,255}', re.IGNORECASE)): def norm_name(name: str, replreg=re.compile(r'\W{1,255}', re.IGNORECASE)):
return replreg.sub('', name) return replreg.sub('', name)
for dev in Device.objects.exclude(devtype='On', ip_address='127.0.0.1').select_related('parent_dev').only('ip_address', 'comment', 'parent_dev'):
for dev in Device.objects.exclude(devtype='On', ip_address='127.0.0.1').select_related('parent_dev').only(
'ip_address', 'comment', 'parent_dev'):
conf = templ(host_name=norm_name("%d%s" % (dev.pk, translit(dev.comment, language_code='ru', reversed=True))), conf = templ(host_name=norm_name("%d%s" % (dev.pk, translit(dev.comment, language_code='ru', reversed=True))),
host_addr=dev.ip_address, host_addr=dev.ip_address,
parent_host_name=norm_name("%d%s" % (dev.parent_dev.pk, parent_host_name=norm_name("%d%s" % (dev.parent_dev.pk,

Loading…
Cancel
Save