mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-24 17:38:37 -06:00
Drop family column from Aggregate, Prefix, and IPAddress models
This commit is contained in:
parent
1a8eea5aa9
commit
b475a575e4
@ -63,6 +63,7 @@ IPNetworkField.register_lookup(lookups.NetContained)
|
|||||||
IPNetworkField.register_lookup(lookups.NetContainedOrEqual)
|
IPNetworkField.register_lookup(lookups.NetContainedOrEqual)
|
||||||
IPNetworkField.register_lookup(lookups.NetContains)
|
IPNetworkField.register_lookup(lookups.NetContains)
|
||||||
IPNetworkField.register_lookup(lookups.NetContainsOrEquals)
|
IPNetworkField.register_lookup(lookups.NetContainsOrEquals)
|
||||||
|
IPNetworkField.register_lookup(lookups.NetFamily)
|
||||||
IPNetworkField.register_lookup(lookups.NetMaskLength)
|
IPNetworkField.register_lookup(lookups.NetMaskLength)
|
||||||
|
|
||||||
|
|
||||||
@ -90,4 +91,5 @@ IPAddressField.register_lookup(lookups.NetContainsOrEquals)
|
|||||||
IPAddressField.register_lookup(lookups.NetHost)
|
IPAddressField.register_lookup(lookups.NetHost)
|
||||||
IPAddressField.register_lookup(lookups.NetIn)
|
IPAddressField.register_lookup(lookups.NetIn)
|
||||||
IPAddressField.register_lookup(lookups.NetHostContained)
|
IPAddressField.register_lookup(lookups.NetHostContained)
|
||||||
|
IPAddressField.register_lookup(lookups.NetFamily)
|
||||||
IPAddressField.register_lookup(lookups.NetMaskLength)
|
IPAddressField.register_lookup(lookups.NetMaskLength)
|
||||||
|
@ -91,7 +91,7 @@ class AggregateFilterSet(CustomFieldFilterSet, CreatedUpdatedFilterSet):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Aggregate
|
model = Aggregate
|
||||||
fields = ['family', 'date_added']
|
fields = ('date_added',)
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
if not value.strip():
|
if not value.strip():
|
||||||
@ -211,7 +211,7 @@ class PrefixFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilt
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Prefix
|
model = Prefix
|
||||||
fields = ['family', 'is_pool']
|
fields = ('is_pool',)
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
if not value.strip():
|
if not value.strip():
|
||||||
@ -350,7 +350,7 @@ class IPAddressFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedF
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IPAddress
|
model = IPAddress
|
||||||
fields = ['family', 'dns_name']
|
fields = ('dns_name',)
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
if not value.strip():
|
if not value.strip():
|
||||||
|
@ -154,6 +154,15 @@ class NetHostContained(Lookup):
|
|||||||
return 'CAST(HOST(%s) AS INET) << %s' % (lhs, rhs), params
|
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):
|
class NetMaskLength(Transform):
|
||||||
lookup_name = 'net_mask_length'
|
lookup_name = 'net_mask_length'
|
||||||
function = 'MASKLEN'
|
function = 'MASKLEN'
|
||||||
|
@ -13,4 +13,4 @@ class IPAddressManager(models.Manager):
|
|||||||
IP address as a /32 or /128.
|
IP address as a /32 or /128.
|
||||||
"""
|
"""
|
||||||
qs = super().get_queryset()
|
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')
|
||||||
|
38
netbox/ipam/migrations/0035_drop_ip_family.py
Normal file
38
netbox/ipam/migrations/0035_drop_ip_family.py
Normal file
@ -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',
|
||||||
|
),
|
||||||
|
]
|
@ -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
|
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.
|
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()
|
prefix = IPNetworkField()
|
||||||
rir = models.ForeignKey(
|
rir = models.ForeignKey(
|
||||||
to='ipam.RIR',
|
to='ipam.RIR',
|
||||||
@ -182,7 +179,7 @@ class Aggregate(ChangeLoggedModel, CustomFieldModel):
|
|||||||
]
|
]
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('family', 'prefix', 'pk') # (family, prefix) may be non-unique
|
ordering = ('prefix', 'pk') # prefix may be non-unique
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.prefix)
|
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):
|
def to_csv(self):
|
||||||
return (
|
return (
|
||||||
self.prefix,
|
self.prefix,
|
||||||
@ -239,6 +230,12 @@ class Aggregate(ChangeLoggedModel, CustomFieldModel):
|
|||||||
self.description,
|
self.description,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def family(self):
|
||||||
|
if self.prefix:
|
||||||
|
return self.prefix.version
|
||||||
|
return None
|
||||||
|
|
||||||
def get_utilization(self):
|
def get_utilization(self):
|
||||||
"""
|
"""
|
||||||
Determine the prefix utilization of the aggregate and return it as a percentage.
|
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
|
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.
|
assigned to a VLAN where appropriate.
|
||||||
"""
|
"""
|
||||||
family = models.PositiveSmallIntegerField(
|
|
||||||
choices=IPAddressFamilyChoices,
|
|
||||||
editable=False
|
|
||||||
)
|
|
||||||
prefix = IPNetworkField(
|
prefix = IPNetworkField(
|
||||||
help_text='IPv4 or IPv6 network with mask'
|
help_text='IPv4 or IPv6 network with mask'
|
||||||
)
|
)
|
||||||
@ -376,7 +369,7 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Meta:
|
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'
|
verbose_name_plural = 'prefixes'
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@ -423,9 +416,6 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
|
|||||||
# Clear host bits from prefix
|
# Clear host bits from prefix
|
||||||
self.prefix = self.prefix.cidr
|
self.prefix = self.prefix.cidr
|
||||||
|
|
||||||
# Record address family
|
|
||||||
self.family = self.prefix.version
|
|
||||||
|
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
def to_csv(self):
|
def to_csv(self):
|
||||||
@ -442,6 +432,12 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
|
|||||||
self.description,
|
self.description,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def family(self):
|
||||||
|
if self.prefix:
|
||||||
|
return self.prefix.version
|
||||||
|
return None
|
||||||
|
|
||||||
def _set_prefix_length(self, value):
|
def _set_prefix_length(self, value):
|
||||||
"""
|
"""
|
||||||
Expose the IPNetwork object's prefixlen attribute on the parent model so that it can be manipulated directly,
|
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
|
# All IP addresses within a point-to-point prefix (IPv4 /31 or IPv6 /127) are considered usable
|
||||||
if (
|
if (
|
||||||
self.family == 4 and self.prefix.prefixlen == 31 # RFC 3021
|
self.prefix.version == 4 and self.prefix.prefixlen == 31 # RFC 3021
|
||||||
) or (
|
) 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
|
return available_ips
|
||||||
|
|
||||||
@ -546,7 +542,7 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
|
|||||||
# Compile an IPSet to avoid counting duplicate IPs
|
# Compile an IPSet to avoid counting duplicate IPs
|
||||||
child_count = netaddr.IPSet([ip.address.ip for ip in self.get_child_ips()]).size
|
child_count = netaddr.IPSet([ip.address.ip for ip in self.get_child_ips()]).size
|
||||||
prefix_size = self.prefix.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
|
prefix_size -= 2
|
||||||
return int(float(child_count) / prefix_size * 100)
|
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
|
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.
|
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(
|
address = IPAddressField(
|
||||||
help_text='IPv4 or IPv6 address (with mask)'
|
help_text='IPv4 or IPv6 address (with mask)'
|
||||||
)
|
)
|
||||||
@ -659,7 +651,7 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel):
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Meta:
|
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 = 'IP address'
|
||||||
verbose_name_plural = 'IP addresses'
|
verbose_name_plural = 'IP addresses'
|
||||||
|
|
||||||
@ -727,10 +719,6 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel):
|
|||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
|
||||||
# Record address family
|
|
||||||
if isinstance(self.address, netaddr.IPNetwork):
|
|
||||||
self.family = self.address.version
|
|
||||||
|
|
||||||
# Force dns_name to lowercase
|
# Force dns_name to lowercase
|
||||||
self.dns_name = self.dns_name.lower()
|
self.dns_name = self.dns_name.lower()
|
||||||
|
|
||||||
@ -754,9 +742,9 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel):
|
|||||||
def to_csv(self):
|
def to_csv(self):
|
||||||
|
|
||||||
# Determine if this IP is primary for a Device
|
# 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
|
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
|
is_primary = True
|
||||||
else:
|
else:
|
||||||
is_primary = False
|
is_primary = False
|
||||||
@ -775,6 +763,12 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel):
|
|||||||
self.description,
|
self.description,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def family(self):
|
||||||
|
if self.address:
|
||||||
|
return self.address.version
|
||||||
|
return None
|
||||||
|
|
||||||
def _set_mask_length(self, value):
|
def _set_mask_length(self, value):
|
||||||
"""
|
"""
|
||||||
Expose the IPNetwork object's prefixlen attribute on the parent model so that it can be manipulated directly,
|
Expose the IPNetwork object's prefixlen attribute on the parent model so that it can be manipulated directly,
|
||||||
|
@ -207,7 +207,7 @@ class RIRListView(PermissionRequiredMixin, ObjectListView):
|
|||||||
'deprecated': 0,
|
'deprecated': 0,
|
||||||
'available': 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:
|
for aggregate in aggregate_list:
|
||||||
|
|
||||||
queryset = Prefix.objects.filter(prefix__net_contained_or_equal=str(aggregate.prefix))
|
queryset = Prefix.objects.filter(prefix__net_contained_or_equal=str(aggregate.prefix))
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
<table class="table table-hover panel-body attr-table">
|
<table class="table table-hover panel-body attr-table">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Family</td>
|
<td>Family</td>
|
||||||
<td>{{ aggregate.get_family_display }}</td>
|
<td>IPv{{ aggregate.family }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>RIR</td>
|
<td>RIR</td>
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
<table class="table table-hover panel-body attr-table">
|
<table class="table table-hover panel-body attr-table">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Family</td>
|
<td>Family</td>
|
||||||
<td>{{ ipaddress.get_family_display }}</td>
|
<td>IPv{{ ipaddress.family }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>VRF</td>
|
<td>VRF</td>
|
||||||
|
@ -85,7 +85,7 @@
|
|||||||
<table class="table table-hover panel-body attr-table">
|
<table class="table table-hover panel-body attr-table">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Family</td>
|
<td>Family</td>
|
||||||
<td>{{ prefix.get_family_display }}</td>
|
<td>IPv{{ prefix.family }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>VRF</td>
|
<td>VRF</td>
|
||||||
|
Loading…
Reference in New Issue
Block a user