Browse Source

Реализовал работу с устройствами. Их можно будет привязать абоненту, и авторизовывать абонентов через устройство

devel
bashmak 9 years ago
parent
commit
ccc1db65e9
  1. 10
      devapp/base_intr.py
  2. 58
      devapp/dev_types.py
  3. 37
      devapp/forms.py
  4. 55
      devapp/locale/ru/LC_MESSAGES/django.po
  5. 14
      devapp/templates/devapp/add_dev.html
  6. 15
      devapp/templates/devapp/custom_dev_page/olt.html
  7. 33
      devapp/templates/devapp/custom_dev_page/onu.html
  8. 5
      devapp/templates/devapp/custom_dev_page/ports.html
  9. 9
      devapp/templates/devapp/dev.html
  10. 20
      devapp/templates/devapp/devices.html
  11. 4
      devapp/templates/devapp/devices_null_group.html
  12. 11
      devapp/templates/devapp/ext.htm
  13. 89
      devapp/templates/devapp/manage_ports/add_ports.html
  14. 60
      devapp/templates/devapp/manage_ports/list.html
  15. 37
      devapp/templates/devapp/manage_ports/modal_add_edit_port.html
  16. 18
      devapp/templates/devapp/manage_ports/modal_del_port.html
  17. 11
      devapp/urls.py
  18. 205
      devapp/views.py

10
devapp/base_intr.py

@ -28,6 +28,16 @@ class DevBase(object, metaclass=ABCMeta):
def get_template_name(self): def get_template_name(self):
"""Получаем путь к html шаблону отображения устройства""" """Получаем путь к html шаблону отображения устройства"""
@staticmethod
@abstractmethod
def has_attachable_to_subscriber():
"""Можно-ли подключать устройство к абоненту"""
@staticmethod
@abstractmethod
def is_use_device_port():
"""True если при авторизации по opt82 используется порт"""
class BasePort(object, metaclass=ABCMeta): class BasePort(object, metaclass=ABCMeta):
def __init__(self, num, name, status, mac, speed): def __init__(self, num, name, status, mac, speed):

58
devapp/dev_types.py

@ -83,13 +83,21 @@ class DLinkDevice(DevBase, SNMPBaseWorker):
return tm return tm
def get_template_name(self): def get_template_name(self):
return 'devapp/ports.html'
return 'ports.html'
@staticmethod
def has_attachable_to_subscriber():
return True
@staticmethod
def is_use_device_port():
return True
class ONUdev(BasePort): class ONUdev(BasePort):
def __init__(self, num, name, status, mac, speed, signal, snmpWorker): def __init__(self, num, name, status, mac, speed, signal, snmpWorker):
BasePort.__init__(self, num, name, status, mac, speed)
assert issubclass(snmpWorker.__class__ , SNMPBaseWorker)
super(ONUdev, self).__init__(num, name, status, mac, speed)
assert issubclass(snmpWorker.__class__, SNMPBaseWorker)
self.snmp_worker = snmpWorker self.snmp_worker = snmpWorker
self.signal = signal self.signal = signal
@ -113,7 +121,7 @@ class OLTDevice(DevBase, SNMPBaseWorker):
@staticmethod @staticmethod
def description(): def description():
return _('PON ONU')
return _('PON OLT')
def reboot(self): def reboot(self):
pass pass
@ -146,10 +154,42 @@ class OLTDevice(DevBase, SNMPBaseWorker):
return tm return tm
def get_template_name(self): def get_template_name(self):
return 'devapp/olt.html'
return 'olt.html'
@staticmethod
def has_attachable_to_subscriber():
return False
DEVICE_TYPES = (
('Dl', DLinkDevice),
('Pn', OLTDevice)
)
@staticmethod
def is_use_device_port():
return False
class OnuDevice(DevBase, SNMPBaseWorker):
@staticmethod
def description():
return _('PON ONU')
def reboot(self):
pass
def get_ports(self):
pass
def get_device_name(self):
pass
def uptime(self):
pass
def get_template_name(self):
return "onu.html"
@staticmethod
def has_attachable_to_subscriber():
return True
@staticmethod
def is_use_device_port():
return False

37
devapp/forms.py

