diff --git a/initializers/aggregates.yml b/initializers/aggregates.yml new file mode 100644 index 0000000..3dc65e6 --- /dev/null +++ b/initializers/aggregates.yml @@ -0,0 +1,4 @@ +#- prefix: 10.0.0.0/16 +# rir: RFC1918 +#- prefix: fd00:ccdd::/32 +# rir: RFC4193 ULA diff --git a/initializers/cluster_types.yml b/initializers/cluster_types.yml new file mode 100644 index 0000000..03365ae --- /dev/null +++ b/initializers/cluster_types.yml @@ -0,0 +1,2 @@ +#- name: Hyper-V +# slug: hyper-v diff --git a/initializers/clusters.yml b/initializers/clusters.yml new file mode 100644 index 0000000..a8dc121 --- /dev/null +++ b/initializers/clusters.yml @@ -0,0 +1,5 @@ +#- name: cluster1 +# type: Hyper-V +#- name: cluster2 +# type: Hyper-V +# site: SING 1 diff --git a/initializers/dcim_interfaces.yml b/initializers/dcim_interfaces.yml new file mode 100644 index 0000000..8e6281e --- /dev/null +++ b/initializers/dcim_interfaces.yml @@ -0,0 +1,8 @@ +#- device: server01 +# enabled: true +# form_factor: Virtual +# name: to-server02 +#- device: server02 +# enabled: true +# form_factor: Virtual +# name: to-server01 diff --git a/initializers/ip_addresses.yml b/initializers/ip_addresses.yml new file mode 100644 index 0000000..abcc918 --- /dev/null +++ b/initializers/ip_addresses.yml @@ -0,0 +1,13 @@ +#- address: 10.1.1.1/24 +# device: server01 +# interface: Loopback0 +# status: Active +# vrf: vrf1 +#- address: 10.1.1.2/24 +# device: server02 +# interface: Vlan5 +# status: Active +#- address: 10.1.1.10/24 +# description: reserved IP +# status: Reserved +# tenant: tenant1 diff --git a/initializers/prefix_vlan_roles.yml b/initializers/prefix_vlan_roles.yml new file mode 100644 index 0000000..309acc9 --- /dev/null +++ b/initializers/prefix_vlan_roles.yml @@ -0,0 +1,2 @@ +#- name: Main Management +# slug: main-management diff --git a/initializers/prefixes.yml b/initializers/prefixes.yml new file mode 100644 index 0000000..ef6330a --- /dev/null +++ b/initializers/prefixes.yml @@ -0,0 +1,21 @@ +#- description: prefix1 +# prefix: 10.1.1.0/24 +# site: AMS 1 +# status: Active +# tenant: tenant1 +# vlan: vlan1 +#- description: prefix2 +# prefix: 10.1.2.0/24 +# site: AMS 2 +# status: Active +# tenant: tenant2 +# vlan: vlan2 +# is_pool: true +# vrf: vrf2 +# tenant: tenant2 +#- description: ipv6 prefix1 +# prefix: fd00:ccdd:a000:1::/64 +# site: AMS 2 +# status: Active +# tenant: tenant2 +# vlan: vlan2 diff --git a/initializers/rirs.yml b/initializers/rirs.yml new file mode 100644 index 0000000..1a0c84d --- /dev/null +++ b/initializers/rirs.yml @@ -0,0 +1,6 @@ +#- is_private: true +# name: RFC1918 +# slug: rfc1918 +#- is_private: true +# name: RFC4193 ULA +# slug: rfc4193-ula diff --git a/initializers/tenants.yml b/initializers/tenants.yml new file mode 100644 index 0000000..86db54f --- /dev/null +++ b/initializers/tenants.yml @@ -0,0 +1,5 @@ +#- name: tenant1 +# slug: tenant1 +#- name: tenant2 +# slug: tenant2 +# group: Tenant Group 2 diff --git a/initializers/tenants_groups.yml b/initializers/tenants_groups.yml new file mode 100644 index 0000000..53f0ce8 --- /dev/null +++ b/initializers/tenants_groups.yml @@ -0,0 +1,4 @@ +#- name: Tenant Group 1 +# slug: tenant-group-1 +#- name: Tenant Group 2 +# slug: tenant-group-2 diff --git a/initializers/virtual_machines.yml b/initializers/virtual_machines.yml new file mode 100644 index 0000000..ca61a80 --- /dev/null +++ b/initializers/virtual_machines.yml @@ -0,0 +1,18 @@ +#- cluster: cluster1 +# comments: VM1 +# disk: 200 +# memory: 4096 +# name: virtual machine 1 +# platform: Platform 2 +# status: Active +# tenant: tenant1 +# vcpus: 8 +#- cluster: cluster1 +# comments: VM2 +# disk: 100 +# memory: 2048 +# name: virtual machine 2 +# platform: Platform 2 +# status: Active +# tenant: tenant1 +# vcpus: 8 diff --git a/initializers/virtualization_interfaces.yml b/initializers/virtualization_interfaces.yml new file mode 100644 index 0000000..15a64ab --- /dev/null +++ b/initializers/virtualization_interfaces.yml @@ -0,0 +1,12 @@ +#- description: Network Interface 1 +# enabled: true +# mac_address: 00:77:77:77:77:77 +# mtu: 1500 +# name: Network Interface 1 +# virtual_machine: virtual_machine1 +#- description: Network Interface 2 +# enabled: true +# mac_address: 00:55:55:55:55:55 +# mtu: 1500 +# name: Network Interface 2 +# virtual_machine: virtual_machine1 \ No newline at end of file diff --git a/initializers/vlan_groups.yml b/initializers/vlan_groups.yml new file mode 100644 index 0000000..11a48fc --- /dev/null +++ b/initializers/vlan_groups.yml @@ -0,0 +1,6 @@ +#- name: VLAN group 1 +# site: AMS 1 +# slug: vlan-group-2 +#- name: VLAN group 2 +# site: AMS 1 +# slug: vlan-group-2 diff --git a/initializers/vlans.yml b/initializers/vlans.yml new file mode 100644 index 0000000..c78f6ca --- /dev/null +++ b/initializers/vlans.yml @@ -0,0 +1,11 @@ +#- name: vlan1 +# site: AMS 1 +# status: Active +# vid: 5 +# role: Main Management +# description: VLAN 5 for MGMT +#- group: VLAN group 2 +# name: vlan2 +# site: AMS 1 +# status: Active +# vid: 1300 diff --git a/initializers/vrfs.yml b/initializers/vrfs.yml new file mode 100644 index 0000000..0f3684d --- /dev/null +++ b/initializers/vrfs.yml @@ -0,0 +1,9 @@ +#- enforce_unique: true +# name: vrf1 +# tenant: tenant1 +# description: main VRF +#- enforce_unique: true +# name: vrf2 +# rd: "6500:6500" +# tenant: tenant2 +# tenant_group: Tenant Group 2 diff --git a/startup_scripts/110_tenant_groups.py b/startup_scripts/110_tenant_groups.py new file mode 100644 index 0000000..eaf75dc --- /dev/null +++ b/startup_scripts/110_tenant_groups.py @@ -0,0 +1,19 @@ +from tenancy.models import TenantGroup +from ruamel.yaml import YAML +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/tenant_groups.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + tenant_groups = yaml.load(stream) + + if tenant_groups is not None: + for params in tenant_groups: + tenant_group, created = TenantGroup.objects.get_or_create(**params) + + if created: + print("πŸ”³ Created Tenant Group", tenant_group.name) diff --git a/startup_scripts/120_tenants.py b/startup_scripts/120_tenants.py new file mode 100644 index 0000000..8252dc7 --- /dev/null +++ b/startup_scripts/120_tenants.py @@ -0,0 +1,45 @@ +from tenancy.models import Tenant, TenantGroup +from extras.models import CustomField, CustomFieldValue +from ruamel.yaml import YAML + +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/tenants.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + tenants = yaml.load(stream) + + optional_assocs = { + 'group': (TenantGroup, 'name') + } + + if tenants is not None: + for params in tenants: + custom_fields = params.pop('custom_fields', None) + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = { field: params.pop(assoc) } + + params[assoc] = model.objects.get(**query) + + tenant, created = Tenant.objects.get_or_create(**params) + + if created: + if custom_fields is not None: + for cf_name, cf_value in custom_fields.items(): + custom_field = CustomField.objects.get(name=cf_name) + custom_field_value = CustomFieldValue.objects.create( + field=custom_field, + obj=tenant, + value=cf_value + ) + + tenant.custom_field_values.add(custom_field_value) + + print("πŸ‘©β€πŸ’» Created Tenant", tenant.name) diff --git a/startup_scripts/110_devices.py b/startup_scripts/130_devices.py similarity index 100% rename from startup_scripts/110_devices.py rename to startup_scripts/130_devices.py diff --git a/startup_scripts/140_cluster_types.py b/startup_scripts/140_cluster_types.py new file mode 100644 index 0000000..9bd4be1 --- /dev/null +++ b/startup_scripts/140_cluster_types.py @@ -0,0 +1,19 @@ +from virtualization.models import ClusterType +from ruamel.yaml import YAML +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/cluster_types.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + cluster_types = yaml.load(stream) + + if cluster_types is not None: + for params in cluster_types: + cluster_type, created = ClusterType.objects.get_or_create(**params) + + if created: + print("🧰 Created Cluster Type", cluster_type.name) diff --git a/startup_scripts/150_rirs.py b/startup_scripts/150_rirs.py new file mode 100644 index 0000000..9cee56f --- /dev/null +++ b/startup_scripts/150_rirs.py @@ -0,0 +1,19 @@ +from ipam.models import RIR +from ruamel.yaml import YAML +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/rirs.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + rirs = yaml.load(stream) + + if rirs is not None: + for params in rirs: + rir, created = RIR.objects.get_or_create(**params) + + if created: + print("πŸ—ΊοΈ Created RIR", rir.name) diff --git a/startup_scripts/160_aggregates.py b/startup_scripts/160_aggregates.py new file mode 100644 index 0000000..f932709 --- /dev/null +++ b/startup_scripts/160_aggregates.py @@ -0,0 +1,46 @@ +from ipam.models import Aggregate, RIR +from ruamel.yaml import YAML +from extras.models import CustomField, CustomFieldValue + +from netaddr import IPNetwork +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/aggregates.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + aggregates = yaml.load(stream) + + required_assocs = { + 'rir': (RIR, 'name') + } + + if aggregates is not None: + for params in aggregates: + custom_fields = params.pop('custom_fields', None) + params['prefix'] = IPNetwork(params['prefix']) + + for assoc, details in required_assocs.items(): + model, field = details + query = { field: params.pop(assoc) } + + params[assoc] = model.objects.get(**query) + + aggregate, created = Aggregate.objects.get_or_create(**params) + + if created: + if custom_fields is not None: + for cf_name, cf_value in custom_fields.items(): + custom_field = CustomField.objects.get(name=cf_name) + custom_field_value = CustomFieldValue.objects.create( + field=custom_field, + obj=aggregate, + value=cf_value + ) + + aggregate.custom_field_values.add(custom_field_value) + + print("πŸ—žοΈ Created Aggregate", aggregate.prefix) diff --git a/startup_scripts/170_clusters.py b/startup_scripts/170_clusters.py new file mode 100644 index 0000000..597f73f --- /dev/null +++ b/startup_scripts/170_clusters.py @@ -0,0 +1,57 @@ +from dcim.models import Site +from virtualization.models import Cluster, ClusterType, ClusterGroup +from extras.models import CustomField, CustomFieldValue +from ruamel.yaml import YAML + +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/clusters.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + clusters = yaml.load(stream) + + required_assocs = { + 'type': (ClusterType, 'name') + } + + optional_assocs = { + 'site': (Site, 'name'), + 'group': (ClusterGroup, 'name') + } + + if clusters is not None: + for params in clusters: + custom_fields = params.pop('custom_fields', None) + + for assoc, details in required_assocs.items(): + model, field = details + query = { field: params.pop(assoc) } + + params[assoc] = model.objects.get(**query) + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = { field: params.pop(assoc) } + + params[assoc] = model.objects.get(**query) + + cluster, created = Cluster.objects.get_or_create(**params) + + if created: + if custom_fields is not None: + for cf_name, cf_value in custom_fields.items(): + custom_field = CustomField.objects.get(name=cf_name) + custom_field_value = CustomFieldValue.objects.create( + field=custom_field, + obj=cluster, + value=cf_value + ) + + cluster.custom_field_values.add(custom_field_value) + + print("πŸ—„οΈ Created cluster", cluster.name) diff --git a/startup_scripts/180_vrfs.py b/startup_scripts/180_vrfs.py new file mode 100644 index 0000000..d611c04 --- /dev/null +++ b/startup_scripts/180_vrfs.py @@ -0,0 +1,46 @@ +from ipam.models import VRF +from tenancy.models import Tenant +from ruamel.yaml import YAML +from extras.models import CustomField, CustomFieldValue + +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/vrfs.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + vrfs = yaml.load(stream) + + optional_assocs = { + 'tenant': (Tenant, 'name') + } + + if vrfs is not None: + for params in vrfs: + custom_fields = params.pop('custom_fields', None) + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = { field: params.pop(assoc) } + + params[assoc] = model.objects.get(**query) + + vrf, created = VRF.objects.get_or_create(**params) + + if created: + if custom_fields is not None: + for cf_name, cf_value in custom_fields.items(): + custom_field = CustomField.objects.get(name=cf_name) + custom_field_value = CustomFieldValue.objects.create( + field=custom_field, + obj=vrf, + value=cf_value + ) + + vrf.custom_field_values.add(custom_field_value) + + print("πŸ“¦ Created VRF", vrf.name) diff --git a/startup_scripts/190_prefix_vlan_roles.py b/startup_scripts/190_prefix_vlan_roles.py new file mode 100644 index 0000000..61fa606 --- /dev/null +++ b/startup_scripts/190_prefix_vlan_roles.py @@ -0,0 +1,19 @@ +from ipam.models import Role +from ruamel.yaml import YAML +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/prefix_vlan_roles.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + roles = yaml.load(stream) + + if roles is not None: + for params in roles: + role, created = Role.objects.get_or_create(**params) + + if created: + print("⛹️‍ Created Prefix/VLAN Role", role.name) diff --git a/startup_scripts/200_vlan_groups.py b/startup_scripts/200_vlan_groups.py new file mode 100644 index 0000000..54250fb --- /dev/null +++ b/startup_scripts/200_vlan_groups.py @@ -0,0 +1,46 @@ +from dcim.models import Site +from ipam.models import VLANGroup +from extras.models import CustomField, CustomFieldValue +from ruamel.yaml import YAML + +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/vlan_groups.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + vlan_groups = yaml.load(stream) + + optional_assocs = { + 'site': (Site, 'name') + } + + if vlan_groups is not None: + for params in vlan_groups: + custom_fields = params.pop('custom_fields', None) + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = { field: params.pop(assoc) } + + params[assoc] = model.objects.get(**query) + + vlan_group, created = VLANGroup.objects.get_or_create(**params) + + if created: + if custom_fields is not None: + for cf_name, cf_value in custom_fields.items(): + custom_field = CustomField.objects.get(name=cf_name) + custom_field_value = CustomFieldValue.objects.create( + field=custom_field, + obj=vlan_group, + value=cf_value + ) + + vlan_group.custom_field_values.add(custom_field_value) + + print("🏘️ Created VLAN Group", vlan_group.name) diff --git a/startup_scripts/210_vlans.py b/startup_scripts/210_vlans.py new file mode 100644 index 0000000..c667354 --- /dev/null +++ b/startup_scripts/210_vlans.py @@ -0,0 +1,57 @@ +from dcim.models import Site +from ipam.models import VLAN, VLANGroup, Role +from ipam.constants import VLAN_STATUS_CHOICES +from tenancy.models import Tenant, TenantGroup +from extras.models import CustomField, CustomFieldValue +from ruamel.yaml import YAML + +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/vlans.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + vlans = yaml.load(stream) + + optional_assocs = { + 'site': (Site, 'name'), + 'tenant': (Tenant, 'name'), + 'tenant_group': (TenantGroup, 'name'), + 'group': (VLANGroup, 'name'), + 'role': (Role, 'name') + } + + if vlans is not None: + for params in vlans: + custom_fields = params.pop('custom_fields', None) + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = { field: params.pop(assoc) } + + params[assoc] = model.objects.get(**query) + + if 'status' in params: + for vlan_status in VLAN_STATUS_CHOICES: + if params['status'] in vlan_status: + params['status'] = vlan_status[0] + + vlan, created = VLAN.objects.get_or_create(**params) + + if created: + if custom_fields is not None: + for cf_name, cf_value in custom_fields.items(): + custom_field = CustomField.objects.get(name=cf_name) + custom_field_value = CustomFieldValue.objects.create( + field=custom_field, + obj=vlan, + value=cf_value + ) + + vlan.custom_field_values.add(custom_field_value) + + print("🏠 Created VLAN", vlan.name) diff --git a/startup_scripts/220_prefixes.py b/startup_scripts/220_prefixes.py new file mode 100644 index 0000000..69d78f2 --- /dev/null +++ b/startup_scripts/220_prefixes.py @@ -0,0 +1,60 @@ +from dcim.models import Site +from ipam.models import Prefix, VLAN, Role, VRF +from ipam.constants import PREFIX_STATUS_CHOICES +from tenancy.models import Tenant, TenantGroup +from extras.models import CustomField, CustomFieldValue +from ruamel.yaml import YAML + +from netaddr import IPNetwork +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/prefixes.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + prefixes = yaml.load(stream) + + optional_assocs = { + 'site': (Site, 'name'), + 'tenant': (Tenant, 'name'), + 'tenant_group': (TenantGroup, 'name'), + 'vlan': (VLAN, 'name'), + 'role': (Role, 'name'), + 'vrf': (VRF, 'name') + } + + if prefixes is not None: + for params in prefixes: + custom_fields = params.pop('custom_fields', None) + params['prefix'] = IPNetwork(params['prefix']) + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = { field: params.pop(assoc) } + + params[assoc] = model.objects.get(**query) + + if 'status' in params: + for prefix_status in PREFIX_STATUS_CHOICES: + if params['status'] in prefix_status: + params['status'] = prefix_status[0] + + prefix, created = Prefix.objects.get_or_create(**params) + + if created: + if custom_fields is not None: + for cf_name, cf_value in custom_fields.items(): + custom_field = CustomField.objects.get(name=cf_name) + custom_field_value = CustomFieldValue.objects.create( + field=custom_field, + obj=prefix, + value=cf_value + ) + + prefix.custom_field_values.add(custom_field_value) + + print("πŸ“Œ Created Prefix", prefix.prefix) diff --git a/startup_scripts/230_virtual_machines.py b/startup_scripts/230_virtual_machines.py new file mode 100644 index 0000000..af30ee2 --- /dev/null +++ b/startup_scripts/230_virtual_machines.py @@ -0,0 +1,65 @@ +from dcim.models import Site, Platform, DeviceRole +from virtualization.models import Cluster, VirtualMachine +from virtualization.constants import VM_STATUS_CHOICES +from tenancy.models import Tenant +from extras.models import CustomField, CustomFieldValue +from ruamel.yaml import YAML + +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/virtual_machines.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + virtual_machines = yaml.load(stream) + + required_assocs = { + 'cluster': (Cluster, 'name') + } + + optional_assocs = { + 'tenant': (Tenant, 'name'), + 'platform': (Platform, 'name'), + 'role': (DeviceRole, 'name') + } + + if virtual_machines is not None: + for params in virtual_machines: + custom_fields = params.pop('custom_fields', None) + + for assoc, details in required_assocs.items(): + model, field = details + query = { field: params.pop(assoc) } + + params[assoc] = model.objects.get(**query) + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = { field: params.pop(assoc) } + + params[assoc] = model.objects.get(**query) + + if 'status' in params: + for vm_status in VM_STATUS_CHOICES: + if params['status'] in vm_status: + params['status'] = vm_status[0] + + virtual_machine, created = VirtualMachine.objects.get_or_create(**params) + + if created: + if custom_fields is not None: + for cf_name, cf_value in custom_fields.items(): + custom_field = CustomField.objects.get(name=cf_name) + custom_field_value = CustomFieldValue.objects.create( + field=custom_field, + obj=virtual_machine, + value=cf_value + ) + + virtual_machine.custom_field_values.add(custom_field_value) + + print("πŸ–₯️ Created virtual machine", virtual_machine.name) diff --git a/startup_scripts/240_virtualization_interfaces.py b/startup_scripts/240_virtualization_interfaces.py new file mode 100644 index 0000000..8d2ca96 --- /dev/null +++ b/startup_scripts/240_virtualization_interfaces.py @@ -0,0 +1,45 @@ +from dcim.models import Interface +from virtualization.models import VirtualMachine +from extras.models import CustomField, CustomFieldValue +from ruamel.yaml import YAML + +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/virtualization_interfaces.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + interfaces = yaml.load(stream) + + required_assocs = { + 'virtual_machine': (VirtualMachine, 'name') + } + + if interfaces is not None: + for params in interfaces: + custom_fields = params.pop('custom_fields', None) + + for assoc, details in required_assocs.items(): + model, field = details + query = { field: params.pop(assoc) } + + params[assoc] = model.objects.get(**query) + + interface, created = Interface.objects.get_or_create(**params) + + if created: + if custom_fields is not None: + for cf_name, cf_value in custom_fields.items(): + custom_field = CustomField.objects.get(name=cf_name) + custom_field_value = CustomFieldValue.objects.create( + field=custom_field, + obj=interface, + value=cf_value + ) + + interface.custom_field_values.add(custom_field_value) + + print("🧷 Created interface", interface.name, interface.virtual_machine.name) diff --git a/startup_scripts/250_dcim_interfaces.py b/startup_scripts/250_dcim_interfaces.py new file mode 100644 index 0000000..b0baf39 --- /dev/null +++ b/startup_scripts/250_dcim_interfaces.py @@ -0,0 +1,55 @@ +from dcim.models import Interface, Device +from dcim.constants import IFACE_TYPE_CHOICES +from extras.models import CustomField, CustomFieldValue +from ruamel.yaml import YAML + +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/dcim_interfaces.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + interfaces = yaml.load(stream) + + required_assocs = { + 'device': (Device, 'name') + } + + if interfaces is not None: + for params in interfaces: + custom_fields = params.pop('custom_fields', None) + + for assoc, details in required_assocs.items(): + model, field = details + query = { field: params.pop(assoc) } + + params[assoc] = model.objects.get(**query) + + if 'form_factor' in params: + for outer_list in IFACE_TYPE_CHOICES: + for ffactor_choices in outer_list[1]: + if params['form_factor'] in ffactor_choices: + params['form_factor'] = ffactor_choices[0] + break + else: + continue + break + + interface, created = Interface.objects.get_or_create(**params) + + if created: + if custom_fields is not None: + for cf_name, cf_value in custom_fields.items(): + custom_field = CustomField.objects.get(name=cf_name) + custom_field_value = CustomFieldValue.objects.create( + field=custom_field, + obj=interface, + value=cf_value + ) + + interface.custom_field_values.add(custom_field_value) + + print("🧷 Created interface", interface.name, interface.device.name) diff --git a/startup_scripts/260_ip_addresses.py b/startup_scripts/260_ip_addresses.py new file mode 100644 index 0000000..589c5d3 --- /dev/null +++ b/startup_scripts/260_ip_addresses.py @@ -0,0 +1,71 @@ +from ipam.models import IPAddress, VRF +from ipam.constants import IPADDRESS_STATUS_CHOICES +from dcim.models import Device, Interface +from virtualization.models import VirtualMachine +from tenancy.models import Tenant +from extras.models import CustomField, CustomFieldValue +from ruamel.yaml import YAML + +from netaddr import IPNetwork +from pathlib import Path +import sys + +file = Path('/opt/netbox/initializers/ip_addresses.yml') +if not file.is_file(): + sys.exit() + +with file.open('r') as stream: + yaml = YAML(typ='safe') + ip_addresses = yaml.load(stream) + + optional_assocs = { + 'tenant': (Tenant, 'name'), + 'vrf': (VRF, 'name'), + 'interface': (Interface, 'name') + } + + if ip_addresses is not None: + for params in ip_addresses: + vm = params.pop('virtual_machine', None) + device = params.pop('device', None) + custom_fields = params.pop('custom_fields', None) + params['address'] = IPNetwork(params['address']) + + if vm and device: + print("IP Address can only specify one of the following: virtual_machine or device.") + sys.exit() + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + if assoc == 'interface': + if vm: + vm_id = VirtualMachine.objects.get(name=vm).id + query = { field: params.pop(assoc), "virtual_machine_id": vm_id } + elif device: + dev_id = Device.objects.get(name=device).id + query = { field: params.pop(assoc), "device_id": dev_id } + else: + query = { field: params.pop(assoc) } + params[assoc] = model.objects.get(**query) + + if 'status' in params: + for ip_status in IPADDRESS_STATUS_CHOICES: + if params['status'] in ip_status: + params['status'] = ip_status[0] + + ip_address, created = IPAddress.objects.get_or_create(**params) + + if created: + if custom_fields is not None: + for cf_name, cf_value in custom_fields.items(): + custom_field = CustomField.objects.get(name=cf_name) + custom_field_value = CustomFieldValue.objects.create( + field=custom_field, + obj=ip_address, + value=cf_value + ) + + ip_address.custom_field_values.add(custom_field_value) + + print("🧬 Created IP Address", ip_address.address)