diff --git a/netbox_routing/api/_serializers/ospf.py b/netbox_routing/api/_serializers/ospf.py index cf28518..3fa82dc 100644 --- a/netbox_routing/api/_serializers/ospf.py +++ b/netbox_routing/api/_serializers/ospf.py @@ -2,6 +2,7 @@ from dcim.api.serializers_.device_components import InterfaceSerializer from dcim.api.serializers_.devices import DeviceSerializer +from ipam.api.serializers_.vrfs import VRFSerializer from netbox.api.serializers import NetBoxModelSerializer from netbox_routing.models import OSPFInstance, OSPFArea, OSPFInterface @@ -16,11 +17,14 @@ class OSPFInstanceSerializer(NetBoxModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='plugins-api:netbox_routing-api:ospfinstance-detail') device = DeviceSerializer(nested=True) + vrf = VRFSerializer(nested=True) class Meta: model = OSPFInstance - fields = ('url', 'id', 'display', 'name', 'router_id', 'process_id', 'device', 'description', 'comments', ) - brief_fields = ('url', 'id', 'display', 'name', 'router_id', 'process_id', 'device', ) + fields = ( + 'url', 'id', 'display', 'name', 'router_id', 'process_id', 'device', 'vrf', 'description', 'comments', + ) + brief_fields = ('url', 'id', 'display', 'name', 'router_id', 'process_id', 'device', 'vrf', ) class OSPFAreaSerializer(NetBoxModelSerializer): diff --git a/netbox_routing/filtersets/ospf.py b/netbox_routing/filtersets/ospf.py index 597425c..677c05b 100644 --- a/netbox_routing/filtersets/ospf.py +++ b/netbox_routing/filtersets/ospf.py @@ -4,6 +4,7 @@ from django.utils.translation import gettext as _ from dcim.models import Device, Interface +from ipam.models import VRF from utilities.filters import MultiValueCharFilter from netbox.filtersets import NetBoxModelFilterSet @@ -30,6 +31,17 @@ class OSPFInstanceFilterSet(NetBoxModelFilterSet): to_field_name='name', label='Device', ) + vrf_id = django_filters.ModelMultipleChoiceFilter( + field_name='vrf', + queryset=VRF.objects.all(), + label='VRF (ID)', + ) + vrf = django_filters.ModelMultipleChoiceFilter( + field_name='vrf__name', + queryset=VRF.objects.all(), + to_field_name='name', + label='VRF', + ) router_id = MultiValueCharFilter( method='filter_rid', @@ -38,7 +50,7 @@ class OSPFInstanceFilterSet(NetBoxModelFilterSet): class Meta: model = OSPFInstance - fields = ('device_id', 'device', 'name', 'device', 'router_id', 'process_id') + fields = ('device_id', 'device', 'name', 'vrf_id', 'vrf', 'router_id', 'process_id') def search(self, queryset, name, value): if not value.strip(): @@ -94,6 +106,17 @@ class OSPFInterfaceFilterSet(NetBoxModelFilterSet): to_field_name='name', label='Instance', ) + vrf_id = django_filters.ModelMultipleChoiceFilter( + field_name='instance__vrf', + queryset=VRF.objects.all(), + label='VRF (ID)', + ) + vrf = django_filters.ModelMultipleChoiceFilter( + field_name='instance__vrf__name', + queryset=VRF.objects.all(), + to_field_name='name', + label='VRF', + ) area_id = django_filters.ModelMultipleChoiceFilter( field_name='area', queryset=OSPFArea.objects.all(), diff --git a/netbox_routing/forms/bulk_edit/ospf.py b/netbox_routing/forms/bulk_edit/ospf.py index 8a79d12..34cddec 100644 --- a/netbox_routing/forms/bulk_edit/ospf.py +++ b/netbox_routing/forms/bulk_edit/ospf.py @@ -2,6 +2,7 @@ from django.utils.translation import gettext as _ from dcim.models import Device +from ipam.models import VRF from netbox.forms import NetBoxModelBulkEditForm from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, add_blank_choice from utilities.forms.fields import DynamicModelChoiceField, CommentField @@ -25,6 +26,12 @@ class OSPFInstanceBulkEditForm(NetBoxModelBulkEditForm): required=False, selector=True ) + vrf = DynamicModelChoiceField( + queryset=VRF.objects.all(), + label=_('VRF'), + required=False, + selector=True + ) description = forms.CharField( label=_('Description'), @@ -35,10 +42,10 @@ class OSPFInstanceBulkEditForm(NetBoxModelBulkEditForm): model = OSPFInstance fieldsets = ( - FieldSet('device', name='OSPF'), + FieldSet('device', 'vrf', name='OSPF'), FieldSet('description', ), ) - nullable_fields = () + nullable_fields = ('vrf', 'description', ) class OSPFAreaBulkEditForm(NetBoxModelBulkEditForm): diff --git a/netbox_routing/forms/bulk_import/ospf.py b/netbox_routing/forms/bulk_import/ospf.py index 084516b..a66445e 100644 --- a/netbox_routing/forms/bulk_import/ospf.py +++ b/netbox_routing/forms/bulk_import/ospf.py @@ -1,6 +1,7 @@ from django.utils.translation import gettext as _ -from dcim.models import Interface +from dcim.models import Interface, Device +from ipam.models import VRF from netbox.forms import NetBoxModelImportForm from utilities.forms.fields import CSVModelChoiceField @@ -16,15 +17,21 @@ class OSPFInstanceImportForm(NetBoxModelImportForm): device = CSVModelChoiceField( - queryset=Interface.objects.all(), - required=False, + queryset=Device.objects.all(), + required=True, to_field_name='name', help_text=_('Name of device') ) + vrf = CSVModelChoiceField( + queryset=VRF.objects.all(), + required=False, + to_field_name='name', + help_text=_('Name of VRF') + ) class Meta: model = OSPFInstance - fields = ('name', 'router_id', 'process_id', 'device', 'description', 'comments', 'tags',) + fields = ('name', 'router_id', 'process_id', 'device', 'vrf', 'description', 'comments', 'tags',) class OSPFAreaImportForm(NetBoxModelImportForm): diff --git a/netbox_routing/forms/filtersets/ospf.py b/netbox_routing/forms/filtersets/ospf.py index 2139a6e..ca21861 100644 --- a/netbox_routing/forms/filtersets/ospf.py +++ b/netbox_routing/forms/filtersets/ospf.py @@ -2,6 +2,7 @@ from django.utils.translation import gettext as _ from dcim.models import Interface, Device +from ipam.models import VRF from netbox.forms import NetBoxModelFilterSetForm from netbox_routing.choices import AuthenticationChoices from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, add_blank_choice @@ -26,6 +27,12 @@ class OSPFInstanceFilterForm(NetBoxModelFilterSetForm): selector=True, label=_('Device'), ) + vrf = DynamicModelMultipleChoiceField( + queryset=VRF.objects.all(), + required=False, + selector=True, + label=_('VRF'), + ) model = OSPFInstance fieldsets = ( FieldSet('q', 'filter_id', 'tag', 'device'), @@ -49,19 +56,31 @@ class OSPFInterfaceFilterForm(NetBoxModelFilterSetForm): FieldSet('interface', name=_('Device')), FieldSet('priority', 'bfd', 'authentication', name=_('Attributes')) ) - instance = DynamicModelMultipleChoiceField( + device_id = DynamicModelMultipleChoiceField( + queryset=Device.objects.all(), + required=False, + selector=True, + label=_('Device'), + ) + vrf_id = DynamicModelMultipleChoiceField( + queryset=VRF.objects.all(), + required=False, + selector=True, + label=_('VRF'), + ) + instance_id = DynamicModelMultipleChoiceField( queryset=OSPFInstance.objects.all(), required=False, selector=True, label=_('Instance'), ) - area = DynamicModelMultipleChoiceField( + area_id = DynamicModelMultipleChoiceField( queryset=OSPFArea.objects.all(), required=False, selector=True, label=_('Area'), ) - interface = DynamicModelMultipleChoiceField( + interface_id = DynamicModelMultipleChoiceField( queryset=Interface.objects.all(), required=False, selector=True, diff --git a/netbox_routing/forms/ospf.py b/netbox_routing/forms/ospf.py index 522e50d..46dd363 100644 --- a/netbox_routing/forms/ospf.py +++ b/netbox_routing/forms/ospf.py @@ -3,6 +3,7 @@ from django.utils.translation import gettext as _ from dcim.models import Interface, Device +from ipam.models import VRF from netbox.forms import NetBoxModelForm from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField, CommentField @@ -24,11 +25,17 @@ class OSPFInstanceForm(NetBoxModelForm): selector=True, label=_('Device'), ) + vrf = DynamicModelChoiceField( + queryset=VRF.objects.all(), + required=False, + selector=True, + label=_('VRF'), + ) comments = CommentField() class Meta: model = OSPFInstance - fields = ('name', 'router_id', 'process_id', 'device', 'description', 'comments', ) + fields = ('name', 'router_id', 'process_id', 'device', 'vrf', 'description', 'comments', ) class OSPFAreaForm(NetBoxModelForm): diff --git a/netbox_routing/graphql/types.py b/netbox_routing/graphql/types.py index 11d089b..f21962a 100644 --- a/netbox_routing/graphql/types.py +++ b/netbox_routing/graphql/types.py @@ -47,6 +47,7 @@ class OSPFInstanceType(NetBoxObjectType): name: str device: Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')] + vrf: Annotated["VRFType", strawberry.lazy('ipam.graphql.types')] | None router_id: str process_id: str diff --git a/netbox_routing/migrations/0012_osfp_instance_vrf.py b/netbox_routing/migrations/0012_osfp_instance_vrf.py new file mode 100644 index 0000000..90d4590 --- /dev/null +++ b/netbox_routing/migrations/0012_osfp_instance_vrf.py @@ -0,0 +1,26 @@ +# Generated by Django 5.0.8 on 2024-09-28 04:42 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0070_vlangroup_vlan_id_ranges'), + ('netbox_routing', '0011_osfp_passive_interface'), + ] + + operations = [ + migrations.AddField( + model_name='ospfinstance', + name='vrf', + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name='ospf_instances', + to='ipam.vrf', + ), + ), + ] diff --git a/netbox_routing/models/ospf.py b/netbox_routing/models/ospf.py index 2c8287f..1a6f959 100644 --- a/netbox_routing/models/ospf.py +++ b/netbox_routing/models/ospf.py @@ -28,6 +28,14 @@ class OSPFInstance(PrimaryModel): blank=False, null=False ) + vrf = models.ForeignKey( + verbose_name=_('VRF'), + to='ipam.VRF', + related_name='ospf_instances', + on_delete=models.CASCADE, + blank=True, + null=True + ) clone_fields = ('device',) prerequisite_models = ( diff --git a/netbox_routing/tables/ospf.py b/netbox_routing/tables/ospf.py index 83aa82d..c9d6b3f 100644 --- a/netbox_routing/tables/ospf.py +++ b/netbox_routing/tables/ospf.py @@ -15,8 +15,8 @@ class OSPFInstanceTable(NetBoxTable): class Meta(NetBoxTable.Meta): model = OSPFInstance - fields = ('pk', 'id', 'name', 'router_id', 'process_id', 'device') - default_columns = ('pk', 'id', 'name', 'router_id', 'process_id', 'device') + fields = ('pk', 'id', 'name', 'router_id', 'process_id', 'device', 'vrf', ) + default_columns = ('pk', 'id', 'name', 'router_id', 'process_id', 'device', ) class OSPFAreaTable(NetBoxTable): diff --git a/netbox_routing/templates/netbox_routing/ospfinstance.html b/netbox_routing/templates/netbox_routing/ospfinstance.html index 9d679b2..8ce4e86 100644 --- a/netbox_routing/templates/netbox_routing/ospfinstance.html +++ b/netbox_routing/templates/netbox_routing/ospfinstance.html @@ -34,6 +34,12 @@