@ -1,11 +1,23 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django import forms from django import forms
from django.utils.translation import ugettext as _
from django.db import IntegrityError
from . import models from . import models
from mydefs import ip_addr_regex from mydefs import ip_addr_regex
from djing import MAC_ADDR_REGEX
class DeviceForm(forms.ModelForm): class DeviceForm(forms.ModelForm):
mac_addr = forms.CharField(widget=forms.TextInput(attrs={
'pattern': MAC_ADDR_REGEX,
'required': True,
'class': 'form-control'
}), error_messages={
'required': _('Mac address is required for fill'),
'unique': _('Device with that mac is already exist')
})
class Meta: class Meta:
model = models.Device model = models.Device
fields = '__all__' fields = '__all__'
@ -13,7 +25,6 @@ class DeviceForm(forms.ModelForm):
'ip_address': forms.TextInput(attrs={ 'ip_address': forms.TextInput(attrs={
'pattern': ip_addr_regex, 'pattern': ip_addr_regex,
'placeholder': '192.168.0.100', 'placeholder': '192.168.0.100',
'required': True,
'class': 'form-control' 'class': 'form-control'
}), }),
'comment': forms.Textarea(attrs={ 'comment': forms.Textarea(attrs={
@ -33,3 +44,27 @@ class DeviceForm(forms.ModelForm):
'class': 'form-control' 'class': 'form-control'
}) })
} }
class PortForm(forms.ModelForm):
class Meta:
model = models.Port
exclude = ['device']
widgets = {
'num': forms.NumberInput(attrs={
'class': 'form-control',
'min': '0'
}),
'descr': forms.TextInput(attrs={
'class': 'form-control'
})
}
def save(self, commit=True):
try:
super(PortForm, self).save(commit)
except IntegrityError as e:
if "Duplicate entry" in str(e):
raise models.DeviceDBException(_('Port number on device must be unique'))
else:
raise models.DeviceDBException(e)

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

@ -32,7 +32,7 @@ msgid "does not fetch the mac"
msgstr "не нашёл мак" msgstr "не нашёл мак"
#: devapp/dev_types.py:116 #: devapp/dev_types.py:116
msgid "PON ONU"
msgid "PON OLT"
msgstr "ONU Голова" msgstr "ONU Голова"
#: devapp/templates/devapp/add_dev.html:7 #: devapp/templates/devapp/add_dev.html:7
@ -134,6 +134,9 @@ msgstr "Добавить группу"
msgid "Mac" msgid "Mac"
msgstr "Мак" msgstr "Мак"
msgid "Mac address"
msgstr "Мак адрес"
#: devapp/templates/devapp/olt.html:14 #: devapp/templates/devapp/olt.html:14
msgid "Name" msgid "Name"
msgstr "Имя" msgstr "Имя"
@ -148,7 +151,7 @@ msgstr "Ур. сигнала"
#: devapp/templates/devapp/olt.html:34 #: devapp/templates/devapp/olt.html:34
msgid "Ports not found" msgid "Ports not found"
msgstr "Онушки не получил"
msgstr "Порты не найдены"
#: devapp/templates/devapp/ports.html:9 #: devapp/templates/devapp/ports.html:9
msgid "Title of the type of switch" msgid "Title of the type of switch"
@ -194,6 +197,9 @@ msgstr "Комментарии портов"
msgid "Port" msgid "Port"
msgstr "Порт" msgstr "Порт"
msgid "Ports"
msgstr "Порты"
#: devapp/templates/devapp/ports.html:86 #: devapp/templates/devapp/ports.html:86
msgid "Title" msgid "Title"
msgstr "Название" msgstr "Название"
@ -232,3 +238,48 @@ msgstr "Ошибка SNMP на устройстве"
msgid "Edit" msgid "Edit"
msgstr "Редактировать" msgstr "Редактировать"
msgid "Device does not exist"
msgstr "Устойство не найдено"
msgid "Number"
msgstr "Номер"
msgid "Mode"
msgstr "Режим"
msgid "Add"
msgstr "Добавить"
msgid "Add ports"
msgstr "Добавить порты"
msgid "Device is not have a group, please fix that"
msgstr "У устройства нет группы, пожалуйста, исправьте это"
msgid "Delete"
msgstr "Удалить"
msgid "Port does not exist"
msgstr "Порт не найден"
msgid "Port successfully removed"
msgstr "Порт успешно удалён"
msgid "PON ONU"
msgstr "Онушка"
msgid "Are you sure that you want to delete switch port from db?"
msgstr "Вы уверены что хотите удалить порт свича из бд?"
msgid "Port successfully saved"
msgstr "Порт успешно сохранён"
msgid "Port number on device must be unique"
msgstr "Номер порта на устройстве должен быть уникальным"
msgid "Mac address is required for fill"
msgstr "MAC-адрес необходим для заполнения"
msgid "Device with that mac is already exist"
msgstr "Устройство с этим мак-адресом уже есть"

14
devapp/templates/devapp/add_dev.html

