Merge pull request #342 from netbox-community/Fix337

Prepare for Netbox v2.10.x
This commit is contained in:
Christian Mäder 2020-12-14 22:51:24 +01:00 committed by GitHub
commit d77b3c1222
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 178 additions and 278 deletions

View File

@ -43,20 +43,16 @@
# required: false # required: false
# filter_logic: exact # filter_logic: exact
# weight: 30 # weight: 30
# default: First Item
# on_objects: # on_objects:
# - dcim.models.Device # - dcim.models.Device
# choices: # choices:
# - value: First Item # - First Item
# weight: 10 # - Second Item
# - value: Second Item # - Third Item
# weight: 20 # - Fifth Item
# - value: Third Item # - Fourth Item
# weight: 30 # select_field_legacy_format:
# - value: Fifth Item
# weight: 50
# - value: Fourth Item
# weight: 40
# select_field_auto_weight:
# type: select # type: select
# label: Choose between items # label: Choose between items
# required: false # required: false
@ -65,9 +61,9 @@
# on_objects: # on_objects:
# - dcim.models.Device # - dcim.models.Device
# choices: # choices:
# - value: A # - value: A # this is the deprecated format.
# - value: B # - value: B # we only use it for the tests.
# - value: C # - value: C # please see above for the new format.
# - value: "D like deprecated" # - value: "D like deprecated"
# weight: 999 # weight: 999
# - value: E # - value: E
@ -76,7 +72,7 @@
# label: Yes Or No? # label: Yes Or No?
# required: true # required: true
# filter_logic: loose # filter_logic: loose
# default: "false" # important: but "false" in quotes! # default: "false" # important: put "false" in quotes!
# weight: 90 # weight: 90
# on_objects: # on_objects:
# - dcim.models.Device # - dcim.models.Device

View File

@ -2,22 +2,22 @@
# manufacturer: Manufacturer 1 # manufacturer: Manufacturer 1
# slug: model-1 # slug: model-1
# u_height: 2 # u_height: 2
# custom_fields: # custom_field_data:
# text_field: Description # text_field: Description
# - model: Model 2 # - model: Model 2
# manufacturer: Manufacturer 1 # manufacturer: Manufacturer 1
# slug: model-2 # slug: model-2
# custom_fields: # custom_field_data:
# text_field: Description # text_field: Description
# - model: Model 3 # - model: Model 3
# manufacturer: Manufacturer 1 # manufacturer: Manufacturer 1
# slug: model-3 # slug: model-3
# is_full_depth: false # is_full_depth: false
# u_height: 0 # u_height: 0
# custom_fields: # custom_field_data:
# text_field: Description # text_field: Description
# - model: Other # - model: Other
# manufacturer: No Name # manufacturer: No Name
# slug: other # slug: other
# custom_fields: # custom_field_data:
# text_field: Description # text_field: Description

View File

@ -20,7 +20,7 @@
# rack: rack-01 # rack: rack-01
# face: front # face: front
# position: 1 # position: 1
# custom_fields: # custom_field_data:
# text_field: Description # text_field: Description
# - name: server02 # - name: server02
# device_role: server # device_role: server
@ -31,7 +31,7 @@
# position: 2 # position: 2
# primary_ip4: 10.1.1.2/24 # primary_ip4: 10.1.1.2/24
# primary_ip6: 2001:db8:a000:1::2/64 # primary_ip6: 2001:db8:a000:1::2/64
# custom_fields: # custom_field_data:
# text_field: Description # text_field: Description
# - name: server03 # - name: server03
# device_role: server # device_role: server
@ -40,5 +40,5 @@
# rack: rack-03 # rack: rack-03
# face: front # face: front
# position: 3 # position: 3
# custom_fields: # custom_field_data:
# text_field: Description # text_field: Description

View File

