mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-26 17:26:10 -06:00
Add relationship from ASN to ASNRange
This commit is contained in:
parent
7e7c9e981d
commit
6ce40b58cb
@ -38,6 +38,7 @@ class ASNRangeSerializer(NetBoxModelSerializer):
|
|||||||
|
|
||||||
class ASNSerializer(NetBoxModelSerializer):
|
class ASNSerializer(NetBoxModelSerializer):
|
||||||
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:asn-detail')
|
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:asn-detail')
|
||||||
|
range = NestedASNRangeSerializer(required=False, allow_null=True)
|
||||||
tenant = NestedTenantSerializer(required=False, allow_null=True)
|
tenant = NestedTenantSerializer(required=False, allow_null=True)
|
||||||
site_count = serializers.IntegerField(read_only=True)
|
site_count = serializers.IntegerField(read_only=True)
|
||||||
provider_count = serializers.IntegerField(read_only=True)
|
provider_count = serializers.IntegerField(read_only=True)
|
||||||
@ -45,7 +46,7 @@ class ASNSerializer(NetBoxModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = ASN
|
model = ASN
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'url', 'display', 'asn', 'rir', 'tenant', 'description', 'comments', 'tags', 'custom_fields',
|
'id', 'url', 'display', 'asn', 'rir', 'range', 'tenant', 'description', 'comments', 'tags', 'custom_fields',
|
||||||
'created', 'last_updated', 'site_count', 'provider_count',
|
'created', 'last_updated', 'site_count', 'provider_count',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -192,6 +192,16 @@ class ASNFilterSet(OrganizationalModelFilterSet, TenancyFilterSet):
|
|||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label=_('RIR (slug)'),
|
label=_('RIR (slug)'),
|
||||||
)
|
)
|
||||||
|
range_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
queryset=ASNRange.objects.all(),
|
||||||
|
label=_('Range (ID)'),
|
||||||
|
)
|
||||||
|
range = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
field_name='range__slug',
|
||||||
|
queryset=ASNRange.objects.all(),
|
||||||
|
to_field_name='slug',
|
||||||
|
label=_('Range (slug)'),
|
||||||
|
)
|
||||||
site_id = django_filters.ModelMultipleChoiceFilter(
|
site_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='sites',
|
field_name='sites',
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
|
@ -125,6 +125,10 @@ class ASNBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
required=False,
|
required=False,
|
||||||
label=_('RIR')
|
label=_('RIR')
|
||||||
)
|
)
|
||||||
|
range = DynamicModelChoiceField(
|
||||||
|
queryset=ASNRange.objects.all(),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
tenant = DynamicModelChoiceField(
|
tenant = DynamicModelChoiceField(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
required=False
|
required=False
|
||||||
@ -140,9 +144,9 @@ class ASNBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
|
|
||||||
model = ASN
|
model = ASN
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, ('sites', 'rir', 'tenant', 'description')),
|
(None, ('sites', 'rir', 'range', 'tenant', 'description')),
|
||||||
)
|
)
|
||||||
nullable_fields = ('date_added', 'description', 'comments')
|
nullable_fields = ('range', 'description', 'comments')
|
||||||
|
|
||||||
|
|
||||||
class AggregateBulkEditForm(NetBoxModelBulkEditForm):
|
class AggregateBulkEditForm(NetBoxModelBulkEditForm):
|
||||||
|
@ -107,6 +107,11 @@ class ASNImportForm(NetBoxModelImportForm):
|
|||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
help_text=_('Assigned RIR')
|
help_text=_('Assigned RIR')
|
||||||
)
|
)
|
||||||
|
range = CSVModelChoiceField(
|
||||||
|
queryset=ASNRange.objects.all(),
|
||||||
|
to_field_name='name',
|
||||||
|
help_text=_('ASN range')
|
||||||
|
)
|
||||||
tenant = CSVModelChoiceField(
|
tenant = CSVModelChoiceField(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -116,7 +121,7 @@ class ASNImportForm(NetBoxModelImportForm):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ASN
|
model = ASN
|
||||||
fields = ('asn', 'rir', 'tenant', 'description', 'comments', 'tags')
|
fields = ('asn', 'rir', 'range', 'tenant', 'description', 'comments', 'tags')
|
||||||
|
|
||||||
|
|
||||||
class RoleImportForm(NetBoxModelImportForm):
|
class RoleImportForm(NetBoxModelImportForm):
|
||||||
|
@ -135,7 +135,7 @@ class ASNFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|||||||
model = ASN
|
model = ASN
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, ('q', 'filter_id', 'tag')),
|
(None, ('q', 'filter_id', 'tag')),
|
||||||
('Assignment', ('rir_id', 'site_id')),
|
('Assignment', ('rir_id', 'range_id', 'site_id')),
|
||||||
('Tenant', ('tenant_group_id', 'tenant_id')),
|
('Tenant', ('tenant_group_id', 'tenant_id')),
|
||||||
)
|
)
|
||||||
rir_id = DynamicModelMultipleChoiceField(
|
rir_id = DynamicModelMultipleChoiceField(
|
||||||
@ -143,6 +143,11 @@ class ASNFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|||||||
required=False,
|
required=False,
|
||||||
label=_('RIR')
|
label=_('RIR')
|
||||||
)
|
)
|
||||||
|
range_id = DynamicModelMultipleChoiceField(
|
||||||
|
queryset=ASNRange.objects.all(),
|
||||||
|
required=False,
|
||||||
|
label=_('Range')
|
||||||
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
|
@ -106,7 +106,7 @@ class ASNRange(OrganizationalModel):
|
|||||||
verbose_name_plural = 'ASN ranges'
|
verbose_name_plural = 'ASN ranges'
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f'ASNs {self.range_as_string()}'
|
return f'{self.name} ({self.range_as_string()})'
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('ipam:asnrange', args=[self.pk])
|
return reverse('ipam:asnrange', args=[self.pk])
|
||||||
|
@ -37,6 +37,12 @@ class ASNTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
asn = tables.Column(
|
asn = tables.Column(
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
|
rir = tables.Column(
|
||||||
|
linkify=True
|
||||||
|
)
|
||||||
|
range = tables.Column(
|
||||||
|
linkify=True
|
||||||
|
)
|
||||||
asn_asdot = tables.Column(
|
asn_asdot = tables.Column(
|
||||||
accessor=tables.A('asn_asdot'),
|
accessor=tables.A('asn_asdot'),
|
||||||
linkify=True,
|
linkify=True,
|
||||||
@ -63,7 +69,9 @@ class ASNTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
class Meta(NetBoxTable.Meta):
|
class Meta(NetBoxTable.Meta):
|
||||||
model = ASN
|
model = ASN
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'asn', 'asn_asdot', 'rir', 'site_count', 'provider_count', 'tenant', 'tenant_group', 'description',
|
'pk', 'asn', 'asn_asdot', 'rir', 'range', 'site_count', 'provider_count', 'tenant', 'tenant_group',
|
||||||
'comments', 'sites', 'tags', 'created', 'last_updated', 'actions',
|
'description', 'comments', 'sites', 'tags', 'created', 'last_updated', 'actions',
|
||||||
|
)
|
||||||
|
default_columns = (
|
||||||
|
'pk', 'asn', 'rir', 'range', 'site_count', 'provider_count', 'sites', 'description', 'tenant',
|
||||||
)
|
)
|
||||||
default_columns = ('pk', 'asn', 'rir', 'site_count', 'provider_count', 'sites', 'description', 'tenant')
|
|
||||||
|
@ -213,7 +213,7 @@ class ASNRangeView(generic.ObjectView):
|
|||||||
|
|
||||||
def get_extra_context(self, request, instance):
|
def get_extra_context(self, request, instance):
|
||||||
related_models = (
|
related_models = (
|
||||||
(ASN.objects.restrict(request.user, 'view').filter(range=instance), 'asn_id'),
|
(ASN.objects.restrict(request.user, 'view').filter(range=instance), 'range_id'),
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'ipam:asn_list' %}?rir_id={{ object.rir.pk }}">{{ object.rir }}</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'ipam:asn_list' %}?rir_id={{ object.rir.pk }}">{{ object.rir }}</a></li>
|
||||||
|
{% if object.range %}
|
||||||
|
<li class="breadcrumb-item"><a href="{% url 'ipam:asn_list' %}?range_id={{ object.range.pk }}">{{ object.range }}</a></li>
|
||||||
|
{% endif %}
|
||||||
{% endblock breadcrumbs %}
|
{% endblock breadcrumbs %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
@ -26,6 +29,10 @@
|
|||||||
<a href="{% url 'ipam:asn_list' %}?rir={{ object.rir.slug }}">{{ object.rir }}</a>
|
<a href="{% url 'ipam:asn_list' %}?rir={{ object.rir.slug }}">{{ object.rir }}</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Range</td>
|
||||||
|
<td>{{ object.range|linkify|placeholder }}</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Tenant</td>
|
<td>Tenant</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -46,6 +46,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-md-12">
|
<div class="col col-md-12">
|
||||||
|
<div class="card">
|
||||||
|
<h5 class="card-header">ASNs</h5>
|
||||||
|
<div class="card-body htmx-container table-responsive"
|
||||||
|
hx-get="{% url 'ipam:asn_list' %}?range_id={{ object.pk }}"
|
||||||
|
hx-trigger="load"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
{% plugin_full_width_page object %}
|
{% plugin_full_width_page object %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user