diff --git a/initializers/devices.yml b/initializers/devices.yml index 708b68c..e968503 100644 --- a/initializers/devices.yml +++ b/initializers/devices.yml @@ -29,6 +29,8 @@ # rack: rack-02 # face: front # position: 2 +# primary_ip4: 10.1.1.2/24 +# primary_ip6: 2001:db8:a000:1::2/64 # custom_fields: # text_field: Description # - name: server03 diff --git a/initializers/virtual_machines.yml b/initializers/virtual_machines.yml index 2122920..918df93 100644 --- a/initializers/virtual_machines.yml +++ b/initializers/virtual_machines.yml @@ -21,6 +21,8 @@ # memory: 2048 # name: virtual machine 2 # platform: Platform 2 +# primary_ip4: 10.1.1.10/24 +# primary_ip6: 2001:db8:a000:1::10/64 # status: active # tenant: tenant1 # vcpus: 8 diff --git a/startup_scripts/130_devices.py b/startup_scripts/130_devices.py index 1e0d894..7233dd0 100644 --- a/startup_scripts/130_devices.py +++ b/startup_scripts/130_devices.py @@ -1,5 +1,4 @@ from dcim.models import Site, Rack, DeviceRole, DeviceType, Device, Platform -from ipam.models import IPAddress from virtualization.models import Cluster from tenancy.models import Tenant from extras.models import CustomField, CustomFieldValue @@ -21,13 +20,14 @@ optional_assocs = { 'tenant': (Tenant, 'name'), 'platform': (Platform, 'name'), 'rack': (Rack, 'name'), - 'cluster': (Cluster, 'name'), - 'primary_ip4': (IPAddress, 'address'), - 'primary_ip6': (IPAddress, 'address') + 'cluster': (Cluster, 'name') } for params in devices: custom_fields = params.pop('custom_fields', None) + # primary ips are handled later in `270_primary_ips.py` + params.pop('primary_ip4', None) + params.pop('primary_ip6', None) for assoc, details in required_assocs.items(): model, field = details diff --git a/startup_scripts/230_virtual_machines.py b/startup_scripts/230_virtual_machines.py index 6776c4d..f138886 100644 --- a/startup_scripts/230_virtual_machines.py +++ b/startup_scripts/230_virtual_machines.py @@ -22,6 +22,9 @@ optional_assocs = { for params in virtual_machines: custom_fields = params.pop('custom_fields', None) + # primary ips are handled later in `270_primary_ips.py` + params.pop('primary_ip4', None) + params.pop('primary_ip6', None) for assoc, details in required_assocs.items(): model, field = details diff --git a/startup_scripts/270_primary_ips.py b/startup_scripts/270_primary_ips.py new file mode 100644 index 0000000..2ddab81 --- /dev/null +++ b/startup_scripts/270_primary_ips.py @@ -0,0 +1,43 @@ +from dcim.models import Device +from ipam.models import IPAddress +from virtualization.models import VirtualMachine +from startup_script_utils import load_yaml +import sys + +def link_primary_ip(assets, asset_model): + for params in assets: + primary_ip_fields = set(params) & {'primary_ip4', 'primary_ip6'} + if not primary_ip_fields: + continue + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = { field: params.pop(assoc) } + + try: + params[assoc] = model.objects.get(**query) + except model.DoesNotExist: + primary_ip_fields -= {assoc} + print(f"⚠️ IP Address {query[field]} not found") + + asset = asset_model.objects.get(name=params['name']) + for field in primary_ip_fields: + if getattr(asset, field) != params[field]: + setattr(asset, field, params[field]) + print(f"🧬 Linked primary IP {params[field].address} on {asset.name}") + asset.save() + +devices = load_yaml('/opt/netbox/initializers/devices.yml') +virtual_machines = load_yaml('/opt/netbox/initializers/virtual_machines.yml') + +if devices is None and virtual_machines is None: + sys.exit() + +optional_assocs = { + 'primary_ip4': (IPAddress, 'address'), + 'primary_ip6': (IPAddress, 'address') +} + +link_primary_ip(devices, Device) +link_primary_ip(virtual_machines, VirtualMachine)