diff --git a/accounts_app/views.py b/accounts_app/views.py
index bf9a317..48d932f 100644
--- a/accounts_app/views.py
+++ b/accounts_app/views.py
@@ -199,7 +199,8 @@ def perms(request, uid):
klasses = (
'abonapp.Abon', 'accounts_app.UserProfile',
'abonapp.AbonTariff', 'abonapp.AbonStreet', 'devapp.Device',
- 'abonapp.PassportInfo', 'abonapp.AdditionalTelephone', 'tariff_app.PeriodicPay'
+ 'abonapp.PassportInfo', 'abonapp.AdditionalTelephone', 'tariff_app.PeriodicPay',
+ 'group_app.Group'
)
return render(request, 'accounts/perms/objects_types.html', {
'userprofile': userprofile,
diff --git a/devapp/dev_types.py b/devapp/dev_types.py
index 31f97b5..7dda24e 100644
--- a/devapp/dev_types.py
+++ b/devapp/dev_types.py
@@ -1,4 +1,4 @@
-from typing import AnyStr
+from typing import AnyStr, Iterable
from datetime import timedelta
from easysnmp import EasySNMPTimeoutError
from django.utils.translation import gettext_lazy as _, gettext
@@ -8,11 +8,11 @@ from .base_intr import DevBase, SNMPBaseWorker, BasePort, DeviceImplementationEr
class DLinkPort(BasePort):
- def __init__(self, num, name, status, mac, speed, snmpWorker):
+ def __init__(self, num, name, status, mac, speed, snmp_worker):
BasePort.__init__(self, num, name, status, mac, speed)
- if not issubclass(snmpWorker.__class__, SNMPBaseWorker):
+ if not issubclass(snmp_worker.__class__, SNMPBaseWorker):
raise TypeError
- self.snmp_worker = snmpWorker
+ self.snmp_worker = snmp_worker
def disable(self):
self.snmp_worker.set_int_value(
@@ -79,11 +79,11 @@ class DLinkDevice(DevBase, SNMPBaseWorker):
class ONUdev(BasePort):
- def __init__(self, num, name, status, mac, speed, signal, snmpWorker):
+ def __init__(self, num, name, status, mac, speed, signal, snmp_worker):
super(ONUdev, self).__init__(num, name, status, mac, speed)
- if not issubclass(snmpWorker.__class__, SNMPBaseWorker):
+ if not issubclass(snmp_worker.__class__, SNMPBaseWorker):
raise TypeError
- self.snmp_worker = snmpWorker
+ self.snmp_worker = snmp_worker
self.signal = signal
def disable(self):
@@ -103,14 +103,13 @@ class OLTDevice(DevBase, SNMPBaseWorker):
@staticmethod
def description():
- return _('PON OLT')
+ return gettext('PON OLT')
def reboot(self):
pass
def get_ports(self) -> ListOrError:
nms = self.get_list('.1.3.6.1.4.1.3320.101.10.1.1.79')
-
res = []
try:
for nm in nms:
@@ -124,7 +123,7 @@ class OLTDevice(DevBase, SNMPBaseWorker):
mac=self.get_item('.1.3.6.1.4.1.3320.101.10.1.1.3.%d' % n),
speed=0,
signal=int(signal) / 10 if signal != 'NOSUCHINSTANCE' else 0,
- snmpWorker=self)
+ snmp_worker=self)
res.append(onu)
except EasySNMPTimeoutError as e:
return EasySNMPTimeoutError(
@@ -136,8 +135,8 @@ class OLTDevice(DevBase, SNMPBaseWorker):
return self.get_item('.1.3.6.1.2.1.1.5.0')
def uptime(self):
- uptimestamp = safe_int(self.get_item('.1.3.6.1.2.1.1.9.1.4.1'))
- tm = RuTimedelta(timedelta(seconds=uptimestamp / 100)) or RuTimedelta(timedelta())
+ up_timestamp = safe_int(self.get_item('.1.3.6.1.2.1.1.9.1.4.1'))
+ tm = RuTimedelta(timedelta(seconds=up_timestamp / 100)) or RuTimedelta(timedelta())
return tm
def get_template_name(self):
@@ -163,7 +162,9 @@ class OnuDevice(DevBase, SNMPBaseWorker):
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(gettext('Ip address or parent device with ip address required for ONU device'))
+ raise DeviceImplementationError(gettext(
+ 'Ip address or parent device with ip address required for ONU device'
+ ))
SNMPBaseWorker.__init__(self, dev_ip_addr, dev_instance.man_passw, 2)
@staticmethod
@@ -217,11 +218,11 @@ class OnuDevice(DevBase, SNMPBaseWorker):
class EltexPort(BasePort):
- def __init__(self, snmpWorker, *args, **kwargs):
+ def __init__(self, snmp_worker, *args, **kwargs):
BasePort.__init__(self, *args, **kwargs)
- if not issubclass(snmpWorker.__class__, SNMPBaseWorker):
+ if not issubclass(snmp_worker.__class__, SNMPBaseWorker):
raise TypeError
- self.snmp_worker = snmpWorker
+ self.snmp_worker = snmp_worker
def disable(self):
self.snmp_worker.set_int_value(
@@ -269,3 +270,59 @@ class EltexSwitch(DLinkDevice):
@staticmethod
def is_use_device_port():
return False
+
+
+class Olt_ZTE_C320(OLTDevice):
+
+ @staticmethod
+ def description():
+ return gettext('OLT ZTE C320')
+
+ def get_fibers(self):
+ fibers = ({
+ 'fb_id': fiber_id,
+ 'fb_name': fiber_name,
+ 'fb_onu_num': safe_int(self.get_item('.1.3.6.1.4.1.3902.1012.3.13.1.1.13.%d' % int(fiber_id)))
+ } for fiber_name, fiber_id in self.get_list_keyval('.1.3.6.1.4.1.3902.1012.3.13.1.1.1'))
+ return fibers
+
+ def get_ports_on_fiber(self, fiber_num: int) -> Iterable:
+ def conv_signal(lvl: int) -> float:
+ if lvl == 65535: return 0.0
+ r = 0
+ if 0 < lvl < 30000:
+ r = lvl * 0.002 - 30
+ elif 60000 < lvl < 65534:
+ r = (lvl - 65534) * 0.002 - 30
+ return round(r, 2)
+
+ onu_types = self.get_list('.1.3.6.1.4.1.3902.1012.3.28.1.1.1.%d' % fiber_num)
+ onu_ports = self.get_list('.1.3.6.1.4.1.3902.1012.3.28.1.1.2.%d' % fiber_num)
+ onu_signals = self.get_list('.1.3.6.1.4.1.3902.1012.3.50.12.1.1.10.%d' % fiber_num)
+
+ # Real sn in last 3 octets
+ onu_sns = self.get_list('.1.3.6.1.4.1.3902.1012.3.28.1.1.5.%d' % fiber_num)
+ onu_prefixs = self.get_list('.1.3.6.1.4.1.3902.1012.3.50.11.2.1.1.%d' % fiber_num)
+ onu_list = ({
+ 'onu_type': onu_type,
+ 'onu_port': onu_port,
+ 'onu_signal': conv_signal(safe_int(onu_signal)),
+ 'onu_sn': onu_prefix + ''.join('%.2X' % ord(i) for i in onu_sn[-4:]), # Real sn in last 4 octets
+ } for onu_type, onu_port, onu_signal, onu_sn, onu_prefix in zip(
+ onu_types, onu_ports, onu_signals, onu_sns, onu_prefixs
+ ))
+ return onu_list
+
+ def uptime(self):
+ up_timestamp = safe_int(self.get_item('.1.3.6.1.2.1.1.3.0'))
+ tm = RuTimedelta(timedelta(seconds=up_timestamp / 100)) or RuTimedelta(timedelta())
+ return tm
+
+ def get_long_description(self):
+ return self.get_item('.1.3.6.1.2.1.1.1.0')
+
+ def get_hostname(self):
+ return self.get_item('.1.3.6.1.2.1.1.5.0')
+
+ def get_template_name(self):
+ return 'olt_ztec320.html'
diff --git a/devapp/forms.py b/devapp/forms.py
index f6953bb..c3145c4 100644
--- a/devapp/forms.py
+++ b/devapp/forms.py
@@ -25,8 +25,7 @@ class DeviceForm(forms.ModelForm):
}),
'comment': forms.TextInput(attrs={
'required': True
- }),
- 'man_passw': forms.PasswordInput(render_value=True)
+ })
}
diff --git a/devapp/models.py b/devapp/models.py
index f268a02..abf87c5 100644
--- a/devapp/models.py
+++ b/devapp/models.py
@@ -26,7 +26,8 @@ class Device(models.Model):
('Dl', dev_types.DLinkDevice),
('Pn', dev_types.OLTDevice),
('On', dev_types.OnuDevice),
- ('Ex', dev_types.EltexSwitch)
+ ('Ex', dev_types.EltexSwitch),
+ ('Zt', dev_types.Olt_ZTE_C320)
)
devtype = models.CharField(_('Device type'), max_length=2, default=DEVICE_TYPES[0][0],
choices=MyChoicesAdapter(DEVICE_TYPES))
diff --git a/devapp/templates/devapp/custom_dev_page/olt_ztec320.html b/devapp/templates/devapp/custom_dev_page/olt_ztec320.html
new file mode 100644
index 0000000..43c146f
--- /dev/null
+++ b/devapp/templates/devapp/custom_dev_page/olt_ztec320.html
@@ -0,0 +1,44 @@
+{% extends request.is_ajax|yesno:'nullcont.htm,devapp/ext.htm' %}
+{% load i18n %}
+{% block content %}
+
+
+
+
+
+ {% with uptime=dev_manager.uptime %}
+ {% if uptime %}
+
{% trans 'Uptime' %} {{ uptime }}
+ {% endif %}
+ {% endwith %}
+
+
+ {% with grp=dev.group.pk mng=dev_manager %}
+ {% for fiber in dev_manager.get_fibers %}
+
+
{{ fiber.fb_name }}
+ {% if fiber.fb_onu_num > 0 %}
+
+ {{ fiber.fb_onu_num }}
+
+ {% else %}
+
+ 0
+
+ {% endif %}
+
+ {% empty %}
+
{% trans 'We have not received info, please check options :(' %}
+ {% endfor %}
+
+
+
+ {% endwith %}
+
+
+
+
+{% endblock %}
diff --git a/devapp/templates/devapp/custom_dev_page/olt_ztec320_ports.html b/devapp/templates/devapp/custom_dev_page/olt_ztec320_ports.html
new file mode 100644
index 0000000..19c6db0
--- /dev/null
+++ b/devapp/templates/devapp/custom_dev_page/olt_ztec320_ports.html
@@ -0,0 +1,60 @@
+{% extends request.is_ajax|yesno:'nullcont.htm,devapp/ext.htm' %}
+{% load i18n %}
+
+{% block breadcrumb %}
+
+
+ - {% trans 'Groups' %}
+ {% if dev.group %}
+ - {{ dev.group.title }}
+ - {{ dev.comment }}
+ {% else %}
+ - {% trans 'Not assigned' %}
+ - {{ dev.comment }}
+ {% endif %}
+ - {% trans 'OLT Scan' %}
+
+{% endblock %}
+
+{% block content %}
+
+
+
+
+
+
+ | # |
+ {% trans 'Onu type' %} |
+ {% trans 'Onu port' %} |
+ {% trans 'Onu signal' %} |
+ {% trans 'Serial' %} |
+ # |
+
+
+
+
+ {% for onu in onu_list %}
+
+ | -
+ |
+ {{ onu.onu_type }} |
+ {{ onu.onu_port }} |
+ {{ onu.onu_signal }} |
+ {{ onu.onu_sn }} |
+
+
+
+
+ |
+
+ {% empty %}
+
+ | {% trans 'ONU not found' %} |
+
+ {% endfor %}
+
+
+
+
+
+{% endblock %}
diff --git a/devapp/templates/devapp/ext.htm b/devapp/templates/devapp/ext.htm
index 8a293bf..1563558 100644
--- a/devapp/templates/devapp/ext.htm
+++ b/devapp/templates/devapp/ext.htm
@@ -2,16 +2,18 @@
{% load i18n %}
{% block main %}
-
-
- - {% trans 'Groups' %}
- {% if dev.group %}
- - {{ dev.group.title }}
- {% else %}
- - {% trans 'Not assigned' %}
- {% endif %}
- - {{ dev.comment }}
-
+ {% block breadcrumb %}
+
+
+ - {% trans 'Groups' %}
+ {% if dev.group %}
+ - {{ dev.group.title }}
+ {% else %}
+ - {% trans 'Not assigned' %}
+ {% endif %}
+ - {{ dev.comment }}
+
+ {% endblock %}
{% include 'message_block.html' %}
diff --git a/devapp/urls.py b/devapp/urls.py
index 136fb39..9731624 100644
--- a/devapp/urls.py
+++ b/devapp/urls.py
@@ -25,6 +25,9 @@ urlpatterns = [
url(r'^fix_device_group/(?P\d+)$', views.fix_device_group, name='fix_device_group'),
url(r'^search_dev$', views.search_dev),
+ # ZTE ports under fibers
+ url(r'^(?P\d+)/(?P\d+)/(?P\d+)$', views.zte_port_view, name='zte_port_view'),
+
# Monitoring api
url(r'^on_device_event/$', views.OnDeviceMonitoringEvent.as_view()),
diff --git a/devapp/views.py b/devapp/views.py
index 08bcf83..2d6ba68 100644
--- a/devapp/views.py
+++ b/devapp/views.py
@@ -5,7 +5,7 @@ from django.contrib.gis.shortcuts import render_to_text
from django.core.exceptions import PermissionDenied
from django.db import IntegrityError
from django.db.models import Q, Count
-from django.http import HttpResponse, JsonResponse, Http404
+from django.http import HttpResponse, Http404
from django.shortcuts import render, redirect, get_object_or_404, resolve_url
from django.contrib import messages
from django.utils.decorators import method_decorator
@@ -72,10 +72,10 @@ class DevicesWithoutGroupsListView(global_base_views.OrderingMixin, BaseDeviceLi
@permission_required('devapp.delete_device')
def devdel(request, device_id):
try:
- dev = Device.objects.get(pk=device_id)
- back_url = resolve_url('devapp:devs', group_id=dev.group.pk if dev.group else 0)
- dev.update_dhcp(remove=True)
- dev.delete()
+ device_instance = Device.objects.get(pk=device_id)
+ back_url = resolve_url('devapp:devs', group_id=device_instance.group.pk if device_instance.group else 0)
+ device_instance.update_dhcp(remove=True)
+ device_instance.delete()
return res_success(request, back_url)
except Device.DoesNotExist:
return res_error(request, _('Delete failed'))
@@ -163,12 +163,13 @@ def dev(request, group_id, device_id=0):
@login_required
@permission_required('devapp.change_device')
def manage_ports(request, device_id):
+ device = ports = None
try:
- dev = Device.objects.get(pk=device_id)
- if dev.group is None:
+ device = Device.objects.get(pk=device_id)
+ if device.group is None:
messages.error(request, _('Device does not have a group, please fix that'))
- return redirect('devapp:fix_device_group', dev.pk)
- ports = Port.objects.filter(device=dev).annotate(num_abons=Count('abon'))
+ return redirect('devapp:fix_device_group', device.pk)
+ ports = Port.objects.filter(device=device).annotate(num_abons=Count('abon'))
except Device.DoesNotExist:
messages.error(request, _('Device does not exist'))
@@ -177,7 +178,7 @@ def manage_ports(request, device_id):
messages.error(request, e)
return render(request, 'devapp/manage_ports/list.html', {
'ports': ports,
- 'dev': dev
+ 'dev': device
})
@@ -224,12 +225,12 @@ def add_ports(request, device_id):
def __str__(self):
return "p:%d\tT:%s" % (self.pid, self.text)
+ device = get_object_or_404(Device, pk=device_id)
+ res_ports = list()
try:
- res_ports = list()
- dev = Device.objects.get(pk=device_id)
- if dev.group is None:
+ if device.group is None:
messages.error(request, _('Device does not have a group, please fix that'))
- return redirect('devapp:fix_device_group', dev.pk)
+ return redirect('devapp:fix_device_group', device.pk)
if request.method == 'POST':
ports = zip(
request.POST.getlist('p_text'),
@@ -239,20 +240,20 @@ def add_ports(request, device_id):
if port_text == '' or port_text is None:
continue
try:
- port = Port.objects.get(num=port_num, device=dev)
+ port = Port.objects.get(num=port_num, device=device)
port.descr = port_text
port.save(update_fields=('descr',))
except Port.DoesNotExist:
Port.objects.create(
num=port_num,
- device=dev,
+ device=device,
descr=port_text
)
- db_ports = Port.objects.filter(device=dev)
+ db_ports = Port.objects.filter(device=device)
db_ports = tuple(TempPort(p.num, p.descr, None, True, p.pk) for p in db_ports)
- manager = dev.get_manager_object()
+ manager = device.get_manager_object()
ports = manager.get_ports()
if ports is not None:
ports = tuple(TempPort(p.num, p.nm, p.st, False) for p in ports)
@@ -269,7 +270,7 @@ def add_ports(request, device_id):
messages.error(request, _('wait for a reply from the SNMP Timeout'))
return render(request, 'devapp/manage_ports/add_ports.html', {
'ports': res_ports,
- 'dev': dev
+ 'dev': device
})
@@ -356,30 +357,30 @@ def add_single_port(request, group_id, device_id):
@permission_required('devapp.can_view_device')
def devview(request, device_id):
ports, manager = None, None
- dev = get_object_or_404(Device, id=device_id)
+ device = get_object_or_404(Device, id=device_id)
- if not dev.group:
+ if not device.group:
messages.warning(request, _('Please attach group for device'))
- return redirect('devapp:fix_device_group', dev.pk)
+ return redirect('devapp:fix_device_group', device.pk)
template_name = 'ports.html'
try:
- if dev.ip_address:
- if not ping(dev.ip_address):
+ if device.ip_address:
+ if not ping(device.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):
+ if device.man_passw:
+ manager = device.get_manager_object()
+ ports = tuple(manager.get_ports())
+ if ports is not None and 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'))
return render(request, 'devapp/custom_dev_page/' + template_name, {
- 'dev': dev,
+ 'dev': device,
'ports': ports,
- 'dev_accs': Abon.objects.filter(device=dev),
+ 'dev_accs': Abon.objects.filter(device=device),
'dev_manager': manager
})
except EasySNMPError as e:
@@ -387,21 +388,34 @@ def devview(request, device_id):
except (DeviceDBException, DeviceImplementationError) as e:
messages.error(request, e)
return render(request, 'devapp/custom_dev_page/' + template_name, {
- 'dev': dev
+ 'dev': device
+ })
+
+
+@login_required
+def zte_port_view(request, group_id: str, device_id: str, fiber_id: str):
+ fiber_id = safe_int(fiber_id)
+ zte_olt_device = get_object_or_404(Device, id=device_id)
+ manager = zte_olt_device.get_manager_object()
+ onu_list = manager.get_ports_on_fiber(fiber_id)
+ return render(request, 'devapp/custom_dev_page/olt_ztec320_ports.html', {
+ 'onu_list': onu_list,
+ 'dev': zte_olt_device,
+ 'grp': group_id
})
@login_required
@permission_required('devapp.can_toggle_ports')
-def toggle_port(request, device_id, portid, status=0):
+def toggle_port(request, device_id: int, portid: int, status=0):
portid = int(portid)
status = int(status)
- dev = get_object_or_404(Device, id=int(device_id))
+ device = get_object_or_404(Device, id=int(device_id))
try:
- if ping(dev.ip_address):
- if dev.man_passw:
- manager = dev.get_manager_object()
- ports = manager.get_ports()
+ if ping(device.ip_address):
+ if device.man_passw:
+ manager = device.get_manager_object()
+ ports = tuple(manager.get_ports())
if status:
ports[portid - 1].enable()
else:
@@ -414,7 +428,7 @@ def toggle_port(request, device_id, portid, status=0):
messages.error(request, _('wait for a reply from the SNMP Timeout'))
except EasySNMPError as e:
messages.error(request, 'EasySNMPError: %s' % e)
- return redirect('devapp:view', dev.group.pk if dev.group is not None else 0, device_id)
+ return redirect('devapp:view', device.group.pk if device.group is not None else 0, device_id)
@method_decorator((login_required, only_admins), name='dispatch')
@@ -440,14 +454,16 @@ def search_dev(request):
results = Device.objects.filter(
Q(comment__icontains=word) | Q(ip_address=word)
).only('pk', 'ip_address', 'comment')[:16]
- 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)
+ results = ({
+ 'id': device.pk,
+ 'text': "%s: %s" % (device.ip_address or '', device.comment)
+ } for device in results)
return results
@login_required
def fix_device_group(request, device_id):
- dev = get_object_or_404(Device, pk=device_id)
+ device = get_object_or_404(Device, pk=device_id)
try:
if request.method == 'POST':
frm = DeviceForm(request.POST, instance=dev)
@@ -466,8 +482,8 @@ def fix_device_group(request, device_id):
return HttpResponse('ValueError')
return render(request, 'devapp/fix_dev_group.html', {
'form': frm,
- 'dev': dev,
- 'selected_parent_dev': dev.parent_dev
+ 'dev': device,
+ 'selected_parent_dev': device.parent_dev
})
@@ -594,25 +610,25 @@ class NagiosObjectsConfView(global_base_views.AuthenticatedOrHashAuthView):
def norm_name(name: str, replreg=re.compile(r'\W{1,255}', re.IGNORECASE)):
return replreg.sub('', name)
- for dev in Device.objects.exclude(Q(mac_addr=None) | Q(ip_address='127.0.0.1')) \
+ for device in Device.objects.exclude(Q(mac_addr=None) | Q(ip_address='127.0.0.1')) \
.select_related('parent_dev') \
.only('ip_address', 'comment', 'parent_dev'):
- host_name = norm_name("%d%s" % (dev.pk, translit(dev.comment, language_code='ru', reversed=True)))
+ host_name = norm_name("%d%s" % (device.pk, translit(device.comment, language_code='ru', reversed=True)))
conf = None
- mac_addr = dev.mac_addr
- if dev.devtype == 'On':
- if dev.parent_dev:
- host_addr = dev.parent_dev.ip_address
- conf = self.templ_onu(host_name, host_addr, mac=mac_addr, snmp_item=dev.snmp_item_num or None)
+ mac_addr = device.mac_addr
+ if device.devtype == 'On':
+ if device.parent_dev:
+ host_addr = device.parent_dev.ip_address
+ conf = self.templ_onu(host_name, host_addr, mac=mac_addr, snmp_item=device.snmp_item_num or None)
else:
- if dev.ip_address:
- host_addr = dev.ip_address
- conf = self.templ_onu(host_name, host_addr, mac=mac_addr, snmp_item=dev.snmp_item_num or None)
+ if device.ip_address:
+ host_addr = device.ip_address
+ conf = self.templ_onu(host_name, host_addr, mac=mac_addr, snmp_item=device.snmp_item_num or None)
else:
parent_host_name = norm_name("%d%s" % (
- dev.parent_dev.pk, translit(dev.parent_dev.comment, language_code='ru', reversed=True)
- )) if dev.parent_dev else None
- conf = self.templ(host_name, host_addr=dev.ip_address, mac=mac_addr, parent_host_name=parent_host_name)
+ device.parent_dev.pk, translit(device.parent_dev.comment, language_code='ru', reversed=True)
+ )) if device.parent_dev else None
+ conf = self.templ(host_name, host_addr=device.ip_address, mac=mac_addr, parent_host_name=parent_host_name)
if conf is not None:
confs.append(conf)
response = HttpResponse(''.join(confs), content_type='text/plain')