Browse Source

Remove dhcp timeout in NAS

devel
bashmak 8 years ago
parent
commit
7033a1c8de
  1. 24
      abonapp/models.py
  2. 9
      agent/commands/dhcp.py
  3. 64
      agent/core.py
  4. 7
      devapp/templates/devapp/devices.html
  5. 3
      djing/local_settings.py.template
  6. 2
      djing/settings.py
  7. 2
      docs/install.md

24
abonapp/models.py

@ -247,7 +247,9 @@ class Abon(BaseAccount):
abon_tariff.delete()
# is subscriber have access to service, view in tariff_app.custom_tariffs.<TariffBase>.manage_access()
def is_access(self):
def is_access(self) -> bool:
if not self.is_active:
return False
abon_tariff = self.active_tariff()
if abon_tariff is None:
return False
@ -257,16 +259,15 @@ class Abon(BaseAccount):
# make subscriber from agent structure
def build_agent_struct(self):
if not self.is_access():
return
if self.ip_address:
user_ip = ip2int(self.ip_address)
else:
return
abon_tariff = self.active_tariff()
if abon_tariff is None:
agent_trf = None
else:
trf = abon_tariff.tariff
agent_trf = TariffStruct(trf.id, trf.speedIn, trf.speedOut)
trf = abon_tariff.tariff
agent_trf = TariffStruct(trf.id, trf.speedIn, trf.speedOut)
return AbonStruct(self.pk, user_ip, agent_trf, bool(self.is_active))
def save(self, *args, **kwargs):
@ -276,19 +277,16 @@ class Abon(BaseAccount):
raise LogicError(_('Ip address already exist'))
super(Abon, self).save(*args, **kwargs)
def sync_with_nas(self, created: bool) -> Optional[Union[Exception, bool]]:
timeout = 0
if hasattr(self, 'is_dhcp') and self.is_dhcp:
timeout = getattr(settings, 'DHCP_TIMEOUT', 14400)
def sync_with_nas(self, created: bool) -> Optional[Exception]:
agent_abon = self.build_agent_struct()
if agent_abon is None:
return True
return
try:
tm = Transmitter()
if created:
tm.add_user(agent_abon, ip_timeout=timeout)
tm.add_user(agent_abon)
else:
tm.update_user(agent_abon, ip_timeout=timeout)
tm.update_user(agent_abon)
except (NasFailedResult, NasNetworkError, ConnectionResetError) as e:
print('ERROR:', e)
return e

9
agent/commands/dhcp.py

@ -4,14 +4,15 @@ from abonapp.models import Abon
from devapp.models import Device, Port
def dhcp_commit(client_ip, client_mac, switch_mac, switch_port):
def dhcp_commit(client_ip: str, client_mac: str, switch_mac: str, switch_port: int) -> None:
try:
dev = Device.objects.get(mac_addr=switch_mac)
mngr_class = dev.get_manager_klass()
if mngr_class.is_use_device_port():
port = Port.objects.get(device=dev, num=switch_port)
abon = Abon.objects.get(dev_port=port, device=dev)
abon = Abon.objects.get(dev_port__device=dev,
dev_port__num=switch_port,
device=dev)
else:
abon = Abon.objects.get(device=dev)
if not abon.is_dynamic_ip:
@ -33,7 +34,7 @@ def dhcp_commit(client_ip, client_mac, switch_mac, switch_port):
'switch_mac': switch_mac
})
except MultipleObjectsReturned as e:
print('E:', 'MultipleObjectsReturned:', type(e), e, port, dev)
print('E:', 'MultipleObjectsReturned:', type(e), e, switch_port, dev)
def dhcp_expiry(client_ip):

64
agent/core.py

