diff --git a/initializers/aggregates.yml b/initializers/aggregates.yml new file mode 100644 index 0000000..d923a04 --- /dev/null +++ b/initializers/aggregates.yml @@ -0,0 +1,6 @@ +# - prefix: 10.0.0.0/16 +# rir: RFC1918 +# - prefix: fd00:ccdd::/32 +# rir: RFC4193 ULA +# - prefix: 2001:db8::/32 +# rir: RFC3849 diff --git a/initializers/cluster_types.yml b/initializers/cluster_types.yml new file mode 100644 index 0000000..136dd1d --- /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..1b1aca0 --- /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..18920fe --- /dev/null +++ b/initializers/dcim_interfaces.yml @@ -0,0 +1,8 @@ +# - device: server01 +# enabled: true +# type: Virtual +# name: to-server02 +# - device: server02 +# enabled: true +# type: Virtual +# name: to-server01 diff --git a/initializers/device_types.yml b/initializers/device_types.yml index d0e4c36..9b27da3 100644 --- a/initializers/device_types.yml +++ b/initializers/device_types.yml @@ -17,7 +17,7 @@ # custom_fields: # text_field: Description # - model: Other -# manufacturer: NoName +# manufacturer: No Name # slug: other # custom_fields: # text_field: Description diff --git a/initializers/ip_addresses.yml b/initializers/ip_addresses.yml new file mode 100644 index 0000000..5738749 --- /dev/null +++ b/initializers/ip_addresses.yml @@ -0,0 +1,26 @@ +# - address: 10.1.1.1/24 +# device: server01 +# interface: to-server02 +# status: Active +# vrf: vrf1 +# - address: 2001:db8:a000:1::1/64 +# device: server01 +# interface: to-server02 +# status: Active +# vrf: vrf1 +# - address: 10.1.1.2/24 +# device: server02 +# interface: to-server01 +# status: Active +# - address: 2001:db8:a000:1::2/64 +# device: server02 +# interface: to-server01 +# status: Active +# - address: 10.1.1.10/24 +# description: reserved IP +# status: Reserved +# tenant: tenant1 +# - address: 2001:db8:a000:1::10/64 +# description: reserved IP +# status: Reserved +# tenant: tenant1 diff --git a/initializers/manufacturers.yml b/initializers/manufacturers.yml index d737a5f..023e8e1 100644 --- a/initializers/manufacturers.yml +++ b/initializers/manufacturers.yml @@ -2,5 +2,5 @@ # slug: manufacturer-1 # - name: Manufacturer 2 # slug: manufacturer-2 -# - name: NoName -# slug: noname +# - name: No Name +# slug: no-name diff --git a/initializers/platforms.yml b/initializers/platforms.yml index 732dbeb..b0b7ba3 100644 --- a/initializers/platforms.yml +++ b/initializers/platforms.yml @@ -10,6 +10,6 @@ # napalm_args: "{'arg1': 'value1', 'arg2': 'value2'}" # - name: Platform 3 # slug: platform-3 -# manufacturer: NoName +# manufacturer: No Name # napalm_driver: driver3 # napalm_args: "{'arg1': 'value1', 'arg2': 'value2'}" diff --git a/initializers/prefix_vlan_roles.yml b/initializers/prefix_vlan_roles.yml new file mode 100644 index 0000000..0ea7720 --- /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..a7e6815 --- /dev/null +++ b/initializers/prefixes.yml @@ -0,0 +1,20 @@ +# - 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 +# - description: ipv6 prefix1 +# prefix: 2001:db8: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..0aacd59 --- /dev/null +++ b/initializers/rirs.yml @@ -0,0 +1,9 @@ +# - is_private: true +# name: RFC1918 +# slug: rfc1918 +# - is_private: true +# name: RFC4193 ULA +# slug: rfc4193-ula +# - is_private: true +# name: RFC3849 +# slug: rfc3849 diff --git a/initializers/tenant_groups.yml b/initializers/tenant_groups.yml new file mode 100644 index 0000000..87ecd4d --- /dev/null +++ b/initializers/tenant_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/tenants.yml b/initializers/tenants.yml new file mode 100644 index 0000000..1dbfbe5 --- /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/virtual_machines.yml b/initializers/virtual_machines.yml new file mode 100644 index 0000000..5da75a2 --- /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..aeedd58 --- /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 machine 1 +# - description: Network Interface 2 +# enabled: true +# mac_address: 00:55:55:55:55:55 +# mtu: 1500 +# name: Network Interface 2 +# virtual_machine: virtual machine 1 diff --git a/initializers/vlan_groups.yml b/initializers/vlan_groups.yml new file mode 100644 index 0000000..3e0bb00 --- /dev/null +++ b/initializers/vlan_groups.yml @@ -0,0 +1,6 @@ +# - name: VLAN group 1 +# site: AMS 1 +# slug: vlan-group-1 +# - 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..26532c7 --- /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..40b9031 --- /dev/null +++ b/initializers/vrfs.yml @@ -0,0 +1,8 @@ +# - enforce_unique: true +# name: vrf1 +# tenant: tenant1 +# description: main VRF +# - enforce_unique: true +# name: vrf2 +# rd: "6500:6500" +# tenant: tenant2 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 99% rename from startup_scripts/110_devices.py rename to startup_scripts/130_devices.py index 16c6f9e..2d8d3ca 100644 --- a/startup_scripts/110_devices.py +++ b/startup_scripts/130_devices.py @@ -53,6 +53,7 @@ with file.open('r') as stream: for rack_face in RACK_FACE_CHOICES: if params['face'] in rack_face: params['face'] = rack_face[0] + break device, created = Device.objects.get_or_create(**params) 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..e3a0ef1 --- /dev/null +++ b/startup_scripts/210_vlans.py @@ -0,0 +1,58 @@ +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] + break + + 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..a832c88 --- /dev/null +++ b/startup_scripts/220_prefixes.py @@ -0,0 +1,61 @@ +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] + break + + 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..065b600 --- /dev/null +++ b/startup_scripts/230_virtual_machines.py @@ -0,0 +1,66 @@ +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] + break + + 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..ce7e7bd --- /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 'type' in params: + for outer_list in IFACE_TYPE_CHOICES: + for type_choices in outer_list[1]: + if params['type'] in type_choices: + params['type'] = type_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..f7f2bc7 --- /dev/null +++ b/startup_scripts/260_ip_addresses.py @@ -0,0 +1,72 @@ +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] + break + + 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)