Browse Source

Move dhcp manager to view

devel
ns 8 years ago
parent
commit
3bb1d96a9b
  1. 3
      abonapp/urls.py
  2. 50
      abonapp/views.py
  3. 22
      agent/commands/dhcp.py
  4. 47
      dhcp_lever.py

3
abonapp/urls.py

@ -65,5 +65,6 @@ urlpatterns = [
# Api's # Api's
url(r'^api/abons$', views.abons), url(r'^api/abons$', views.abons),
url(r'^api/abon_filter$', views.search_abon)
url(r'^api/abon_filter$', views.search_abon),
url(r'^api/dhcp_lever/$', views.DhcpLever.as_view())
] ]

50
abonapp/views.py

@ -1,3 +1,4 @@
from typing import Dict, Optional
from django.contrib.gis.shortcuts import render_to_text from django.contrib.gis.shortcuts import render_to_text
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.db import IntegrityError, ProgrammingError, transaction from django.db import IntegrityError, ProgrammingError, transaction
@ -12,6 +13,7 @@ from django.views.generic import ListView, UpdateView, CreateView
from django.conf import settings from django.conf import settings
from jsonview.decorators import json_view from jsonview.decorators import json_view
from agent.commands.dhcp import dhcp_commit, dhcp_expiry, dhcp_release
from statistics.models import StatCache from statistics.models import StatCache
from tariff_app.models import Tariff from tariff_app.models import Tariff
from agent import NasFailedResult, Transmitter, NasNetworkError from agent import NasFailedResult, Transmitter, NasNetworkError
@ -26,8 +28,7 @@ from statistics.models import getModel
from group_app.models import Group from group_app.models import Group
from guardian.shortcuts import get_objects_for_user, assign_perm from guardian.shortcuts import get_objects_for_user, assign_perm
from guardian.decorators import permission_required_or_403 as permission_required from guardian.decorators import permission_required_or_403 as permission_required
from djing.global_base_views import OrderingMixin, BaseListWithFiltering
from djing import ping
from djing.global_base_views import OrderingMixin, BaseListWithFiltering, HashAuthView, AllowedSubnetMixin
PAGINATION_ITEMS_PER_PAGE = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10) PAGINATION_ITEMS_PER_PAGE = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
@ -697,7 +698,7 @@ def abon_ping(request):
tm = Transmitter() tm = Transmitter()
ping_result = tm.ping(ip) ping_result = tm.ping(ip)
if ping_result is None: if ping_result is None:
if ping(ip, 10):
if mydefs.ping(ip, 10):
status = True status = True
text = '<span class="glyphicon glyphicon-ok"></span> %s' % _('ping ok') text = '<span class="glyphicon glyphicon-ok"></span> %s' % _('ping ok')
else: else:
@ -1118,3 +1119,46 @@ def search_abon(request):
results = models.Abon.objects.filter(fio__icontains=word)[:8] results = models.Abon.objects.filter(fio__icontains=word)[:8]
results = [{'id': usr.pk, 'text': "%s: %s" % (usr.username, usr.fio)} for usr in results] results = [{'id': usr.pk, 'text': "%s: %s" % (usr.username, usr.fio)} for usr in results]
return results return results
class DhcpLever(AllowedSubnetMixin, HashAuthView):
#
# Api view for dhcp event
#
http_method_names = ['get']
@method_decorator(json_view)
def get(self, request, *args, **kwargs):
data = request.GET.copy()
r = self.on_dhcp_event(data)
if r is not None:
return {'text': r}
return {'status': 'ok'}
@staticmethod
def on_dhcp_event(data: Dict) -> Optional[str]:
'''
data = {
'client_ip': ip2int('127.0.0.1'),
'client_mac': 'aa:bb:cc:dd:ee:ff',
'switch_mac': 'aa:bb:cc:dd:ee:ff',
'switch_port': 3,
'cmd': 'commit'
}
'''
r = None
try:
action = data['cmd']
if action == 'commit':
r = dhcp_commit(
data['client_ip'], data['client_mac'],
data['switch_mac'], data['switch_port']
)
elif action == 'expiry':
r = dhcp_expiry(data['client_ip'])
elif action == 'release':
r = dhcp_release(data['client_ip'])
except mydefs.LogicError as e:
print('LogicError', e)
r = str(e)
return r

