mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-01 13:26:25 -06:00
feat: add cable reconnection
This commit is contained in:
parent
4f7626828a
commit
f8d7c024e7
@ -4269,6 +4269,574 @@ class CableCSVForm(CustomFieldModelCSVForm):
|
|||||||
return length_unit if length_unit is not None else ''
|
return length_unit if length_unit is not None else ''
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectCableToDeviceForm(BootstrapMixin, forms.ModelForm):
|
||||||
|
"""
|
||||||
|
Base form for connecting a Cable to a Device component
|
||||||
|
"""
|
||||||
|
termination_a_site = DynamicModelChoiceField(
|
||||||
|
queryset=Site.objects.all(),
|
||||||
|
label='Site',
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
termination_a_rack = DynamicModelChoiceField(
|
||||||
|
queryset=Rack.objects.all(),
|
||||||
|
label='Rack',
|
||||||
|
required=False,
|
||||||
|
display_field='display_name',
|
||||||
|
null_option='None',
|
||||||
|
query_params={
|
||||||
|
'site_id': '$termination_a_site'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_a_device = DynamicModelChoiceField(
|
||||||
|
queryset=Device.objects.all(),
|
||||||
|
label='Device',
|
||||||
|
required=False,
|
||||||
|
display_field='display_name',
|
||||||
|
query_params={
|
||||||
|
'site_id': '$termination_a_site',
|
||||||
|
'rack_id': '$termination_a_rack',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_site = DynamicModelChoiceField(
|
||||||
|
queryset=Site.objects.all(),
|
||||||
|
label='Site',
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
termination_b_rack = DynamicModelChoiceField(
|
||||||
|
queryset=Rack.objects.all(),
|
||||||
|
label='Rack',
|
||||||
|
required=False,
|
||||||
|
display_field='display_name',
|
||||||
|
null_option='None',
|
||||||
|
query_params={
|
||||||
|
'site_id': '$termination_b_site'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_device = DynamicModelChoiceField(
|
||||||
|
queryset=Device.objects.all(),
|
||||||
|
label='Device',
|
||||||
|
required=False,
|
||||||
|
display_field='display_name',
|
||||||
|
query_params={
|
||||||
|
'site_id': '$termination_b_site',
|
||||||
|
'rack_id': '$termination_b_rack',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Cable
|
||||||
|
fields = [
|
||||||
|
'termination_a_site', 'termination_a_rack', 'termination_a_device', 'termination_a_id',
|
||||||
|
'termination_b_site', 'termination_b_rack', 'termination_b_device', 'termination_b_id'
|
||||||
|
]
|
||||||
|
|
||||||
|
def clean_termination_a_id(self):
|
||||||
|
# Return the PK rather than the object
|
||||||
|
return getattr(self.cleaned_data['termination_a_id'], 'pk', None)
|
||||||
|
|
||||||
|
def clean_termination_b_id(self):
|
||||||
|
# Return the PK rather than the object
|
||||||
|
return getattr(self.cleaned_data['termination_b_id'], 'pk', None)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectConsolePortToConsoleServerPortForm(ReconnectCableToDeviceForm):
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=ConsolePort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_a_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=ConsoleServerPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectConsolePortToFrontPortForm(ReconnectCableToDeviceForm):
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=ConsolePort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_a_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=FrontPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectConsolePortToRearPortForm(ReconnectCableToDeviceForm):
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=ConsolePort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_a_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=RearPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectConsoleServerPortToFrontPortForm(ReconnectCableToDeviceForm):
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=ConsoleServerPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_a_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=FrontPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectConsoleServerPortToRearPortForm(ReconnectCableToDeviceForm):
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=ConsoleServerPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_a_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=RearPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectPowerfeedToPowerPortForm(ReconnectCableToDeviceForm):
|
||||||
|
termination_a_site = DynamicModelChoiceField(
|
||||||
|
queryset=Site.objects.all(),
|
||||||
|
label='Site',
|
||||||
|
required=False,
|
||||||
|
display_field='cid'
|
||||||
|
)
|
||||||
|
termination_a_rackgroup = DynamicModelChoiceField(
|
||||||
|
queryset=Location.objects.all(),
|
||||||
|
label='Location',
|
||||||
|
required=False,
|
||||||
|
display_field='cid',
|
||||||
|
query_params={
|
||||||
|
'site_id': '$termination_a_site'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_a_powerpanel = DynamicModelChoiceField(
|
||||||
|
queryset=PowerPanel.objects.all(),
|
||||||
|
label='Power Panel',
|
||||||
|
required=False,
|
||||||
|
query_params={
|
||||||
|
'site_id': '$termination_a_site',
|
||||||
|
'rack_group_id': '$termination_a_rackgroup',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=PowerFeed.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'power_panel_id': '$termination_a_powerpanel'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=PowerPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Cable
|
||||||
|
fields = [
|
||||||
|
'termination_a_site', 'termination_a_rackgroup', 'termination_a_powerpanel', 'termination_a_id',
|
||||||
|
'termination_b_site', 'termination_b_rack', 'termination_b_device', 'termination_b_id'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectPowerOutletToPowerPortForm(ReconnectCableToDeviceForm):
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=PowerOutlet.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_a_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=PowerPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectInterfaceForm(ReconnectCableToDeviceForm):
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=Interface.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_a_device',
|
||||||
|
'kind': 'physical',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=Interface.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device',
|
||||||
|
'kind': 'physical',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectFrontPortToInterfaceForm(ReconnectCableToDeviceForm):
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=FrontPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_a_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=Interface.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device',
|
||||||
|
'kind': 'physical',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectInterfaceToRearPortForm(ReconnectCableToDeviceForm):
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=Interface.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_a_device',
|
||||||
|
'kind': 'physical',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=RearPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectCircuitTerminationToInterfaceForm(ReconnectCableToDeviceForm):
|
||||||
|
termination_a_provider = DynamicModelChoiceField(
|
||||||
|
queryset=Provider.objects.all(),
|
||||||
|
label='Provider',
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
termination_a_site = DynamicModelChoiceField(
|
||||||
|
queryset=Site.objects.all(),
|
||||||
|
label='Site',
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
termination_a_circuit = DynamicModelChoiceField(
|
||||||
|
queryset=Circuit.objects.all(),
|
||||||
|
label='Circuit',
|
||||||
|
display_field='cid',
|
||||||
|
query_params={
|
||||||
|
'provider_id': '$termination_a_provider',
|
||||||
|
'site_id': '$termination_a_site',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=CircuitTermination.objects.all(),
|
||||||
|
label='Side',
|
||||||
|
display_field='term_side',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'circuit_id': '$termination_a_circuit'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=Interface.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device',
|
||||||
|
'kind': 'physical',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Cable
|
||||||
|
fields = [
|
||||||
|
'termination_a_provider', 'termination_a_site', 'termination_a_circuit', 'termination_a_id',
|
||||||
|
'termination_b_site', 'termination_b_rack', 'termination_b_device', 'termination_b_id'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectCircuitTerminationForm(BootstrapMixin, forms.ModelForm):
|
||||||
|
termination_a_provider = DynamicModelChoiceField(
|
||||||
|
queryset=Provider.objects.all(),
|
||||||
|
label='Provider',
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
termination_a_site = DynamicModelChoiceField(
|
||||||
|
queryset=Site.objects.all(),
|
||||||
|
label='Site',
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
termination_a_circuit = DynamicModelChoiceField(
|
||||||
|
queryset=Circuit.objects.all(),
|
||||||
|
label='Circuit',
|
||||||
|
display_field='cid',
|
||||||
|
query_params={
|
||||||
|
'provider_id': '$termination_a_provider',
|
||||||
|
'site_id': '$termination_a_site',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=CircuitTermination.objects.all(),
|
||||||
|
label='Side',
|
||||||
|
display_field='term_side',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'circuit_id': '$termination_a_circuit'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_provider = DynamicModelChoiceField(
|
||||||
|
queryset=Provider.objects.all(),
|
||||||
|
label='Provider',
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
termination_b_site = DynamicModelChoiceField(
|
||||||
|
queryset=Site.objects.all(),
|
||||||
|
label='Site',
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
termination_b_circuit = DynamicModelChoiceField(
|
||||||
|
queryset=Circuit.objects.all(),
|
||||||
|
label='Circuit',
|
||||||
|
display_field='cid',
|
||||||
|
query_params={
|
||||||
|
'provider_id': '$termination_b_provider',
|
||||||
|
'site_id': '$termination_b_site',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=CircuitTermination.objects.all(),
|
||||||
|
label='Side',
|
||||||
|
display_field='term_side',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'circuit_id': '$termination_b_circuit'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Cable
|
||||||
|
fields = [
|
||||||
|
'termination_a_provider', 'termination_a_site', 'termination_a_circuit', 'termination_a_id',
|
||||||
|
'termination_b_provider', 'termination_b_site', 'termination_b_circuit', 'termination_b_id', 'type',
|
||||||
|
'status', 'label', 'color', 'length', 'length_unit',
|
||||||
|
]
|
||||||
|
|
||||||
|
def clean_termination_a_id(self):
|
||||||
|
# Return the PK rather than the object
|
||||||
|
return getattr(self.cleaned_data['termination_a_id'], 'pk', None)
|
||||||
|
|
||||||
|
def clean_termination_b_id(self):
|
||||||
|
# Return the PK rather than the object
|
||||||
|
return getattr(self.cleaned_data['termination_b_id'], 'pk', None)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectFrontPortForm(ReconnectCableToDeviceForm):
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=FrontPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_a_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=FrontPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectFrontPortToRearPortForm(ReconnectCableToDeviceForm):
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=FrontPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_a_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=RearPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectRearPortForm(ReconnectCableToDeviceForm):
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=RearPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_a_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=RearPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectCircuitTerminationToForm(BootstrapMixin, forms.ModelForm):
|
||||||
|
termination_a_provider = DynamicModelChoiceField(
|
||||||
|
queryset=Provider.objects.all(),
|
||||||
|
label='Provider',
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
termination_a_site = DynamicModelChoiceField(
|
||||||
|
queryset=Site.objects.all(),
|
||||||
|
label='Site',
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
termination_a_circuit = DynamicModelChoiceField(
|
||||||
|
queryset=Circuit.objects.all(),
|
||||||
|
label='Circuit',
|
||||||
|
display_field='cid',
|
||||||
|
query_params={
|
||||||
|
'provider_id': '$termination_a_provider',
|
||||||
|
'site_id': '$termination_a_site',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_a_id = DynamicModelChoiceField(
|
||||||
|
queryset=CircuitTermination.objects.all(),
|
||||||
|
label='Side',
|
||||||
|
display_field='term_side',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'circuit_id': '$termination_a_circuit'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_site = DynamicModelChoiceField(
|
||||||
|
queryset=Site.objects.all(),
|
||||||
|
label='Site',
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
termination_b_rack = DynamicModelChoiceField(
|
||||||
|
queryset=Rack.objects.all(),
|
||||||
|
label='Rack',
|
||||||
|
required=False,
|
||||||
|
display_field='display_name',
|
||||||
|
null_option='None',
|
||||||
|
query_params={
|
||||||
|
'site_id': '$termination_b_site'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
termination_b_device = DynamicModelChoiceField(
|
||||||
|
queryset=Device.objects.all(),
|
||||||
|
label='Device',
|
||||||
|
required=False,
|
||||||
|
display_field='display_name',
|
||||||
|
query_params={
|
||||||
|
'site_id': '$termination_b_site',
|
||||||
|
'rack_id': '$termination_b_rack',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Cable
|
||||||
|
fields = [
|
||||||
|
'termination_a_provider', 'termination_a_site', 'termination_a_circuit', 'termination_a_id',
|
||||||
|
'termination_b_site', 'termination_b_rack', 'termination_b_device', 'termination_b_id'
|
||||||
|
]
|
||||||
|
|
||||||
|
def clean_termination_a_id(self):
|
||||||
|
# Return the PK rather than the object
|
||||||
|
return getattr(self.cleaned_data['termination_a_id'], 'pk', None)
|
||||||
|
|
||||||
|
def clean_termination_b_id(self):
|
||||||
|
# Return the PK rather than the object
|
||||||
|
return getattr(self.cleaned_data['termination_b_id'], 'pk', None)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectCircuitTerminationToFrontPortForm(ReconnectCircuitTerminationToForm):
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=FrontPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReconnectCircuitTerminationToRearPortForm(ReconnectCircuitTerminationToForm):
|
||||||
|
termination_b_id = DynamicModelChoiceField(
|
||||||
|
queryset=RearPort.objects.all(),
|
||||||
|
label='Name',
|
||||||
|
disabled_indicator='cable',
|
||||||
|
query_params={
|
||||||
|
'device_id': '$termination_b_device'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CableBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
|
class CableBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
|
||||||
pk = forms.ModelMultipleChoiceField(
|
pk = forms.ModelMultipleChoiceField(
|
||||||
queryset=Cable.objects.all(),
|
queryset=Cable.objects.all(),
|
||||||
|
@ -378,6 +378,7 @@ urlpatterns = [
|
|||||||
path('cables/<int:pk>/delete/', views.CableDeleteView.as_view(), name='cable_delete'),
|
path('cables/<int:pk>/delete/', views.CableDeleteView.as_view(), name='cable_delete'),
|
||||||
path('cables/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='cable_changelog', kwargs={'model': Cable}),
|
path('cables/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='cable_changelog', kwargs={'model': Cable}),
|
||||||
path('cables/<int:pk>/journal/', ObjectJournalView.as_view(), name='cable_journal', kwargs={'model': Cable}),
|
path('cables/<int:pk>/journal/', ObjectJournalView.as_view(), name='cable_journal', kwargs={'model': Cable}),
|
||||||
|
path(r'cables/<int:pk>/reconnect/', views.CableReconnectView.as_view(), name='cable_reconnect'),
|
||||||
|
|
||||||
# Console/power/interface connections (read-only)
|
# Console/power/interface connections (read-only)
|
||||||
path('console-connections/', views.ConsoleConnectionsListView.as_view(), name='console_connections_list'),
|
path('console-connections/', views.ConsoleConnectionsListView.as_view(), name='console_connections_list'),
|
||||||
|
@ -2478,6 +2478,104 @@ class CableBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.CableTable
|
table = tables.CableTable
|
||||||
|
|
||||||
|
|
||||||
|
class CableReconnectView(ObjectPermissionRequiredMixin, GetReturnURLMixin, View):
|
||||||
|
queryset = Cable.objects.prefetch_related('termination_a', 'termination_b')
|
||||||
|
template_name = 'dcim/cable_reconnect.html'
|
||||||
|
|
||||||
|
def get_required_permission(self):
|
||||||
|
return 'dcim.change_cable'
|
||||||
|
|
||||||
|
def dispatch(self, request, *args, pk=None, **kwargs):
|
||||||
|
self.obj = Cable.objects.get(pk=pk)
|
||||||
|
|
||||||
|
idx = (self.obj.termination_a_type.model, self.obj.termination_b_type.model)
|
||||||
|
idx_sorted = tuple(sorted(idx))
|
||||||
|
if idx != idx_sorted:
|
||||||
|
termination_a = self.obj.termination_a
|
||||||
|
self.obj.termination_a = self.obj.termination_b
|
||||||
|
self.obj.termination_b = termination_a
|
||||||
|
|
||||||
|
self.form_class = {
|
||||||
|
('circuittermination', 'circuittermination'): forms.ReconnectCircuitTerminationForm,
|
||||||
|
('circuittermination', 'rearport'): forms.ReconnectCircuitTerminationToRearPortForm,
|
||||||
|
('consoleport', 'consoleserverport'): forms.ReconnectConsolePortToConsoleServerPortForm,
|
||||||
|
('consoleport', 'frontport'): forms.ReconnectConsolePortToFrontPortForm,
|
||||||
|
('consoleport', 'rearport'): forms.ReconnectConsolePortToRearPortForm,
|
||||||
|
('consoleserverport', 'frontport'): forms.ReconnectConsoleServerPortToFrontPortForm,
|
||||||
|
('consoleserverport', 'rearport'): forms.ReconnectConsoleServerPortToRearPortForm,
|
||||||
|
('powerfeed', 'powerport'): forms.ReconnectPowerfeedToPowerPortForm,
|
||||||
|
('poweroutlet', 'powerport'): forms.ReconnectPowerOutletToPowerPortForm,
|
||||||
|
('circuittermination', 'interface'): forms.ReconnectCircuitTerminationToInterfaceForm,
|
||||||
|
('frontport', 'interface'): forms.ReconnectFrontPortToInterfaceForm,
|
||||||
|
('interface', 'rearport'): forms.ReconnectInterfaceToRearPortForm,
|
||||||
|
('interface', 'interface'): forms.ReconnectInterfaceForm,
|
||||||
|
('frontport', 'frontport'): forms.ReconnectFrontPortForm,
|
||||||
|
('frontport', 'rearport'): forms.ReconnectFrontPortToRearPortForm,
|
||||||
|
('circuittermination', 'frontport'): forms.ReconnectCircuitTerminationToFrontPortForm,
|
||||||
|
('rearport', 'rearport'): forms.ReconnectRearPortForm,
|
||||||
|
}[idx_sorted]
|
||||||
|
|
||||||
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def prefill_form(self, initial_data, termination):
|
||||||
|
o = getattr(self.obj, termination)
|
||||||
|
if o and hasattr(o, 'device'):
|
||||||
|
device = o.device
|
||||||
|
initial_data['{}_device'.format(termination)] = device
|
||||||
|
if device.site:
|
||||||
|
initial_data['{}_site'.format(termination)] = device.site
|
||||||
|
if device.rack:
|
||||||
|
initial_data['{}_rack'.format(termination)] = device.rack
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
# Parse initial data manually to avoid setting field values as lists
|
||||||
|
initial_data = {k: request.GET[k] for k in request.GET}
|
||||||
|
|
||||||
|
self.prefill_form(initial_data, 'termination_a')
|
||||||
|
self.prefill_form(initial_data, 'termination_b')
|
||||||
|
|
||||||
|
form = self.form_class(instance=self.obj, initial=initial_data)
|
||||||
|
|
||||||
|
return render(request, self.template_name, {
|
||||||
|
'obj': self.obj,
|
||||||
|
'obj_type': Cable._meta.verbose_name,
|
||||||
|
'form': form,
|
||||||
|
'return_url': self.get_return_url(request, self.obj),
|
||||||
|
})
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
with transaction.atomic():
|
||||||
|
try:
|
||||||
|
if hasattr(self.obj.termination_a, '_path') and self.obj.termination_a._path_id:
|
||||||
|
self.obj.termination_a._path = None
|
||||||
|
except CablePath.DoesNotExist:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
if hasattr(self.obj.termination_b, '_path') and self.obj.termination_b._path_id:
|
||||||
|
self.obj.termination_b._path = None
|
||||||
|
except CablePath.DoesNotExist:
|
||||||
|
pass
|
||||||
|
self.obj.delete()
|
||||||
|
|
||||||
|
self.obj.termination_a.cable = None
|
||||||
|
self.obj.termination_b.cable = None
|
||||||
|
|
||||||
|
form = self.form_class(request.POST, request.FILES, instance=self.obj)
|
||||||
|
if form.is_valid():
|
||||||
|
obj = form.save()
|
||||||
|
|
||||||
|
return redirect(self.get_return_url(request, obj))
|
||||||
|
|
||||||
|
return render(request, self.template_name, {
|
||||||
|
'obj': self.obj,
|
||||||
|
'obj_type': Cable._meta.verbose_name,
|
||||||
|
'form': form,
|
||||||
|
|
||||||
|
|
||||||
|
'return_url': self.get_return_url(request, self.obj),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Connections
|
# Connections
|
||||||
#
|
#
|
||||||
|
@ -10,6 +10,10 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block buttons %}
|
{% block buttons %}
|
||||||
|
{% if request.user|can_change:object %}
|
||||||
|
<a href="{% url 'dcim:cable_reconnect' pk=object.pk %}" class="btn btn-primary">
|
||||||
|
<span class="mdi mdi-ethernet-cable" aria-hidden="true"></span> Reconnect </a>
|
||||||
|
{% endif %}
|
||||||
{% if request.user|can_change:object %}
|
{% if request.user|can_change:object %}
|
||||||
{% edit_button object %}
|
{% edit_button object %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
140
netbox/templates/dcim/cable_reconnect.html
Normal file
140
netbox/templates/dcim/cable_reconnect.html
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load static %}
|
||||||
|
{% load helpers %}
|
||||||
|
{% load form_helpers %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form method="post" class="form form-horizontal">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% for field in form.hidden_fields %}
|
||||||
|
{{ field }}
|
||||||
|
{% endfor %}
|
||||||
|
{% if form.non_field_errors %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 col-md-offset-3">
|
||||||
|
<div class="panel panel-danger">
|
||||||
|
<div class="panel-heading"><strong>Errors</strong></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{{ form.non_field_errors }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% with termination_a=form.instance.termination_a %}
|
||||||
|
<h3>{% block title %}Reconnect {{ form.instance.termination_a_type.name|bettertitle }}<->{{ form.instance.termination_b_type.name|bettertitle }} cable{% endblock %}</h3>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading text-center">
|
||||||
|
<strong>A Side</strong>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{% if tabs %}
|
||||||
|
<ul class="nav nav-tabs">
|
||||||
|
{% for url, link in tabs %}
|
||||||
|
<li role="presentation"><a href="{{ url }}">{{ link }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_a_provider' in form.fields %}
|
||||||
|
{% render_field form.termination_a_provider %}
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_a_site' in form.fields %}
|
||||||
|
{% render_field form.termination_a_site %}
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_a_rackgroup' in form.fields %}
|
||||||
|
{% render_field form.termination_a_rackgroup %}
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_a_rack' in form.fields %}
|
||||||
|
{% render_field form.termination_a_rack %}
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_a_device' in form.fields %}
|
||||||
|
{% render_field form.termination_a_device %}
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_a_type' in form.fields %}
|
||||||
|
{% render_field form.termination_a_type %}
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_a_powerpanel' in form.fields %}
|
||||||
|
{% render_field form.termination_a_powerpanel %}
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_a_circuit' in form.fields %}
|
||||||
|
{% render_field form.termination_a_circuit %}
|
||||||
|
{% endif %}
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-md-3 control-label required">Type</label>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<p class="form-control-static">{{ form.instance.termination_a_type.name|capfirst }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% render_field form.termination_a_id %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 text-center" style="padding-top: 90px;">
|
||||||
|
<i class="fa fa-exchange fa-4x"></i>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading text-center">
|
||||||
|
<strong>B Side</strong>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{% if tabs %}
|
||||||
|
<ul class="nav nav-tabs">
|
||||||
|
{% for url, link in tabs %}
|
||||||
|
<li role="presentation"><a href="{{ url }}">{{ link }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_b_provider' in form.fields %}
|
||||||
|
{% render_field form.termination_b_provider %}
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_b_site' in form.fields %}
|
||||||
|
{% render_field form.termination_b_site %}
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_b_rackgroup' in form.fields %}
|
||||||
|
{% render_field form.termination_b_rackgroup %}
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_b_rack' in form.fields %}
|
||||||
|
{% render_field form.termination_b_rack %}
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_b_device' in form.fields %}
|
||||||
|
{% render_field form.termination_b_device %}
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_b_type' in form.fields %}
|
||||||
|
{% render_field form.termination_b_type %}
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_b_powerpanel' in form.fields %}
|
||||||
|
{% render_field form.termination_b_powerpanel %}
|
||||||
|
{% endif %}
|
||||||
|
{% if 'termination_b_circuit' in form.fields %}
|
||||||
|
{% render_field form.termination_b_circuit %}
|
||||||
|
{% endif %}
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-md-3 control-label required">Type</label>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<p class="form-control-static">{{ form.instance.termination_b_type.name|capfirst }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% render_field form.termination_b_id %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="display: none">
|
||||||
|
{% include 'dcim/inc/cable_form.html' %}
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-md-12 text-center">
|
||||||
|
<button type="submit" name="_update" class="btn btn-primary">Reconnect</button>
|
||||||
|
<a href="{{ return_url }}" class="btn btn-default">Cancel</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endwith %}
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block javascript %}
|
||||||
|
<script src="{% static 'js/livesearch.js' %}?v{{ settings.VERSION }}"></script>
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue
Block a user