1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Model import/export route targets on VRFs

This commit is contained in:
Jeremy Stretch
2020-09-24 12:09:28 -04:00
parent dfb5a06d9d
commit f684d07c61
10 changed files with 138 additions and 8 deletions

View File

@ -26,14 +26,16 @@ from .nested_serializers import *
class VRFSerializer(TaggedObjectSerializer, CustomFieldModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vrf-detail')
tenant = NestedTenantSerializer(required=False, allow_null=True)
import_targets = NestedRouteTargetSerializer(required=False, allow_null=True, many=True)
export_targets = NestedRouteTargetSerializer(required=False, allow_null=True, many=True)
ipaddress_count = serializers.IntegerField(read_only=True)
prefix_count = serializers.IntegerField(read_only=True)
class Meta:
model = VRF
fields = [
'id', 'url', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'tags', 'display_name',
'custom_fields', 'created', 'last_updated', 'ipaddress_count', 'prefix_count',
'id', 'url', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'import_targets', 'export_targets',
'tags', 'display_name', 'custom_fields', 'created', 'last_updated', 'ipaddress_count', 'prefix_count',
]

View File

@ -30,7 +30,9 @@ class IPAMRootView(APIRootView):
#
class VRFViewSet(CustomFieldModelViewSet):
queryset = VRF.objects.prefetch_related('tenant').prefetch_related('tags').annotate(
queryset = VRF.objects.prefetch_related('tenant').prefetch_related(
'import_targets', 'export_targets', 'tags'
).annotate(
ipaddress_count=get_subquery(IPAddress, 'vrf'),
prefix_count=get_subquery(Prefix, 'vrf')
).order_by(*VRF._meta.ordering)

View File

@ -35,6 +35,28 @@ class VRFFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, Create
method='search',
label='Search',
)
import_target_id = django_filters.ModelMultipleChoiceFilter(
field_name='import_targets',
queryset=RouteTarget.objects.all(),
label='Import target',
)
import_target = django_filters.ModelMultipleChoiceFilter(
field_name='import_targets__name',
queryset=RouteTarget.objects.all(),
to_field_name='name',
label='Import target (name)',
)
export_target_id = django_filters.ModelMultipleChoiceFilter(
field_name='export_targets',
queryset=RouteTarget.objects.all(),
label='Export target',
)
export_target = django_filters.ModelMultipleChoiceFilter(
field_name='export_targets__name',
queryset=RouteTarget.objects.all(),
to_field_name='name',
label='Export target (name)',
)
tag = TagFilter()
def search(self, queryset, name, value):
@ -56,6 +78,28 @@ class RouteTargetFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet
method='search',
label='Search',
)
importing_vrf_id = django_filters.ModelMultipleChoiceFilter(
field_name='importing_vrfs',
queryset=VRF.objects.all(),
label='Importing VRF',
)
importing_vrf = django_filters.ModelMultipleChoiceFilter(
field_name='importing_vrfs__rd',
queryset=VRF.objects.all(),
to_field_name='rd',
label='Import VRF (RD)',
)
exporting_vrf_id = django_filters.ModelMultipleChoiceFilter(
field_name='exporting_vrfs',
queryset=VRF.objects.all(),
label='Exporting VRF',
)
exporting_vrf = django_filters.ModelMultipleChoiceFilter(
field_name='exporting_vrfs__rd',
queryset=VRF.objects.all(),
to_field_name='rd',
label='Export VRF (RD)',
)
tag = TagFilter()
def search(self, queryset, name, value):

View File