@ -20,7 +20,7 @@
# type: 4-post-cabinet # type: 4-post-cabinet
# width: 19 # width: 19
# u_height: 47 # u_height: 47
# custom_fields: # custom_field_data:
# text_field: Description # text_field: Description
# - site: AMS 2 # - site: AMS 2
# name: rack-02 # name: rack-02
@ -28,7 +28,7 @@
# type: 4-post-cabinet # type: 4-post-cabinet
# width: 19 # width: 19
# u_height: 47 # u_height: 47
# custom_fields: # custom_field_data:
# text_field: Description # text_field: Description
# - site: SING 1 # - site: SING 1
# name: rack-03 # name: rack-03
@ -37,5 +37,5 @@
# type: 4-post-cabinet # type: 4-post-cabinet
# width: 19 # width: 19
# u_height: 47 # u_height: 47
# custom_fields: # custom_field_data:
# text_field: Description # text_field: Description

View File

@ -4,29 +4,29 @@
# status: active # status: active
# facility: Amsterdam 1 # facility: Amsterdam 1
# asn: 12345 # asn: 12345
# custom_fields: # custom_field_data:
# text_field: Description # text_field: Description for AMS1
# - name: AMS 2 # - name: AMS 2
# slug: ams2 # slug: ams2
# region: Downtown # region: Downtown
# status: active # status: active
# facility: Amsterdam 2 # facility: Amsterdam 2
# asn: 54321 # asn: 54321
# custom_fields: # custom_field_data:
# text_field: Description # text_field: Description for AMS2
# - name: AMS 3 # - name: AMS 3
# slug: ams3 # slug: ams3
# region: Suburbs # region: Suburbs
# status: active # status: active
# facility: Amsterdam 3 # facility: Amsterdam 3
# asn: 67890 # asn: 67890
# custom_fields: # custom_field_data:
# text_field: Description # text_field: Description for AMS3
# - name: SING 1 # - name: SING 1
# slug: sing1 # slug: sing1
# region: Singapore # region: Singapore
# status: active # status: active
# facility: Singapore 1 # facility: Singapore 1
# asn: 09876 # asn: 09876
# custom_fields: # custom_field_data:
# text_field: Description # text_field: Description for SING1

View File

@ -1,6 +1,6 @@
import sys import sys
from django.contrib.auth.models import Group, User from django.contrib.auth.models import User
from startup_script_utils import load_yaml, set_permissions from startup_script_utils import load_yaml, set_permissions
from users.models import Token from users.models import Token

View File

@ -1,8 +1,8 @@
from extras.models import CustomField, CustomFieldChoice
from startup_script_utils import load_yaml
import sys import sys
from extras.models import CustomField
from startup_script_utils import load_yaml
def get_class_for_class_path(class_path): def get_class_for_class_path(class_path):
import importlib import importlib
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
@ -21,34 +21,38 @@ for cf_name, cf_details in customfields.items():
custom_field, created = CustomField.objects.get_or_create(name = cf_name) custom_field, created = CustomField.objects.get_or_create(name = cf_name)
if created: if created:
if cf_details.get('default', 0): if cf_details.get('default', False):
custom_field.default = cf_details['default'] custom_field.default = cf_details['default']
if cf_details.get('description', 0): if cf_details.get('description', False):
custom_field.description = cf_details['description'] custom_field.description = cf_details['description']
if cf_details.get('label', 0): if cf_details.get('label', False):
custom_field.label = cf_details['label'] custom_field.label = cf_details['label']
for object_type in cf_details.get('on_objects', []): for object_type in cf_details.get('on_objects', []):
custom_field.obj_type.add(get_class_for_class_path(object_type)) custom_field.content_types.add(get_class_for_class_path(object_type))
if cf_details.get('required', 0): if cf_details.get('required', False):
custom_field.required = cf_details['required'] custom_field.required = cf_details['required']
if cf_details.get('type', 0): if cf_details.get('type', False):
custom_field.type = cf_details['type'] custom_field.type = cf_details['type']
if cf_details.get('weight', 0): if cf_details.get('weight', -1) >= 0:
custom_field.weight = cf_details['weight'] custom_field.weight = cf_details['weight']
if cf_details.get('choices', False):
custom_field.choices = []
for choice_detail in cf_details.get('choices', []):
if isinstance(choice_detail, dict) and 'value' in choice_detail:
# legacy mode
print(f"⚠️ Please migrate the choice '{choice_detail['value']}' of '{cf_name}' to the new format, as 'weight' is no longer supported!")
custom_field.choices.append(choice_detail['value'])
else:
custom_field.choices.append(choice_detail)
custom_field.save() custom_field.save()
for idx, choice_details in enumerate(cf_details.get('choices', [])):
choice, _ = CustomFieldChoice.objects.get_or_create(
field=custom_field,
value=choice_details['value'],
defaults={'weight': idx * 10}
)
print("🔧 Created custom field", cf_name) print("🔧 Created custom field", cf_name)