@ -5,13 +5,14 @@
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li> <li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'devapp:group_list' %}">{% trans 'Groups' %}</a></li> <li><a href="{% url 'devapp:group_list' %}">{% trans 'Groups' %}</a></li>
<li><a href="{% url 'devapp:devs' group.pk %}">{{ group.title }}</a></li>
<li class="active">{% trans 'Add new device' %}</li> <li class="active">{% trans 'Add new device' %}</li>
</ol> </ol>
{% include 'message_block.html' %} {% include 'message_block.html' %}
<div class="page-header"> <div class="page-header">
<h2>{{ dev.comment|default:_('Not assigned') }}</h2>
<h2>{{ group.title|default:_('Not assigned') }}</h2>
</div> </div>
<div class="panel panel-default"> <div class="panel panel-default">
@ -20,7 +21,7 @@
</div> </div>
<div class="panel-body"> <div class="panel-body">
<form role="form" action="{% url 'devapp:add' %}" method="post">{% csrf_token %}
<form role="form" action="{% url 'devapp:add' group.pk %}" method="post" autocomplete="off">{% csrf_token %}
<div class="form-group"> <div class="form-group">
<label for="id_ip_address">{% trans 'Ip address' %}</label> <label for="id_ip_address">{% trans 'Ip address' %}</label>
@ -31,6 +32,15 @@
</div> </div>
</div> </div>
<div class="form-group">
<label for="id_mac_addr">{% trans 'Mac address' %}</label>
<div class="input-group{% if form.mac_addr.errors %} has-error{% endif %}">
<span class="input-group-addon"><span class="glyphicon glyphicon-globe"></span></span>
{{ form.mac_addr }}{{ form.mac_addr.errors }}
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="id_comment">{% trans 'Comment' %}</label> <label for="id_comment">{% trans 'Comment' %}</label>

15
devapp/templates/devapp/olt.html → devapp/templates/devapp/custom_dev_page/olt.html

@ -2,38 +2,45 @@
{% load i18n %} {% load i18n %}
{% block content %} {% block content %}
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped table-bordered"> <table class="table table-striped table-bordered">
<thead> <thead>
<tr> <tr>
<th width="50">#</th>
<th width="10">#</th>
<th>{% trans 'Mac' %}</th> <th>{% trans 'Mac' %}</th>
<th>{% trans 'Name' %}</th> <th>{% trans 'Name' %}</th>
<th>{% trans 'Distance(m)' %}</th> <th>{% trans 'Distance(m)' %}</th>
<th width="250">{% trans 'Signal' %}</th> <th width="250">{% trans 'Signal' %}</th>
<th width="10">#</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% with dip=dev.ip_address grp=dev.user_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-remove text-danger"></span>
{% else %}<span class="glyphicon glyphicon-warning-sign text-danger"></span>
{% endif %} {% endif %}
</td> </td>
<td>{{ port.mac }}</td> <td>{{ port.mac }}</td>
<td>{{ port.nm }}</td> <td>{{ port.nm }}</td>
<td>{{ port.sp }}</td> <td>{{ port.sp }}</td>
<td>{{ port.signal }}</td> <td>{{ port.signal }}</td>
<td>
<a href="{% url 'devapp:add' grp %}?mac={{ port.mac }}&t=On&c={{ port.nm }}&ip={{ dip }}" title="Создать устройство">
<span class="glyphicon glyphicon-plus"></span>
</a>
</td>
</tr> </tr>
{% empty %} {% empty %}
<tr> <tr>
<td colspan="5">{% trans 'Ports not found' %}</td>
<td colspan="6">{% trans 'Ports not found' %}</td>
</tr> </tr>
{% endfor %} {% endfor %}
{% endwith %}
</tbody> </tbody>
</table> </table>

33
devapp/templates/devapp/custom_dev_page/onu.html

