Browse Source

maked sure ready for start new version

devel
Dmitry Novikov 8 years ago
parent
commit
9e7c4ac51d
  1. 19
      abonapp/models.py
  2. 6
      abonapp/templates/abonapp/editAbon.html
  3. 48
      abonapp/views.py
  4. 5
      agent/commands/dhcp.py
  5. 8
      agent/core.py
  6. 2
      agent/mod_mikrotik.py
  7. 20
      agent/structs.py
  8. 2
      devapp/migrations/0003_auto_20180529_1311.py
  9. 6
      devapp/views.py
  10. 2
      ip_pool/migrations/0001_initial.py
  11. 2
      ip_pool/models.py
  12. 4
      periodic.py

19
abonapp/models.py

@ -16,7 +16,7 @@ from accounts_app.models import UserProfile, MyUserManager, BaseAccount
from agent import Transmitter, AbonStruct, TariffStruct, NasFailedResult, NasNetworkError from agent import Transmitter, AbonStruct, TariffStruct, NasFailedResult, NasNetworkError
from group_app.models import Group from group_app.models import Group
from djing.lib import LogicError from djing.lib import LogicError
from ip_pool.models import IpLeaseModel
from ip_pool.models import IpLeaseModel, NetworkModel
from tariff_app.models import Tariff, PeriodicPay from tariff_app.models import Tariff, PeriodicPay
from bitfield import BitField from bitfield import BitField
@ -225,18 +225,12 @@ class Abon(BaseAccount):
agent_trf = TariffStruct(trf.id, trf.speedIn, trf.speedOut) agent_trf = TariffStruct(trf.id, trf.speedIn, trf.speedOut)
return AbonStruct(self.pk, abon_addresses, agent_trf, self.is_access()) return AbonStruct(self.pk, abon_addresses, agent_trf, self.is_access())
# def clean(self):
# # check if ip address already busy
# abon_addresses = tuple(p.ip for p in self.ip_addresses.all().iterator())
# if self.ip_address is not None and Abon.objects.filter(ip_address=self.ip_address).exclude(
# pk=self.pk).count() > 0:
# raise ValidationError({'ip_address': (gettext('Ip address already exist'),)})
# return super(Abon, self).clean()
def sync_with_nas(self, created: bool) -> Optional[Exception]: def sync_with_nas(self, created: bool) -> Optional[Exception]:
agent_abon = self.build_agent_struct() agent_abon = self.build_agent_struct()
if agent_abon is None: if agent_abon is None:
return return
if len(agent_abon.ips) < 1:
return _('Account has no one ips')
try: try:
tm = Transmitter() tm = Transmitter()
if created: if created:
@ -250,14 +244,13 @@ class Abon(BaseAccount):
def get_absolute_url(self): def get_absolute_url(self):
return resolve_url('abonapp:abon_home', self.group.id, self.username) return resolve_url('abonapp:abon_home', self.group.id, self.username)
def add_lease(self, ip: str, mac_addr=None):
def add_lease(self, ip: str, network: Optional[NetworkModel], mac_addr=None):
existed_client_ips = tuple(l.ip for l in self.ip_addresses.all()) existed_client_ips = tuple(l.ip for l in self.ip_addresses.all())
if ip not in existed_client_ips: if ip not in existed_client_ips:
lease = IpLeaseModel.objects.create_from_ip(ip=ip, net=None, mac=mac_addr)
lease = IpLeaseModel.objects.create_from_ip(ip=ip, net=network, mac=mac_addr)
if lease is None: if lease is None:
return 'Subnet not found'
return 'Error while creating a ip lease'
self.ip_addresses.add(lease) self.ip_addresses.add(lease)
#self.save()
class PassportInfo(models.Model): class PassportInfo(models.Model):

6
abonapp/templates/abonapp/editAbon.html

@ -215,7 +215,11 @@
{% endif %} {% endif %}
<span{{ lease.is_active|yesno:', class="text-muted"'|safe }}> <span{{ lease.is_active|yesno:', class="text-muted"'|safe }}>
<b>{{ lease }}</b> <b>{{ lease }}</b>
<small>{% trans 'Leased by:' %} {{ lease.lease_time|date:'d-m H:i:s' }}</small>
<small>{% trans 'Leased by:' %} {{ lease.lease_time|date:'d-m H:i:s' }}.
{% if lease.mac_addr %}
{% trans 'From' %}: {{ lease.mac_addr }}.
{% endif %}
</small>
</span> </span>
</li> </li>
{% empty %} {% empty %}