View File

@ -1,9 +1,9 @@
from dcim.models import Region, Site
from extras.models import CustomField, CustomFieldValue
from tenancy.models import Tenant
from startup_script_utils import load_yaml
import sys import sys
from dcim.models import Region, Site
from startup_script_utils import *
from tenancy.models import Tenant
sites = load_yaml('/opt/netbox/initializers/sites.yml') sites = load_yaml('/opt/netbox/initializers/sites.yml')
if sites is None: if sites is None:
@ -15,7 +15,7 @@ optional_assocs = {
} }
for params in sites: for params in sites:
custom_fields = params.pop('custom_fields', None) custom_field_data = pop_custom_fields(params)
for assoc, details in optional_assocs.items(): for assoc, details in optional_assocs.items():
if assoc in params: if assoc in params:
@ -27,15 +27,6 @@ for params in sites:
site, created = Site.objects.get_or_create(**params) site, created = Site.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(site, custom_field_data)
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=site,
value=cf_value
)
site.custom_field_values.add(custom_field_value)
print("📍 Created site", site.name) print("📍 Created site", site.name)

View File

@ -1,9 +1,9 @@
from dcim.models import DeviceType, Manufacturer, Region
from tenancy.models import Tenant
from extras.models import CustomField, CustomFieldValue
from startup_script_utils import load_yaml
import sys import sys
from dcim.models import DeviceType, Manufacturer, Region
from startup_script_utils import *
from tenancy.models import Tenant
device_types = load_yaml('/opt/netbox/initializers/device_types.yml') device_types = load_yaml('/opt/netbox/initializers/device_types.yml')
if device_types is None: if device_types is None:
@ -19,7 +19,7 @@ optional_assocs = {
} }
for params in device_types: for params in device_types:
custom_fields = params.pop('custom_fields', None) custom_field_data = pop_custom_fields(params)
for assoc, details in required_assocs.items(): for assoc, details in required_assocs.items():
model, field = details model, field = details
@ -37,15 +37,6 @@ for params in device_types:
device_type, created = DeviceType.objects.get_or_create(**params) device_type, created = DeviceType.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(device_type, custom_field_data)
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=device_type,
value=cf_value
)
device_type.custom_field_values.add(custom_field_value)
print("🔡 Created device type", device_type.manufacturer, device_type.model) print("🔡 Created device type", device_type.manufacturer, device_type.model)

View File

@ -1,9 +1,9 @@
from dcim.models import Site, RackRole, Rack, RackGroup
from tenancy.models import Tenant
from extras.models import CustomField, CustomFieldValue
from startup_script_utils import load_yaml
import sys import sys
from dcim.models import Site, RackRole, Rack, RackGroup
from startup_script_utils import *
from tenancy.models import Tenant
racks = load_yaml('/opt/netbox/initializers/racks.yml') racks = load_yaml('/opt/netbox/initializers/racks.yml')
if racks is None: if racks is None:
@ -20,7 +20,7 @@ optional_assocs = {
} }
for params in racks: for params in racks:
custom_fields = params.pop('custom_fields', None) custom_field_data = pop_custom_fields(params)
for assoc, details in required_assocs.items(): for assoc, details in required_assocs.items():
model, field = details model, field = details
@ -38,15 +38,6 @@ for params in racks:
rack, created = Rack.objects.get_or_create(**params) rack, created = Rack.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(rack, custom_field_data)
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=rack,
value=cf_value
)
rack.custom_field_values.add(custom_field_value)
print("🔳 Created rack", rack.site, rack.name) print("🔳 Created rack", rack.site, rack.name)

View File

