From 7b47e1d6d973fbb13346b841daa03da0d1652454 Mon Sep 17 00:00:00 2001 From: Nikolai R Kristiansen Date: Fri, 25 Mar 2016 13:41:58 +0100 Subject: [PATCH] refactor(admin): Move admin specific code out of models --- mdb/admin.py | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ mdb/models.py | 59 ------------------------------------------------- 2 files changed, 61 insertions(+), 59 deletions(-) diff --git a/mdb/admin.py b/mdb/admin.py index 3fc9f44..93e21a1 100644 --- a/mdb/admin.py +++ b/mdb/admin.py @@ -1,4 +1,7 @@ +import ipaddress + from django.contrib import admin, messages +from django.db.models import Count from mdb.forms import InterfaceForm from mdb.models import Ip6Address, Interface, Ip4Address, DhcpOption, DhcpCustomField, DomainSrvRecord, DomainTxtRecord, \ DomainCnameRecord, DomainARecord, Domain, Host, Ip4Subnet, Ip6Subnet, Nameserver, MailExchange, OperatingSystem, \ @@ -46,6 +49,26 @@ class HostAdmin(admin.ModelAdmin): ) actions = ['set_installable'] + def mac_addresses(self, host): + addresses = host.interface_set.filter(macaddr__isnull=False).values_list('macaddr', flat=True) + return ", ".join(addresses) + + def ip_addresses(self, host): + addresses = host.interface_set.filter(ip4address__isnull=False).values_list('ip4address__address', flat=True) + return ", ".join(addresses) + + def in_domain(self, host): + domains = host.interface_set.values_list('domain__domain_name', flat=True) + return ",".join(domains) + + in_domain.short_description = "in domains" + + def ipv6_enabled(self, host): + ipv6_ifs = host.interface_set.annotate(num_ipv6=Count('ip6address')).filter(num_ipv6__gt=0) + return ipv6_ifs.exists() + + ipv6_enabled.boolean = True + def _get_host_warning_message(self, host, ifs): ifs_str = ', '.join([_if.name for _if in ifs]) return 'Host {} might not be installable since interface(s) {} has no IP set.'.format(host, ifs_str) @@ -74,6 +97,11 @@ class Ip4AddressInline(admin.TabularInline): extra = 0 readonly_fields = ['address', 'assigned_to_host'] + def assigned_to_host(self, addr): + return addr.interface.host + + assigned_to_host.short_description = "Assigned to Host" + class DhcpOptionInline(admin.TabularInline): model = DhcpOption @@ -89,6 +117,27 @@ class SubnetAdmin(admin.ModelAdmin): list_display = ['name', 'network', 'netmask', 'num_addresses', 'broadcast_address', 'first_address', 'last_address'] inlines = [DhcpOptionInline, DhcpCustomFieldInline, Ip4AddressInline] + def num_addresses(self, ip4subnet): + subnet = ipaddress.IPv4Network(ip4subnet.network + "/" + ip4subnet.netmask) + return subnet.num_addresses + + def broadcast_address(self, ip4subnet): + subnet = ipaddress.IPv4Network(ip4subnet.network + "/" + ip4subnet.netmask) + return subnet.broadcast_address + + def first_address(self, ip4subnet): + subnet = ipaddress.IPv4Network(ip4subnet.network + "/" + ip4subnet.netmask) + return next(subnet.hosts()) + + def last_address(self, ip4subnet): + subnet = ipaddress.IPv4Network(ip4subnet.network + "/" + ip4subnet.netmask) + return list(subnet.hosts())[-1] + + broadcast_address.short_description = 'broadcast' + num_addresses.short_description = '#addresses' + first_address.short_description = 'first address' + last_address.short_description = 'last address' + def get_queryset(self, request): # TODO: optimize return super(SubnetAdmin, self).get_queryset(request) @@ -125,6 +174,18 @@ class DomainAdmin(admin.ModelAdmin): list_display = ['domain_name', 'domain_soa', 'domain_admin', 'num_records', 'domain_ipaddr', 'domain_ip6addr'] search_fields = ['domain_name'] + def num_records(self, domain): + host_a_records = Host.objects.filter(interface__domain=domain).count() + size = { + "CNAME": domain.domaincnamerecord_set.count(), + "SRV": domain.domainsrvrecord_set.count(), + "TXT": domain.domaintxtrecord_set.count(), + "A": domain.domainarecord_set.count() + host_a_records + } + return ', '.join(['{}: {}'.format(k, v) for k, v in size.items()]) + + num_records.short_description = "Num Records" + class HostTypeAdmin(admin.ModelAdmin): list_display = ['host_type', 'description', 'num_members'] diff --git a/mdb/models.py b/mdb/models.py index 5e55122..8ac5bac 100644 --- a/mdb/models.py +++ b/mdb/models.py @@ -1,5 +1,4 @@ from django.db import models -from django.db.models import Count from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ from mdb.utils import host_as_pxe_files @@ -50,18 +49,6 @@ class Domain(models.Model): def __str__(self): return self.domain_name - def num_records(self): - host_a_records = Host.objects.filter(interface__domain=self).count() - size = { - "CNAME": self.domaincnamerecord_set.count(), - "SRV": self.domainsrvrecord_set.count(), - "TXT": self.domaintxtrecord_set.count(), - "A": self.domainarecord_set.count() + host_a_records - } - return ', '.join(['{}: {}'.format(k, v) for k, v in size.items()]) - - num_records.short_description = "Num Records" - def __eq__(self, other): if not other or not hasattr(other, 'domain_name'): return False @@ -380,27 +367,6 @@ class Ip4Subnet(models.Model): def __str__(self): return self.network + " (" + self.name + ")" - def num_addresses(self): - subnet = ipaddress.IPv4Network(self.network + "/" + self.netmask) - return subnet.num_addresses - - def broadcast_address(self): - subnet = ipaddress.IPv4Network(self.network + "/" + self.netmask) - return subnet.broadcast_address - - def first_address(self): - subnet = ipaddress.IPv4Network(self.network + "/" + self.netmask) - return next(subnet.hosts()) - - def last_address(self): - subnet = ipaddress.IPv4Network(self.network + "/" + self.netmask) - return list(subnet.hosts())[-1] - - broadcast_address.short_description = 'broadcast' - num_addresses.short_description = '#addresses' - first_address.short_description = 'first address' - last_address.short_description = 'last address' - def zone_file_contents(self, generate_unassigned=False): content = "" content += "; zone file for %s\n" % self.domain_name @@ -474,11 +440,6 @@ class Ip4Address(models.Model): def __str__(self): return self.address - def assigned_to_host(self): - return self.interface.host - - assigned_to_host.short_description = "Assigned to Host" - class Meta: verbose_name = 'IPv4 address' verbose_name_plural = 'IPv4 addresses' @@ -548,26 +509,6 @@ class Host(models.Model): def __str__(self): return self.hostname - def in_domain(self): - domains = self.interface_set.values_list('domain__domain_name', flat=True) - return ",".join(domains) - - in_domain.short_description = "in domains" - - def ipv6_enabled(self): - ipv6_ifs = self.interface_set.annotate(num_ipv6=Count('ip6address')).filter(num_ipv6__gt=0) - return ipv6_ifs.exists() - - ipv6_enabled.boolean = True - - def mac_addresses(self): - addresses = self.interface_set.filter(macaddr__isnull=False).values_list('macaddr', flat=True) - return ", ".join(addresses) - - def ip_addresses(self): - addresses = self.interface_set.filter(ip4address__isnull=False).values_list('ip4address__address', flat=True) - return ", ".join(addresses) - def as_pxe_files(self): return host_as_pxe_files(self)