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. 50
      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. 14
      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 group_app.models import Group
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 bitfield import BitField
@ -225,18 +225,12 @@ class Abon(BaseAccount):
agent_trf = TariffStruct(trf.id, trf.speedIn, trf.speedOut)
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]:
agent_abon = self.build_agent_struct()
if agent_abon is None:
return
if len(agent_abon.ips) < 1:
return _('Account has no one ips')
try:
tm = Transmitter()
if created:
@ -250,14 +244,13 @@ class Abon(BaseAccount):
def get_absolute_url(self):
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())
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:
return 'Subnet not found'
return 'Error while creating a ip lease'
self.ip_addresses.add(lease)
#self.save()
class PassportInfo(models.Model):

6
abonapp/templates/abonapp/editAbon.html

@ -215,7 +215,11 @@
{% endif %}
<span{{ lease.is_active|yesno:', class="text-muted"'|safe }}>
<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>
</li>
{% empty %}

50
abonapp/views.py

@ -421,8 +421,11 @@ def pick_tariff(request, gid, uname):
else:
deadline = datetime.strptime(deadline, '%Y-%m-%d %H:%M:%S')
abon.pick_tariff(trf, request.user, deadline=deadline, comment=log_comment)
abon.sync_with_nas(created=False)
messages.success(request, _('Tariff has been picked'))
r = abon.sync_with_nas(created=False)
if r is None:
messages.success(request, _('Tariff has been picked'))
else:
messages.error(request, r)
return redirect('abonapp:abon_services', gid=gid, uname=abon.username)
except (lib.LogicError, NasFailedResult) as e:
messages.error(request, e)
@ -554,7 +557,6 @@ def chgroup_tariff(request, gid):
tr = request.POST.getlist('tr')
grp.tariff_set.clear()
grp.tariff_set.add(*tr)
grp.save()
messages.success(request, _('Successfully saved'))
return redirect('abonapp:ch_group_tariff', gid)
tariffs = Tariff.objects.all()
@ -1001,20 +1003,6 @@ def abon_export(request, gid):
}, 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
@lib.decorators.only_admins
def fin_report(request):
@ -1151,6 +1139,11 @@ def lease_add(request, gid, uname):
network = get_object_or_404(NetworkModel, pk=network_id)
lease = IpLeaseModel.objects.create_from_ip(ip, net=network, is_dynamic=is_dynamic)
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'))
return redirect('abonapp:abon_home', gid, uname)
except lib.DuplicateEntry as e:
@ -1233,19 +1226,24 @@ class DhcpLever(SecureApiView):
'switch_port': 3,
'cmd': 'commit'
}"""
r = None
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':
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':
r = dhcp_expiry(data['client_ip'])
return dhcp_expiry(client_ip)
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:
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)
if not abon.is_dynamic_ip:
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 abon.is_access():
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):
list_for_add, list_for_del = self._diff_users(users_from_db)
if len(list_for_del) > 0:
print('List for del:')
print('List for del:', len(list_for_del))
for ld in list_for_del:
print('\t', ld.ips)
print('\t', ld)
self.remove_user_range(list_for_del)
if len(list_for_add) > 0:
print('List for add:')
print('List for add:', len(list_for_add))
for la in list_for_add:
print('\t', la.ips)
print('\t', la)
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'))
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)
if ip is None:
self.add_ip(LIST_USERS_ALLOWED, lease)

20
agent/structs.py

@ -36,30 +36,38 @@ class TariffStruct(BaseStruct):
# Abon from database
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):
self.uid = int(uid or 0)
if ips is None:
self.ips = ()
self._ips = ()
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.is_access = is_access
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):
if not isinstance(other, AbonStruct):
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
return r
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):
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)

2
devapp/migrations/0003_auto_20180529_1311.py

@ -14,7 +14,7 @@ def snmp_backup_info(apps, _):
Device = apps.get_model('devapp', 'Device')
obs = Device.objects.only('snmp_item_num')
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, _):

14
devapp/views.py

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

2
ip_pool/migrations/0001_initial.py

@ -56,7 +56,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='ipleasemodel',
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(
name='ipleasemodel',

2
ip_pool/models.py

@ -163,7 +163,7 @@ class IpLeaseManager(models.Manager):
class IpLeaseModel(models.Model):
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)
lease_time = models.DateTimeField(_('Lease time'), auto_now_add=True)
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()
from django.utils import timezone
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 ip_pool.models import IpLeaseModel
from agent import Transmitter, NasNetworkError, NasFailedResult
@ -42,6 +42,8 @@ def main():
users = Abon.objects\
.filter(is_active=True)\
.exclude(current_tariff=None)\
.annotate(ips_count=Count('ip_addresses'))\
.filter(ips_count__gt=0)\
.prefetch_related('ip_addresses')\
.iterator()
tm.sync_nas(users)

Loading…
Cancel
Save