@ -1,8 +1,8 @@
from tenancy.models import Tenant, TenantGroup
from extras.models import CustomField, CustomFieldValue
from startup_script_utils import load_yaml
import sys import sys
from startup_script_utils import *
from tenancy.models import Tenant, TenantGroup
tenants = load_yaml('/opt/netbox/initializers/tenants.yml') tenants = load_yaml('/opt/netbox/initializers/tenants.yml')
if tenants is None: if tenants is None:
@ -13,7 +13,7 @@ optional_assocs = {
} }
for params in tenants: for params in tenants:
custom_fields = params.pop('custom_fields', None) custom_field_data = pop_custom_fields(params)
for assoc, details in optional_assocs.items(): for assoc, details in optional_assocs.items():
if assoc in params: if assoc in params:
@ -25,15 +25,6 @@ for params in tenants:
tenant, created = Tenant.objects.get_or_create(**params) tenant, created = Tenant.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(tenant, custom_field_data)
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) print("👩‍💻 Created Tenant", tenant.name)

View File

@ -1,10 +1,10 @@
from dcim.models import Site, Rack, DeviceRole, DeviceType, Device, Platform
from virtualization.models import Cluster
from tenancy.models import Tenant
from extras.models import CustomField, CustomFieldValue
from startup_script_utils import load_yaml
import sys import sys
from dcim.models import Site, Rack, DeviceRole, DeviceType, Device, Platform
from startup_script_utils import *
from tenancy.models import Tenant
from virtualization.models import Cluster
devices = load_yaml('/opt/netbox/initializers/devices.yml') devices = load_yaml('/opt/netbox/initializers/devices.yml')
if devices is None: if devices is None:
@ -24,7 +24,8 @@ optional_assocs = {
} }
for params in devices: for params in devices:
custom_fields = params.pop('custom_fields', None) custom_field_data = pop_custom_fields(params)
# primary ips are handled later in `270_primary_ips.py` # primary ips are handled later in `270_primary_ips.py`
params.pop('primary_ip4', None) params.pop('primary_ip4', None)
params.pop('primary_ip6', None) params.pop('primary_ip6', None)
@ -45,15 +46,6 @@ for params in devices:
device, created = Device.objects.get_or_create(**params) device, created = Device.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(device, custom_field_data)
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=device,
value=cf_value
)
device.custom_field_values.add(custom_field_value)
print("🖥️ Created device", device.name) print("🖥️ Created device", device.name)

View File

@ -1,11 +1,9 @@
from ipam.models import Aggregate, RIR
from extras.models import CustomField, CustomFieldValue
from netaddr import IPNetwork
from startup_script_utils import load_yaml
import sys import sys
from ipam.models import Aggregate, RIR
from netaddr import IPNetwork
from startup_script_utils import *
aggregates = load_yaml('/opt/netbox/initializers/aggregates.yml') aggregates = load_yaml('/opt/netbox/initializers/aggregates.yml')
if aggregates is None: if aggregates is None:
@ -16,7 +14,8 @@ required_assocs = {
} }
for params in aggregates: for params in aggregates:
custom_fields = params.pop('custom_fields', None) custom_field_data = pop_custom_fields(params)
params['prefix'] = IPNetwork(params['prefix']) params['prefix'] = IPNetwork(params['prefix'])
for assoc, details in required_assocs.items(): for assoc, details in required_assocs.items():
@ -28,15 +27,6 @@ for params in aggregates:
aggregate, created = Aggregate.objects.get_or_create(**params) aggregate, created = Aggregate.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(aggregate, custom_field_data)
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) print("🗞️ Created Aggregate", aggregate.prefix)

View File

@ -1,9 +1,9 @@
from dcim.models import Site
from virtualization.models import Cluster, ClusterType, ClusterGroup
from extras.models import CustomField, CustomFieldValue
from startup_script_utils import load_yaml
import sys import sys
from dcim.models import Site
from startup_script_utils import *
from virtualization.models import Cluster, ClusterType, ClusterGroup
clusters = load_yaml('/opt/netbox/initializers/clusters.yml') clusters = load_yaml('/opt/netbox/initializers/clusters.yml')
if clusters is None: if clusters is None:
@ -19,7 +19,7 @@ optional_assocs = {
} }
for params in clusters: for params in clusters:
custom_fields = params.pop('custom_fields', None) custom_field_data = pop_custom_fields(params)
for assoc, details in required_assocs.items(): for assoc, details in required_assocs.items():
model, field = details model, field = details
@ -37,15 +37,6 @@ for params in clusters:
cluster, created = Cluster.objects.get_or_create(**params) cluster, created = Cluster.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(cluster, custom_field_data)
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) print("🗄️ Created cluster", cluster.name)

