Add RIR assignment for ASNRange

This commit is contained in:
jeremystretch 2023-02-25 16:24:57 -05:00
parent feb52d5c93
commit b3e03f337c
10 changed files with 66 additions and 18 deletions

View File

@ -34,7 +34,7 @@ class IPAMRootView(APIRootView):
# #
class ASNRangeViewSet(NetBoxModelViewSet): class ASNRangeViewSet(NetBoxModelViewSet):
queryset = ASNRange.objects.prefetch_related('tenant').annotate( queryset = ASNRange.objects.prefetch_related('tenant', 'rir').annotate(
asn_count=count_related(ASN, 'range') asn_count=count_related(ASN, 'range')
) )
serializer_class = serializers.ASNRangeSerializer serializer_class = serializers.ASNRangeSerializer
@ -251,8 +251,11 @@ class AvailableASNsView(ObjectValidationMixin, APIView):
# Assign ASNs from the list of available IPs and copy VRF assignment from the parent # Assign ASNs from the list of available IPs and copy VRF assignment from the parent
for i, requested_asn in enumerate(requested_asns): for i, requested_asn in enumerate(requested_asns):
requested_asn['asn'] = available_asns[i] requested_asn.update({
requested_asn['range'] = asnrange.pk 'rir': asnrange.rir.pk,
'range': asnrange.pk,
'asn': available_asns[i],
})
# Initialize the serializer with a list or a single object depending on what was requested # Initialize the serializer with a list or a single object depending on what was requested
context = {'request': request} context = {'request': request}

View File

@ -169,6 +169,16 @@ class AggregateFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
class ASNRangeFilterSet(OrganizationalModelFilterSet, TenancyFilterSet): class ASNRangeFilterSet(OrganizationalModelFilterSet, TenancyFilterSet):
rir_id = django_filters.ModelMultipleChoiceFilter(
queryset=RIR.objects.all(),
label=_('RIR (ID)'),
)
rir = django_filters.ModelMultipleChoiceFilter(
field_name='rir__slug',
queryset=RIR.objects.all(),
to_field_name='slug',
label=_('RIR (slug)'),
)
class Meta: class Meta:
model = ASNRange model = ASNRange

View File

@ -99,6 +99,11 @@ class RIRBulkEditForm(NetBoxModelBulkEditForm):
class ASNRangeBulkEditForm(NetBoxModelBulkEditForm): class ASNRangeBulkEditForm(NetBoxModelBulkEditForm):
rir = DynamicModelChoiceField(
queryset=RIR.objects.all(),
required=False,
label=_('RIR')
)
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
@ -110,9 +115,9 @@ class ASNRangeBulkEditForm(NetBoxModelBulkEditForm):
model = ASNRange model = ASNRange
fieldsets = ( fieldsets = (
(None, ('tenant', 'description')), (None, ('rir', 'tenant', 'description')),
) )
nullable_fields = ('date_added', 'description') nullable_fields = ('description',)
class ASNBulkEditForm(NetBoxModelBulkEditForm): class ASNBulkEditForm(NetBoxModelBulkEditForm):

View File

@ -89,6 +89,11 @@ class AggregateImportForm(NetBoxModelImportForm):
class ASNRangeImportForm(NetBoxModelImportForm): class ASNRangeImportForm(NetBoxModelImportForm):
rir = CSVModelChoiceField(
queryset=RIR.objects.all(),
to_field_name='name',
help_text=_('Assigned RIR')
)
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
@ -98,7 +103,7 @@ class ASNRangeImportForm(NetBoxModelImportForm):
class Meta: class Meta:
model = ASNRange model = ASNRange
fields = ('name', 'slug', 'start', 'end', 'tenant', 'description', 'tags') fields = ('name', 'slug', 'rir', 'start', 'end', 'tenant', 'description', 'tags')
class ASNImportForm(NetBoxModelImportForm): class ASNImportForm(NetBoxModelImportForm):

View File

@ -119,9 +119,14 @@ class ASNRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = ASNRange model = ASNRange
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Range', ('start', 'end')), ('Range', ('rir_id', 'start', 'end')),
('Tenant', ('tenant_group_id', 'tenant_id')), ('Tenant', ('tenant_group_id', 'tenant_id')),
) )
rir_id = DynamicModelMultipleChoiceField(
queryset=RIR.objects.all(),
required=False,
label=_('RIR')
)
start = forms.IntegerField( start = forms.IntegerField(
required=False required=False
) )

View File

