From edb570b63df74aff9dbbfd745c29bca60b1cd1bd Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Fri, 20 Sep 2024 09:47:12 +0200 Subject: [PATCH] Add script to replace a device Used for instance to upgrade or replace classroom PCs. --- devices.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 devices.py diff --git a/devices.py b/devices.py new file mode 100644 index 0000000..aad9982 --- /dev/null +++ b/devices.py @@ -0,0 +1,62 @@ +from dcim.models import Device +from extras.scripts import Script, ObjectVar + +class ReplaceDevice(Script): + ''' + Replace a device with another. Used for instance to upgrade classroom PCs. + This renames the new device, switches existing primary IPs from the old device to it and sets it active. + The old device is unnamed and set as inventory. + ''' + + class Meta: + name = 'Replace device' + description = 'Replace a device with another, preserving the name and primary IPs' + commit_default = False + scheduling_enabled = False + + old = ObjectVar(model=Device, label='Old device') + new = ObjectVar(model=Device, label='New device') + + def run(self, data, commit): + old = data['old'] + new = data['new'] + + new.name = old.name + new.status = 'active' + + old.name = None + if old.status == 'active': # could be failed + old.status = 'inventory' + + if ip4 := old.primary_ip4: + old.primary_ip4 = None + old.full_clean() + old.save() + + old_iface = ip4.interface.get() + new_iface = new.interfaces.get(name=old_iface.name) + ip4.assigned_object = new_iface + ip4.full_clean() + ip4.save() + + new.primary_ip4 = ip4 + self.log_info(f'set {ip4} as primary IP for new {new.name} ({new.asset_tag})') + + if ip6 := old.primary_ip6: + old.primary_ip6 = None + old.full_clean() + old.save() + + old_iface = ip6.interface.get() + new_iface = new.interfaces.get(name=old_iface.name) + ip6.assigned_object = new_iface + ip6.full_clean() + ip6.save() + + new.primary_ip6 = ip6 + self.log_info(f'set {ip6} as primary IP for new {new.name} ({new.asset_tag})') + + new.full_clean() + new.save() + + self.log_success(f'replaced device {new.name}: {old.asset_tag} → {new.asset_tag}')