Skip to content

Commit

Permalink
Send events to MQ when hosts are renamed.
Browse files Browse the repository at this point in the history
  - Captures the old name with pre_save.
  - Makes no assumtion on signal consistency in Django...

Fixes #476
  • Loading branch information
terjekv committed Jun 9, 2023
1 parent e8424ee commit f9eb441
Showing 1 changed file with 41 additions and 0 deletions.
41 changes: 41 additions & 0 deletions mreg/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,25 @@ def send_event_ip_added_to_host(sender, instance, created, **kwargs):
}
MQSender().send_event(obj, "host.ipaddress")

# In case of host rename, we need to know the old name, so we
# capture it here and store it in the instance. Note that we first
# try to get the object in its original state from the database,
# and if it does not exist there, we set the old name to None as
# we are being called as part of an object creation.
@receiver(pre_save, sender=Host)
def capture_old_name(sender, instance, **kwargs):
try:
obj = sender.objects.get(pk=instance.pk)
instance._old_name = obj.name
except sender.DoesNotExist:
instance._old_name = None

# Process host events, and send them to the message queue.
# If the hostname itself is changed, send a host_updated
# event with both the old and new hostname.
# The old hostname is captured in the pre_save signal above.
# Also note that _old_name is not a field in the model, so it
# will not be saved to the database.
@receiver(post_save, sender=Host)
def send_event_host_created(sender, instance, created, **kwargs):
if created:
Expand All @@ -326,6 +345,28 @@ def send_event_host_created(sender, instance, created, **kwargs):
'action': 'host_created',
}
MQSender().send_event(obj, "host")
else:
# There are situations in Django where singals do not
# complete correctly, or pre_save isn't triggered at
# all. In these cases, _old_name will not be set, but
# the created boolean sent to post_save will still be
# false.
# To handle such eventualities, we don't simply assume
# that old_name is set during updates. The best we can
# do in these cases is to send a host_updated event.
old_name = getattr(instance, '_old_name', None)
if old_name is not None and old_name != instance.name:
obj = {
'old_host': old_name,
'new_host': instance.name,
'action': 'host_updated',
}
else:
obj = {
'host': instance.name,
'action': 'host_updated',
}
MQSender().send_event(obj, "host")

@receiver(post_delete, sender=Host)
def send_event_host_removed(sender, instance, **kwargs):
Expand Down

0 comments on commit f9eb441

Please sign in to comment.