diff --git a/netbox/ipam/api/serializers_/vlans.py b/netbox/ipam/api/serializers_/vlans.py index 05fdd5813..9b5501dc5 100644 --- a/netbox/ipam/api/serializers_/vlans.py +++ b/netbox/ipam/api/serializers_/vlans.py @@ -121,7 +121,7 @@ class VLANTranslationRuleSerializer(NetBoxModelSerializer): class Meta: model = VLANTranslationRule - fields = ['id', 'policy', 'local_vid', 'remote_vid'] + fields = ['id', 'url', 'display', 'policy', 'local_vid', 'remote_vid', 'description'] class VLANTranslationPolicySerializer(NetBoxModelSerializer): @@ -129,5 +129,5 @@ class VLANTranslationPolicySerializer(NetBoxModelSerializer): class Meta: model = VLANTranslationPolicy - fields = ['id', 'url', 'name', 'description', 'display', 'rules'] - brief_fields = ('id', 'url', 'name', 'description', 'display') + fields = ['id', 'url', 'display', 'name', 'description', 'display', 'rules'] + brief_fields = ('id', 'url', 'display', 'name', 'description') diff --git a/netbox/ipam/forms/bulk_import.py b/netbox/ipam/forms/bulk_import.py index 7e1382be9..e8d48de7c 100644 --- a/netbox/ipam/forms/bulk_import.py +++ b/netbox/ipam/forms/bulk_import.py @@ -487,6 +487,12 @@ class VLANTranslationPolicyImportForm(NetBoxModelImportForm): class VLANTranslationRuleImportForm(NetBoxModelImportForm): + policy = CSVModelChoiceField( + label=_('Policy'), + queryset=VLANTranslationPolicy.objects.all(), + to_field_name='name', + help_text=_('VLAN translation policy') + ) class Meta: model = VLANTranslationRule diff --git a/netbox/ipam/models/vlans.py b/netbox/ipam/models/vlans.py index dfa814619..4c7f191c9 100644 --- a/netbox/ipam/models/vlans.py +++ b/netbox/ipam/models/vlans.py @@ -379,6 +379,8 @@ class VLANTranslationRule(NetBoxModel): 'ipam.VLANTranslationPolicy', ) + clone_fields = ['policy'] + class Meta: verbose_name = _('VLAN translation rule') ordering = ('policy', 'local_vid',) diff --git a/netbox/ipam/tables/vlans.py b/netbox/ipam/tables/vlans.py index e3d7c7e63..aa1900e41 100644 --- a/netbox/ipam/tables/vlans.py +++ b/netbox/ipam/tables/vlans.py @@ -231,6 +231,11 @@ class VLANTranslationPolicyTable(NetBoxTable): verbose_name=_('Name'), linkify=True ) + rule_count = columns.LinkedCountColumn( + viewname='ipam:vlantranslationrule_list', + url_params={'policy_id': 'pk'}, + verbose_name=_('Rules') + ) description = tables.Column( verbose_name=_('Description'), ) @@ -241,9 +246,9 @@ class VLANTranslationPolicyTable(NetBoxTable): class Meta(NetBoxTable.Meta): model = VLANTranslationPolicy fields = ( - 'pk', 'id', 'name', 'description', 'tags', 'created', 'last_updated', + 'pk', 'id', 'name', 'rule_count', 'description', 'tags', 'created', 'last_updated', ) - default_columns = ('pk', 'name', 'description') + default_columns = ('pk', 'name', 'rule_count', 'description') class VLANTranslationRuleTable(NetBoxTable): diff --git a/netbox/ipam/tests/test_views.py b/netbox/ipam/tests/test_views.py index e9903d766..d7d367bb7 100644 --- a/netbox/ipam/tests/test_views.py +++ b/netbox/ipam/tests/test_views.py @@ -973,16 +973,16 @@ class VLANTranslationRuleTestCase(ViewTestCases.PrimaryObjectViewTestCase): cls.csv_data = ( "policy,local_vid,remote_vid", - f"{vlan_translation_policies[0].pk},103,203", - f"{vlan_translation_policies[0].pk},104,204", - f"{vlan_translation_policies[1].pk},105,205", + f"{vlan_translation_policies[0].name},103,203", + f"{vlan_translation_policies[0].name},104,204", + f"{vlan_translation_policies[1].name},105,205", ) cls.csv_update_data = ( - "id,policy,local_vid,remote_vid", - f"{vlan_translation_rules[0].pk},{vlan_translation_policies[1].pk},105,205", - f"{vlan_translation_rules[1].pk},{vlan_translation_policies[1].pk},106,206", - f"{vlan_translation_rules[2].pk},{vlan_translation_policies[0].pk},107,207", + "id,local_vid,remote_vid", + f"{vlan_translation_rules[0].pk},105,205", + f"{vlan_translation_rules[1].pk},106,206", + f"{vlan_translation_rules[2].pk},107,207", ) cls.bulk_edit_data = { diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index f83934906..f145716e9 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -1050,7 +1050,9 @@ class VLANGroupVLANsView(generic.ObjectChildrenView): @register_model_view(VLANTranslationPolicy, 'list', path='', detail=False) class VLANTranslationPolicyListView(generic.ObjectListView): - queryset = VLANTranslationPolicy.objects.all() + queryset = VLANTranslationPolicy.objects.annotate( + rule_count=count_related(VLANTranslationRule, 'policy'), + ) filterset = filtersets.VLANTranslationPolicyFilterSet filterset_form = forms.VLANTranslationPolicyFilterForm table = tables.VLANTranslationPolicyTable diff --git a/netbox/templates/ipam/vlantranslationpolicy.html b/netbox/templates/ipam/vlantranslationpolicy.html index 5217db913..58a1201d4 100644 --- a/netbox/templates/ipam/vlantranslationpolicy.html +++ b/netbox/templates/ipam/vlantranslationpolicy.html @@ -18,6 +18,16 @@ {% trans "Description" %} {{ object.description|placeholder }} + + {% trans "Rules" %} + + {% if object.rules.count %} + {{ object.rules.count }} + {% else %} + 0 + {% endif %} + + {% plugin_left_page object %}