Browse Source

add OLT ZTE support

devel
bashmak 8 years ago
parent
commit
66b2536d8d
  1. 3
      accounts_app/views.py
  2. 89
      devapp/dev_types.py
  3. 3
      devapp/forms.py
  4. 3
      devapp/models.py
  5. 44
      devapp/templates/devapp/custom_dev_page/olt_ztec320.html
  6. 60
      devapp/templates/devapp/custom_dev_page/olt_ztec320_ports.html
  7. 22
      devapp/templates/devapp/ext.htm
  8. 3
      devapp/urls.py
  9. 128
      devapp/views.py

3
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,

89
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'

3
devapp/forms.py

@ -25,8 +25,7 @@ class DeviceForm(forms.ModelForm):
}),
'comment': forms.TextInput(attrs={
'required': True
}),
'man_passw': forms.PasswordInput(render_value=True)
})
}

3
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))

44
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 %}
<div class="row">
<div class="col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">
{% with uptime=dev_manager.uptime %}
{% if uptime %}
<h3 class="panel-title">{% trans 'Uptime' %} {{ uptime }}</h3>
{% endif %}
{% endwith %}
</div>
<div class="panel-body">
{% with grp=dev.group.pk mng=dev_manager %}
{% for fiber in dev_manager.get_fibers %}
<div class="port{% if fiber.fb_onu_num > 0 %} mega{% endif %} text-center">
<b>{{ fiber.fb_name }}</b>
{% if fiber.fb_onu_num > 0 %}
<a href="{% url 'devapp:zte_port_view' grp dev.id fiber.fb_id %}" class="port-img">
<b>{{ fiber.fb_onu_num }}</b>
</a>
{% else %}
<a href="#" class="port-img">
<b>0</b>
</a>
{% endif %}
</div>
{% empty %}
<h3>{% trans 'We have not received info, please check options :(' %}</h3>
{% endfor %}
</div>
<div class="panel-footer">
<b>{% trans 'Long description' %}</b>: {{ mng.get_long_description }}<br>
<b>{% trans 'Hostname' %}</b>: {{ mng.get_hostname }}.
</div>
{% endwith %}
</div>
</div>
</div>
{% endblock %}

60
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 %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'devapp:group_list' %}">{% trans 'Groups' %}</a></li>
{% if dev.group %}
<li><a href="{% url 'devapp:devs' dev.group.pk %}">{{ dev.group.title }}</a></li>
<li><a href="{% url 'devapp:view' dev.group.pk dev.id %}">{{ dev.comment }}</a></li>
{% else %}
<li>{% trans 'Not assigned' %}</li>
<li><a href="#">{{ dev.comment }}</a></li>
{% endif %}
<li class="active">{% trans 'OLT Scan' %}</li>
</ol>
{% endblock %}
{% block content %}
<div class="row">
<div class="col-sm-12">
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th class="col-xs-1">#</th>
<th class="col-xs-2">{% trans 'Onu type' %}</th>
<th class="col-xs-3">{% trans 'Onu port' %}</th>
<th class="col-xs-3">{% trans 'Onu signal' %}</th>
<th class="col-xs-2">{% trans 'Serial' %}</th>
<th class="col-xs-1">#</th>
</tr>
</thead>
<tbody>
{% for onu in onu_list %}
<tr>
<td>-
</td>
<td>{{ onu.onu_type }}</td>
<td>{{ onu.onu_port }}</td>
<td>{{ onu.onu_signal }}</td>
<td>{{ onu.onu_sn }}</td>
<td>
<a href="{% url 'devapp:add' grp %}?t=On&pdev={{ dev.pk }}&c={{ onu.onu_sn }}" title="{% trans 'Create device' %}">
<span class="glyphicon glyphicon-plus"></span>
</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="7">{% trans 'ONU not found' %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}

22
devapp/templates/devapp/ext.htm

@ -2,16 +2,18 @@
{% load i18n %}
{% block main %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'devapp:group_list' %}">{% trans 'Groups' %}</a></li>
{% if dev.group %}
<li><a href="{% url 'devapp:devs' dev.group.pk %}">{{ dev.group.title }}</a></li>
{% else %}
<li>{% trans 'Not assigned' %}</li>
{% endif %}
<li class="active">{{ dev.comment }}</li>
</ol>
{% block breadcrumb %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'devapp:group_list' %}">{% trans 'Groups' %}</a></li>
{% if dev.group %}
<li><a href="{% url 'devapp:devs' dev.group.pk %}">{{ dev.group.title }}</a></li>
{% else %}
<li>{% trans 'Not assigned' %}</li>
{% endif %}
<li class="active">{{ dev.comment }}</li>
</ol>
{% endblock %}
{% include 'message_block.html' %}

3
devapp/urls.py

@ -25,6 +25,9 @@ urlpatterns = [
url(r'^fix_device_group/(?P<device_id>\d+)$', views.fix_device_group, name='fix_device_group'),
url(r'^search_dev$', views.search_dev),
# ZTE ports under fibers
url(r'^(?P<group_id>\d+)/(?P<device_id>\d+)/(?P<fiber_id>\d+)$', views.zte_port_view, name='zte_port_view'),
# Monitoring api
url(r'^on_device_event/$', views.OnDeviceMonitoringEvent.as_view()),

128
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')

Loading…
Cancel
Save