diff --git a/labAdmin/admin.py b/labAdmin/admin.py index 37a2ee7..1302da3 100755 --- a/labAdmin/admin.py +++ b/labAdmin/admin.py @@ -14,6 +14,8 @@ UserProfile, ) +from .arp import get_neighbours + class CardAdmin(admin.ModelAdmin): list_display = ('nfc_id', 'user', 'credits') @@ -66,6 +68,22 @@ class CategoryAdmin(admin.ModelAdmin): class DeviceAdmin(admin.ModelAdmin): list_display = ('name', 'hourlyCost', 'category', 'mac', 'last_activity') ordering = ('name',) + change_form_template = 'labadmin/admin/device_change_form.html' + add_form_template = 'labadmin/admin/device_change_form.html' + + def change_view(self, request, object_id, form_url='', extra_context=None): + extra_context = extra_context or {} + extra_context['labadmin_available_devices'] = get_neighbours() + return super(DeviceAdmin, self).change_view( + request, object_id, form_url, extra_context=extra_context + ) + + def add_view(self, request, form_url='', extra_context=None): + extra_context = extra_context or {} + extra_context['labadmin_available_devices'] = get_neighbours() + return super(DeviceAdmin, self).add_view( + request, form_url, extra_context=extra_context + ) admin.site.register(Device, DeviceAdmin) diff --git a/labAdmin/arp.py b/labAdmin/arp.py new file mode 100644 index 0000000..952120f --- /dev/null +++ b/labAdmin/arp.py @@ -0,0 +1,20 @@ +IP_INDEX = 0 +MAC_INDEX = 3 +NUM_FIELDS = 6 + + +def get_neighbours(): + """ + Returns a generator of ip address, mac address tuples. + Empty mac addresses are filtered out. + """ + with open('/proc/net/arp', 'r') as f: + # skip header + next(f) + for row in f: + fields = row.split() + if len(fields) < NUM_FIELDS: + continue + if fields[MAC_INDEX] == '00:00:00:00:00:00': + continue + yield fields[IP_INDEX], fields[MAC_INDEX] diff --git a/labAdmin/templates/labadmin/admin/device_change_form.html b/labAdmin/templates/labadmin/admin/device_change_form.html new file mode 100644 index 0000000..22cb4dc --- /dev/null +++ b/labAdmin/templates/labadmin/admin/device_change_form.html @@ -0,0 +1,43 @@ +{% extends "admin/change_form.html" %} +{% load i18n admin_urls %} + +{% block object-tools %} +{% if not is_popup %} + +{% endif %} +{% endblock %} + +{% block admin_change_form_document_ready %} + +{% endblock %} diff --git a/labAdmin/tests.py b/labAdmin/tests.py index 4ba4082..43af0eb 100755 --- a/labAdmin/tests.py +++ b/labAdmin/tests.py @@ -1,5 +1,8 @@ import datetime import json +import io + +from unittest.mock import mock_open, patch from django.contrib.auth.models import User from django.test import TestCase, Client, override_settings @@ -13,6 +16,7 @@ Card, Group, LogAccess, Role, TimeSlot, UserProfile, LogCredits, Category, Device, LogDevice, LogError ) +from .arp import get_neighbours class TestLabAdmin(TestCase): @@ -518,3 +522,17 @@ def test_timeslot_manager_now(self): self.assertTrue(ts_now.exists()) self.assertEqual(ts_now.count(), 1) self.assertEqual(ts_now.first().pk, open_ts.pk) + + +class ArpTests(TestCase): + def test_read_neighbours(self): + data = io.StringIO('\n'.join([ + 'IP address HW type Flags HW address Mask Device', + '10.120.0.124 0x1 0x2 55:54:00:4a:b0:35 * wlan0', + '10.120.71.14 0x1 0x2 e4:2d:8c:5e:05:18 *', + '169.254.52.147 0x1 0x0 00:00:00:00:00:00 * virbr0' + ])) + with patch('builtins.open', return_value=data, create=True) as m: + result = list(get_neighbours()) + + self.assertEqual(result, [('10.120.0.124', '55:54:00:4a:b0:35')])