@ -1,96 +1,86 @@
# -*- coding: utf-8 -*-
from abc import ABCMeta, abstractmethod
from typing import Iterator, Any, Tuple
from typing import Iterator, Any, Tuple, Optional, Iterable
from .structs import AbonStruct, TariffStruct, VectorAbon, VectorTariff
# Всплывает если из NAS вернулся не удачный результат
# Raised if NAS has returned failed result
class NasFailedResult(Exception):
pass
# Всплывает когда нет связи с сервером доступа к инету (NAS)
# Raised when is no connection to the NAS
class NasNetworkError(Exception):
pass
# Общается с NAS'ом
# Communicate with NAS
class BaseTransmitter(metaclass=ABCMeta):
@abstractmethod
def add_user_range(self, user_list: VectorAbon):
"""добавляем список абонентов в NAS"""
"""add subscribers list to NAS"""
@abstractmethod
def remove_user_range(self, users: VectorAbon):
"""удаляем список абонентов"""
"""remove subscribers list"""
@abstractmethod
def add_user(self, user: AbonStruct, *args):
"""добавляем абонента"""
"""add subscriber"""
@abstractmethod
def remove_user(self, user: AbonStruct):
"""удаляем абонента"""
"""remove subscriber"""
@abstractmethod
def update_user(self, user: AbonStruct, *args):
"""чтоб обновить абонента можно изменить всё кроме его uid, по uid абонент будет найден"""
"""
Update subscriber by uid, you can change everything except its uid.
Subscriber will found by UID.
"""
@abstractmethod
def add_tariff_range(self, tariff_list: VectorTariff):
"""
Пока не используется, зарезервировано.
Добавляет список тарифов в NAS
"""
"""Add services list to NAS."""
@abstractmethod
def remove_tariff_range(self, tariff_list: VectorTariff):
"""
Пока не используется, зарезервировано.
Удаляем список тарифов по уникальным идентификаторам
"""
"""Remove tariff list by unique id list."""
@abstractmethod
def add_tariff(self, tariff: TariffStruct):
"""
Пока не используется, зарезервировано.
Добавляет тариф
"""
pass
@abstractmethod
def update_tariff(self, tariff: TariffStruct):
"""
Пока не используется, зарезервировано.
Чтоб обновить тариф надо изменить всё кроме его tid, по tid тариф будет найден
Update tariff by uid, you can change everything except its uid.
Tariff will found by UID.
"""
@abstractmethod
def remove_tariff(self, tid: int):
"""
:param tid: id тарифа в среде NAS сервера чтоб удалить по этому номеру
Пока не используется, зарезервировано.
:param tid: unique id of tariff.
"""
@abstractmethod
def ping(self, host: str, count=10):
def ping(self, host: str, count=10) -> Optional[Tuple[int, int]]:
"""
:param host: ip адрес в текстовом виде, например '192.168.0.1'
:param count: количество пингов
:return: None если не пингуется, иначе кортеж, в котором (сколько вернулось, сколько было отправлено)
:param host: ip address in text view, for example '192.168.0.1'
:param count: count of ping queries
:return: None if not response, else tuple it contains count returned and count sent
for example (received, sent) -> (7, 10).
"""
@abstractmethod
def read_users(self):
"""
Читаем пользователей с NAS
:return: список AbonStruct
"""
def read_users(self) -> Iterable[AbonStruct]:
pass
def _diff_users(self, users_from_db: Iterator[Any]) -> Tuple[set, set]:
"""
:param users_from_db: QuerySet всех абонентов у которых может быть обслуживание
:return: на выходе получаем абонентов которых надо добавить в nas и которых надо удалить
:param users_from_db: QuerySet of all subscribers that can have service
:return: Tuple of 2 lists that contain list to add users and list to remove users
"""
users_struct_list = [ab.build_agent_struct() for ab in users_from_db if ab.is_access()]
users_struct_set = set([ab for ab in users_struct_list if ab is not None and ab.tariff is not None])

7
devapp/templates/devapp/devices.html

@ -1,5 +1,6 @@
{% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% load i18n %}
{% load dpagination %}
{% block main %}
<ol class="breadcrumb">
@ -17,13 +18,13 @@
<tr>
<th>#</th>
<th class="col-md-2">
<a href="{% url 'devapp:devs' group.pk %}?order_by=ip_address&dir={{ dir|default:'down' }}">
<a href="{% url 'devapp:devs' group.pk %}?{% url_replace request order_by='ip_address' dir=dir|default:'down' %}">
{% trans 'Ip address' %}
</a>
{% if order_by == 'ip_address' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th class="col-md-5">
<a href="{% url 'devapp:devs' group.pk %}?order_by=comment&dir={{ dir|default:'down' }}">
<a href="{% url 'devapp:devs' group.pk %}?{% url_replace request order_by='comment' dir=dir|default:'down' %}">
{% trans 'Comment' %}
</a>
{% if order_by == 'comment' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
@ -31,7 +32,7 @@
<th class="col-md-3">{% trans 'Mac address' %}</th>
{# <th class="col-md-3 hidden-xs hidden-sm">{% trans 'Plugin output' %}</th> #}
<th class="col-md-1">
<a href="{% url 'devapp:devs' group.pk %}?order_by=devtype&dir={{ dir|default:'down' }}">
<a href="{% url 'devapp:devs' group.pk %}?{% url_replace request order_by='devtype' dir=dir|default:'down' %}">
{% trans 'Device type' %}
</a>
{% if order_by == 'devtype' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}

3
djing/local_settings.py.template

@ -36,9 +36,6 @@ PAY_SECRET = '<secret>'
# path to asterisk dial records
DIALING_MEDIA = 'path/to/asterisk_records'
# DHCP lease time
DHCP_TIMEOUT = 14400
DEFAULT_SNMP_PASSWORD = 'public'
TELEGRAM_BOT_TOKEN = 'bot token'

2
djing/settings.py

@ -175,8 +175,6 @@ PAY_SECRET = local_settings.PAY_SECRET
DIALING_MEDIA = local_settings.DIALING_MEDIA
DHCP_TIMEOUT = local_settings.DHCP_TIMEOUT
DEFAULT_SNMP_PASSWORD = local_settings.DEFAULT_SNMP_PASSWORD
TELEGRAM_BOT_TOKEN = local_settings.TELEGRAM_BOT_TOKEN

2
docs/install.md

@ -204,8 +204,6 @@ plugin=python3
**DIALING_MEDIA** &mdash; Путь, где биллинг сможет найти файлы записей asterisk чтоб вывести статистику звонков.
Подробнее читайте в описании работы с [АТС](./ats.ms).
**DHCP_TIMEOUT** &mdash; Время аренды настроек DHCP в секундах.
**DEFAULT_SNMP_PASSWORD** &mdash; Пароль snmp по умолчанию для устройств, чтоб при создании устройства он был заполнен в нужном поле.
Если нет такого пароля то оставьте пустым или None.

Loading…
Cancel
Save