22
agent/commands/dhcp.py

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from typing import Optional
from django.core.exceptions import MultipleObjectsReturned from django.core.exceptions import MultipleObjectsReturned
from abonapp.models import Abon from abonapp.models import Abon
from devapp.models import Device, Port from devapp.models import Device, Port
def dhcp_commit(client_ip: str, client_mac: str, switch_mac: str, switch_port: int) -> None:
def dhcp_commit(client_ip: str, client_mac: str, switch_mac: str, switch_port: int) -> Optional[str]:
try: try:
dev = Device.objects.get(mac_addr=switch_mac) dev = Device.objects.get(mac_addr=switch_mac)
mngr_class = dev.get_manager_klass() mngr_class = dev.get_manager_klass()
@ -21,31 +22,32 @@ def dhcp_commit(client_ip: str, client_mac: str, switch_mac: str, switch_port: i
if not abon.is_access(): if not abon.is_access():
print('D:', 'User %s is not access to service' % abon.username) print('D:', 'User %s is not access to service' % abon.username)
return return
if abon.ip_address != client_ip:
abon.ip_address = client_ip abon.ip_address = client_ip
abon.save(update_fields=['ip_address']) abon.save(update_fields=['ip_address'])
abon.sync_with_nas(created=False) abon.sync_with_nas(created=False)
except Abon.DoesNotExist: except Abon.DoesNotExist:
print('N:', "User with device '%s' does not exist" % dev)
return "User with device with mac '%s' does not exist" % switch_mac
except Device.DoesNotExist: except Device.DoesNotExist:
print('N:', 'Device with mac %s not found' % switch_mac)
return 'Device with mac %s not found' % switch_mac
except Port.DoesNotExist: except Port.DoesNotExist:
print('N:', 'Port %(switch_port)d on device with mac %(switch_mac)s does not exist' % {
return 'Port %(switch_port)d on device with mac %(switch_mac)s does not exist' % {
'switch_port': int(switch_port), 'switch_port': int(switch_port),
'switch_mac': switch_mac 'switch_mac': switch_mac
})
}
except MultipleObjectsReturned as e: except MultipleObjectsReturned as e:
print('E:', 'MultipleObjectsReturned:', type(e), e, switch_port, dev)
return 'MultipleObjectsReturned:' + ' '.join([type(e), e, str(switch_port)])
def dhcp_expiry(client_ip):
def dhcp_expiry(client_ip) -> Optional[str]:
try: try:
abon = Abon.objects.get(ip_address=client_ip) abon = Abon.objects.get(ip_address=client_ip)
abon.ip_address = None abon.ip_address = None
abon.save(update_fields=['ip_address']) abon.save(update_fields=['ip_address'])
abon.sync_with_nas(created=False) abon.sync_with_nas(created=False)
except Abon.DoesNotExist: except Abon.DoesNotExist:
pass
return "Subscriber with ip %s does not exist" % client_ip
def dhcp_release(client_ip):
dhcp_expiry(client_ip)
def dhcp_release(client_ip) -> Optional[str]:
return dhcp_expiry(client_ip)

47
dhcp_lever.py

@ -1,6 +1,12 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import sys import sys
import socket
from urllib.error import HTTPError
from urllib.parse import urlencode
from urllib.request import urlopen
from hashlib import sha256
API_AUTH_SECRET = 'your api key'
SERVER_DOMAIN = 'http://localhost:8000'
def die(text): def die(text):
@ -19,21 +25,46 @@ obj = {
''' '''
def send_to(data, addr='127.0.0.1', port=5436):
from pickle import dumps
def calc_hash(data):
if type(data) is str:
result_data = data.encode('utf-8')
else:
result_data = bytes(data)
return sha256(result_data).hexdigest()
def make_sign(data: dict):
vars_to_hash = [str(v) for v in data.values()]
vars_to_hash.sort()
vars_to_hash.append(API_AUTH_SECRET)
return calc_hash('_'.join(vars_to_hash))
def send_to(data, server=SERVER_DOMAIN):
sign = make_sign(data)
data.update({'sign': sign})
try: try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((addr, port))
data = dumps(data)
s.send(data)
with urlopen("%s/abons/api/dhcp_lever/?%s" % (server, urlencode(data))) as r:
html = r.read()
print(html)
except ConnectionRefusedError: except ConnectionRefusedError:
print('ERROR: connection refused') print('ERROR: connection refused')
except HTTPError as e:
print('ERROR:', e)
if __name__ == "__main__": if __name__ == "__main__":
argv = sys.argv argv = sys.argv
if len(argv) < 3: if len(argv) < 3:
die('Too few arguments, exiting...')
die(
'Too few arguments, exiting...\n'
'Usage:\n'
'COMMIT: ./dhcp_lever.py commit 192.168.1.100 ff:12:c5:9f:12:56 98:45:28:85:25:1a 3\n'
'EXPIRY or RELEASE: ./dhcp_lever.py [release |commit]'
)
if API_AUTH_SECRET == 'your api key':
raise NotImplementedError('You must specified secret api key')
action = argv[1] action = argv[1]
if action == 'commit': if action == 'commit':
if len(argv) < 6: if len(argv) < 6:

Loading…
Cancel
Save