From 0b0a646f872d3aff41e7c56212e8746f0de21f8f Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Fri, 3 Jun 2022 14:15:28 -0400 Subject: [PATCH] Clean up cable termination changes --- netbox/dcim/forms/connections.py | 4 +-- netbox/dcim/models/cables.py | 2 +- netbox/dcim/signals.py | 39 ++++++++++------------------ netbox/dcim/tests/test_cablepaths.py | 1 + 4 files changed, 17 insertions(+), 29 deletions(-) diff --git a/netbox/dcim/forms/connections.py b/netbox/dcim/forms/connections.py index d39288bd5..f7bfa6431 100644 --- a/netbox/dcim/forms/connections.py +++ b/netbox/dcim/forms/connections.py @@ -83,7 +83,7 @@ def get_cable_form(a_type, b_type): label=term_cls._meta.verbose_name.title(), disabled_indicator='_occupied', query_params={ - 'device_id': f'termination_{cable_end}_device', + 'device_id': f'$termination_{cable_end}_device', } ) @@ -107,7 +107,7 @@ def get_cable_form(a_type, b_type): label='Power Feed', disabled_indicator='_occupied', query_params={ - 'powerpanel_id': f'termination_{cable_end}_powerpanel', + 'powerpanel_id': f'$termination_{cable_end}_powerpanel', } ) diff --git a/netbox/dcim/models/cables.py b/netbox/dcim/models/cables.py index 32250b8bd..55b1512d0 100644 --- a/netbox/dcim/models/cables.py +++ b/netbox/dcim/models/cables.py @@ -316,7 +316,7 @@ class CableTermination(models.Model): # Delete the cable association on the terminating object termination_model = self.termination._meta.model - termination_model.objects.filter(pk=self.termination_id).update(cable=None) + termination_model.objects.filter(pk=self.termination_id).update(cable=None, cable_end='', _path=None) super().delete(*args, **kwargs) diff --git a/netbox/dcim/signals.py b/netbox/dcim/signals.py index 9d249a93e..cb6b32de3 100644 --- a/netbox/dcim/signals.py +++ b/netbox/dcim/signals.py @@ -71,22 +71,23 @@ def clear_virtualchassis_members(instance, **kwargs): @receiver(trace_paths, sender=Cable) def update_connected_endpoints(instance, created, raw=False, **kwargs): """ - When a Cable is saved, check for and update its two connected endpoints + When a Cable is saved with new terminations, retrace any affected cable paths. """ logger = logging.getLogger('netbox.dcim.cable') if raw: logger.debug(f"Skipping endpoint updates for imported cable {instance}") return - # TODO: Update link peers - - # Create/update cable paths - if created: - _terms = { - 'A': [t.termination for t in instance.terminations.filter(cable_end='A')], - 'B': [t.termination for t in instance.terminations.filter(cable_end='B')], - } - for nodes in _terms.values(): + # Update cable paths if new terminations have been set + if hasattr(instance, 'a_terminations') or hasattr(instance, 'b_terminations'): + a_terminations = [] + b_terminations = [] + for t in instance.terminations.all(): + if t.cable_end == 'A': + a_terminations.append(t.termination) + else: + b_terminations.append(t.termination) + for nodes in [a_terminations, b_terminations]: # Examine type of first termination to determine object type (all must be the same) if not nodes: continue @@ -94,29 +95,15 @@ def update_connected_endpoints(instance, created, raw=False, **kwargs): create_cablepath(nodes) else: rebuild_paths(nodes) + + # Update status of CablePaths if Cable status has been changed elif instance.status != instance._orig_status: - # We currently don't support modifying either termination of an existing Cable. (This - # may change in the future.) However, we do need to capture status changes and update - # any CablePaths accordingly. if instance.status != LinkStatusChoices.STATUS_CONNECTED: CablePath.objects.filter(_nodes__contains=instance).update(is_active=False) else: rebuild_paths([instance]) -# @receiver(post_save, sender=CableTermination) -# def cache_cable_on_endpoints(instance, created, raw=False, **kwargs): -# if not raw: -# model = instance.termination_type.model_class() -# model.objects.filter(pk=instance.termination_id).update(cable=instance.cable) -# -# -# @receiver(post_delete, sender=CableTermination) -# def clear_cable_on_endpoints(instance, **kwargs): -# model = instance.termination_type.model_class() -# model.objects.filter(pk=instance.termination_id).update(cable=None) - - @receiver(post_delete, sender=Cable) def retrace_cable_paths(instance, **kwargs): """ diff --git a/netbox/dcim/tests/test_cablepaths.py b/netbox/dcim/tests/test_cablepaths.py index a810f3975..6d158bb10 100644 --- a/netbox/dcim/tests/test_cablepaths.py +++ b/netbox/dcim/tests/test_cablepaths.py @@ -1754,6 +1754,7 @@ class CablePathTestCase(TestCase): self.assertEqual(CablePath.objects.count(), 2) # Change cable 2's status to "planned" + cable2 = Cable.objects.get(pk=cable2.pk) # Rebuild object to ditch A/B terminations set earlier cable2.status = LinkStatusChoices.STATUS_PLANNED cable2.save() self.assertPathExists(