View File

@ -1,11 +1,9 @@
from ipam.models import VRF
from tenancy.models import Tenant
from extras.models import CustomField, CustomFieldValue
from startup_script_utils import load_yaml
import sys import sys
from ipam.models import VRF
from startup_script_utils import *
from tenancy.models import Tenant
vrfs = load_yaml('/opt/netbox/initializers/vrfs.yml') vrfs = load_yaml('/opt/netbox/initializers/vrfs.yml')
if vrfs is None: if vrfs is None:
@ -16,7 +14,7 @@ optional_assocs = {
} }
for params in vrfs: for params in vrfs:
custom_fields = params.pop('custom_fields', None) custom_field_data = pop_custom_fields(params)
for assoc, details in optional_assocs.items(): for assoc, details in optional_assocs.items():
if assoc in params: if assoc in params:
@ -28,15 +26,6 @@ for params in vrfs:
vrf, created = VRF.objects.get_or_create(**params) vrf, created = VRF.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(vrf, custom_field_data)
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) print("📦 Created VRF", vrf.name)

View File

@ -1,8 +1,8 @@
import sys
from dcim.models import Site from dcim.models import Site
from ipam.models import VLANGroup from ipam.models import VLANGroup
from extras.models import CustomField, CustomFieldValue from startup_script_utils import *
from startup_script_utils import load_yaml
import sys
vlan_groups = load_yaml('/opt/netbox/initializers/vlan_groups.yml') vlan_groups = load_yaml('/opt/netbox/initializers/vlan_groups.yml')
@ -14,7 +14,7 @@ optional_assocs = {
} }
for params in vlan_groups: for params in vlan_groups:
custom_fields = params.pop('custom_fields', None) custom_field_data = pop_custom_fields(params)
for assoc, details in optional_assocs.items(): for assoc, details in optional_assocs.items():
if assoc in params: if assoc in params:
@ -26,15 +26,6 @@ for params in vlan_groups:
vlan_group, created = VLANGroup.objects.get_or_create(**params) vlan_group, created = VLANGroup.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(vlan_group, custom_field_data)
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) print("🏘️ Created VLAN Group", vlan_group.name)

View File

@ -1,9 +1,9 @@
import sys
from dcim.models import Site from dcim.models import Site
from ipam.models import VLAN, VLANGroup, Role from ipam.models import VLAN, VLANGroup, Role
from startup_script_utils import *
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup
from extras.models import CustomField, CustomFieldValue
from startup_script_utils import load_yaml
import sys
vlans = load_yaml('/opt/netbox/initializers/vlans.yml') vlans = load_yaml('/opt/netbox/initializers/vlans.yml')
@ -19,7 +19,7 @@ optional_assocs = {
} }
for params in vlans: for params in vlans:
custom_fields = params.pop('custom_fields', None) custom_field_data = pop_custom_fields(params)
for assoc, details in optional_assocs.items(): for assoc, details in optional_assocs.items():
if assoc in params: if assoc in params:
@ -31,15 +31,6 @@ for params in vlans:
vlan, created = VLAN.objects.get_or_create(**params) vlan, created = VLAN.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(vlan, custom_field_data)
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) print("🏠 Created VLAN", vlan.name)

View File

@ -1,10 +1,10 @@
import sys
from dcim.models import Site from dcim.models import Site
from ipam.models import Prefix, VLAN, Role, VRF from ipam.models import Prefix, VLAN, Role, VRF
from tenancy.models import Tenant, TenantGroup
from extras.models import CustomField, CustomFieldValue
from netaddr import IPNetwork from netaddr import IPNetwork
from startup_script_utils import load_yaml from startup_script_utils import *
import sys from tenancy.models import Tenant, TenantGroup
prefixes = load_yaml('/opt/netbox/initializers/prefixes.yml') prefixes = load_yaml('/opt/netbox/initializers/prefixes.yml')
@ -21,7 +21,8 @@ optional_assocs = {
} }
for params in prefixes: for params in prefixes:
custom_fields = params.pop('custom_fields', None) custom_field_data = pop_custom_fields(params)
params['prefix'] = IPNetwork(params['prefix']) params['prefix'] = IPNetwork(params['prefix'])
for assoc, details in optional_assocs.items(): for assoc, details in optional_assocs.items():
@ -33,14 +34,6 @@ for params in prefixes:
prefix, created = Prefix.objects.get_or_create(**params) prefix, created = Prefix.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(prefix, custom_field_data)
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) print("📌 Created Prefix", prefix.prefix)