@ -0,0 +1,33 @@
{% 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">
<div class="panel-title">{{ dev.get_devtype_display|default:_('Title of the type of switch') }}.
{% if uptime %}
{% trans 'Uptime' %} {{ uptime }}
{% endif %}
</div>
</div>
<div class="panel-body">
<ul class="list-group">
<li class="list-group-item">{{ dev.ip_address }}</li>
<li class="list-group-item">{{ dev.mac_addr }}</li>
<li class="list-group-item"> {{ dev.comment }}</li>
{% for da in dev_accs %}
{% if da.group %}
<li class="list-group-item"><a href="{% url 'abonapp:abon_home' da.group.pk da.pk %}" target="_blank">{{ da.get_full_name }}</a></li>
{% else %}
<li class="list-group-item">{{ da.get_full_name }}</li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
{% endblock %}

5
devapp/templates/devapp/ports.html → devapp/templates/devapp/custom_dev_page/ports.html

@ -7,7 +7,10 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<div class="panel-title">{{ dev.get_devtype_display|default:_('Title of the type of switch') }}. <div class="panel-title">{{ dev.get_devtype_display|default:_('Title of the type of switch') }}.
{% trans 'Uptime' %} {{ uptime }}</div>
{% if uptime %}
{% trans 'Uptime' %} {{ uptime }}
{% endif %}
</div>
</div> </div>
<div class="panel-body"> <div class="panel-body">

9
devapp/templates/devapp/dev.html

@ -19,6 +19,15 @@
</div> </div>
</div> </div>
<div class="form-group">
<label for="id_mac_addr">{% trans 'Mac address' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-globe"></span></span>
{{ form.mac_addr }}{{ form.mac_addr.errors }}
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="id_comment">{% trans 'Comment' %}</label> <label for="id_comment">{% trans 'Comment' %}</label>

20
devapp/templates/devapp/devices.html

@ -27,6 +27,7 @@
</a> </a>
{% if order_by == 'comment' %}<span class="glyphicon glyphicon-filter"></span>{% endif %} {% if order_by == 'comment' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th> </th>
<th>{% trans 'Mac address' %}</th>
<th width="250"> <th width="250">
<a href="{% url 'devapp:devs' group.pk %}?order_by=devtype&dir={{ dir|default:"down" }}"> <a href="{% url 'devapp:devs' group.pk %}?order_by=devtype&dir={{ dir|default:"down" }}">
{% trans 'Device type' %} {% trans 'Device type' %}
@ -38,19 +39,21 @@
</thead> </thead>
<tbody> <tbody>
{% with can_del_dev=perms.devapp.delete_device can_ch_dev=perms.devapp.change_device %}
{% for dev in devices %} {% for dev in devices %}
<tr> <tr>
<td><a href="{% url 'devapp:view' dev.user_group.pk|default:0 dev.pk %}">{{ dev.ip_address }}</a></td>
<td><a href="{% url 'devapp:view' dev.user_group.pk dev.pk %}">{{ dev.ip_address }}</a></td>
<td>{{ dev.comment }}</td> <td>{{ dev.comment }}</td>
<td>{{ dev.mac_addr }}</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">
{% if perms.devapp.delete_device %}
<a href="{% url 'devapp:del' dev.user_group.pk|default:0 dev.pk %}" class="btn btn-default btn-sm">
{% if can_del_dev %}
<a href="{% url 'devapp:del' dev.user_group.pk dev.pk %}" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-remove"></span> <span class="glyphicon glyphicon-remove"></span>
</a> </a>
{% endif %} {% endif %}
{% if perms.devapp.change_device %}
<a href="{% url 'devapp:edit' dev.user_group.pk|default:0 dev.id %}" class="btn btn-default btn-sm">
{% if can_ch_dev %}
<a href="{% url 'devapp:edit' dev.user_group.pk dev.id %}" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-edit"></span> <span class="glyphicon glyphicon-edit"></span>
</a> </a>
{% endif %} {% endif %}
@ -58,15 +61,16 @@
</tr> </tr>
{% empty %} {% empty %}
<tr> <tr>
<td colspan="4">{% trans 'Devices does not found' %}. <a href="{% url 'devapp:add' %}">{% trans 'Create' %}</a></td>
<td colspan="5">{% trans 'Devices does not found' %}. <a href="{% url 'devapp:add' group.pk %}">{% trans 'Create' %}</a></td>
</tr> </tr>
{% endfor %} {% endfor %}
{% endwith %}
</tbody> </tbody>
<tfoot> <tfoot>
<tr> <tr>
<td colspan="4">
<a href="{% url 'devapp:add' %}" class="btn btn-success btn-sm">
<td colspan="5">
<a href="{% url 'devapp:add' group.pk %}" class="btn btn-success btn-sm">
<span class="glyphicon glyphicon-plus"></span> {% trans 'Create' %} <span class="glyphicon glyphicon-plus"></span> {% trans 'Create' %}
</a> </a>
</td> </td>

4
devapp/templates/devapp/devices_null_group.html

@ -58,7 +58,7 @@
</tr> </tr>
{% empty %} {% empty %}
<tr> <tr>
<td colspan="4">{% trans 'Devices does not found' %}. <a href="{% url 'devapp:add' %}">{% trans 'Create' %}</a></td>
<td colspan="4">{% trans 'Devices does not found' %}. <a href="{% url 'devapp:add' 0 %}">{% trans 'Create' %}</a></td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@ -66,7 +66,7 @@
<tfoot> <tfoot>
<tr> <tr>
<td colspan="4"> <td colspan="4">
<a href="{% url 'devapp:add' %}" class="btn btn-success btn-sm">
<a href="{% url 'devapp:add' 0 %}" class="btn btn-success btn-sm">
<span class="glyphicon glyphicon-plus"></span> {% trans 'Create' %} <span class="glyphicon glyphicon-plus"></span> {% trans 'Create' %}
</a> </a>
</td> </td>

11
devapp/templates/devapp/ext.htm

@ -21,7 +21,7 @@
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
{% url 'devapp:view' dev.user_group.pk|default:0 dev.id as devapp_view %}
{% url 'devapp:view' dev.user_group.pk|default:0 dev.pk as devapp_view %}
<li{% if devapp_view == request.path %} class="active"{% endif %}> <li{% if devapp_view == request.path %} class="active"{% endif %}>
<a href="{{ devapp_view }}"> <a href="{{ devapp_view }}">
{% trans 'Ports' %} {{ dev.ip_address }} {% trans 'Ports' %} {{ dev.ip_address }}
@ -29,10 +29,15 @@
</li> </li>
{% if perms.devapp.change_device %} {% if perms.devapp.change_device %}
{% url 'devapp:edit' dev.user_group.pk|default:0 dev.id as devapp_edit %}
{% url 'devapp:edit' dev.user_group.pk|default:0 dev.pk as devapp_edit %}
<li{% if devapp_edit == request.path %} class="active"{% endif %}> <li{% if devapp_edit == request.path %} class="active"{% endif %}>
<a href="{{ devapp_edit }}">{% trans 'Edit' %}</a> <a href="{{ devapp_edit }}">{% trans 'Edit' %}</a>
</li> </li>
{% url 'devapp:manage_ports' dev.user_group.pk|default:0 dev.pk as devapp_mports %}
<li{% if devapp_mports == request.path %} class="active"{% endif %}>
<a href="{{ devapp_mports }}">{% trans 'Ports' %}</a>
</li>
{% endif %} {% endif %}
</ul> </ul>
@ -42,4 +47,4 @@
</div> </div>
</div> </div>
{% endblock %}
{% endblock %}

89
devapp/templates/devapp/manage_ports/add_ports.html

@ -0,0 +1,89 @@
{% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% 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>
<li><a href="{% url 'devapp:devs' dev.user_group.pk %}">{{ dev.user_group.title }}</a></li>
<li><a href="{% url 'devapp:view' dev.user_group.pk dev.pk %}">{{ dev.comment }}</a></li>
<li class="active">{% trans 'Add ports' %}</li>
</ol>
{% include 'message_block.html' %}
<div class="page-header">
<h2>{{ dev.comment|default:_('Not assigned') }}</h2>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{ dev.comment }}</h3>
</div>
<div class="panel-body">
<form class="table-responsive" role="form" action="{% url 'devapp:add_ports' dev.user_group.pk dev.pk %}" method="post">{% csrf_token %}
<table class="table table-striped table-bordered">
<thead>
<tr>
<th width="10">#</th>
<th></th>
<th>{% trans 'Mode' %}</th>
<th>{% trans 'Description' %}</th>
</tr>
</thead>
<tbody>
{% with gid=dev.user_group.pk did=dev.pk can_del_port=perms.devapp.delete_port %}
{% for port in ports %}
<tr>
<td>{% if port.status %}
<span class="glyphicon glyphicon-ok text-success"></span>
{% else %}
<span class="glyphicon glyphicon-warning-sign text-danger"></span>
{% endif %}</td>
<td>{{ port.pid }}</td>
<td>{{ port.mode }}</td>
<td class="input-group">
<input type="text" class="form-control input-sm" name="p_text" value="{{ port.text }}">
<input type="hidden" name="pids" value="{{ port.pid }}">
<span class="input-group-btn">
{% if port.from_db %}
{% if can_del_port %}
<a href="{% url 'devapp:del_port' gid did port.pk %}" class="btn btn-sm btn-danger btn-modal" title="{% trans 'Delete' %}">
{% else %}
<a href="#" class="btn btn-danger btn-sm disabled" title="{% trans 'Delete' %}">
{% endif %}
<span class="glyphicon glyphicon-remove"></span>
</a>
{% else %}
<a href="{% url 'devapp:add_port' gid did %}?n={{ port.pid }}&t={{ port.text }}" class="btn btn-sm btn-success btn-modal" title="{% trans 'Add' %}">
<span class="glyphicon glyphicon-plus"></span>
</a>
{% endif %}
</span>
</td>
</tr>
{% endfor %}
{% endwith %}
</tbody>
<tfoot>
<tr>
<td colspan="4" class="btn-group">
{% if perms.devapp.add_port %}
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-save"></span> {% trans 'Save' %}
</button>
{% endif %}
</td>
</tr>
</tfoot>
</table>
</form>
</div>
</div>
{% endblock %}

60
devapp/templates/devapp/manage_ports/list.html

@ -0,0 +1,60 @@
{% extends request.is_ajax|yesno:'nullcont.htm,devapp/ext.htm' %}
{% load i18n %}
{% block content %}
<div class="row">
<div class="col-sm-12">
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th width="50">{% trans 'Number' %}</th>
<th>{% trans 'Description' %}</th>
<th width="100">#</th>
</tr>
</thead>
<tbody>
{% with gid=dev.user_group.pk did=dev.pk can_del_port=perms.devapp.delete_port can_edit_port=perms.devapp.change_port %}
{% for port in ports %}
<tr>
<td>{{ port.num }}</td>
<td>{{ port.descr }}</td>
<td class="btn-group btn-group-sm">
{% if can_del_port %}
<a href="{% url 'devapp:del_port' gid did port.pk %}" class="btn btn-danger btn-modal" title="{% trans 'Delete' %}">
<span class="glyphicon glyphicon-remove-circle"></span>
</a>
{% endif %}
{% if can_edit_port %}
<a href="{% url 'devapp:edit_port' gid did port.pk %}" class="btn btn-primary btn-modal" title="{% trans 'Edit' %}">
<span class="glyphicon glyphicon-edit"></span>
</a>
{% endif %}
</td>
</tr>
{% empty %}
<tr>
<td colspan="3">{% trans 'Ports not found' %}</td>
</tr>
{% endfor %}
{% endwith %}
</tbody>
<tfoot>
<tr>
<td colspan="3" class="btn-group">
{% if perms.devapp.add_port %}
<a href="{% url 'devapp:add_ports' dev.user_group.pk dev.pk %}" class="btn btn-sm btn-default" title="{% trans 'Add' %}">
<span class="glyphicon glyphicon-plus"></span> {% trans 'Add ports' %}
</a>
{% endif %}
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
{% endblock %}

37
devapp/templates/devapp/manage_ports/modal_add_edit_port.html

@ -0,0 +1,37 @@
{% load i18n %}
{% if port_id %}
<form role="form" action="{% url 'devapp:edit_port' gid did port_id %}" method="post">{% else %}
<form role="form" action="{% url 'devapp:add_port' gid did %}" method="post">{% endif %}{% csrf_token %}
<input type="hidden" value="yes" name="confirm">
<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 'Are you sure?' %}</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="id_num">{% trans 'Number' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-bishop"></span></span>
{{ form.num }}{{ form.num.errors }}
</div>
</div>
<div class="form-group">
<label for="id_descr">{% trans 'Description' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span>
{{ form.descr }}{{ form.descr.errors }}
</div>
</div>
<button type="submit" class="btn btn-sm btn-primary">
<span class="glyphicon glyphicon-save"></span> {% trans 'Save' %}
</button>
</div>
</form>

18
devapp/templates/devapp/manage_ports/modal_del_port.html

@ -0,0 +1,18 @@
{% load i18n %}
<form role="form" action="{% url 'devapp:del_port' grp did port_id %}" method="post">{% csrf_token %}
<input type="hidden" value="yes" name="confirm">
<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 'Are you sure?' %}</h4>
</div>
<div class="modal-body">
<p>{% trans 'Are you sure that you want to delete switch port from db?' %}</p>
<button type="submit" class="btn btn-sm btn-danger">
<span class="glyphicon glyphicon-remove"></span> {% trans 'Delete' %}
</button>
</div>
</form>

11
devapp/urls.py

@ -5,11 +5,16 @@ from . import views
urlpatterns = [ urlpatterns = [
url(r'^$', views.group_list, name='group_list'), url(r'^$', views.group_list, name='group_list'),
url(r'^add$', views.dev, name='add'),
url(r'^devices_without_groups$', views.devices_null_group, name='devices_null_group'), url(r'^devices_without_groups$', views.devices_null_group, name='devices_null_group'),
url(r'^(?P<grp>\d+)$', views.devices, name='devs'), url(r'^(?P<grp>\d+)$', views.devices, name='devs'),
url(r'^(?P<grp>\d+)/add$', views.dev, name='add'),
url(r'^(\d+)/(?P<did>\d+)$', views.devview, name='view'), url(r'^(\d+)/(?P<did>\d+)$', views.devview, name='view'),
url(r'^(\d+)/(?P<did>\d+)/del$', views.devdel, name='del'), url(r'^(\d+)/(?P<did>\d+)/del$', views.devdel, name='del'),
url(r'^(\d+)/(?P<devid>\d+)/edit$', views.dev, name='edit'),
url(r'^(\d+)/(?P<did>\d+)/(?P<portid>\d+)_(?P<status>[0-1]{1})$', views.toggle_port, name='port_toggle')
url(r'^(?P<grp>\d+)/(?P<did>\d+)/add$', views.add_single_port, name='add_port'),
url(r'^(?P<grp>\d+)/(?P<devid>\d+)/edit$', views.dev, name='edit'),
url(r'^(\d+)/(?P<devid>\d+)/ports$', views.manage_ports, name='manage_ports'),
url(r'^(\d+)/(?P<devid>\d+)/ports_add', views.add_ports, name='add_ports'),
url(r'^(\d+)/(?P<did>\d+)/(?P<portid>\d+)_(?P<status>[0-1]{1})$', views.toggle_port, name='port_toggle'),
url(r'^(?P<grp>\d+)/(?P<did>\d+)/(?P<portid>\d+)/del$', views.delete_single_port, name='del_port'),
url(r'^(?P<grp>\d+)/(?P<did>\d+)/(?P<pid>\d+)/edit$', views.edit_single_port, name='edit_port')
] ]

205
devapp/views.py

@ -1,15 +1,17 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.gis.shortcuts import render_to_text
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.shortcuts import render, redirect, get_object_or_404, resolve_url from django.shortcuts import render, redirect, get_object_or_404, resolve_url
from django.contrib import messages from django.contrib import messages
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from easysnmp import EasySNMPTimeoutError, EasySNMPError from easysnmp import EasySNMPTimeoutError, EasySNMPError
from .models import Device
from .models import Device, Port, DeviceDBException
from mydefs import pag_mn, res_success, res_error, only_admins, ping, order_helper from mydefs import pag_mn, res_success, res_error, only_admins, ping, order_helper
from .forms import DeviceForm
from abonapp.models import AbonGroup
from .forms import DeviceForm, PortForm
from abonapp.models import AbonGroup, Abon
from djing.settings import DEFAULT_SNMP_PASSWORD
@login_required @login_required
@ -61,12 +63,15 @@ def devdel(request, did):
return res_success(request, back_url) return res_success(request, back_url)
except Device.DoesNotExist: except Device.DoesNotExist:
return res_error(request, _('Delete failed')) return res_error(request, _('Delete failed'))
except DeviceDBException as e:
return res_error(request, e)
@login_required @login_required
@only_admins @only_admins
def dev(request, devid=0):
def dev(request, grp, devid=0):
devinst = get_object_or_404(Device, id=devid) if devid != 0 else None devinst = get_object_or_404(Device, id=devid) if devid != 0 else None
user_group = get_object_or_404(AbonGroup, pk=grp)
if request.method == 'POST': if request.method == 'POST':
if devid == 0: if devid == 0:
@ -79,14 +84,26 @@ def dev(request, devid=0):
if frm.is_valid(): if frm.is_valid():
frm.save() frm.save()
messages.success(request, _('Device info has been saved')) messages.success(request, _('Device info has been saved'))
return redirect('devapp:devs', grp)
else: else:
messages.error(request, _('Form is invalid, check fields and try again')) messages.error(request, _('Form is invalid, check fields and try again'))
else: else:
frm = DeviceForm(instance=devinst)
if devinst is None:
frm = DeviceForm(initial={
'user_group': user_group,
'devtype': request.GET.get('t'),
'mac_addr': request.GET.get('mac'),
'comment': request.GET.get('c'),
'ip_address': request.GET.get('ip'),
'man_passw': DEFAULT_SNMP_PASSWORD
})
else:
frm = DeviceForm(instance=devinst)
if devinst is None: if devinst is None:
return render(request, 'devapp/add_dev.html', { return render(request, 'devapp/add_dev.html', {
'form': frm
'form': frm,
'group': user_group
}) })
else: else:
return render(request, 'devapp/dev.html', { return render(request, 'devapp/dev.html', {
@ -95,14 +112,179 @@ def dev(request, devid=0):
}) })
@login_required
@permission_required('devapp.change_device')
def manage_ports(request, devid):
try:
dev = Device.objects.get(pk=devid)
if dev.user_group is None:
messages.error(request, _('Device is not have a group, please fix that'))
return redirect('devapp:group_list')
ports = Port.objects.filter(device=dev)
except Device.DoesNotExist:
messages.error(request, _('Device does not exist'))
return redirect('devapp:view', dev.user_group.pk if dev.user_group else 0, did=devid)
except DeviceDBException as e:
messages.error(request, e)
return render(request, 'devapp/manage_ports/list.html', {
'ports': ports,
'dev': dev
})
@login_required
@permission_required('devapp.add_port')
def add_ports(request, devid):
class TempPort:
def __init__(self, pid, text, status, from_db, pk=None):
self.pid = pid
self.text = text
self.status = status
self.from_db = from_db
self.pk = pk
def __eq__(self, other):
return self.pid == other.pid
def __hash__(self):
return self.pid
def __str__(self):
return "p:%d\tM:%s\tT:%s" % (self.pid, self.text)
try:
dev = Device.objects.get(pk=devid)
if dev.user_group is None:
messages.error(request, _('Device is not have a group, please fix that'))
return redirect('devapp:group_list')
if request.method == 'POST':
ports = zip(
request.POST.getlist('p_text'),
request.POST.getlist('pids')
)
for port_text, port_num in ports:
if port_text == '' or port_text is None:
continue
try:
port = Port.objects.get(num=port_num, device=dev)
port.descr = port_text
port.save(update_fields=['descr'])
except Port.DoesNotExist:
Port.objects.create(
num=port_num,
device=dev,
descr=port_text
)
db_ports = Port.objects.filter(device=dev)
db_ports = [TempPort(p.num, p.descr, None, True, p.pk) for p in db_ports]
manager = dev.get_manager_klass()(dev.ip_address, dev.man_passw)
ports = manager.get_ports()
if ports is not None:
ports = [TempPort(p.num, p.nm, p.st, False) for p in ports]
res_ports = set(db_ports + ports)
else:
res_ports = db_ports
except Device.DoesNotExist:
messages.error(request, _('Device does not exist'))
return redirect('devapp:group_list')
except DeviceDBException as e:
messages.error(request, e)
return render(request, 'devapp/manage_ports/add_ports.html', {
'ports': res_ports,
'dev': dev
})
@login_required
@permission_required('devapp.delete_port')
def delete_single_port(request, grp, did, portid):
try:
if request.method == 'POST':
if request.POST.get('confirm') == 'yes':
Port.objects.get(pk=portid).delete()
messages.success(request, _('Port successfully removed'))
else:
return render_to_text('devapp/manage_ports/modal_del_port.html', {
'grp': grp,
'did': did,
'port_id': portid
}, request=request)
except Port.DoesNotExist:
messages.error(request, _('Port does not exist'))
except DeviceDBException as e:
messages.error(request, e)
return redirect('devapp:manage_ports', grp, did)
@login_required
@permission_required('devapp.add_port')
def edit_single_port(request, grp, did, pid):
try:
port = Port.objects.get(pk=pid)
if request.method == 'POST':
frm = PortForm(request.POST, instance=port)
if frm.is_valid():
frm.save()
messages.success(request, _('Port successfully saved'))
else:
messages.error(request, _('Form is invalid, check fields and try again'))
return redirect('devapp:manage_ports', grp, did)
frm = PortForm(instance=port)
return render_to_text('devapp/manage_ports/modal_add_edit_port.html', {
'port_id': pid,
'did': did,
'gid': grp,
'form': frm
}, request=request)
except Port.DoesNotExist:
messages.error(request, _('Port does not exist'))
except DeviceDBException as e:
messages.error(request, e)
return redirect('devapp:manage_ports', grp, did)
@login_required
@permission_required('devapp.add_port')
def add_single_port(request, grp, did):
try:
device = Device.objects.get(pk=did)
if request.method == 'POST':
frm = PortForm(request.POST, instance=Port(device=device))
if frm.is_valid():
frm.save()
messages.success(request, _('Port successfully saved'))
return redirect('devapp:manage_ports', grp, did)
else:
messages.error(request, _('Form is invalid, check fields and try again'))
else:
frm = PortForm(initial={
'num': request.GET.get('n'),
'descr': request.GET.get('t')
})
return render_to_text('devapp/manage_ports/modal_add_edit_port.html', {
'did': did,
'gid': grp,
'form': frm
}, request=request)
except Device.DoesNotExist:
messages.error(request, _('Device does not exist'))
except DeviceDBException as e:
messages.error(request, e)
return redirect('devapp:manage_ports', grp, did)
@login_required @login_required
@only_admins @only_admins
def devview(request, did): def devview(request, did):
ports = None ports = None
uptime = 0 uptime = 0
dev = get_object_or_404(Device, id=did) dev = get_object_or_404(Device, id=did)
template_name = 'devapp/ports.html'
template_name = 'ports.html'
try: try:
if ping(dev.ip_address): if ping(dev.ip_address):
if dev.man_passw: if dev.man_passw:
@ -118,11 +300,14 @@ def devview(request, did):
messages.error(request, _('wait for a reply from the SNMP Timeout')) messages.error(request, _('wait for a reply from the SNMP Timeout'))
except EasySNMPError: except EasySNMPError:
messages.error(request, _('SNMP error on device')) messages.error(request, _('SNMP error on device'))
except DeviceDBException as e:
messages.error(request, e)
return render(request, template_name, {
return render(request, 'devapp/custom_dev_page/'+template_name, {
'dev': dev, 'dev': dev,
'ports': ports, 'ports': ports,
'uptime': uptime
'uptime': uptime,
'dev_accs': Abon.objects.filter(device=dev)
}) })

Loading…
Cancel
Save