Clean up Prefix TODOs
Some checks failed
CI / build (20.x, 3.10) (push) Has been cancelled
CI / build (20.x, 3.11) (push) Has been cancelled
CI / build (20.x, 3.12) (push) Has been cancelled

This commit is contained in:
Daniel Sheppard 2025-08-08 09:29:12 -05:00
parent b54196f595
commit b1bc933e98
7 changed files with 128 additions and 26 deletions

View File

@ -207,7 +207,11 @@ class RoleBulkEditForm(NetBoxModelBulkEditForm):
class PrefixBulkEditForm(ScopedBulkEditForm, NetBoxModelBulkEditForm): class PrefixBulkEditForm(ScopedBulkEditForm, NetBoxModelBulkEditForm):
# TODO: Alter for parent prefix parent = DynamicModelChoiceField(
queryset=Prefix.objects.all(),
required=False,
label=_('Parent Prefix')
)
vlan_group = DynamicModelChoiceField( vlan_group = DynamicModelChoiceField(
queryset=VLANGroup.objects.all(), queryset=VLANGroup.objects.all(),
required=False, required=False,
@ -267,7 +271,7 @@ class PrefixBulkEditForm(ScopedBulkEditForm, NetBoxModelBulkEditForm):
model = Prefix model = Prefix
fieldsets = ( fieldsets = (
FieldSet('tenant', 'status', 'role', 'description'), FieldSet('tenant', 'status', 'role', 'description'),
FieldSet('vrf', 'prefix_length', 'is_pool', 'mark_utilized', name=_('Addressing')), FieldSet('parent', 'vrf', 'prefix_length', 'is_pool', 'mark_utilized', name=_('Addressing')),
FieldSet('scope_type', 'scope', name=_('Scope')), FieldSet('scope_type', 'scope', name=_('Scope')),
FieldSet('vlan_group', 'vlan', name=_('VLAN Assignment')), FieldSet('vlan_group', 'vlan', name=_('VLAN Assignment')),
) )
@ -277,7 +281,11 @@ class PrefixBulkEditForm(ScopedBulkEditForm, NetBoxModelBulkEditForm):
class IPRangeBulkEditForm(NetBoxModelBulkEditForm): class IPRangeBulkEditForm(NetBoxModelBulkEditForm):
# TODO: Alter for prefix prefix = DynamicModelChoiceField(
queryset=Prefix.objects.all(),
required=False,
label=_('Prefix')
)
vrf = DynamicModelChoiceField( vrf = DynamicModelChoiceField(
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
required=False, required=False,
@ -325,7 +333,11 @@ class IPRangeBulkEditForm(NetBoxModelBulkEditForm):
class IPAddressBulkEditForm(NetBoxModelBulkEditForm): class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
# TODO: Alter for prefix prefix = DynamicModelChoiceField(
queryset=Prefix.objects.all(),
required=False,
label=_('Prefix')
)
prefix = DynamicModelChoiceField( prefix = DynamicModelChoiceField(
queryset=Prefix.objects.all(), queryset=Prefix.objects.all(),
required=False, required=False,

View File

@ -156,8 +156,18 @@ class RoleImportForm(NetBoxModelImportForm):
class PrefixImportForm(ScopedImportForm, NetBoxModelImportForm): class PrefixImportForm(ScopedImportForm, NetBoxModelImportForm):
# TODO: Alter for aggregate aggregate = CSVModelChoiceField(
# TODO: Alter for parent prefix label=_('Aggregate'),
queryset=Aggregate.objects.all(),
to_field_name='prefix',
required=False
)
parent = CSVModelChoiceField(
label=_('Prefix'),
queryset=Prefix.objects.all(),
to_field_name='prefix',
required=False
)
vrf = CSVModelChoiceField( vrf = CSVModelChoiceField(
label=_('VRF'), label=_('VRF'),
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
@ -245,9 +255,26 @@ class PrefixImportForm(ScopedImportForm, NetBoxModelImportForm):
queryset = self.fields['vlan'].queryset.filter(query) queryset = self.fields['vlan'].queryset.filter(query)
self.fields['vlan'].queryset = queryset self.fields['vlan'].queryset = queryset
# Limit Prefix queryset by assigned vrf
vrf = data.get('vrf')
query = Q()
if vrf:
query &= Q(**{
f"vrf__{self.fields['vrf'].to_field_name}": vrf
})
queryset = self.fields['parent'].queryset.filter(query)
self.fields['parent'].queryset = queryset
class IPRangeImportForm(NetBoxModelImportForm): class IPRangeImportForm(NetBoxModelImportForm):
# TODO: Alter for prefix prefix = CSVModelChoiceField(
label=_('Prefix'),
queryset=Prefix.objects.all(),
to_field_name='prefix',
required=True,
help_text=_('Assigned prefix')
)
vrf = CSVModelChoiceField( vrf = CSVModelChoiceField(
label=_('VRF'), label=_('VRF'),
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
@ -282,9 +309,22 @@ class IPRangeImportForm(NetBoxModelImportForm):
'description', 'comments', 'tags', 'description', 'comments', 'tags',
) )
def __init__(self, data=None, *args, **kwargs):
super().__init__(data, *args, **kwargs)
# Limit Prefix queryset by assigned vrf
vrf = data.get('vrf')
query = Q()
if vrf:
query &= Q(**{
f"vrf__{self.fields['vrf'].to_field_name}": vrf
})
queryset = self.fields['prefix'].queryset.filter(query)
self.fields['prefix'].queryset = queryset
class IPAddressImportForm(NetBoxModelImportForm): class IPAddressImportForm(NetBoxModelImportForm):
# TODO: Alter for prefix
prefix = CSVModelChoiceField( prefix = CSVModelChoiceField(
label=_('Prefix'), label=_('Prefix'),
queryset=Prefix.objects.all(), queryset=Prefix.objects.all(),
@ -368,6 +408,15 @@ class IPAddressImportForm(NetBoxModelImportForm):
if data: if data:
# Limit Prefix queryset by assigned vrf
vrf = data.get('vrf')
query = Q()
if vrf:
query &= Q(**{f"vrf__{self.fields['vrf'].to_field_name}": vrf})
queryset = self.fields['prefix'].queryset.filter(query)
self.fields['prefix'].queryset = queryset
# Limit interface queryset by assigned device # Limit interface queryset by assigned device
if data.get('device'): if data.get('device'):
self.fields['interface'].queryset = Interface.objects.filter( self.fields['interface'].queryset = Interface.objects.filter(

View File

@ -155,7 +155,10 @@ class PrefixUtilizationColumn(columns.UtilizationColumn):
class PrefixTable(TenancyColumnsMixin, NetBoxTable): class PrefixTable(TenancyColumnsMixin, NetBoxTable):
# TODO: Alter for parent prefix parent = tables.Column(
verbose_name=_('Parent'),
linkify=True
)
prefix = columns.TemplateColumn( prefix = columns.TemplateColumn(
verbose_name=_('Prefix'), verbose_name=_('Prefix'),
template_code=PREFIX_LINK_WITH_DEPTH, template_code=PREFIX_LINK_WITH_DEPTH,
@ -237,9 +240,9 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Prefix model = Prefix
fields = ( fields = (
'pk', 'id', 'prefix', 'prefix_flat', 'status', 'children', 'vrf', 'utilization', 'tenant', 'tenant_group', 'pk', 'id', 'prefix', 'status', 'parent', 'parent_flat', 'children', 'vrf', 'utilization',
'scope', 'scope_type', 'vlan_group', 'vlan', 'role', 'is_pool', 'mark_utilized', 'description', 'comments', 'tenant', 'tenant_group', 'scope', 'scope_type', 'vlan_group', 'vlan', 'role', 'is_pool', 'mark_utilized',
'tags', 'created', 'last_updated', 'description', 'comments', 'tags', 'created', 'last_updated',
) )
default_columns = ( default_columns = (
'pk', 'prefix', 'status', 'children', 'vrf', 'utilization', 'tenant', 'scope', 'vlan', 'role', 'pk', 'prefix', 'status', 'children', 'vrf', 'utilization', 'tenant', 'scope', 'vlan', 'role',
@ -254,7 +257,10 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
# IP ranges # IP ranges
# #
class IPRangeTable(TenancyColumnsMixin, NetBoxTable): class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
# TODO: Alter for prefix prefix = tables.Column(
verbose_name=_('Prefix'),
linkify=True
)
start_address = tables.Column( start_address = tables.Column(
verbose_name=_('Start address'), verbose_name=_('Start address'),
linkify=True linkify=True
@ -294,9 +300,9 @@ class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = IPRange model = IPRange
fields = ( fields = (
'pk', 'id', 'start_address', 'end_address', 'size', 'vrf', 'status', 'role', 'tenant', 'tenant_group', 'pk', 'id', 'start_address', 'end_address', 'prefix', 'size', 'vrf', 'status', 'role', 'tenant',
'mark_populated', 'mark_utilized', 'utilization', 'description', 'comments', 'tags', 'created', 'tenant_group', 'mark_populated', 'mark_utilized', 'utilization', 'description', 'comments', 'tags',
'last_updated', 'created', 'last_updated',
) )
default_columns = ( default_columns = (
'pk', 'start_address', 'end_address', 'size', 'vrf', 'status', 'role', 'tenant', 'description', 'pk', 'start_address', 'end_address', 'size', 'vrf', 'status', 'role', 'tenant', 'description',
@ -311,7 +317,10 @@ class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
# #
class IPAddressTable(TenancyColumnsMixin, NetBoxTable): class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
# TODO: Alter for prefix prefix = tables.Column(
verbose_name=_('Prefix'),
linkify=True
)
address = tables.TemplateColumn( address = tables.TemplateColumn(
template_code=IPADDRESS_LINK, template_code=IPADDRESS_LINK,
verbose_name=_('IP Address') verbose_name=_('IP Address')
@ -371,8 +380,8 @@ class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = IPAddress model = IPAddress
fields = ( fields = (
'pk', 'id', 'address', 'vrf', 'status', 'role', 'tenant', 'tenant_group', 'nat_inside', 'nat_outside', 'pk', 'id', 'address', 'vrf', 'prefix', 'status', 'role', 'tenant', 'tenant_group', 'nat_inside',
'assigned', 'dns_name', 'description', 'comments', 'tags', 'created', 'last_updated', 'nat_outside', 'assigned', 'dns_name', 'description', 'comments', 'tags', 'created', 'last_updated',
) )
default_columns = ( default_columns = (
'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'assigned', 'dns_name', 'description', 'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'assigned', 'dns_name', 'description',

View File

@ -16,12 +16,20 @@ PREFIX_COPY_BUTTON = """
PREFIX_LINK_WITH_DEPTH = """ PREFIX_LINK_WITH_DEPTH = """
{% load helpers %} {% load helpers %}
{% if record.depth %} {% if record.depth_count %}
{% if object %}
<div class="record-depth"> <div class="record-depth">
{% for i in record.depth|as_range %} {% for i in record.depth_count|parent_depth:object|as_range %}
<span></span> <span></span>
{% endfor %} {% endfor %}
</div> </div>
{% else %}
<div class="record-depth">
{% for i in record.depth_count|as_range %}
<span></span>
{% endfor %}
</div>
{% endif %}
{% endif %} {% endif %}
""" + PREFIX_LINK """ + PREFIX_LINK

View File

@ -13,6 +13,10 @@
<th scope="row">{% trans "Family" %}</th> <th scope="row">{% trans "Family" %}</th>
<td>IPv{{ object.family }}</td> <td>IPv{{ object.family }}</td>
</tr> </tr>
<tr>
<th scope="row">{% trans "Prefix" %}</th>
<td>{{ object.prefix|linkify|placeholder }}</td>
</tr>
<tr> <tr>
<th scope="row">{% trans "Starting Address" %}</th> <th scope="row">{% trans "Starting Address" %}</th>
<td>{{ object.start_address }}</td> <td>{{ object.start_address }}</td>

View File

@ -157,6 +157,26 @@ def as_range(n):
return range(n) return range(n)
@register.filter()
def parent_depth(n, parent=None):
"""
Return the depth of a node based on the parent's depth
"""
parent_depth = 0
if parent and hasattr(parent, 'depth_count'):
parent_depth = parent.depth_count + 1
elif parent and hasattr(parent, 'depth'):
try:
parent_depth = int(parent.depth) + 1
except TypeError:
pass
try:
depth = int(n) - int(parent_depth)
except TypeError:
return n
return depth
@register.filter() @register.filter()
def meters_to_feet(n): def meters_to_feet(n):
""" """