48
abonapp/views.py

@ -421,8 +421,11 @@ def pick_tariff(request, gid, uname):
else: else:
deadline = datetime.strptime(deadline, '%Y-%m-%d %H:%M:%S') deadline = datetime.strptime(deadline, '%Y-%m-%d %H:%M:%S')
abon.pick_tariff(trf, request.user, deadline=deadline, comment=log_comment) abon.pick_tariff(trf, request.user, deadline=deadline, comment=log_comment)
abon.sync_with_nas(created=False)
r = abon.sync_with_nas(created=False)
if r is None:
messages.success(request, _('Tariff has been picked')) messages.success(request, _('Tariff has been picked'))
else:
messages.error(request, r)
return redirect('abonapp:abon_services', gid=gid, uname=abon.username) return redirect('abonapp:abon_services', gid=gid, uname=abon.username)
except (lib.LogicError, NasFailedResult) as e: except (lib.LogicError, NasFailedResult) as e:
messages.error(request, e) messages.error(request, e)
@ -554,7 +557,6 @@ def chgroup_tariff(request, gid):
tr = request.POST.getlist('tr') tr = request.POST.getlist('tr')
grp.tariff_set.clear() grp.tariff_set.clear()
grp.tariff_set.add(*tr) grp.tariff_set.add(*tr)
grp.save()
messages.success(request, _('Successfully saved')) messages.success(request, _('Successfully saved'))
return redirect('abonapp:ch_group_tariff', gid) return redirect('abonapp:ch_group_tariff', gid)
tariffs = Tariff.objects.all() tariffs = Tariff.objects.all()
@ -1001,20 +1003,6 @@ def abon_export(request, gid):
}, request=request) }, request=request)
# @login_required
# @permission_required('abonapp.change_abon')
# @permission_required('group_app.can_view_group', (Group, 'pk', 'gid'))
# @json_view
# def reset_ip(request, gid, uname):
# abon = get_object_or_404(models.Abon, username=uname)
# abon.ip_address = None
# abon.save(update_fields=('ip_address',))
# return {
# 'status': 0,
# 'dat': "<span class='glyphicon glyphicon-refresh'></span>"
# }
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
def fin_report(request): def fin_report(request):
@ -1151,6 +1139,11 @@ def lease_add(request, gid, uname):
network = get_object_or_404(NetworkModel, pk=network_id) network = get_object_or_404(NetworkModel, pk=network_id)
lease = IpLeaseModel.objects.create_from_ip(ip, net=network, is_dynamic=is_dynamic) lease = IpLeaseModel.objects.create_from_ip(ip, net=network, is_dynamic=is_dynamic)
abon.ip_addresses.add(lease) abon.ip_addresses.add(lease)
tm = Transmitter()
tm.lease_start(
user=abon.build_agent_struct(),
lease=lease.ip
)
messages.success(request, _('Ip lease has been created')) messages.success(request, _('Ip lease has been created'))
return redirect('abonapp:abon_home', gid, uname) return redirect('abonapp:abon_home', gid, uname)
except lib.DuplicateEntry as e: except lib.DuplicateEntry as e:
@ -1233,19 +1226,24 @@ class DhcpLever(SecureApiView):
'switch_port': 3, 'switch_port': 3,
'cmd': 'commit' 'cmd': 'commit'
}""" }"""
r = None
try: try:
action = data['cmd']
action = data.get('cmd')
if action is None:
return '"cmd" parameter is missing'
client_ip = data.get('client_ip')
if client_ip is None:
return '"client_ip" parameter is missing'
if action == 'commit': if action == 'commit':
r = dhcp_commit(
data['client_ip'], data['client_mac'],
data['switch_mac'], data['switch_port']
return dhcp_commit(
client_ip, data.get('client_mac'),
data.get('switch_mac'), data.get('switch_port')
) )
elif action == 'expiry': elif action == 'expiry':
r = dhcp_expiry(data['client_ip'])
return dhcp_expiry(client_ip)
elif action == 'release': elif action == 'release':
r = dhcp_release(data['client_ip'])
return dhcp_release(client_ip)
else:
return '"cmd" parameter is invalid: %s' % action
except lib.LogicError as e: except lib.LogicError as e:
print('LogicError', e) print('LogicError', e)
r = str(e)
return r
return str(e)

5
agent/commands/dhcp.py

