mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-29 11:56:25 -06:00
Reorganize "Addressing" sections to remove from proximity to "Device Components" and related groupings
This commit is contained in:
parent
fc4483db48
commit
0214b9e382
@ -42,7 +42,6 @@ router.register('virtual-device-contexts', views.VirtualDeviceContextViewSet)
|
|||||||
router.register('modules', views.ModuleViewSet)
|
router.register('modules', views.ModuleViewSet)
|
||||||
|
|
||||||
# Device components
|
# Device components
|
||||||
router.register('mac-addresses', views.MACAddressViewSet)
|
|
||||||
router.register('console-ports', views.ConsolePortViewSet)
|
router.register('console-ports', views.ConsolePortViewSet)
|
||||||
router.register('console-server-ports', views.ConsoleServerPortViewSet)
|
router.register('console-server-ports', views.ConsoleServerPortViewSet)
|
||||||
router.register('power-ports', views.PowerPortViewSet)
|
router.register('power-ports', views.PowerPortViewSet)
|
||||||
@ -57,6 +56,9 @@ router.register('inventory-items', views.InventoryItemViewSet)
|
|||||||
# Device component roles
|
# Device component roles
|
||||||
router.register('inventory-item-roles', views.InventoryItemRoleViewSet)
|
router.register('inventory-item-roles', views.InventoryItemRoleViewSet)
|
||||||
|
|
||||||
|
# Addressing
|
||||||
|
router.register('mac-addresses', views.MACAddressViewSet)
|
||||||
|
|
||||||
# Cables
|
# Cables
|
||||||
router.register('cables', views.CableViewSet)
|
router.register('cables', views.CableViewSet)
|
||||||
router.register('cable-terminations', views.CableTerminationViewSet)
|
router.register('cable-terminations', views.CableTerminationViewSet)
|
||||||
|
@ -408,12 +408,6 @@ class ModuleViewSet(NetBoxModelViewSet):
|
|||||||
# Device components
|
# Device components
|
||||||
#
|
#
|
||||||
|
|
||||||
class MACAddressViewSet(NetBoxModelViewSet):
|
|
||||||
queryset = MACAddress.objects.all()
|
|
||||||
serializer_class = serializers.MACAddressSerializer
|
|
||||||
filterset_class = filtersets.MACAddressFilterSet
|
|
||||||
|
|
||||||
|
|
||||||
class ConsolePortViewSet(PathEndpointMixin, NetBoxModelViewSet):
|
class ConsolePortViewSet(PathEndpointMixin, NetBoxModelViewSet):
|
||||||
queryset = ConsolePort.objects.prefetch_related(
|
queryset = ConsolePort.objects.prefetch_related(
|
||||||
'_path', 'cable__terminations',
|
'_path', 'cable__terminations',
|
||||||
@ -505,6 +499,16 @@ class InventoryItemRoleViewSet(NetBoxModelViewSet):
|
|||||||
filterset_class = filtersets.InventoryItemRoleFilterSet
|
filterset_class = filtersets.InventoryItemRoleFilterSet
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Addressing
|
||||||
|
#
|
||||||
|
|
||||||
|
class MACAddressViewSet(NetBoxModelViewSet):
|
||||||
|
queryset = MACAddress.objects.all()
|
||||||
|
serializer_class = serializers.MACAddressSerializer
|
||||||
|
filterset_class = filtersets.MACAddressFilterSet
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Cables
|
# Cables
|
||||||
#
|
#
|
||||||
|
@ -1274,32 +1274,6 @@ class InventoryItemTemplateBulkEditForm(BulkEditForm):
|
|||||||
nullable_fields = ('label', 'role', 'manufacturer', 'part_id', 'description')
|
nullable_fields = ('label', 'role', 'manufacturer', 'part_id', 'description')
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Addressing
|
|
||||||
#
|
|
||||||
|
|
||||||
class MACAddressBulkEditForm(NetBoxModelBulkEditForm):
|
|
||||||
description = forms.CharField(
|
|
||||||
label=_('Description'),
|
|
||||||
max_length=200,
|
|
||||||
required=False
|
|
||||||
)
|
|
||||||
is_primary = forms.NullBooleanField(
|
|
||||||
label=_('Is primary'),
|
|
||||||
required=False,
|
|
||||||
widget=BulkEditNullBooleanSelect(),
|
|
||||||
)
|
|
||||||
comments = CommentField()
|
|
||||||
|
|
||||||
model = MACAddress
|
|
||||||
fieldsets = (
|
|
||||||
FieldSet('description', 'is_primary'),
|
|
||||||
)
|
|
||||||
nullable_fields = (
|
|
||||||
'description', 'comments',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Device components
|
# Device components
|
||||||
#
|
#
|
||||||
@ -1746,3 +1720,29 @@ class VirtualDeviceContextBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
FieldSet('device', 'status', 'tenant'),
|
FieldSet('device', 'status', 'tenant'),
|
||||||
)
|
)
|
||||||
nullable_fields = ('device', 'tenant', )
|
nullable_fields = ('device', 'tenant', )
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Addressing
|
||||||
|
#
|
||||||
|
|
||||||
|
class MACAddressBulkEditForm(NetBoxModelBulkEditForm):
|
||||||
|
description = forms.CharField(
|
||||||
|
label=_('Description'),
|
||||||
|
max_length=200,
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
is_primary = forms.NullBooleanField(
|
||||||
|
label=_('Is primary'),
|
||||||
|
required=False,
|
||||||
|
widget=BulkEditNullBooleanSelect(),
|
||||||
|
)
|
||||||
|
comments = CommentField()
|
||||||
|
|
||||||
|
model = MACAddress
|
||||||
|
fieldsets = (
|
||||||
|
FieldSet('description', 'is_primary'),
|
||||||
|
)
|
||||||
|
nullable_fields = (
|
||||||
|
'description', 'comments',
|
||||||
|
)
|
||||||
|
@ -696,90 +696,6 @@ class ModuleImportForm(ModuleCommonForm, NetBoxModelImportForm):
|
|||||||
return self.cleaned_data['replicate_components']
|
return self.cleaned_data['replicate_components']
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Addressing
|
|
||||||
#
|
|
||||||
|
|
||||||
class MACAddressImportForm(NetBoxModelImportForm):
|
|
||||||
device = CSVModelChoiceField(
|
|
||||||
label=_('Device'),
|
|
||||||
queryset=Device.objects.all(),
|
|
||||||
required=False,
|
|
||||||
to_field_name='name',
|
|
||||||
help_text=_('Parent device of assigned interface (if any)')
|
|
||||||
)
|
|
||||||
virtual_machine = CSVModelChoiceField(
|
|
||||||
label=_('Virtual machine'),
|
|
||||||
queryset=VirtualMachine.objects.all(),
|
|
||||||
required=False,
|
|
||||||
to_field_name='name',
|
|
||||||
help_text=_('Parent VM of assigned interface (if any)')
|
|
||||||
)
|
|
||||||
interface = CSVModelChoiceField(
|
|
||||||
label=_('Interface'),
|
|
||||||
queryset=Interface.objects.none(), # Can also refer to VMInterface
|
|
||||||
required=False,
|
|
||||||
to_field_name='name',
|
|
||||||
help_text=_('Assigned interface')
|
|
||||||
)
|
|
||||||
is_primary = forms.BooleanField(
|
|
||||||
label=_('Is primary'),
|
|
||||||
help_text=_('Make this the primary MAC address for the assigned interface'),
|
|
||||||
required=False
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = MACAddress
|
|
||||||
fields = [
|
|
||||||
'mac_address', 'device', 'virtual_machine', 'interface', 'is_primary',
|
|
||||||
'description', 'comments', 'tags',
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(self, data=None, *args, **kwargs):
|
|
||||||
super().__init__(data, *args, **kwargs)
|
|
||||||
|
|
||||||
if data:
|
|
||||||
|
|
||||||
# Limit interface queryset by assigned device
|
|
||||||
if data.get('device'):
|
|
||||||
self.fields['interface'].queryset = Interface.objects.filter(
|
|
||||||
**{f"device__{self.fields['device'].to_field_name}": data['device']}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Limit interface queryset by assigned device
|
|
||||||
elif data.get('virtual_machine'):
|
|
||||||
self.fields['interface'].queryset = VMInterface.objects.filter(
|
|
||||||
**{f"virtual_machine__{self.fields['virtual_machine'].to_field_name}": data['virtual_machine']}
|
|
||||||
)
|
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
super().clean()
|
|
||||||
|
|
||||||
device = self.cleaned_data.get('device')
|
|
||||||
virtual_machine = self.cleaned_data.get('virtual_machine')
|
|
||||||
interface = self.cleaned_data.get('interface')
|
|
||||||
is_primary = self.cleaned_data.get('is_primary')
|
|
||||||
|
|
||||||
# Validate is_primary
|
|
||||||
# TODO: scope to interface rather than device/VM
|
|
||||||
if is_primary and not device and not virtual_machine:
|
|
||||||
raise forms.ValidationError({
|
|
||||||
"is_primary": _("No device or virtual machine specified; cannot set as primary")
|
|
||||||
})
|
|
||||||
if is_primary and not interface:
|
|
||||||
raise forms.ValidationError({
|
|
||||||
"is_primary": _("No interface specified; cannot set as primary")
|
|
||||||
})
|
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
|
|
||||||
# Set interface assignment
|
|
||||||
if self.cleaned_data.get('interface'):
|
|
||||||
self.instance.assigned_object = self.cleaned_data['interface']
|
|
||||||
|
|
||||||
return super().save(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Device components
|
# Device components
|
||||||
#
|
#
|
||||||
@ -1252,6 +1168,90 @@ class InventoryItemRoleImportForm(NetBoxModelImportForm):
|
|||||||
fields = ('name', 'slug', 'color', 'description')
|
fields = ('name', 'slug', 'color', 'description')
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Addressing
|
||||||
|
#
|
||||||
|
|
||||||
|
class MACAddressImportForm(NetBoxModelImportForm):
|
||||||
|
device = CSVModelChoiceField(
|
||||||
|
label=_('Device'),
|
||||||
|
queryset=Device.objects.all(),
|
||||||
|
required=False,
|
||||||
|
to_field_name='name',
|
||||||
|
help_text=_('Parent device of assigned interface (if any)')
|
||||||
|
)
|
||||||
|
virtual_machine = CSVModelChoiceField(
|
||||||
|
label=_('Virtual machine'),
|
||||||
|
queryset=VirtualMachine.objects.all(),
|
||||||
|
required=False,
|
||||||
|
to_field_name='name',
|
||||||
|
help_text=_('Parent VM of assigned interface (if any)')
|
||||||
|
)
|
||||||
|
interface = CSVModelChoiceField(
|
||||||
|
label=_('Interface'),
|
||||||
|
queryset=Interface.objects.none(), # Can also refer to VMInterface
|
||||||
|
required=False,
|
||||||
|
to_field_name='name',
|
||||||
|
help_text=_('Assigned interface')
|
||||||
|
)
|
||||||
|
is_primary = forms.BooleanField(
|
||||||
|
label=_('Is primary'),
|
||||||
|
help_text=_('Make this the primary MAC address for the assigned interface'),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = MACAddress
|
||||||
|
fields = [
|
||||||
|
'mac_address', 'device', 'virtual_machine', 'interface', 'is_primary',
|
||||||
|
'description', 'comments', 'tags',
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, data=None, *args, **kwargs):
|
||||||
|
super().__init__(data, *args, **kwargs)
|
||||||
|
|
||||||
|
if data:
|
||||||
|
|
||||||
|
# Limit interface queryset by assigned device
|
||||||
|
if data.get('device'):
|
||||||
|
self.fields['interface'].queryset = Interface.objects.filter(
|
||||||
|
**{f"device__{self.fields['device'].to_field_name}": data['device']}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Limit interface queryset by assigned device
|
||||||
|
elif data.get('virtual_machine'):
|
||||||
|
self.fields['interface'].queryset = VMInterface.objects.filter(
|
||||||
|
**{f"virtual_machine__{self.fields['virtual_machine'].to_field_name}": data['virtual_machine']}
|
||||||
|
)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
super().clean()
|
||||||
|
|
||||||
|
device = self.cleaned_data.get('device')
|
||||||
|
virtual_machine = self.cleaned_data.get('virtual_machine')
|
||||||
|
interface = self.cleaned_data.get('interface')
|
||||||
|
is_primary = self.cleaned_data.get('is_primary')
|
||||||
|
|
||||||
|
# Validate is_primary
|
||||||
|
# TODO: scope to interface rather than device/VM
|
||||||
|
if is_primary and not device and not virtual_machine:
|
||||||
|
raise forms.ValidationError({
|
||||||
|
"is_primary": _("No device or virtual machine specified; cannot set as primary")
|
||||||
|
})
|
||||||
|
if is_primary and not interface:
|
||||||
|
raise forms.ValidationError({
|
||||||
|
"is_primary": _("No interface specified; cannot set as primary")
|
||||||
|
})
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
|
||||||
|
# Set interface assignment
|
||||||
|
if self.cleaned_data.get('interface'):
|
||||||
|
self.instance.assigned_object = self.cleaned_data['interface']
|
||||||
|
|
||||||
|
return super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Cables
|
# Cables
|
||||||
#
|
#
|
||||||
|
@ -1202,35 +1202,6 @@ class PowerFeedFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Addressing
|
|
||||||
#
|
|
||||||
|
|
||||||
class MACAddressFilterForm(NetBoxModelFilterSetForm):
|
|
||||||
model = MACAddress
|
|
||||||
fieldsets = (
|
|
||||||
FieldSet('q', 'filter_id', 'tag'),
|
|
||||||
FieldSet('mac_address', name=_('Addressing')),
|
|
||||||
FieldSet('device_id', 'virtual_machine_id', name=_('Device/VM')),
|
|
||||||
)
|
|
||||||
selector_fields = ('filter_id', 'q', 'device_id', 'virtual_machine_id')
|
|
||||||
mac_address = forms.CharField(
|
|
||||||
required=False,
|
|
||||||
label=_('MAC address')
|
|
||||||
)
|
|
||||||
device_id = DynamicModelMultipleChoiceField(
|
|
||||||
queryset=Device.objects.all(),
|
|
||||||
required=False,
|
|
||||||
label=_('Assigned Device'),
|
|
||||||
)
|
|
||||||
virtual_machine_id = DynamicModelMultipleChoiceField(
|
|
||||||
queryset=VirtualMachine.objects.all(),
|
|
||||||
required=False,
|
|
||||||
label=_('Assigned VM'),
|
|
||||||
)
|
|
||||||
tag = TagFilterField(model)
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Device components
|
# Device components
|
||||||
#
|
#
|
||||||
@ -1604,6 +1575,35 @@ class InventoryItemRoleFilterForm(NetBoxModelFilterSetForm):
|
|||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Addressing
|
||||||
|
#
|
||||||
|
|
||||||
|
class MACAddressFilterForm(NetBoxModelFilterSetForm):
|
||||||
|
model = MACAddress
|
||||||
|
fieldsets = (
|
||||||
|
FieldSet('q', 'filter_id', 'tag'),
|
||||||
|
FieldSet('mac_address', name=_('Addressing')),
|
||||||
|
FieldSet('device_id', 'virtual_machine_id', name=_('Device/VM')),
|
||||||
|
)
|
||||||
|
selector_fields = ('filter_id', 'q', 'device_id', 'virtual_machine_id')
|
||||||
|
mac_address = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
label=_('MAC address')
|
||||||
|
)
|
||||||
|
device_id = DynamicModelMultipleChoiceField(
|
||||||
|
queryset=Device.objects.all(),
|
||||||
|
required=False,
|
||||||
|
label=_('Assigned Device'),
|
||||||
|
)
|
||||||
|
virtual_machine_id = DynamicModelMultipleChoiceField(
|
||||||
|
queryset=VirtualMachine.objects.all(),
|
||||||
|
required=False,
|
||||||
|
label=_('Assigned VM'),
|
||||||
|
)
|
||||||
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Connections
|
# Connections
|
||||||
#
|
#
|
||||||
|
@ -866,92 +866,6 @@ class VCMemberSelectForm(forms.Form):
|
|||||||
return device
|
return device
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Addressing
|
|
||||||
#
|
|
||||||
|
|
||||||
class MACAddressForm(NetBoxModelForm):
|
|
||||||
mac_address = forms.CharField(
|
|
||||||
required=True,
|
|
||||||
label=_('MAC address')
|
|
||||||
)
|
|
||||||
interface = DynamicModelChoiceField(
|
|
||||||
label=_('Interface'),
|
|
||||||
queryset=Interface.objects.all(),
|
|
||||||
required=False,
|
|
||||||
)
|
|
||||||
vminterface = DynamicModelChoiceField(
|
|
||||||
label=_('VM Interface'),
|
|
||||||
queryset=VMInterface.objects.all(),
|
|
||||||
required=False,
|
|
||||||
)
|
|
||||||
is_primary = forms.BooleanField(
|
|
||||||
required=False,
|
|
||||||
label=_('Primary for interface'),
|
|
||||||
)
|
|
||||||
|
|
||||||
fieldsets = (
|
|
||||||
FieldSet(
|
|
||||||
'mac_address', 'description', 'tags',
|
|
||||||
),
|
|
||||||
FieldSet(
|
|
||||||
TabbedGroups(
|
|
||||||
FieldSet('interface', name=_('Device')),
|
|
||||||
FieldSet('vminterface', name=_('Virtual Machine')),
|
|
||||||
),
|
|
||||||
'is_primary', name=_('Assignment')
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = MACAddress
|
|
||||||
fields = [
|
|
||||||
'mac_address', 'interface', 'vminterface', 'is_primary', 'description', 'tags',
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
|
|
||||||
# Initialize helper selectors
|
|
||||||
instance = kwargs.get('instance')
|
|
||||||
initial = kwargs.get('initial', {}).copy()
|
|
||||||
if instance:
|
|
||||||
if type(instance.assigned_object) is Interface:
|
|
||||||
initial['interface'] = instance.assigned_object
|
|
||||||
elif type(instance.assigned_object) is VMInterface:
|
|
||||||
initial['vminterface'] = instance.assigned_object
|
|
||||||
kwargs['initial'] = initial
|
|
||||||
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
super().clean()
|
|
||||||
|
|
||||||
# Handle object assignment
|
|
||||||
selected_objects = [
|
|
||||||
field for field in ('interface', 'vminterface') if self.cleaned_data[field]
|
|
||||||
]
|
|
||||||
if len(selected_objects) > 1:
|
|
||||||
raise forms.ValidationError({
|
|
||||||
selected_objects[1]: _("A MAC address can only be assigned to a single object.")
|
|
||||||
})
|
|
||||||
elif selected_objects:
|
|
||||||
assigned_object = self.cleaned_data[selected_objects[0]]
|
|
||||||
if self.instance.pk and self.instance.assigned_object and self.instance.is_primary and assigned_object != self.instance.assigned_object:
|
|
||||||
raise ValidationError(
|
|
||||||
_("Cannot reassign MAC address while it is designated as the primary for the interface")
|
|
||||||
)
|
|
||||||
self.instance.assigned_object = assigned_object
|
|
||||||
else:
|
|
||||||
self.instance.assigned_object = None
|
|
||||||
|
|
||||||
# Primary MAC address assignment is only available if an interface has been assigned.
|
|
||||||
interface = self.cleaned_data.get('interface') or self.cleaned_data.get('vminterface')
|
|
||||||
if self.cleaned_data.get('is_primary') and not interface:
|
|
||||||
self.add_error(
|
|
||||||
'is_primary', _("Only IP addresses assigned to an interface can be designated as primary IPs.")
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Device component templates
|
# Device component templates
|
||||||
#
|
#
|
||||||
@ -1820,3 +1734,89 @@ class VirtualDeviceContextForm(TenancyForm, NetBoxModelForm):
|
|||||||
'device', 'name', 'status', 'identifier', 'primary_ip4', 'primary_ip6', 'tenant_group', 'tenant',
|
'device', 'name', 'status', 'identifier', 'primary_ip4', 'primary_ip6', 'tenant_group', 'tenant',
|
||||||
'comments', 'tags'
|
'comments', 'tags'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Addressing
|
||||||
|
#
|
||||||
|
|
||||||
|
class MACAddressForm(NetBoxModelForm):
|
||||||
|
mac_address = forms.CharField(
|
||||||
|
required=True,
|
||||||
|
label=_('MAC address')
|
||||||
|
)
|
||||||
|
interface = DynamicModelChoiceField(
|
||||||
|
label=_('Interface'),
|
||||||
|
queryset=Interface.objects.all(),
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
vminterface = DynamicModelChoiceField(
|
||||||
|
label=_('VM Interface'),
|
||||||
|
queryset=VMInterface.objects.all(),
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
is_primary = forms.BooleanField(
|
||||||
|
required=False,
|
||||||
|
label=_('Primary for interface'),
|
||||||
|
)
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
FieldSet(
|
||||||
|
'mac_address', 'description', 'tags',
|
||||||
|
),
|
||||||
|
FieldSet(
|
||||||
|
TabbedGroups(
|
||||||
|
FieldSet('interface', name=_('Device')),
|
||||||
|
FieldSet('vminterface', name=_('Virtual Machine')),
|
||||||
|
),
|
||||||
|
'is_primary', name=_('Assignment')
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = MACAddress
|
||||||
|
fields = [
|
||||||
|
'mac_address', 'interface', 'vminterface', 'is_primary', 'description', 'tags',
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
||||||
|
# Initialize helper selectors
|
||||||
|
instance = kwargs.get('instance')
|
||||||
|
initial = kwargs.get('initial', {}).copy()
|
||||||
|
if instance:
|
||||||
|
if type(instance.assigned_object) is Interface:
|
||||||
|
initial['interface'] = instance.assigned_object
|
||||||
|
elif type(instance.assigned_object) is VMInterface:
|
||||||
|
initial['vminterface'] = instance.assigned_object
|
||||||
|
kwargs['initial'] = initial
|
||||||
|
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
super().clean()
|
||||||
|
|
||||||
|
# Handle object assignment
|
||||||
|
selected_objects = [
|
||||||
|
field for field in ('interface', 'vminterface') if self.cleaned_data[field]
|
||||||
|
]
|
||||||
|
if len(selected_objects) > 1:
|
||||||
|
raise forms.ValidationError({
|
||||||
|
selected_objects[1]: _("A MAC address can only be assigned to a single object.")
|
||||||
|
})
|
||||||
|
elif selected_objects:
|
||||||
|
assigned_object = self.cleaned_data[selected_objects[0]]
|
||||||
|
if self.instance.pk and self.instance.assigned_object and self.instance.is_primary and assigned_object != self.instance.assigned_object:
|
||||||
|
raise ValidationError(
|
||||||
|
_("Cannot reassign MAC address while it is designated as the primary for the interface")
|
||||||
|
)
|
||||||
|
self.instance.assigned_object = assigned_object
|
||||||
|
else:
|
||||||
|
self.instance.assigned_object = None
|
||||||
|
|
||||||
|
# Primary MAC address assignment is only available if an interface has been assigned.
|
||||||
|
interface = self.cleaned_data.get('interface') or self.cleaned_data.get('vminterface')
|
||||||
|
if self.cleaned_data.get('is_primary') and not interface:
|
||||||
|
self.add_error(
|
||||||
|
'is_primary', _("Only IP addresses assigned to an interface can be designated as primary IPs.")
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user