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. 28
      agent/commands/dhcp.py
  4. 47
      dhcp_lever.py

3
abonapp/urls.py

@ -65,5 +65,6 @@ urlpatterns = [
# Api's
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.core.exceptions import PermissionDenied
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 jsonview.decorators import json_view
from agent.commands.dhcp import dhcp_commit, dhcp_expiry, dhcp_release
from statistics.models import StatCache
from tariff_app.models import Tariff
from agent import NasFailedResult, Transmitter, NasNetworkError
@ -26,8 +28,7 @@ from statistics.models import getModel
from group_app.models import Group
from guardian.shortcuts import get_objects_for_user, assign_perm
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)
@ -697,7 +698,7 @@ def abon_ping(request):
tm = Transmitter()
ping_result = tm.ping(ip)
if ping_result is None:
if ping(ip, 10):
if mydefs.ping(ip, 10):
status = True
text = '<span class="glyphicon glyphicon-ok"></span> %s' % _('ping ok')
else:
@ -1118,3 +1119,46 @@ def search_abon(request):
results = models.Abon.objects.filter(fio__icontains=word)[:8]
results = [{'id': usr.pk, 'text': "%s: %s" % (usr.username, usr.fio)} for usr in 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

28
agent/commands/dhcp.py

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from typing import Optional
from django.core.exceptions import MultipleObjectsReturned
from abonapp.models import Abon
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:
dev = Device.objects.get(mac_addr=switch_mac)
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():
print('D:', 'User %s is not access to service' % abon.username)
return
abon.ip_address = client_ip
abon.save(update_fields=['ip_address'])
abon.sync_with_nas(created=False)
if abon.ip_address != client_ip:
abon.ip_address = client_ip
abon.save(update_fields=['ip_address'])
abon.sync_with_nas(created=False)
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:
print('N:', 'Device with mac %s not found' % switch_mac)
return 'Device with mac %s not found' % switch_mac
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_mac': switch_mac
})
}
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:
abon = Abon.objects.get(ip_address=client_ip)
abon.ip_address = None
abon.save(update_fields=['ip_address'])
abon.sync_with_nas(created=False)
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
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):
@ -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:
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:
print('ERROR: connection refused')
except HTTPError as e:
print('ERROR:', e)
if __name__ == "__main__":
argv = sys.argv
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]
if action == 'commit':
if len(argv) < 6:

Loading…
Cancel
Save