View File

@ -1,10 +1,10 @@
from dcim.models import Site, Platform, DeviceRole
from virtualization.models import Cluster, VirtualMachine
from tenancy.models import Tenant
from extras.models import CustomField, CustomFieldValue
from startup_script_utils import load_yaml
import sys import sys
from dcim.models import Platform, DeviceRole
from startup_script_utils import *
from tenancy.models import Tenant
from virtualization.models import Cluster, VirtualMachine
virtual_machines = load_yaml('/opt/netbox/initializers/virtual_machines.yml') virtual_machines = load_yaml('/opt/netbox/initializers/virtual_machines.yml')
if virtual_machines is None: if virtual_machines is None:
@ -21,7 +21,8 @@ optional_assocs = {
} }
for params in virtual_machines: for params in virtual_machines:
custom_fields = params.pop('custom_fields', None) custom_field_data = pop_custom_fields(params)
# primary ips are handled later in `270_primary_ips.py` # primary ips are handled later in `270_primary_ips.py`
params.pop('primary_ip4', None) params.pop('primary_ip4', None)
params.pop('primary_ip6', None) params.pop('primary_ip6', None)
@ -42,15 +43,6 @@ for params in virtual_machines:
virtual_machine, created = VirtualMachine.objects.get_or_create(**params) virtual_machine, created = VirtualMachine.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(virtual_machine, custom_field_data)
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) print("🖥️ Created virtual machine", virtual_machine.name)

View File

@ -1,8 +1,8 @@
from virtualization.models import VirtualMachine, VMInterface
from extras.models import CustomField, CustomFieldValue
from startup_script_utils import load_yaml
import sys import sys
from startup_script_utils import *
from virtualization.models import VirtualMachine, VMInterface
interfaces = load_yaml('/opt/netbox/initializers/virtualization_interfaces.yml') interfaces = load_yaml('/opt/netbox/initializers/virtualization_interfaces.yml')
if interfaces is None: if interfaces is None:
@ -13,7 +13,7 @@ required_assocs = {
} }
for params in interfaces: for params in interfaces:
custom_fields = params.pop('custom_fields', None) custom_field_data = pop_custom_fields(params)
for assoc, details in required_assocs.items(): for assoc, details in required_assocs.items():
model, field = details model, field = details
@ -24,15 +24,6 @@ for params in interfaces:
interface, created = VMInterface.objects.get_or_create(**params) interface, created = VMInterface.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(interface, custom_field_data)
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) print("🧷 Created interface", interface.name, interface.virtual_machine.name)

View File

@ -1,9 +1,9 @@
from dcim.models import Interface, Device
from extras.models import CustomField, CustomFieldValue
from startup_script_utils import load_yaml
import sys import sys
interfaces= load_yaml('/opt/netbox/initializers/dcim_interfaces.yml') from dcim.models import Interface, Device
from startup_script_utils import *
interfaces = load_yaml('/opt/netbox/initializers/dcim_interfaces.yml')
if interfaces is None: if interfaces is None:
sys.exit() sys.exit()
@ -13,7 +13,7 @@ required_assocs = {
} }
for params in interfaces: for params in interfaces:
custom_fields = params.pop('custom_fields', None) custom_field_data = pop_custom_fields(params)
for assoc, details in required_assocs.items(): for assoc, details in required_assocs.items():
model, field = details model, field = details
@ -24,15 +24,6 @@ for params in interfaces:
interface, created = Interface.objects.get_or_create(**params) interface, created = Interface.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(interface, custom_field_data)
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) print("🧷 Created interface", interface.name, interface.device.name)

View File

