diff --git a/abonapp/models.py b/abonapp/models.py
index b3f81b7..59c692b 100644
--- a/abonapp/models.py
+++ b/abonapp/models.py
@@ -238,7 +238,6 @@ class Abon(BaseAccount):
name="uid%d" % self.pk,
network=self.ip_address,
max_limit=(abon_tariff.speedIn, abon_tariff.speedOut),
- queue_type=SubnetQueue.QUEUE_LEAF,
is_access=self.is_access()
)
diff --git a/abonapp/templates/abonapp/peoples.html b/abonapp/templates/abonapp/peoples.html
index de9e206..843fc3a 100644
--- a/abonapp/templates/abonapp/peoples.html
+++ b/abonapp/templates/abonapp/peoples.html
@@ -32,6 +32,7 @@
{% if order_by == 'username' %}{% endif %}
- |
+ |
{% trans 'Subscribers not found' %}.
{% if perms.abonapp.add_abon %}
{% trans 'Add abon' %}
diff --git a/ip_pool/migrations/0003_auto_20181015_1430.py b/ip_pool/migrations/0003_auto_20181019_1230.py
similarity index 57%
rename from ip_pool/migrations/0003_auto_20181015_1430.py
rename to ip_pool/migrations/0003_auto_20181019_1230.py
index 7870879..1f25d68 100644
--- a/ip_pool/migrations/0003_auto_20181015_1430.py
+++ b/ip_pool/migrations/0003_auto_20181019_1230.py
@@ -1,4 +1,4 @@
-# Generated by Django 2.1 on 2018-10-15 14:30
+# Generated by Django 2.1 on 2018-10-19 12:30
from django.db import migrations, models
import djing.fields
@@ -14,10 +14,23 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='LeasesHistory',
fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('id', models.AutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name='ID'
+ )),
('ip', models.GenericIPAddressField(verbose_name='Ip address')),
- ('lease_time', models.DateTimeField(auto_now_add=True, verbose_name='Lease time')),
- ('mac_addr', djing.fields.MACAddressField(blank=True, integer=True, null=True, verbose_name='Mac address')),
+ ('lease_time', models.DateTimeField(
+ auto_now_add=True,
+ verbose_name='Lease time'
+ )),
+ ('mac_addr', djing.fields.MACAddressField(
+ blank=True,
+ integer=True,
+ null=True,
+ verbose_name='Mac address'
+ )),
],
options={
'verbose_name': 'History lease',
@@ -34,10 +47,4 @@ class Migration(migrations.Migration):
model_name='ipleasemodel',
name='is_dynamic',
),
- migrations.AddField(
- model_name='networkmodel',
- name='speed',
- field=models.FloatField(default=0.0, verbose_name='Speed for subnet'),
- preserve_default=False,
- ),
]
diff --git a/ip_pool/models.py b/ip_pool/models.py
index 4ac7c2a..daf15bd 100644
--- a/ip_pool/models.py
+++ b/ip_pool/models.py
@@ -39,8 +39,6 @@ class NetworkModel(models.Model):
ip_start = models.GenericIPAddressField(_('Start work ip range'))
ip_end = models.GenericIPAddressField(_('End work ip range'))
- speed = models.FloatField(_('Speed for subnet'))
-
def __str__(self):
netw = self.get_network()
return "%s: %s" % (self.description, netw.with_prefixlen)
diff --git a/nas_app/nas_managers/mod_mikrotik.py b/nas_app/nas_managers/mod_mikrotik.py
index 84dfa58..571eb16 100644
--- a/nas_app/nas_managers/mod_mikrotik.py
+++ b/nas_app/nas_managers/mod_mikrotik.py
@@ -4,14 +4,13 @@ import socket
from abc import ABCMeta
from hashlib import md5
from ipaddress import ip_network, _BaseNetwork
-from typing import Iterable, Optional, Tuple, Generator, Dict, Iterator, Any
+from typing import Iterable, Optional, Tuple, Generator, Dict, Iterator
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from djing.lib.decorators import LazyInitMetaclass
from nas_app.nas_managers import core
from nas_app.nas_managers import structs as i_structs
-from ip_pool.models import NetworkModel
DEBUG = getattr(settings, 'DEBUG', False)
@@ -21,14 +20,14 @@ LIST_DEVICES_ALLOWED = 'DjingDevicesAllowed'
class ApiRos(object):
"""Routeros api"""
- sk = None
+ __sk = None
is_login = False
def __init__(self, ip: str, port: int):
- if self.sk is None:
+ if self.__sk is None:
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.connect((ip, port or 8728))
- self.sk = sk
+ self.__sk = sk
def login(self, username, pwd):
if self.is_login:
@@ -147,7 +146,7 @@ class ApiRos(object):
def write_bytes(self, s):
n = 0
while n < len(s):
- r = self.sk.send(s[n:])
+ r = self.__sk.send(s[n:])
if r == 0:
raise core.NasFailedResult("connection closed by remote end")
n += r
@@ -155,16 +154,15 @@ class ApiRos(object):
def read_bytes(self, length):
ret = b''
while len(ret) < length:
- s = self.sk.recv(length - len(ret))
+ s = self.__sk.recv(length - len(ret))
if len(s) == 0:
raise core.NasFailedResult("connection closed by remote end")
ret += s
return ret
def __del__(self):
- sk = getattr(self, 'sk')
- if sk is not None:
- self.sk.close()
+ if self.__sk is not None:
+ self.__sk.close()
class MikrotikTransmitter(core.BaseTransmitter, ApiRos,
@@ -247,14 +245,6 @@ class MikrotikTransmitter(core.BaseTransmitter, ApiRos,
is_access=not disabled,
queue_id=info.get('=.id')
)
- if name.startswith('uid'):
- a.queue_type = i_structs.SubnetQueue.QUEUE_LEAF
- elif name.startswith('net_'):
- a.queue_type = i_structs.SubnetQueue.QUEUE_SUBNET
- elif name == 'queue-root':
- a.queue_type = i_structs.SubnetQueue.QUEUE_ROOT
- else:
- a.queue_type = i_structs.SubnetQueue.QUEUE_UNKNOWN
return a
except ValueError as e:
print('ValueError:', e)
@@ -269,8 +259,7 @@ class MikrotikTransmitter(core.BaseTransmitter, ApiRos,
if r:
return self._build_shape_obj(r.get('!re'))
- def add_queue(self, queue: i_structs.SubnetQueue,
- parent_name: str) -> None:
+ def add_queue(self, queue: i_structs.SubnetQueue) -> None:
if not isinstance(queue, i_structs.SubnetQueue):
raise TypeError('queue must be instance of SubnetQueue')
self._exec_cmd((
@@ -279,10 +268,9 @@ class MikrotikTransmitter(core.BaseTransmitter, ApiRos,
# FIXME: тут в разных микротиках или =target-addresses или =target
'=target=%s' % queue.network,
'=max-limit=%.3fM/%.3fM' % queue.max_limit,
- '=queue=Djing_SFQ/Djing_SFQ',
+ '=queue=Djing_pcq/Djing_pcq',
'=burst-time=1/1',
- '=parent=%s' % parent_name,
- '=total-queue=Djing_SFQ'
+ '=total-queue=Djing_pcq'
))
def remove_queue(self, queue: i_structs.SubnetQueue) -> None:
@@ -302,13 +290,13 @@ class MikrotikTransmitter(core.BaseTransmitter, ApiRos,
if len(ids) > 1:
self._exec_cmd(('/queue/simple/remove', '=numbers=%s' % ids))
- def update_queue(self, queue: i_structs.SubnetQueue, parent_name: str):
+ def update_queue(self, queue: i_structs.SubnetQueue):
if not isinstance(queue, i_structs.SubnetQueue):
raise TypeError
if not queue.queue_id:
queue = self.find_queue(queue.name)
if queue is None:
- return self.add_queue(queue, parent_name)
+ return self.add_queue(queue)
else:
cmd = [
'/queue/simple/set',
@@ -317,8 +305,7 @@ class MikrotikTransmitter(core.BaseTransmitter, ApiRos,
# FIXME: тут в разных версиях прошивки микротика
# или =target-addresses или =target
'=target=%s' % queue.network,
- '=queue=Djing_SFQ/Djing_SFQ',
- '=parent=%s' % parent_name,
+ '=queue=Djing_pcq/Djing_pcq',
'=burst-time=1/1'
]
if queue.queue_id:
@@ -375,8 +362,9 @@ class MikrotikTransmitter(core.BaseTransmitter, ApiRos,
'?dynamic=no'
))
for dat in nets:
- yield ip_network(dat.get('=address'), strict=False), dat.get(
- '=.id')
+ n = ip_network(dat.get('=address'))
+ n.queue_id = dat.get('=.id')
+ yield n
#################################################
# BaseTransmitter implementation
@@ -397,9 +385,9 @@ class MikrotikTransmitter(core.BaseTransmitter, ApiRos,
if ip_list_entity:
self.remove_ip(ip_list_entity.get('=.id'))
- def add_user(self, queue: i_structs.SubnetQueue, parent_name=None, *args):
+ def add_user(self, queue: i_structs.SubnetQueue, *args):
try:
- self.add_queue(queue, parent_name=parent_name)
+ self.add_queue(queue)
except core.NasFailedResult as e:
print('Error:', e)
net = queue.network
@@ -416,9 +404,8 @@ class MikrotikTransmitter(core.BaseTransmitter, ApiRos,
ip_id = r.get('=.id')
self.remove_ip(ip_id)
- def update_user(self, queue: i_structs.SubnetQueue, parent_name=None,
- *args):
- self.update_queue(queue, parent_name)
+ def update_user(self, queue: i_structs.SubnetQueue, *args):
+ self.update_queue(queue)
def ping(self, host, count=10) -> Optional[Tuple[int, int]]:
r = self._exec_cmd((
@@ -441,80 +428,30 @@ class MikrotikTransmitter(core.BaseTransmitter, ApiRos,
def read_users(self) -> i_structs.VectorQueue:
return self.read_queue_iter()
- @staticmethod
- def _build_db_queues(users_from_db: Iterator[Any]) -> Generator:
- # Корневая очередь
- # FIXME: Корневую очередь надо брать откуда-то
- root_queue = i_structs.SubnetQueue(
- name='queue-root',
- network='10.0.0.0/8',
- max_limit=2048,
- queue_type=i_structs.SubnetQueue.QUEUE_ROOT
- )
-
- # выберем структуры подсетей
- db_subnet_queues = (i_structs.SubnetQueue(
- name="net_%s" % db_net.network,
- network=db_net.get_network(),
- max_limit=float(db_net.speed),
- queue_type=i_structs.SubnetQueue.QUEUE_SUBNET
- ) for db_net in NetworkModel.objects.all().iterator())
-
- queues_struct_gen = (
+ def sync_nas(self, users_from_db: Iterator):
+ queues_from_db = (
ab.build_agent_struct() for ab in users_from_db
if ab is not None and ab.is_access()
)
+ queues_from_db = set(filter(lambda x: x is not None, queues_from_db))
+ queues_from_gw = self.read_queue_iter()
- r = [q for q in queues_struct_gen if q is not None]
- r.insert(0, root_queue)
- r.extend(db_subnet_queues)
- return r, root_queue
-
- def _queues_diff(self, users_from_db: Iterator):
- queues_from_db, root_queue = self._build_db_queues(users_from_db)
- queues_from_gw = tuple(self.read_queue_iter())
-
- # TODO: надо чтоб корневая очередь тоже создавалась
-
- db_queues_subnets = (
- q for q in queues_from_db
- if q.queue_type == i_structs.SubnetQueue.QUEUE_SUBNET
- )
- gw_queues_subnets = tuple(
- q for q in queues_from_gw
- if q.queue_type == i_structs.SubnetQueue.QUEUE_SUBNET
- )
- subnets_for_add, subnets_for_del = core.diff_set(
- set(db_queues_subnets), set(gw_queues_subnets))
-
- self.remove_queue_range(
- (q.queue_id for q in subnets_for_del)
- )
- for q in subnets_for_add:
- self.add_queue(q, parent_name=root_queue.name)
- del subnets_for_add, subnets_for_del
-
- db_queue_users = (
- q for q in queues_from_db
- if q.queue_type == i_structs.SubnetQueue.QUEUE_LEAF
- )
- gw_queue_users = (
- q for q in queues_from_gw
- if q.queue_type == i_structs.SubnetQueue.QUEUE_LEAF
- )
- user_q_for_add, user_q_for_del = core.diff_set(set(db_queue_users),
- set(gw_queue_users))
+ user_q_for_add, user_q_for_del = core.diff_set(queues_from_db,
+ set(queues_from_gw))
self.remove_queue_range(
(q.queue_id for q in user_q_for_del)
)
for q in user_q_for_add:
- find_filter = filter(
- lambda qe: qe.network.overlaps(q.network),
- gw_queues_subnets
- )
- parent_subnet = next(find_filter, root_queue)
- self.add_queue(q, parent_name=parent_subnet.name)
-
- def sync_nas(self, users_from_db: Iterator):
- self._queues_diff(users_from_db)
+ self.add_queue(q)
+ del user_q_for_add, user_q_for_del
+
+ # sync ip addrs list
+ db_nets = set(net.network for net in queues_from_db)
+ gw_nets = set(self.read_nets_iter(LIST_USERS_ALLOWED))
+ nets_add, nets_del = core.diff_set(db_nets, gw_nets)
+ self.remove_ip_range(
+ (q.queue_id for q in nets_del)
+ )
+ for q in nets_add:
+ self.add_ip(LIST_USERS_ALLOWED, q)
diff --git a/nas_app/nas_managers/structs.py b/nas_app/nas_managers/structs.py
index 7fa105f..7cd8230 100644
--- a/nas_app/nas_managers/structs.py
+++ b/nas_app/nas_managers/structs.py
@@ -8,22 +8,14 @@ class BaseStruct(object, metaclass=ABCMeta):
class SubnetQueue(BaseStruct):
- __slots__ = ('name', '_net', '_max_limit', '_queue_type',
- 'is_access', 'queue_id')
-
- # Queue types
- QUEUE_UNKNOWN = 0
- QUEUE_ROOT = 1
- QUEUE_SUBNET = 2
- QUEUE_LEAF = 3
+ __slots__ = ('name', '_net', '_max_limit', 'is_access', 'queue_id')
def __init__(self, name: str, network, max_limit=0.0,
- queue_type=QUEUE_UNKNOWN, is_access=True, queue_id=None):
+ is_access=True, queue_id=None):
super().__init__()
self.name = name
self.network = network
self.max_limit = max_limit
- self.queue_type = queue_type
self.is_access = is_access
self.queue_id = queue_id
@@ -57,18 +49,6 @@ class SubnetQueue(BaseStruct):
network = property(get_network, set_network)
- def get_queue_type(self):
- return self._queue_type
-
- def set_queue_type(self, v):
- if not isinstance(v, int):
- raise ValueError('queue_type must be int')
- if v < self.QUEUE_UNKNOWN or v > self.QUEUE_LEAF:
- raise IndexError('queue_type out of range')
- self._queue_type = v
-
- queue_type = property(get_queue_type, set_queue_type)
-
def __eq__(self, other):
return self.network == other.network and self.max_limit == other.max_limit
|