4867 multiple mac addresses (#17902)

* Create MACAddress model and migrations to convert existing .mac_address fields to standalone objects

* Add migrations

* All views/filtering working and documentation done; no unit tests yet

* Redo migrations following VLAN Translation

* Remove mac_address filter fields and add table columns for device/vm

* Remove unnecessary "bulk rename"

* Fix filterset tests for Device

* Fix filterset tests for Interface

* Fix tests on single-object forms

* Fix serializer tests

* Fix filterset tests for VMInterface

* Fix filterset tests for Device and VirtualMachine

* Move new field check into lookup_map iteration

* Fix general MACAddress filter tests

* Add GraphQL types/filters/schema

* Fix bulk edit/create tests (bulk editing Interfaces will be unsupported because of inheritance from ComponentBulkEditForm)

* Make mac_address read_only on InterfaceSerializer/VMInterfaceSerializer

* Undo unrelated work

* Cleanup unused IPAddress derived stuff

* API endpoints

* Add serializer objects to interface serializers

* Clean up unnecessary bulk create forms/views/routes

* Add SearchIndex and adjust indexable fields for Interface and VMInterface

* Reorganize MACAddress classes out of association with DeviceComponents

* Move MACAddressSerializer

* Enforce saving only a single is_primary MACAddress per interface/vminterface

* Perform is_primary validation on MACAddress model and just check if one already exists for the interface

* Remove form-level validation

* Fix check for current is_primary setting when reassigning

* Model cleanup

* Documentation notes and cleanup

* Simplify serializer and add ip_addresses

* Add to VMInterfaceSerializer too

* Style cleanup

* Standardize "MAC Address" instead of "MAC"

* Remove unused views

* Add is_primary field for bulk edit

* HTML cleanup and add copy-to-clipboard button

* Remove mac_address from Interface and VMInterface bulk-edit forms

* Add device and VM filtering

* Use combined assigned_object_parent in table to match structure of IPAddressTable

* Add GFK fields to MACAddressSerializer

* Reorganize "Addressing" sections to remove from proximity to "Device Components" and related groupings

* Clean up migrations

* Misc cleanup

* Add filterset test

* Remove mac_address field from interface forms

* Designate primary MAC address via a ForeignKey on the interface models

* Add serializer fields for primary_mac_address

* Update docs

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
bctiemann
2024-11-18 15:11:24 -05:00
committed by GitHub
parent b4f15092db
commit 353214098b
46 changed files with 1156 additions and 173 deletions

View File

@@ -2538,6 +2538,51 @@ class PowerOutletBulkDeleteView(generic.BulkDeleteView):
register_model_view(PowerOutlet, 'trace', kwargs={'model': PowerOutlet})(PathTraceView)
#
# MAC addresses
#
class MACAddressListView(generic.ObjectListView):
queryset = MACAddress.objects.all()
filterset = filtersets.MACAddressFilterSet
filterset_form = forms.MACAddressFilterForm
table = tables.MACAddressTable
@register_model_view(MACAddress)
class MACAddressView(generic.ObjectView):
queryset = MACAddress.objects.all()
@register_model_view(MACAddress, 'edit')
class MACAddressEditView(generic.ObjectEditView):
queryset = MACAddress.objects.all()
form = forms.MACAddressForm
@register_model_view(MACAddress, 'delete')
class MACAddressDeleteView(generic.ObjectDeleteView):
queryset = MACAddress.objects.all()
class MACAddressBulkImportView(generic.BulkImportView):
queryset = MACAddress.objects.all()
model_form = forms.MACAddressImportForm
class MACAddressBulkEditView(generic.BulkEditView):
queryset = MACAddress.objects.all()
filterset = filtersets.MACAddressFilterSet
table = tables.MACAddressTable
form = forms.MACAddressBulkEditForm
class MACAddressBulkDeleteView(generic.BulkDeleteView):
queryset = MACAddress.objects.all()
filterset = filtersets.MACAddressFilterSet
table = tables.MACAddressTable
#
# Interfaces
#
@@ -2571,7 +2616,7 @@ class InterfaceView(generic.ObjectView):
# Get bridge interfaces
bridge_interfaces = Interface.objects.restrict(request.user, 'view').filter(bridge=instance)
bridge_interfaces_tables = tables.InterfaceTable(
bridge_interfaces_table = tables.InterfaceTable(
bridge_interfaces,
exclude=('device', 'parent'),
orderable=False
@@ -2579,7 +2624,7 @@ class InterfaceView(generic.ObjectView):
# Get child interfaces
child_interfaces = Interface.objects.restrict(request.user, 'view').filter(parent=instance)
child_interfaces_tables = tables.InterfaceTable(
child_interfaces_table = tables.InterfaceTable(
child_interfaces,
exclude=('device', 'parent'),
orderable=False
@@ -2609,8 +2654,8 @@ class InterfaceView(generic.ObjectView):
return {
'vdc_table': vdc_table,
'bridge_interfaces_table': bridge_interfaces_tables,
'child_interfaces_table': child_interfaces_tables,
'bridge_interfaces_table': bridge_interfaces_table,
'child_interfaces_table': child_interfaces_table,
'vlan_table': vlan_table,
'vlan_translation_table': vlan_translation_table,
}