@ -130,16 +130,20 @@ class AggregateForm(TenancyForm, NetBoxModelForm):
class ASNRangeForm(TenancyForm, NetBoxModelForm): class ASNRangeForm(TenancyForm, NetBoxModelForm):
rir = DynamicModelChoiceField(
queryset=RIR.objects.all(),
label=_('RIR'),
)
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('ASN Range', ('name', 'slug', 'start', 'end', 'description', 'tags')), ('ASN Range', ('name', 'slug', 'rir', 'start', 'end', 'description', 'tags')),
('Tenancy', ('tenant_group', 'tenant')), ('Tenancy', ('tenant_group', 'tenant')),
) )
class Meta: class Meta:
model = ASNRange model = ASNRange
fields = [ fields = [
'name', 'slug', 'start', 'end', 'tenant_group', 'tenant', 'description', 'tags' 'name', 'slug', 'rir', 'start', 'end', 'tenant_group', 'tenant', 'description', 'tags'
] ]

View File

@ -1,4 +1,4 @@
# Generated by Django 4.1.7 on 2023-02-25 19:49 # Generated by Django 4.1.7 on 2023-02-25 21:18
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
@ -28,6 +28,7 @@ class Migration(migrations.Migration):
('slug', models.SlugField(max_length=100, unique=True)), ('slug', models.SlugField(max_length=100, unique=True)),
('start', ipam.fields.ASNField()), ('start', ipam.fields.ASNField()),
('end', ipam.fields.ASNField()), ('end', ipam.fields.ASNField()),
('rir', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='asn_ranges', to='ipam.rir')),
('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='asn_ranges', to='tenancy.tenant')), ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='asn_ranges', to='tenancy.tenant')),
], ],

View File

@ -17,6 +17,12 @@ class ASN(PrimaryModel):
An autonomous system (AS) number is typically used to represent an independent routing domain. A site can have An autonomous system (AS) number is typically used to represent an independent routing domain. A site can have
one or more ASNs assigned to it. one or more ASNs assigned to it.
""" """
rir = models.ForeignKey(
to='ipam.RIR',
on_delete=models.PROTECT,
related_name='asns',
verbose_name='RIR'
)
range = models.ForeignKey( range = models.ForeignKey(
to='ipam.ASNRange', to='ipam.ASNRange',
on_delete=models.PROTECT, on_delete=models.PROTECT,
@ -28,12 +34,6 @@ class ASN(PrimaryModel):
verbose_name='ASN', verbose_name='ASN',
help_text=_('32-bit autonomous system number') help_text=_('32-bit autonomous system number')
) )
rir = models.ForeignKey(
to='ipam.RIR',
on_delete=models.PROTECT,
related_name='asns',
verbose_name='RIR'
)
tenant = models.ForeignKey( tenant = models.ForeignKey(
to='tenancy.Tenant', to='tenancy.Tenant',
on_delete=models.PROTECT, on_delete=models.PROTECT,
@ -90,6 +90,12 @@ class ASNRange(OrganizationalModel):
max_length=100, max_length=100,
unique=True unique=True
) )
rir = models.ForeignKey(
to='ipam.RIR',
on_delete=models.PROTECT,
related_name='asn_ranges',
verbose_name='RIR'
)
start = ASNField() start = ASNField()
end = ASNField() end = ASNField()
tenant = models.ForeignKey( tenant = models.ForeignKey(

View File

@ -15,6 +15,9 @@ class ASNRangeTable(TenancyColumnsMixin, NetBoxTable):
name = tables.Column( name = tables.Column(
linkify=True linkify=True
) )
rir = tables.Column(
linkify=True
)
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='ipam:asnrange_list' url_name='ipam:asnrange_list'
) )
@ -27,10 +30,10 @@ class ASNRangeTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = ASNRange model = ASNRange
fields = ( fields = (
'pk', 'name', 'slug', 'start', 'end', 'asn_count', 'tenant', 'tenant_group', 'description', 'tags', 'pk', 'name', 'slug', 'rir', 'start', 'end', 'asn_count', 'tenant', 'tenant_group', 'description', 'tags',
'created', 'last_updated', 'actions', 'created', 'last_updated', 'actions',
) )
default_columns = ('pk', 'name', 'start', 'end', 'tenant', 'asn_count', 'description') default_columns = ('pk', 'name', 'rir', 'start', 'end', 'tenant', 'asn_count', 'description')
class ASNTable(TenancyColumnsMixin, NetBoxTable): class ASNTable(TenancyColumnsMixin, NetBoxTable):

View File

@ -15,6 +15,12 @@
<td>Name</td> <td>Name</td>
<td>{{ object.name }}</td> <td>{{ object.name }}</td>
</tr> </tr>
<tr>
<td>RIR</td>
<td>
<a href="{% url 'ipam:asnrange_list' %}?rir={{ object.rir.slug }}">{{ object.rir }}</a>
</td>
</tr>
<tr> <tr>
<td>Range</td> <td>Range</td>
<td>{{ object.range_as_string }}</td> <td>{{ object.range_as_string }}</td>