@ -3,10 +3,9 @@ import sys
from dcim.models import Device, Interface from dcim.models import Device, Interface
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db.models import Q from django.db.models import Q
from extras.models import CustomField, CustomFieldValue
from ipam.models import VRF, IPAddress from ipam.models import VRF, IPAddress
from netaddr import IPNetwork from netaddr import IPNetwork
from startup_script_utils import load_yaml from startup_script_utils import *
from tenancy.models import Tenant from tenancy.models import Tenant
from virtualization.models import VirtualMachine, VMInterface from virtualization.models import VirtualMachine, VMInterface
@ -25,9 +24,10 @@ vm_interface_ct = ContentType.objects.filter(Q(app_label='virtualization', model
interface_ct = ContentType.objects.filter(Q(app_label='dcim', model='interface')).first() interface_ct = ContentType.objects.filter(Q(app_label='dcim', model='interface')).first()
for params in ip_addresses: for params in ip_addresses:
custom_field_data = pop_custom_fields(params)
vm = params.pop('virtual_machine', None) vm = params.pop('virtual_machine', None)
device = params.pop('device', None) device = params.pop('device', None)
custom_fields = params.pop('custom_fields', None)
params['address'] = IPNetwork(params['address']) params['address'] = IPNetwork(params['address'])
if vm and device: if vm and device:
@ -55,15 +55,6 @@ for params in ip_addresses:
ip_address, created = IPAddress.objects.get_or_create(**params) ip_address, created = IPAddress.objects.get_or_create(**params)
if created: if created:
if custom_fields is not None: set_custom_fields_values(ip_address, custom_field_data)
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) print("🧬 Created IP Address", ip_address.address)

View File

@ -1,2 +1,3 @@
from .load_yaml import load_yaml from .load_yaml import load_yaml
from .permissions import set_permissions from .permissions import set_permissions
from .custom_fields import set_custom_fields_values, pop_custom_fields

View File

@ -0,0 +1,15 @@
def set_custom_fields_values(entity, custom_field_data):
if not custom_field_data:
return
entity.custom_field_data = custom_field_data
return entity.save()
def pop_custom_fields(params):
if 'custom_field_data' in params:
return params.pop('custom_field_data')
elif 'custom_fields' in params:
print("⚠️ Please rename 'custom_fields' to 'custom_field_data'!")
return params.pop('custom_fields')
return None

View File

@ -1,5 +1,6 @@
from ruamel.yaml import YAML
from pathlib import Path from pathlib import Path
from ruamel.yaml import YAML
def load_yaml(yaml_file: str): def load_yaml(yaml_file: str):
yf = Path(yaml_file) yf = Path(yaml_file)

21
test.sh
View File

@ -1,12 +1,29 @@
#!/bin/bash #!/bin/bash
# Runs the original Netbox unit tests and tests whether all initializers work.
# Usage:
# ./test.sh latest
# ./test.sh v2.9.7
# ./test.sh develop-2.10
# IMAGE='netboxcommunity/netbox:latest' ./test.sh
# IMAGE='netboxcommunity/netbox:v2.9.7' ./test.sh
# IMAGE='netboxcommunity/netbox:develop-2.10' ./test.sh
# export IMAGE='netboxcommunity/netbox:latest'; ./test.sh
# export IMAGE='netboxcommunity/netbox:v2.9.7'; ./test.sh
# export IMAGE='netboxcommunity/netbox:develop-2.10'; ./test.sh
# exit when a command exits with an exit code != 0 # exit when a command exits with an exit code != 0
set -e set -e
# version is used by `docker-compose.yml` do determine the tag # IMAGE is used by `docker-compose.yml` do determine the tag
# of the Docker Image that is to be used # of the Docker Image that is to be used
export IMAGE="${IMAGE-netboxcommunity/netbox:latest}" if [ "${1}x" != "x" ]; then
# Use the command line argument
export IMAGE="netboxcommunity/netbox:${1}"
else
export IMAGE="${IMAGE-netboxcommunity/netbox:latest}"
fi
# Ensure that an IMAGE is defined
if [ -z "${IMAGE}" ]; then if [ -z "${IMAGE}" ]; then
echo "⚠️ No image defined" echo "⚠️ No image defined"