From 1a8eea5aa943f4f63b76ecadcf9ee7c4ab60e6e2 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 14 Feb 2020 14:27:47 -0500 Subject: [PATCH 1/6] Fixes #4175: Fix potential exception when bulk editing objects from a filtered list --- docs/release-notes/version-2.7.md | 1 + netbox/templates/utilities/obj_list.html | 4 ++-- netbox/utilities/views.py | 6 +----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/release-notes/version-2.7.md b/docs/release-notes/version-2.7.md index d3b889513..e224196ad 100644 --- a/docs/release-notes/version-2.7.md +++ b/docs/release-notes/version-2.7.md @@ -9,6 +9,7 @@ * [#2519](https://github.com/netbox-community/netbox/issues/2519) - Avoid race condition when provisioning "next available" IPs/prefixes via the API * [#4168](https://github.com/netbox-community/netbox/issues/4168) - Role is not required when creating a virtual machine +* [#4175](https://github.com/netbox-community/netbox/issues/4175) - Fix potential exception when bulk editing objects from a filtered list --- diff --git a/netbox/templates/utilities/obj_list.html b/netbox/templates/utilities/obj_list.html index 020a37660..fe70edd3b 100644 --- a/netbox/templates/utilities/obj_list.html +++ b/netbox/templates/utilities/obj_list.html @@ -51,12 +51,12 @@
{% block bulk_buttons %}{% endblock %} {% if bulk_edit_url and permissions.change %} - {% endif %} {% if bulk_delete_url and permissions.delete %} - {% endif %} diff --git a/netbox/utilities/views.py b/netbox/utilities/views.py index c93842d4b..d0257324e 100644 --- a/netbox/utilities/views.py +++ b/netbox/utilities/views.py @@ -634,7 +634,7 @@ class BulkEditView(GetReturnURLMixin, View): post_data['pk'] = [obj.pk for obj in self.filterset(request.GET, model.objects.only('pk')).qs] if '_apply' in request.POST: - form = self.form(model, request.POST, initial=request.GET) + form = self.form(model, request.POST) if form.is_valid(): custom_fields = form.custom_fields if hasattr(form, 'custom_fields') else [] @@ -718,10 +718,6 @@ class BulkEditView(GetReturnURLMixin, View): else: # Pass the PK list as initial data to avoid binding the form initial_data = querydict_to_dict(post_data) - - # Append any normal initial data (passed as GET parameters) - initial_data.update(request.GET) - form = self.form(model, initial=initial_data) # Retrieve objects being edited From b475a575e43003143ae80f858995934a89319860 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 14 Feb 2020 15:04:33 -0500 Subject: [PATCH 2/6] Drop family column from Aggregate, Prefix, and IPAddress models --- netbox/ipam/fields.py | 2 + netbox/ipam/filters.py | 6 +- netbox/ipam/lookups.py | 9 +++ netbox/ipam/managers.py | 2 +- netbox/ipam/migrations/0035_drop_ip_family.py | 38 ++++++++++++ netbox/ipam/models.py | 58 +++++++++---------- netbox/ipam/views.py | 2 +- netbox/templates/ipam/aggregate.html | 2 +- netbox/templates/ipam/ipaddress.html | 2 +- netbox/templates/ipam/prefix.html | 2 +- 10 files changed, 83 insertions(+), 40 deletions(-) create mode 100644 netbox/ipam/migrations/0035_drop_ip_family.py diff --git a/netbox/ipam/fields.py b/netbox/ipam/fields.py index 456a7debc..7d28127a4 100644 --- a/netbox/ipam/fields.py +++ b/netbox/ipam/fields.py @@ -63,6 +63,7 @@ IPNetworkField.register_lookup(lookups.NetContained) IPNetworkField.register_lookup(lookups.NetContainedOrEqual) IPNetworkField.register_lookup(lookups.NetContains) IPNetworkField.register_lookup(lookups.NetContainsOrEquals) +IPNetworkField.register_lookup(lookups.NetFamily) IPNetworkField.register_lookup(lookups.NetMaskLength) @@ -90,4 +91,5 @@ IPAddressField.register_lookup(lookups.NetContainsOrEquals) IPAddressField.register_lookup(lookups.NetHost) IPAddressField.register_lookup(lookups.NetIn) IPAddressField.register_lookup(lookups.NetHostContained) +IPAddressField.register_lookup(lookups.NetFamily) IPAddressField.register_lookup(lookups.NetMaskLength) diff --git a/netbox/ipam/filters.py b/netbox/ipam/filters.py index 5f8bcabff..e773fed27 100644 --- a/netbox/ipam/filters.py +++ b/netbox/ipam/filters.py @@ -91,7 +91,7 @@ class AggregateFilterSet(CustomFieldFilterSet, CreatedUpdatedFilterSet): class Meta: model = Aggregate - fields = ['family', 'date_added'] + fields = ('date_added',) def search(self, queryset, name, value): if not value.strip(): @@ -211,7 +211,7 @@ class PrefixFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilt class Meta: model = Prefix - fields = ['family', 'is_pool'] + fields = ('is_pool',) def search(self, queryset, name, value): if not value.strip(): @@ -350,7 +350,7 @@ class IPAddressFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedF class Meta: model = IPAddress - fields = ['family', 'dns_name'] + fields = ('dns_name',) def search(self, queryset, name, value): if not value.strip(): diff --git a/netbox/ipam/lookups.py b/netbox/ipam/lookups.py index 62b356c5d..306e1e925 100644 --- a/netbox/ipam/lookups.py +++ b/netbox/ipam/lookups.py @@ -154,6 +154,15 @@ class NetHostContained(Lookup): return 'CAST(HOST(%s) AS INET) << %s' % (lhs, rhs), params +class NetFamily(Transform): + lookup_name = 'family' + function = 'FAMILY' + + @property + def output_field(self): + return IntegerField() + + class NetMaskLength(Transform): lookup_name = 'net_mask_length' function = 'MASKLEN' diff --git a/netbox/ipam/managers.py b/netbox/ipam/managers.py index 8aebc60ce..47dd08251 100644 --- a/netbox/ipam/managers.py +++ b/netbox/ipam/managers.py @@ -13,4 +13,4 @@ class IPAddressManager(models.Manager): IP address as a /32 or /128. """ qs = super().get_queryset() - return qs.annotate(host=RawSQL('INET(HOST(ipam_ipaddress.address))', [])).order_by('family', 'host') + return qs.annotate(host=RawSQL('INET(HOST(ipam_ipaddress.address))', [])).order_by('host') diff --git a/netbox/ipam/migrations/0035_drop_ip_family.py b/netbox/ipam/migrations/0035_drop_ip_family.py new file mode 100644 index 000000000..e0142973f --- /dev/null +++ b/netbox/ipam/migrations/0035_drop_ip_family.py @@ -0,0 +1,38 @@ +# Generated by Django 2.2.9 on 2020-02-14 19:36 + +from django.db import migrations +import django.db.models.expressions + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0034_fix_ipaddress_status_dhcp'), + ] + + operations = [ + migrations.AlterModelOptions( + name='aggregate', + options={'ordering': ('prefix', 'pk')}, + ), + migrations.AlterModelOptions( + name='ipaddress', + options={'ordering': ('address', 'pk'), 'verbose_name': 'IP address', 'verbose_name_plural': 'IP addresses'}, + ), + migrations.AlterModelOptions( + name='prefix', + options={'ordering': (django.db.models.expressions.OrderBy(django.db.models.expressions.F('vrf'), nulls_first=True), 'prefix', 'pk'), 'verbose_name_plural': 'prefixes'}, + ), + migrations.RemoveField( + model_name='aggregate', + name='family', + ), + migrations.RemoveField( + model_name='ipaddress', + name='family', + ), + migrations.RemoveField( + model_name='prefix', + name='family', + ), + ] diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index b4ba92fb5..025c4c8af 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -150,9 +150,6 @@ class Aggregate(ChangeLoggedModel, CustomFieldModel): An aggregate exists at the root level of the IP address space hierarchy in NetBox. Aggregates are used to organize the hierarchy and track the overall utilization of available address space. Each Aggregate is assigned to a RIR. """ - family = models.PositiveSmallIntegerField( - choices=IPAddressFamilyChoices - ) prefix = IPNetworkField() rir = models.ForeignKey( to='ipam.RIR', @@ -182,7 +179,7 @@ class Aggregate(ChangeLoggedModel, CustomFieldModel): ] class Meta: - ordering = ('family', 'prefix', 'pk') # (family, prefix) may be non-unique + ordering = ('prefix', 'pk') # prefix may be non-unique def __str__(self): return str(self.prefix) @@ -225,12 +222,6 @@ class Aggregate(ChangeLoggedModel, CustomFieldModel): ) }) - def save(self, *args, **kwargs): - if self.prefix: - # Infer address family from IPNetwork object - self.family = self.prefix.version - super().save(*args, **kwargs) - def to_csv(self): return ( self.prefix, @@ -239,6 +230,12 @@ class Aggregate(ChangeLoggedModel, CustomFieldModel): self.description, ) + @property + def family(self): + if self.prefix: + return self.prefix.version + return None + def get_utilization(self): """ Determine the prefix utilization of the aggregate and return it as a percentage. @@ -291,10 +288,6 @@ class Prefix(ChangeLoggedModel, CustomFieldModel): VRFs. A Prefix must be assigned a status and may optionally be assigned a used-define Role. A Prefix can also be assigned to a VLAN where appropriate. """ - family = models.PositiveSmallIntegerField( - choices=IPAddressFamilyChoices, - editable=False - ) prefix = IPNetworkField( help_text='IPv4 or IPv6 network with mask' ) @@ -376,7 +369,7 @@ class Prefix(ChangeLoggedModel, CustomFieldModel): } class Meta: - ordering = (F('vrf').asc(nulls_first=True), 'family', 'prefix', 'pk') # (vrf, family, prefix) may be non-unique + ordering = (F('vrf').asc(nulls_first=True), 'prefix', 'pk') # (vrf, prefix) may be non-unique verbose_name_plural = 'prefixes' def __str__(self): @@ -423,9 +416,6 @@ class Prefix(ChangeLoggedModel, CustomFieldModel): # Clear host bits from prefix self.prefix = self.prefix.cidr - # Record address family - self.family = self.prefix.version - super().save(*args, **kwargs) def to_csv(self): @@ -442,6 +432,12 @@ class Prefix(ChangeLoggedModel, CustomFieldModel): self.description, ) + @property + def family(self): + if self.prefix: + return self.prefix.version + return None + def _set_prefix_length(self, value): """ Expose the IPNetwork object's prefixlen attribute on the parent model so that it can be manipulated directly, @@ -501,9 +497,9 @@ class Prefix(ChangeLoggedModel, CustomFieldModel): # All IP addresses within a point-to-point prefix (IPv4 /31 or IPv6 /127) are considered usable if ( - self.family == 4 and self.prefix.prefixlen == 31 # RFC 3021 + self.prefix.version == 4 and self.prefix.prefixlen == 31 # RFC 3021 ) or ( - self.family == 6 and self.prefix.prefixlen == 127 # RFC 6164 + self.prefix.version == 6 and self.prefix.prefixlen == 127 # RFC 6164 ): return available_ips @@ -546,7 +542,7 @@ class Prefix(ChangeLoggedModel, CustomFieldModel): # Compile an IPSet to avoid counting duplicate IPs child_count = netaddr.IPSet([ip.address.ip for ip in self.get_child_ips()]).size prefix_size = self.prefix.size - if self.family == 4 and self.prefix.prefixlen < 31 and not self.is_pool: + if self.prefix.version == 4 and self.prefix.prefixlen < 31 and not self.is_pool: prefix_size -= 2 return int(float(child_count) / prefix_size * 100) @@ -562,10 +558,6 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel): for example, when mapping public addresses to private addresses. When an Interface has been assigned an IPAddress which has a NAT outside IP, that Interface's Device can use either the inside or outside IP as its primary IP. """ - family = models.PositiveSmallIntegerField( - choices=IPAddressFamilyChoices, - editable=False - ) address = IPAddressField( help_text='IPv4 or IPv6 address (with mask)' ) @@ -659,7 +651,7 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel): } class Meta: - ordering = ('family', 'address', 'pk') # (family, address) may be non-unique + ordering = ('address', 'pk') # address may be non-unique verbose_name = 'IP address' verbose_name_plural = 'IP addresses' @@ -727,10 +719,6 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel): def save(self, *args, **kwargs): - # Record address family - if isinstance(self.address, netaddr.IPNetwork): - self.family = self.address.version - # Force dns_name to lowercase self.dns_name = self.dns_name.lower() @@ -754,9 +742,9 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel): def to_csv(self): # Determine if this IP is primary for a Device - if self.family == 4 and getattr(self, 'primary_ip4_for', False): + if self.address.version == 4 and getattr(self, 'primary_ip4_for', False): is_primary = True - elif self.family == 6 and getattr(self, 'primary_ip6_for', False): + elif self.address.version == 6 and getattr(self, 'primary_ip6_for', False): is_primary = True else: is_primary = False @@ -775,6 +763,12 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel): self.description, ) + @property + def family(self): + if self.address: + return self.address.version + return None + def _set_mask_length(self, value): """ Expose the IPNetwork object's prefixlen attribute on the parent model so that it can be manipulated directly, diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 053098f0b..faf349222 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -207,7 +207,7 @@ class RIRListView(PermissionRequiredMixin, ObjectListView): 'deprecated': 0, 'available': 0, } - aggregate_list = Aggregate.objects.filter(family=family, rir=rir) + aggregate_list = Aggregate.objects.filter(prefix__family=family, rir=rir) for aggregate in aggregate_list: queryset = Prefix.objects.filter(prefix__net_contained_or_equal=str(aggregate.prefix)) diff --git a/netbox/templates/ipam/aggregate.html b/netbox/templates/ipam/aggregate.html index 66281aace..c34380722 100644 --- a/netbox/templates/ipam/aggregate.html +++ b/netbox/templates/ipam/aggregate.html @@ -64,7 +64,7 @@ - + diff --git a/netbox/templates/ipam/ipaddress.html b/netbox/templates/ipam/ipaddress.html index 50bd90610..167d3fddf 100644 --- a/netbox/templates/ipam/ipaddress.html +++ b/netbox/templates/ipam/ipaddress.html @@ -65,7 +65,7 @@
Family{{ aggregate.get_family_display }}IPv{{ aggregate.family }}
RIR
- + diff --git a/netbox/templates/ipam/prefix.html b/netbox/templates/ipam/prefix.html index 324bd927d..f14cab259 100644 --- a/netbox/templates/ipam/prefix.html +++ b/netbox/templates/ipam/prefix.html @@ -85,7 +85,7 @@
Family{{ ipaddress.get_family_display }}IPv{{ ipaddress.family }}
VRF
- + From 047f13ac5d47038568f49ea55d0861222a93e4b0 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 14 Feb 2020 15:07:59 -0500 Subject: [PATCH 3/6] Update tests --- netbox/dcim/tests/test_filters.py | 4 +- netbox/ipam/tests/test_filters.py | 52 +++++----- netbox/ipam/tests/test_models.py | 95 +++++++++--------- netbox/ipam/tests/test_ordering.py | 154 ++++++++++++++--------------- netbox/ipam/tests/test_views.py | 18 ++-- 5 files changed, 161 insertions(+), 162 deletions(-) diff --git a/netbox/dcim/tests/test_filters.py b/netbox/dcim/tests/test_filters.py index 83f40fe56..16c1ca58d 100644 --- a/netbox/dcim/tests/test_filters.py +++ b/netbox/dcim/tests/test_filters.py @@ -1144,8 +1144,8 @@ class DeviceTestCase(TestCase): # Assign primary IPs for filtering ipaddresses = ( - IPAddress(family=4, address='192.0.2.1/24', interface=interfaces[0]), - IPAddress(family=4, address='192.0.2.2/24', interface=interfaces[1]), + IPAddress(address='192.0.2.1/24', interface=interfaces[0]), + IPAddress(address='192.0.2.2/24', interface=interfaces[1]), ) IPAddress.objects.bulk_create(ipaddresses) Device.objects.filter(pk=devices[0].pk).update(primary_ip4=ipaddresses[0]) diff --git a/netbox/ipam/tests/test_filters.py b/netbox/ipam/tests/test_filters.py index 4737a0f53..f523b1d20 100644 --- a/netbox/ipam/tests/test_filters.py +++ b/netbox/ipam/tests/test_filters.py @@ -96,12 +96,12 @@ class AggregateTestCase(TestCase): RIR.objects.bulk_create(rirs) aggregates = ( - Aggregate(family=4, prefix='10.1.0.0/16', rir=rirs[0], date_added='2020-01-01'), - Aggregate(family=4, prefix='10.2.0.0/16', rir=rirs[0], date_added='2020-01-02'), - Aggregate(family=4, prefix='10.3.0.0/16', rir=rirs[1], date_added='2020-01-03'), - Aggregate(family=6, prefix='2001:db8:1::/48', rir=rirs[1], date_added='2020-01-04'), - Aggregate(family=6, prefix='2001:db8:2::/48', rir=rirs[2], date_added='2020-01-05'), - Aggregate(family=6, prefix='2001:db8:3::/48', rir=rirs[2], date_added='2020-01-06'), + Aggregate(prefix='10.1.0.0/16', rir=rirs[0], date_added='2020-01-01'), + Aggregate(prefix='10.2.0.0/16', rir=rirs[0], date_added='2020-01-02'), + Aggregate(prefix='10.3.0.0/16', rir=rirs[1], date_added='2020-01-03'), + Aggregate(prefix='2001:db8:1::/48', rir=rirs[1], date_added='2020-01-04'), + Aggregate(prefix='2001:db8:2::/48', rir=rirs[2], date_added='2020-01-05'), + Aggregate(prefix='2001:db8:3::/48', rir=rirs[2], date_added='2020-01-06'), ) Aggregate.objects.bulk_create(aggregates) @@ -199,16 +199,16 @@ class PrefixTestCase(TestCase): Role.objects.bulk_create(roles) prefixes = ( - Prefix(family=4, prefix='10.0.0.0/24', site=None, vrf=None, vlan=None, role=None, is_pool=True), - Prefix(family=4, prefix='10.0.1.0/24', site=sites[0], vrf=vrfs[0], vlan=vlans[0], role=roles[0]), - Prefix(family=4, prefix='10.0.2.0/24', site=sites[1], vrf=vrfs[1], vlan=vlans[1], role=roles[1], status=PrefixStatusChoices.STATUS_DEPRECATED), - Prefix(family=4, prefix='10.0.3.0/24', site=sites[2], vrf=vrfs[2], vlan=vlans[2], role=roles[2], status=PrefixStatusChoices.STATUS_RESERVED), - Prefix(family=6, prefix='2001:db8::/64', site=None, vrf=None, vlan=None, role=None, is_pool=True), - Prefix(family=6, prefix='2001:db8:0:1::/64', site=sites[0], vrf=vrfs[0], vlan=vlans[0], role=roles[0]), - Prefix(family=6, prefix='2001:db8:0:2::/64', site=sites[1], vrf=vrfs[1], vlan=vlans[1], role=roles[1], status=PrefixStatusChoices.STATUS_DEPRECATED), - Prefix(family=6, prefix='2001:db8:0:3::/64', site=sites[2], vrf=vrfs[2], vlan=vlans[2], role=roles[2], status=PrefixStatusChoices.STATUS_RESERVED), - Prefix(family=4, prefix='10.0.0.0/16'), - Prefix(family=6, prefix='2001:db8::/32'), + Prefix(prefix='10.0.0.0/24', site=None, vrf=None, vlan=None, role=None, is_pool=True), + Prefix(prefix='10.0.1.0/24', site=sites[0], vrf=vrfs[0], vlan=vlans[0], role=roles[0]), + Prefix(prefix='10.0.2.0/24', site=sites[1], vrf=vrfs[1], vlan=vlans[1], role=roles[1], status=PrefixStatusChoices.STATUS_DEPRECATED), + Prefix(prefix='10.0.3.0/24', site=sites[2], vrf=vrfs[2], vlan=vlans[2], role=roles[2], status=PrefixStatusChoices.STATUS_RESERVED), + Prefix(prefix='2001:db8::/64', site=None, vrf=None, vlan=None, role=None, is_pool=True), + Prefix(prefix='2001:db8:0:1::/64', site=sites[0], vrf=vrfs[0], vlan=vlans[0], role=roles[0]), + Prefix(prefix='2001:db8:0:2::/64', site=sites[1], vrf=vrfs[1], vlan=vlans[1], role=roles[1], status=PrefixStatusChoices.STATUS_DEPRECATED), + Prefix(prefix='2001:db8:0:3::/64', site=sites[2], vrf=vrfs[2], vlan=vlans[2], role=roles[2], status=PrefixStatusChoices.STATUS_RESERVED), + Prefix(prefix='10.0.0.0/16'), + Prefix(prefix='2001:db8::/32'), ) Prefix.objects.bulk_create(prefixes) @@ -333,16 +333,16 @@ class IPAddressTestCase(TestCase): Interface.objects.bulk_create(interfaces) ipaddresses = ( - IPAddress(family=4, address='10.0.0.1/24', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-a'), - IPAddress(family=4, address='10.0.0.2/24', vrf=vrfs[0], interface=interfaces[0], status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-b'), - IPAddress(family=4, address='10.0.0.3/24', vrf=vrfs[1], interface=interfaces[1], status=IPAddressStatusChoices.STATUS_RESERVED, role=IPAddressRoleChoices.ROLE_VIP, dns_name='ipaddress-c'), - IPAddress(family=4, address='10.0.0.4/24', vrf=vrfs[2], interface=interfaces[2], status=IPAddressStatusChoices.STATUS_DEPRECATED, role=IPAddressRoleChoices.ROLE_SECONDARY, dns_name='ipaddress-d'), - IPAddress(family=4, address='10.0.0.1/25', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE), - IPAddress(family=6, address='2001:db8::1/64', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-a'), - IPAddress(family=6, address='2001:db8::2/64', vrf=vrfs[0], interface=interfaces[3], status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-b'), - IPAddress(family=6, address='2001:db8::3/64', vrf=vrfs[1], interface=interfaces[4], status=IPAddressStatusChoices.STATUS_RESERVED, role=IPAddressRoleChoices.ROLE_VIP, dns_name='ipaddress-c'), - IPAddress(family=6, address='2001:db8::4/64', vrf=vrfs[2], interface=interfaces[5], status=IPAddressStatusChoices.STATUS_DEPRECATED, role=IPAddressRoleChoices.ROLE_SECONDARY, dns_name='ipaddress-d'), - IPAddress(family=6, address='2001:db8::1/65', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE), + IPAddress(address='10.0.0.1/24', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-a'), + IPAddress(address='10.0.0.2/24', vrf=vrfs[0], interface=interfaces[0], status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-b'), + IPAddress(address='10.0.0.3/24', vrf=vrfs[1], interface=interfaces[1], status=IPAddressStatusChoices.STATUS_RESERVED, role=IPAddressRoleChoices.ROLE_VIP, dns_name='ipaddress-c'), + IPAddress(address='10.0.0.4/24', vrf=vrfs[2], interface=interfaces[2], status=IPAddressStatusChoices.STATUS_DEPRECATED, role=IPAddressRoleChoices.ROLE_SECONDARY, dns_name='ipaddress-d'), + IPAddress(address='10.0.0.1/25', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE), + IPAddress(address='2001:db8::1/64', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-a'), + IPAddress(address='2001:db8::2/64', vrf=vrfs[0], interface=interfaces[3], status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-b'), + IPAddress(address='2001:db8::3/64', vrf=vrfs[1], interface=interfaces[4], status=IPAddressStatusChoices.STATUS_RESERVED, role=IPAddressRoleChoices.ROLE_VIP, dns_name='ipaddress-c'), + IPAddress(address='2001:db8::4/64', vrf=vrfs[2], interface=interfaces[5], status=IPAddressStatusChoices.STATUS_DEPRECATED, role=IPAddressRoleChoices.ROLE_SECONDARY, dns_name='ipaddress-d'), + IPAddress(address='2001:db8::1/65', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE), ) IPAddress.objects.bulk_create(ipaddresses) diff --git a/netbox/ipam/tests/test_models.py b/netbox/ipam/tests/test_models.py index 235fae67f..6091aa70e 100644 --- a/netbox/ipam/tests/test_models.py +++ b/netbox/ipam/tests/test_models.py @@ -15,22 +15,22 @@ class TestAggregate(TestCase): # 25% utilization Prefix.objects.bulk_create(( - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/12')), - Prefix(family=4, prefix=netaddr.IPNetwork('10.16.0.0/12')), - Prefix(family=4, prefix=netaddr.IPNetwork('10.32.0.0/12')), - Prefix(family=4, prefix=netaddr.IPNetwork('10.48.0.0/12')), + Prefix(prefix=netaddr.IPNetwork('10.0.0.0/12')), + Prefix(prefix=netaddr.IPNetwork('10.16.0.0/12')), + Prefix(prefix=netaddr.IPNetwork('10.32.0.0/12')), + Prefix(prefix=netaddr.IPNetwork('10.48.0.0/12')), )) self.assertEqual(aggregate.get_utilization(), 25) # 50% utilization Prefix.objects.bulk_create(( - Prefix(family=4, prefix=netaddr.IPNetwork('10.64.0.0/10')), + Prefix(prefix=netaddr.IPNetwork('10.64.0.0/10')), )) self.assertEqual(aggregate.get_utilization(), 50) # 100% utilization Prefix.objects.bulk_create(( - Prefix(family=4, prefix=netaddr.IPNetwork('10.128.0.0/9')), + Prefix(prefix=netaddr.IPNetwork('10.128.0.0/9')), )) self.assertEqual(aggregate.get_utilization(), 100) @@ -39,9 +39,9 @@ class TestPrefix(TestCase): def test_get_duplicates(self): prefixes = Prefix.objects.bulk_create(( - Prefix(family=4, prefix=netaddr.IPNetwork('192.0.2.0/24')), - Prefix(family=4, prefix=netaddr.IPNetwork('192.0.2.0/24')), - Prefix(family=4, prefix=netaddr.IPNetwork('192.0.2.0/24')), + Prefix(prefix=netaddr.IPNetwork('192.0.2.0/24')), + Prefix(prefix=netaddr.IPNetwork('192.0.2.0/24')), + Prefix(prefix=netaddr.IPNetwork('192.0.2.0/24')), )) duplicate_prefix_pks = [p.pk for p in prefixes[0].get_duplicates()] @@ -54,11 +54,11 @@ class TestPrefix(TestCase): VRF(name='VRF 3'), )) prefixes = Prefix.objects.bulk_create(( - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/16'), status=PrefixStatusChoices.STATUS_CONTAINER), - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/24'), vrf=None), - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.1.0/24'), vrf=vrfs[0]), - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.2.0/24'), vrf=vrfs[1]), - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.3.0/24'), vrf=vrfs[2]), + Prefix(prefix=netaddr.IPNetwork('10.0.0.0/16'), status=PrefixStatusChoices.STATUS_CONTAINER), + Prefix(prefix=netaddr.IPNetwork('10.0.0.0/24'), vrf=None), + Prefix(prefix=netaddr.IPNetwork('10.0.1.0/24'), vrf=vrfs[0]), + Prefix(prefix=netaddr.IPNetwork('10.0.2.0/24'), vrf=vrfs[1]), + Prefix(prefix=netaddr.IPNetwork('10.0.3.0/24'), vrf=vrfs[2]), )) child_prefix_pks = {p.pk for p in prefixes[0].get_child_prefixes()} @@ -79,13 +79,13 @@ class TestPrefix(TestCase): VRF(name='VRF 3'), )) parent_prefix = Prefix.objects.create( - family=4, prefix=netaddr.IPNetwork('10.0.0.0/16'), status=PrefixStatusChoices.STATUS_CONTAINER + prefix=netaddr.IPNetwork('10.0.0.0/16'), status=PrefixStatusChoices.STATUS_CONTAINER ) ips = IPAddress.objects.bulk_create(( - IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.1/24'), vrf=None), - IPAddress(family=4, address=netaddr.IPNetwork('10.0.1.1/24'), vrf=vrfs[0]), - IPAddress(family=4, address=netaddr.IPNetwork('10.0.2.1/24'), vrf=vrfs[1]), - IPAddress(family=4, address=netaddr.IPNetwork('10.0.3.1/24'), vrf=vrfs[2]), + IPAddress(address=netaddr.IPNetwork('10.0.0.1/24'), vrf=None), + IPAddress(address=netaddr.IPNetwork('10.0.1.1/24'), vrf=vrfs[0]), + IPAddress(address=netaddr.IPNetwork('10.0.2.1/24'), vrf=vrfs[1]), + IPAddress(address=netaddr.IPNetwork('10.0.3.1/24'), vrf=vrfs[2]), )) child_ip_pks = {p.pk for p in parent_prefix.get_child_ips()} @@ -102,10 +102,10 @@ class TestPrefix(TestCase): def test_get_available_prefixes(self): prefixes = Prefix.objects.bulk_create(( - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/16')), # Parent prefix - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/20')), - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.32.0/20')), - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.128.0/18')), + Prefix(prefix=netaddr.IPNetwork('10.0.0.0/16')), # Parent prefix + Prefix(prefix=netaddr.IPNetwork('10.0.0.0/20')), + Prefix(prefix=netaddr.IPNetwork('10.0.32.0/20')), + Prefix(prefix=netaddr.IPNetwork('10.0.128.0/18')), )) missing_prefixes = netaddr.IPSet([ netaddr.IPNetwork('10.0.16.0/20'), @@ -119,15 +119,15 @@ class TestPrefix(TestCase): def test_get_available_ips(self): - parent_prefix = Prefix.objects.create(family=4, prefix=netaddr.IPNetwork('10.0.0.0/28')) + parent_prefix = Prefix.objects.create(prefix=netaddr.IPNetwork('10.0.0.0/28')) IPAddress.objects.bulk_create(( - IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.1/26')), - IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.3/26')), - IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.5/26')), - IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.7/26')), - IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.9/26')), - IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.11/26')), - IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.13/26')), + IPAddress(address=netaddr.IPNetwork('10.0.0.1/26')), + IPAddress(address=netaddr.IPNetwork('10.0.0.3/26')), + IPAddress(address=netaddr.IPNetwork('10.0.0.5/26')), + IPAddress(address=netaddr.IPNetwork('10.0.0.7/26')), + IPAddress(address=netaddr.IPNetwork('10.0.0.9/26')), + IPAddress(address=netaddr.IPNetwork('10.0.0.11/26')), + IPAddress(address=netaddr.IPNetwork('10.0.0.13/26')), )) missing_ips = netaddr.IPSet([ '10.0.0.2/32', @@ -145,40 +145,39 @@ class TestPrefix(TestCase): def test_get_first_available_prefix(self): prefixes = Prefix.objects.bulk_create(( - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/16')), # Parent prefix - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/24')), - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.1.0/24')), - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.2.0/24')), + Prefix(prefix=netaddr.IPNetwork('10.0.0.0/16')), # Parent prefix + Prefix(prefix=netaddr.IPNetwork('10.0.0.0/24')), + Prefix(prefix=netaddr.IPNetwork('10.0.1.0/24')), + Prefix(prefix=netaddr.IPNetwork('10.0.2.0/24')), )) self.assertEqual(prefixes[0].get_first_available_prefix(), netaddr.IPNetwork('10.0.3.0/24')) - Prefix.objects.create(family=4, prefix=netaddr.IPNetwork('10.0.3.0/24')) + Prefix.objects.create(prefix=netaddr.IPNetwork('10.0.3.0/24')) self.assertEqual(prefixes[0].get_first_available_prefix(), netaddr.IPNetwork('10.0.4.0/22')) def test_get_first_available_ip(self): - parent_prefix = Prefix.objects.create(family=4, prefix=netaddr.IPNetwork('10.0.0.0/24')) + parent_prefix = Prefix.objects.create(prefix=netaddr.IPNetwork('10.0.0.0/24')) IPAddress.objects.bulk_create(( - IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.1/24')), - IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.2/24')), - IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.3/24')), + IPAddress(address=netaddr.IPNetwork('10.0.0.1/24')), + IPAddress(address=netaddr.IPNetwork('10.0.0.2/24')), + IPAddress(address=netaddr.IPNetwork('10.0.0.3/24')), )) self.assertEqual(parent_prefix.get_first_available_ip(), '10.0.0.4/24') - IPAddress.objects.create(family=4, address=netaddr.IPNetwork('10.0.0.4/24')) + IPAddress.objects.create(address=netaddr.IPNetwork('10.0.0.4/24')) self.assertEqual(parent_prefix.get_first_available_ip(), '10.0.0.5/24') def test_get_utilization(self): # Container Prefix prefix = Prefix.objects.create( - family=4, prefix=netaddr.IPNetwork('10.0.0.0/24'), status=PrefixStatusChoices.STATUS_CONTAINER ) Prefix.objects.bulk_create(( - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/26')), - Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.128/26')), + Prefix(prefix=netaddr.IPNetwork('10.0.0.0/26')), + Prefix(prefix=netaddr.IPNetwork('10.0.0.128/26')), )) self.assertEqual(prefix.get_utilization(), 50) @@ -187,7 +186,7 @@ class TestPrefix(TestCase): prefix.save() IPAddress.objects.bulk_create( # Create 32 IPAddresses within the Prefix - [IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.{}/24'.format(i))) for i in range(1, 33)] + [IPAddress(address=netaddr.IPNetwork('10.0.0.{}/24'.format(i))) for i in range(1, 33)] ) self.assertEqual(prefix.get_utilization(), 12) # ~= 12% @@ -224,9 +223,9 @@ class TestIPAddress(TestCase): def test_get_duplicates(self): ips = IPAddress.objects.bulk_create(( - IPAddress(family=4, address=netaddr.IPNetwork('192.0.2.1/24')), - IPAddress(family=4, address=netaddr.IPNetwork('192.0.2.1/24')), - IPAddress(family=4, address=netaddr.IPNetwork('192.0.2.1/24')), + IPAddress(address=netaddr.IPNetwork('192.0.2.1/24')), + IPAddress(address=netaddr.IPNetwork('192.0.2.1/24')), + IPAddress(address=netaddr.IPNetwork('192.0.2.1/24')), )) duplicate_ip_pks = [p.pk for p in ips[0].get_duplicates()] diff --git a/netbox/ipam/tests/test_ordering.py b/netbox/ipam/tests/test_ordering.py index 153bedddc..690501e53 100644 --- a/netbox/ipam/tests/test_ordering.py +++ b/netbox/ipam/tests/test_ordering.py @@ -42,45 +42,45 @@ class PrefixOrderingTestCase(OrderingTestBase): # Setup Prefixes prefixes = ( - Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.0.0/16')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.0.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.1.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.2.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.3.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.4.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.5.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=None, prefix=netaddr.IPNetwork('192.168.0.0/16')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('192.168.0.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('192.168.1.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('192.168.2.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('192.168.3.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('192.168.4.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('192.168.5.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.0.0/8')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.0.0/16')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.0.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.1.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.2.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.3.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.4.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.1.0.0/16')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.1.1.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.1.2.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.1.3.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.1.4.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.2.0.0/16')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.2.1.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.2.2.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.2.3.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.2.4.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.0.0/8')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.0.0/16')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.0.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.1.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.2.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.3.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.4.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.1.0.0/16')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.1.1.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.1.2.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.1.3.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.1.4.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.2.0.0/16')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.2.1.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.2.2.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.2.3.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.2.4.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.16.0.0/12')), - Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.16.0.0/16')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.16.0.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.16.1.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.16.2.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.16.3.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.16.4.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.17.0.0/16')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.17.0.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.17.1.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.17.2.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.17.3.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.17.4.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=vrfb, prefix=netaddr.IPNetwork('172.16.0.0/12')), + Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=vrfb, prefix=netaddr.IPNetwork('172.16.0.0/16')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.16.0.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.16.1.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.16.2.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.16.3.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.16.4.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=vrfb, prefix=netaddr.IPNetwork('172.17.0.0/16')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.17.0.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.17.1.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.17.2.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.17.3.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.17.4.0/24')), ) Prefix.objects.bulk_create(prefixes) @@ -109,15 +109,15 @@ class PrefixOrderingTestCase(OrderingTestBase): # Setup Prefixes prefixes = [ - Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=None, family=4, prefix=netaddr.IPNetwork('10.0.0.0/8')), - Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=None, family=4, prefix=netaddr.IPNetwork('10.0.0.0/16')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('10.1.0.0/16')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.0.0/16')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.0.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.1.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.1.0/25')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.1.0.0/24')), - Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.1.1.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=None, prefix=netaddr.IPNetwork('10.0.0.0/8')), + Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=None, prefix=netaddr.IPNetwork('10.0.0.0/16')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('10.1.0.0/16')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('192.168.0.0/16')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.0.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.1.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.1.0/25')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.1.0.0/24')), + Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.1.1.0/24')), ] Prefix.objects.bulk_create(prefixes) @@ -136,39 +136,39 @@ class IPAddressOrderingTestCase(OrderingTestBase): # Setup Addresses addresses = ( - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.0.0.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.0.1.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.0.2.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.0.3.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.0.4.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.1.0.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.1.1.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.1.2.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.1.3.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.1.4.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.2.0.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.2.1.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.2.2.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.2.3.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.2.4.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.0.0.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.0.1.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.0.2.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.0.3.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.0.4.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.1.0.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.1.1.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.1.2.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.1.3.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.1.4.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.2.0.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.2.1.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.2.2.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.2.3.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.2.4.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.16.0.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.16.1.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.16.2.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.16.3.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.16.4.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.17.0.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.17.1.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.17.2.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.17.3.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.17.4.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.16.0.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.16.1.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.16.2.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.16.3.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.16.4.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.17.0.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.17.1.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.17.2.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.17.3.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.17.4.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, family=4, address=netaddr.IPNetwork('192.168.0.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, family=4, address=netaddr.IPNetwork('192.168.1.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, family=4, address=netaddr.IPNetwork('192.168.2.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, family=4, address=netaddr.IPNetwork('192.168.3.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, family=4, address=netaddr.IPNetwork('192.168.4.1/24')), - IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, family=4, address=netaddr.IPNetwork('192.168.5.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.0.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.1.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.2.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.3.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.4.1/24')), + IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.5.1/24')), ) IPAddress.objects.bulk_create(addresses) diff --git a/netbox/ipam/tests/test_views.py b/netbox/ipam/tests/test_views.py index 66e649005..82ae18faf 100644 --- a/netbox/ipam/tests/test_views.py +++ b/netbox/ipam/tests/test_views.py @@ -82,9 +82,9 @@ class AggregateTestCase(ViewTestCases.PrimaryObjectViewTestCase): RIR.objects.bulk_create(rirs) Aggregate.objects.bulk_create([ - Aggregate(family=4, prefix=IPNetwork('10.1.0.0/16'), rir=rirs[0]), - Aggregate(family=4, prefix=IPNetwork('10.2.0.0/16'), rir=rirs[0]), - Aggregate(family=4, prefix=IPNetwork('10.3.0.0/16'), rir=rirs[0]), + Aggregate(prefix=IPNetwork('10.1.0.0/16'), rir=rirs[0]), + Aggregate(prefix=IPNetwork('10.2.0.0/16'), rir=rirs[0]), + Aggregate(prefix=IPNetwork('10.3.0.0/16'), rir=rirs[0]), ]) cls.form_data = { @@ -161,9 +161,9 @@ class PrefixTestCase(ViewTestCases.PrimaryObjectViewTestCase): ) Prefix.objects.bulk_create([ - Prefix(family=4, prefix=IPNetwork('10.1.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]), - Prefix(family=4, prefix=IPNetwork('10.2.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]), - Prefix(family=4, prefix=IPNetwork('10.3.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]), + Prefix(prefix=IPNetwork('10.1.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]), + Prefix(prefix=IPNetwork('10.2.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]), + Prefix(prefix=IPNetwork('10.3.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]), ]) cls.form_data = { @@ -209,9 +209,9 @@ class IPAddressTestCase(ViewTestCases.PrimaryObjectViewTestCase): ) IPAddress.objects.bulk_create([ - IPAddress(family=4, address=IPNetwork('192.0.2.1/24'), vrf=vrfs[0]), - IPAddress(family=4, address=IPNetwork('192.0.2.2/24'), vrf=vrfs[0]), - IPAddress(family=4, address=IPNetwork('192.0.2.3/24'), vrf=vrfs[0]), + IPAddress(address=IPNetwork('192.0.2.1/24'), vrf=vrfs[0]), + IPAddress(address=IPNetwork('192.0.2.2/24'), vrf=vrfs[0]), + IPAddress(address=IPNetwork('192.0.2.3/24'), vrf=vrfs[0]), ]) cls.form_data = { From 8687226cc74b2dfb2c1e06ef929f57e0a58b953d Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 14 Feb 2020 15:11:12 -0500 Subject: [PATCH 4/6] Update family filters in querysets --- netbox/dcim/forms.py | 4 ++-- netbox/virtualization/forms.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 4c8a0821f..ad750404b 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1857,14 +1857,14 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): # Collect interface IPs interface_ips = IPAddress.objects.prefetch_related('interface').filter( - family=family, interface_id__in=interface_ids + address__family=family, interface_id__in=interface_ids ) if interface_ips: ip_list = [(ip.id, '{} ({})'.format(ip.address, ip.interface)) for ip in interface_ips] ip_choices.append(('Interface IPs', ip_list)) # Collect NAT IPs nat_ips = IPAddress.objects.prefetch_related('nat_inside').filter( - family=family, nat_inside__interface__in=interface_ids + address__family=family, nat_inside__interface__in=interface_ids ) if nat_ips: ip_list = [(ip.id, '{} ({})'.format(ip.address, ip.nat_inside.address)) for ip in nat_ips] diff --git a/netbox/virtualization/forms.py b/netbox/virtualization/forms.py index 0dbe38324..d110545c7 100644 --- a/netbox/virtualization/forms.py +++ b/netbox/virtualization/forms.py @@ -408,7 +408,7 @@ class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): ip_choices = [(None, '---------')] # Collect interface IPs interface_ips = IPAddress.objects.prefetch_related('interface').filter( - family=family, interface__virtual_machine=self.instance + address__family=family, interface__virtual_machine=self.instance ) if interface_ips: ip_choices.append( @@ -418,7 +418,7 @@ class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): ) # Collect NAT IPs nat_ips = IPAddress.objects.prefetch_related('nat_inside').filter( - family=family, nat_inside__interface__virtual_machine=self.instance + address__family=family, nat_inside__interface__virtual_machine=self.instance ) if nat_ips: ip_choices.append( From fcdb05238c5ce46e9dac4fd12e640b4decc9d9ad Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 14 Feb 2020 15:16:18 -0500 Subject: [PATCH 5/6] Restore filters --- netbox/ipam/filters.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/netbox/ipam/filters.py b/netbox/ipam/filters.py index e773fed27..486a33a2e 100644 --- a/netbox/ipam/filters.py +++ b/netbox/ipam/filters.py @@ -73,6 +73,10 @@ class AggregateFilterSet(CustomFieldFilterSet, CreatedUpdatedFilterSet): method='search', label='Search', ) + family = django_filters.NumberFilter( + field_name='prefix', + lookup_expr='family' + ) prefix = django_filters.CharFilter( method='filter_prefix', label='Prefix', @@ -134,6 +138,10 @@ class PrefixFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilt method='search', label='Search', ) + family = django_filters.NumberFilter( + field_name='prefix', + lookup_expr='family' + ) prefix = django_filters.CharFilter( method='filter_prefix', label='Prefix', @@ -282,6 +290,10 @@ class IPAddressFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedF method='search', label='Search', ) + family = django_filters.NumberFilter( + field_name='address', + lookup_expr='family' + ) parent = django_filters.CharFilter( method='search_by_parent', label='Parent prefix', From f0ced98dc6cbe25df11191fcceb6676ceb2e19c0 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 14 Feb 2020 15:17:04 -0500 Subject: [PATCH 6/6] Delete unused test data --- netbox/ipam/tests/test_views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/netbox/ipam/tests/test_views.py b/netbox/ipam/tests/test_views.py index 82ae18faf..e168f02a4 100644 --- a/netbox/ipam/tests/test_views.py +++ b/netbox/ipam/tests/test_views.py @@ -88,7 +88,6 @@ class AggregateTestCase(ViewTestCases.PrimaryObjectViewTestCase): ]) cls.form_data = { - 'family': 4, 'prefix': IPNetwork('10.99.0.0/16'), 'rir': rirs[1].pk, 'date_added': datetime.date(2020, 1, 1),
Family{{ prefix.get_family_display }}IPv{{ prefix.family }}
VRF