@ -18,7 +18,10 @@ def dhcp_commit(client_ip: str, client_mac: str, switch_mac: str, switch_port: i
abon = Abon.objects.get(device=dev) abon = Abon.objects.get(device=dev)
if not abon.is_dynamic_ip: if not abon.is_dynamic_ip:
return 'User settings is not dynamic' return 'User settings is not dynamic'
add_lease_result = abon.add_lease(client_ip)
client_ips = tuple(str(ip) for ip in abon.ip_addresses.all())
if client_ip in client_ips:
return 'Ip address already existed'
add_lease_result = abon.add_lease(client_ip, mac_addr=client_mac, network=None)
if add_lease_result is None: if add_lease_result is None:
if abon.is_access(): if abon.is_access():
abon.sync_with_nas(created=False) abon.sync_with_nas(created=False)

8
agent/core.py

@ -108,12 +108,12 @@ class BaseTransmitter(ABC):
def sync_nas(self, users_from_db: Iterator): def sync_nas(self, users_from_db: Iterator):
list_for_add, list_for_del = self._diff_users(users_from_db) list_for_add, list_for_del = self._diff_users(users_from_db)
if len(list_for_del) > 0: if len(list_for_del) > 0:
print('List for del:')
print('List for del:', len(list_for_del))
for ld in list_for_del: for ld in list_for_del:
print('\t', ld.ips)
print('\t', ld)
self.remove_user_range(list_for_del) self.remove_user_range(list_for_del)
if len(list_for_add) > 0: if len(list_for_add) > 0:
print('List for add:')
print('List for add:', len(list_for_add))
for la in list_for_add: for la in list_for_add:
print('\t', la.ips)
print('\t', la)
self.add_user_range(list_for_add) self.add_user_range(list_for_add)

2
agent/mod_mikrotik.py

@ -490,6 +490,8 @@ class MikrotikTransmitter(BaseTransmitter, ApiRos, metaclass=type('_ABC_Lazy_mcs
raise NasFailedResult(_('You cannot disable last session')) raise NasFailedResult(_('You cannot disable last session'))
def lease_start(self, user: AbonStruct, lease): def lease_start(self, user: AbonStruct, lease):
if not issubclass(lease.__class__, _BaseAddress):
lease = ip_address(lease)
ip = self.find_ip(lease, LIST_USERS_ALLOWED) ip = self.find_ip(lease, LIST_USERS_ALLOWED)
if ip is None: if ip is None:
self.add_ip(LIST_USERS_ALLOWED, lease) self.add_ip(LIST_USERS_ALLOWED, lease)

20
agent/structs.py

@ -36,30 +36,38 @@ class TariffStruct(BaseStruct):
# Abon from database # Abon from database
class AbonStruct(BaseStruct): class AbonStruct(BaseStruct):
__slots__ = ('uid', 'ips', 'tariff', 'is_access', 'queue_id')
__slots__ = ('uid', '_ips', 'tariff', 'is_access', 'queue_id')
def __init__(self, uid=0, ips=None, tariff=None, is_access=True): def __init__(self, uid=0, ips=None, tariff=None, is_access=True):
self.uid = int(uid or 0) self.uid = int(uid or 0)
if ips is None: if ips is None:
self.ips = ()
self._ips = ()
else: else:
self.ips = tuple(ip_address(ip) for ip in ips)
self._ips = tuple(ip_address(ip) for ip in ips)
self.tariff = tariff self.tariff = tariff
self.is_access = is_access self.is_access = is_access
self.queue_id = 0 self.queue_id = 0
def get_ips(self):
return self._ips
def set_ips(self, v):
self._ips = set(v)
ips = property(get_ips, set_ips, doc='Ip addresses')
def __eq__(self, other): def __eq__(self, other):
if not isinstance(other, AbonStruct): if not isinstance(other, AbonStruct):
raise TypeError raise TypeError
r = self.uid == other.uid and self.ips == other.ips
r = self.uid == other.uid and self._ips == other._ips
r = r and self.tariff == other.tariff r = r and self.tariff == other.tariff
return r return r
def __str__(self): def __str__(self):
return "uid=%d, ips=[%s], tariff=%s" % (self.uid, ';'.join(self.ips), self.tariff or '<No Service>')
return "uid=%d, ips=[%s], tariff=%s" % (self.uid, ';'.join(str(i) for i in self._ips), self.tariff or '<No Service>')
def __hash__(self): def __hash__(self):
return hash(hash(self.ips) + hash(self.tariff)) if self.tariff is not None else 0
return hash(hash(self._ips) + hash(self.tariff)) if self.tariff is not None else 0
# Shape rule from NAS(Network Access Server) # Shape rule from NAS(Network Access Server)

2
devapp/migrations/0003_auto_20180529_1311.py

@ -14,7 +14,7 @@ def snmp_backup_info(apps, _):
Device = apps.get_model('devapp', 'Device') Device = apps.get_model('devapp', 'Device')
obs = Device.objects.only('snmp_item_num') obs = Device.objects.only('snmp_item_num')
with open(TMP_FILE, 'w') as f: with open(TMP_FILE, 'w') as f:
serializers.serialize('json', obs, stream=f)
serializers.serialize('json', obs, stream=f, fields=('snmp_item_num',))
def snmp_restore_info_to_new_scheme(apps, _): def snmp_restore_info_to_new_scheme(apps, _):

6
devapp/views.py

@ -123,8 +123,11 @@ class DeviceUpdate(UpdateView):
pass pass
r = super().form_valid(form) r = super().form_valid(form)
# change device info in dhcpd.conf # change device info in dhcpd.conf
try:
self.object.update_dhcp() self.object.update_dhcp()
messages.success(self.request, _('Device info has been saved')) messages.success(self.request, _('Device info has been saved'))
except PermissionError as e:
messages.error(self.request, e)
return r return r
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
@ -177,8 +180,11 @@ class DeviceCreateView(CreateView):
pass pass
r = super().form_valid(form) r = super().form_valid(form)
# change device info in dhcpd.conf # change device info in dhcpd.conf
try:
self.object.update_dhcp() self.object.update_dhcp()
messages.success(self.request, _('Device info has been saved')) messages.success(self.request, _('Device info has been saved'))
except PermissionError as e:
messages.error(self.request, e)
return r return r
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):

2
ip_pool/migrations/0001_initial.py

@ -56,7 +56,7 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='ipleasemodel', model_name='ipleasemodel',
name='network', name='network',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ip_pool.NetworkModel', verbose_name='Parent network'),
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ip_pool.NetworkModel', verbose_name='Parent network', blank=True, null=True),
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='ipleasemodel', name='ipleasemodel',

2
ip_pool/models.py

@ -163,7 +163,7 @@ class IpLeaseManager(models.Manager):
class IpLeaseModel(models.Model): class IpLeaseModel(models.Model):
ip = models.GenericIPAddressField(verbose_name=_('Ip address'), unique=True) ip = models.GenericIPAddressField(verbose_name=_('Ip address'), unique=True)
network = models.ForeignKey(NetworkModel, on_delete=models.CASCADE, verbose_name=_('Parent network'))
network = models.ForeignKey(NetworkModel, on_delete=models.CASCADE, verbose_name=_('Parent network'), null=True, blank=True)
mac_addr = MACAddressField(verbose_name=_('Mac address'), null=True, blank=True, unique=True) mac_addr = MACAddressField(verbose_name=_('Mac address'), null=True, blank=True, unique=True)
lease_time = models.DateTimeField(_('Lease time'), auto_now_add=True) lease_time = models.DateTimeField(_('Lease time'), auto_now_add=True)
is_dynamic = models.BooleanField(_('Is dynamic'), default=False) is_dynamic = models.BooleanField(_('Is dynamic'), default=False)

4
periodic.py

@ -6,7 +6,7 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings")
django.setup() django.setup()
from django.utils import timezone from django.utils import timezone
from django.db import transaction from django.db import transaction
from django.db.models import signals
from django.db.models import signals, Count
from abonapp.models import Abon, AbonTariff, abontariff_pre_delete, PeriodicPayForId, AbonLog from abonapp.models import Abon, AbonTariff, abontariff_pre_delete, PeriodicPayForId, AbonLog
from ip_pool.models import IpLeaseModel from ip_pool.models import IpLeaseModel
from agent import Transmitter, NasNetworkError, NasFailedResult from agent import Transmitter, NasNetworkError, NasFailedResult
@ -42,6 +42,8 @@ def main():
users = Abon.objects\ users = Abon.objects\
.filter(is_active=True)\ .filter(is_active=True)\
.exclude(current_tariff=None)\ .exclude(current_tariff=None)\
.annotate(ips_count=Count('ip_addresses'))\
.filter(ips_count__gt=0)\
.prefetch_related('ip_addresses')\ .prefetch_related('ip_addresses')\
.iterator() .iterator()
tm.sync_nas(users) tm.sync_nas(users)

Loading…
Cancel
Save