@ -31,6 +31,14 @@ IPADDRESS_MASK_LENGTH_CHOICES = add_blank_choice([
#
class VRFForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
import_targets = DynamicModelMultipleChoiceField(
queryset=RouteTarget.objects.all(),
required=False
)
export_targets = DynamicModelMultipleChoiceField(
queryset=RouteTarget.objects.all(),
required=False
)
tags = DynamicModelMultipleChoiceField(
queryset=Tag.objects.all(),
required=False
@ -39,7 +47,8 @@ class VRFForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
class Meta:
model = VRF
fields = [
'name', 'rd', 'enforce_unique', 'description', 'tenant_group', 'tenant', 'tags',
'name', 'rd', 'enforce_unique', 'description', 'import_targets', 'export_targets', 'tenant_group', 'tenant',
'tags',
]
labels = {
'rd': "RD",
@ -89,11 +98,21 @@ class VRFBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm
class VRFFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = VRF
field_order = ['q', 'tenant_group', 'tenant']
field_order = ['q', 'import_target', 'export_target', 'tenant_group', 'tenant']
q = forms.CharField(
required=False,
label='Search'
)
import_target = DynamicModelMultipleChoiceField(
queryset=RouteTarget.objects.all(),
to_field_name='name',
required=False
)
export_target = DynamicModelMultipleChoiceField(
queryset=RouteTarget.objects.all(),
to_field_name='name',
required=False
)
tag = TagFilterField(model)
@ -149,11 +168,21 @@ class RouteTargetBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulk
class RouteTargetFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = RouteTarget
field_order = ['q', 'name', 'tenant_group', 'tenant']
field_order = ['q', 'name', 'tenant_group', 'tenant', 'importing_vrfs', 'exporting_vrfs']
q = forms.CharField(
required=False,
label='Search'
)
importing_vrf_id = DynamicModelMultipleChoiceField(
queryset=VRF.objects.all(),
required=False,
label='Imported by VRF'
)
exporting_vrf_id = DynamicModelMultipleChoiceField(
queryset=VRF.objects.all(),
required=False,
label='Exported by VRF'
)
tag = TagFilterField(model)

View File

@ -31,4 +31,14 @@ class Migration(migrations.Migration):
'ordering': ['name'],
},
),
migrations.AddField(
model_name='vrf',
name='export_targets',
field=models.ManyToManyField(blank=True, related_name='exporting_vrfs', to='ipam.RouteTarget'),
),
migrations.AddField(
model_name='vrf',
name='import_targets',
field=models.ManyToManyField(blank=True, related_name='importing_vrfs', to='ipam.RouteTarget'),
),
]

View File

@ -71,6 +71,16 @@ class VRF(ChangeLoggedModel, CustomFieldModel):
max_length=200,
blank=True
)
import_targets = models.ManyToManyField(
to='ipam.RouteTarget',
related_name='importing_vrfs',
blank=True
)
export_targets = models.ManyToManyField(
to='ipam.RouteTarget',
related_name='exporting_vrfs',
blank=True
)
tags = TaggableManager(through=TaggedItem)
objects = RestrictedQuerySet.as_manager()

View File

@ -39,9 +39,20 @@ class VRFView(ObjectView):
vrf = get_object_or_404(self.queryset, pk=pk)
prefix_count = Prefix.objects.restrict(request.user, 'view').filter(vrf=vrf).count()
import_targets_table = tables.RouteTargetTable(
vrf.import_targets.prefetch_related('tenant'),
orderable=False
)
export_targets_table = tables.RouteTargetTable(
vrf.export_targets.prefetch_related('tenant'),
orderable=False
)
return render(request, 'ipam/vrf.html', {
'vrf': vrf,
'prefix_count': prefix_count,
'import_targets_table': import_targets_table,
'export_targets_table': export_targets_table,
})
@ -91,8 +102,19 @@ class RouteTargetView(ObjectView):
def get(self, request, pk):
routetarget = get_object_or_404(self.queryset, pk=pk)
importing_vrfs_table = tables.VRFTable(
routetarget.importing_vrfs.prefetch_related('tenant'),
orderable=False
)
exporting_vrfs_table = tables.VRFTable(
routetarget.exporting_vrfs.prefetch_related('tenant'),
orderable=False
)
return render(request, 'ipam/routetarget.html', {
'routetarget': routetarget,
'importing_vrfs_table': importing_vrfs_table,
'exporting_vrfs_table': exporting_vrfs_table,
})

View File

@ -83,10 +83,12 @@
</table>
</div>
{% include 'extras/inc/tags_panel.html' with tags=routetarget.tags.all url='ipam:routetarget_list' %}
{% include 'inc/custom_fields_panel.html' with obj=routetarget %}
{% plugin_left_page routetarget %}
</div>
<div class="col-md-6">
{% include 'inc/custom_fields_panel.html' with obj=routetarget %}
{% include 'panel_table.html' with table=importing_vrfs_table heading="Importing VRFs" %}
{% include 'panel_table.html' with table=exporting_vrfs_table heading="Exporting VRFs" %}
{% plugin_right_page routetarget %}
</div>
</div>

View File

@ -99,10 +99,12 @@
</table>
</div>
{% include 'extras/inc/tags_panel.html' with tags=vrf.tags.all url='ipam:vrf_list' %}
{% include 'inc/custom_fields_panel.html' with obj=vrf %}
{% plugin_left_page vrf %}
</div>
<div class="col-md-6">
{% include 'inc/custom_fields_panel.html' with obj=vrf %}
{% include 'panel_table.html' with table=import_targets_table heading="Import Route Targets" %}
{% include 'panel_table.html' with table=export_targets_table heading="Export Route Targets" %}
{% plugin_right_page vrf %}
</div>
</div>

View File

@ -11,6 +11,13 @@
{% render_field form.description %}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><strong>Route Targets</strong></div>
<div class="panel-body">
{% render_field form.import_targets %}
{% render_field form.export_targets %}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading"><strong>Tenancy</strong></div>
<div class="panel-body">