Merge pull request #104 from ninech/add-more-seeds
Add seed/initialization scripts for additional resources
This commit is contained in:
commit
c16f72a2ac
@ -161,7 +161,7 @@ if created:
|
|||||||
|
|
||||||
#### Initializers
|
#### Initializers
|
||||||
|
|
||||||
Initializers are built-in startup scripts for defining NetBox custom fields, groups and users.
|
Initializers are built-in startup scripts for defining NetBox custom fields, groups, users and many other resources.
|
||||||
All you need to do is to mount you own `initializers` folder ([see `docker-compose.yml`][netbox-docker-compose]).
|
All you need to do is to mount you own `initializers` folder ([see `docker-compose.yml`][netbox-docker-compose]).
|
||||||
Look at the [`initializers` folder][netbox-docker-initializers] to learn how the files must look like.
|
Look at the [`initializers` folder][netbox-docker-initializers] to learn how the files must look like.
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
# on_objects:
|
# on_objects:
|
||||||
# - dcim.models.Device
|
# - dcim.models.Device
|
||||||
# - dcim.models.Rack
|
# - dcim.models.Rack
|
||||||
|
# - dcim.models.Site
|
||||||
|
# - dcim.models.DeviceType
|
||||||
# - ipam.models.IPAddress
|
# - ipam.models.IPAddress
|
||||||
# - ipam.models.Prefix
|
# - ipam.models.Prefix
|
||||||
# - tenancy.models.Tenant
|
# - tenancy.models.Tenant
|
||||||
|
15
initializers/device_roles.yml
Normal file
15
initializers/device_roles.yml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# - name: switch
|
||||||
|
# slug: switch
|
||||||
|
# color: Grey
|
||||||
|
# - name: router
|
||||||
|
# slug: router
|
||||||
|
# color: Cyan
|
||||||
|
# - name: load-balancer
|
||||||
|
# slug: load-balancer
|
||||||
|
# color: Red
|
||||||
|
# - name: server
|
||||||
|
# slug: server
|
||||||
|
# color: Blue
|
||||||
|
# - name: patchpanel
|
||||||
|
# slug: patchpanel
|
||||||
|
# color: Black
|
23
initializers/device_types.yml
Normal file
23
initializers/device_types.yml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# - model: Model 1
|
||||||
|
# manufacturer: Manufacturer 1
|
||||||
|
# slug: model-1
|
||||||
|
# u_height: 2
|
||||||
|
# custom_fields:
|
||||||
|
# text_field: Description
|
||||||
|
# - model: Model 2
|
||||||
|
# manufacturer: Manufacturer 1
|
||||||
|
# slug: model-2
|
||||||
|
# custom_fields:
|
||||||
|
# text_field: Description
|
||||||
|
# - model: Model 3
|
||||||
|
# manufacturer: Manufacturer 1
|
||||||
|
# slug: model-3
|
||||||
|
# is_full_depth: false
|
||||||
|
# u_height: 0
|
||||||
|
# custom_fields:
|
||||||
|
# text_field: Description
|
||||||
|
# - model: Other
|
||||||
|
# manufacturer: NoName
|
||||||
|
# slug: other
|
||||||
|
# custom_fields:
|
||||||
|
# text_field: Description
|
27
initializers/devices.yml
Normal file
27
initializers/devices.yml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# - name: server01
|
||||||
|
# device_role: server
|
||||||
|
# device_type: Other
|
||||||
|
# site: AMS 1
|
||||||
|
# rack: rack-01
|
||||||
|
# face: Front
|
||||||
|
# position: 1
|
||||||
|
# custom_fields:
|
||||||
|
# text_field: Description
|
||||||
|
# - name: server02
|
||||||
|
# device_role: server
|
||||||
|
# device_type: Other
|
||||||
|
# site: AMS 2
|
||||||
|
# rack: rack-02
|
||||||
|
# face: Front
|
||||||
|
# position: 2
|
||||||
|
# custom_fields:
|
||||||
|
# text_field: Description
|
||||||
|
# - name: server03
|
||||||
|
# device_role: server
|
||||||
|
# device_type: Other
|
||||||
|
# site: SING 1
|
||||||
|
# rack: rack-03
|
||||||
|
# face: Front
|
||||||
|
# position: 3
|
||||||
|
# custom_fields:
|
||||||
|
# text_field: Description
|
6
initializers/manufacturers.yml
Normal file
6
initializers/manufacturers.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# - name: Manufacturer 1
|
||||||
|
# slug: manufacturer-1
|
||||||
|
# - name: Manufacturer 2
|
||||||
|
# slug: manufacturer-2
|
||||||
|
# - name: NoName
|
||||||
|
# slug: noname
|
19
initializers/platforms.yml
Normal file
19
initializers/platforms.yml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# # Allowed rpc clients are: juniper-junos, cisco-ios, opengear
|
||||||
|
# - name: Platform 1
|
||||||
|
# slug: platform-1
|
||||||
|
# manufacturer: Manufacturer 1
|
||||||
|
# napalm_driver: driver1
|
||||||
|
# napalm_args: "{'arg1': 'value1', 'arg2': 'value2'}"
|
||||||
|
# rpc_client: juniper-junos
|
||||||
|
# - name: Platform 2
|
||||||
|
# slug: platform-2
|
||||||
|
# manufacturer: Manufacturer 2
|
||||||
|
# napalm_driver: driver2
|
||||||
|
# napalm_args: "{'arg1': 'value1', 'arg2': 'value2'}"
|
||||||
|
# rpc_client: opengear
|
||||||
|
# - name: Platform 3
|
||||||
|
# slug: platform-3
|
||||||
|
# manufacturer: NoName
|
||||||
|
# napalm_driver: driver3
|
||||||
|
# napalm_args: "{'arg1': 'value1', 'arg2': 'value2'}"
|
||||||
|
# rpc_client: juniper-junos
|
12
initializers/rack_roles.yml
Normal file
12
initializers/rack_roles.yml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# - name: Role 1
|
||||||
|
# slug: role-1
|
||||||
|
# color: Pink
|
||||||
|
# - name: Role 2
|
||||||
|
# slug: role-2
|
||||||
|
# color: Cyan
|
||||||
|
# - name: Role 3
|
||||||
|
# slug: role-3
|
||||||
|
# color: Grey
|
||||||
|
# - name: Role 4
|
||||||
|
# slug: role-4
|
||||||
|
# color: Teal
|
24
initializers/racks.yml
Normal file
24
initializers/racks.yml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# - site: AMS 1
|
||||||
|
# name: rack-01
|
||||||
|
# role: Role 1
|
||||||
|
# type: 4-post cabinet
|
||||||
|
# width: 19 inches
|
||||||
|
# u_height: 47
|
||||||
|
# custom_fields:
|
||||||
|
# text_field: Description
|
||||||
|
# - site: AMS 2
|
||||||
|
# name: rack-02
|
||||||
|
# role: Role 2
|
||||||
|
# type: 4-post cabinet
|
||||||
|
# width: 19 inches
|
||||||
|
# u_height: 47
|
||||||
|
# custom_fields:
|
||||||
|
# text_field: Description
|
||||||
|
# - site: SING 1
|
||||||
|
# name: rack-03
|
||||||
|
# role: Role 3
|
||||||
|
# type: 4-post cabinet
|
||||||
|
# width: 19 inches
|
||||||
|
# u_height: 47
|
||||||
|
# custom_fields:
|
||||||
|
# text_field: Description
|
10
initializers/regions.yml
Normal file
10
initializers/regions.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# - name: Singapore
|
||||||
|
# slug: singapore
|
||||||
|
# - name: Amsterdam
|
||||||
|
# slug: amsterdam
|
||||||
|
# - name: Downtown
|
||||||
|
# slug: downtown
|
||||||
|
# parent: Amsterdam
|
||||||
|
# - name: Suburbs
|
||||||
|
# slug: suburbs
|
||||||
|
# parent: Amsterdam
|
32
initializers/sites.yml
Normal file
32
initializers/sites.yml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# - name: AMS 1
|
||||||
|
# slug: ams1
|
||||||
|
# region: Downtown
|
||||||
|
# status: 1
|
||||||
|
# facility: Amsterdam 1
|
||||||
|
# asn: 12345
|
||||||
|
# custom_fields:
|
||||||
|
# text_field: Description
|
||||||
|
# - name: AMS 2
|
||||||
|
# slug: ams2
|
||||||
|
# region: Downtown
|
||||||
|
# status: 1
|
||||||
|
# facility: Amsterdam 2
|
||||||
|
# asn: 54321
|
||||||
|
# custom_fields:
|
||||||
|
# text_field: Description
|
||||||
|
# - name: AMS 3
|
||||||
|
# slug: ams3
|
||||||
|
# region: Suburbs
|
||||||
|
# status: 1
|
||||||
|
# facility: Amsterdam 3
|
||||||
|
# asn: 67890
|
||||||
|
# custom_fields:
|
||||||
|
# text_field: Description
|
||||||
|
# - name: SING 1
|
||||||
|
# slug: sing1
|
||||||
|
# region: Singapore
|
||||||
|
# status: 1
|
||||||
|
# facility: Singapore 1
|
||||||
|
# asn: 09876
|
||||||
|
# custom_fields:
|
||||||
|
# text_field: Description
|
25
startup_scripts/030_regions.py
Normal file
25
startup_scripts/030_regions.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
from dcim.models import Region
|
||||||
|
from ruamel.yaml import YAML
|
||||||
|
|
||||||
|
with open('/opt/netbox/initializers/regions.yml', 'r') as stream:
|
||||||
|
yaml=YAML(typ='safe')
|
||||||
|
regions = yaml.load(stream)
|
||||||
|
|
||||||
|
optional_assocs = {
|
||||||
|
'parent': (Region, 'name')
|
||||||
|
}
|
||||||
|
|
||||||
|
if regions is not None:
|
||||||
|
for params in regions:
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
region, created = Region.objects.get_or_create(**params)
|
||||||
|
|
||||||
|
if created:
|
||||||
|
print("🌐 Created region", region.name)
|
40
startup_scripts/040_sites.py
Normal file
40
startup_scripts/040_sites.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
from dcim.models import Region, Site
|
||||||
|
from extras.models import CustomField, CustomFieldValue
|
||||||
|
from tenancy.models import Tenant
|
||||||
|
from ruamel.yaml import YAML
|
||||||
|
|
||||||
|
with open('/opt/netbox/initializers/sites.yml', 'r') as stream:
|
||||||
|
yaml = YAML(typ='safe')
|
||||||
|
sites = yaml.load(stream)
|
||||||
|
|
||||||
|
optional_assocs = {
|
||||||
|
'region': (Region, 'name'),
|
||||||
|
'tenant': (Tenant, 'name')
|
||||||
|
}
|
||||||
|
|
||||||
|
if sites is not None:
|
||||||
|
for params in sites:
|
||||||
|
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)
|
||||||
|
|
||||||
|
site, created = Site.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=site,
|
||||||
|
value=cf_value
|
||||||
|
)
|
||||||
|
|
||||||
|
site.custom_field_values.add(custom_field_value)
|
||||||
|
|
||||||
|
print("📍 Created site", site.name)
|
13
startup_scripts/050_manufacturers.py
Normal file
13
startup_scripts/050_manufacturers.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from dcim.models import Manufacturer
|
||||||
|
from ruamel.yaml import YAML
|
||||||
|
|
||||||
|
with open('/opt/netbox/initializers/manufacturers.yml', 'r') as stream:
|
||||||
|
yaml = YAML(typ='safe')
|
||||||
|
manufacturers = yaml.load(stream)
|
||||||
|
|
||||||
|
if manufacturers is not None:
|
||||||
|
for params in manufacturers:
|
||||||
|
manufacturer, created = Manufacturer.objects.get_or_create(**params)
|
||||||
|
|
||||||
|
if created:
|
||||||
|
print("🏭 Created Manufacturer", manufacturer.name)
|
51
startup_scripts/060_device_types.py
Normal file
51
startup_scripts/060_device_types.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
from dcim.models import DeviceType, Manufacturer, Region
|
||||||
|
from tenancy.models import Tenant
|
||||||
|
from extras.models import CustomField, CustomFieldValue
|
||||||
|
from ruamel.yaml import YAML
|
||||||
|
|
||||||
|
with open('/opt/netbox/initializers/device_types.yml', 'r') as stream:
|
||||||
|
yaml = YAML(typ='safe')
|
||||||
|
device_types = yaml.load(stream)
|
||||||
|
|
||||||
|
required_assocs = {
|
||||||
|
'manufacturer': (Manufacturer, 'name')
|
||||||
|
}
|
||||||
|
|
||||||
|
optional_assocs = {
|
||||||
|
'region': (Region, 'name'),
|
||||||
|
'tenant': (Tenant, 'name')
|
||||||
|
}
|
||||||
|
|
||||||
|
if device_types is not None:
|
||||||
|
for params in device_types:
|
||||||
|
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)
|
||||||
|
|
||||||
|
device_type, created = DeviceType.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=device_type,
|
||||||
|
value=cf_value
|
||||||
|
)
|
||||||
|
|
||||||
|
device_type.custom_field_values.add(custom_field_value)
|
||||||
|
|
||||||
|
print("🔡 Created device type", device_type.manufacturer, device_type.model)
|
||||||
|
|
21
startup_scripts/070_rack_roles.py
Normal file
21
startup_scripts/070_rack_roles.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
from dcim.models import RackRole
|
||||||
|
from ruamel.yaml import YAML
|
||||||
|
from utilities.forms import COLOR_CHOICES
|
||||||
|
|
||||||
|
with open('/opt/netbox/initializers/rack_roles.yml', 'r') as stream:
|
||||||
|
yaml=YAML(typ='safe')
|
||||||
|
rack_roles = yaml.load(stream)
|
||||||
|
|
||||||
|
if rack_roles is not None:
|
||||||
|
for params in rack_roles:
|
||||||
|
if 'color' in params:
|
||||||
|
color = params.pop('color')
|
||||||
|
|
||||||
|
for color_tpl in COLOR_CHOICES:
|
||||||
|
if color in color_tpl:
|
||||||
|
params['color'] = color_tpl[0]
|
||||||
|
|
||||||
|
rack_role, created = RackRole.objects.get_or_create(**params)
|
||||||
|
|
||||||
|
if created:
|
||||||
|
print("🎨 Created rack role", rack_role.name)
|
60
startup_scripts/080_racks.py
Normal file
60
startup_scripts/080_racks.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
from dcim.models import Site, RackRole, Rack, RackGroup
|
||||||
|
from tenancy.models import Tenant
|
||||||
|
from extras.models import CustomField, CustomFieldValue
|
||||||
|
from dcim.constants import RACK_TYPE_CHOICES, RACK_WIDTH_CHOICES
|
||||||
|
from ruamel.yaml import YAML
|
||||||
|
|
||||||
|
with open('/opt/netbox/initializers/racks.yml', 'r') as stream:
|
||||||
|
yaml = YAML(typ='safe')
|
||||||
|
racks = yaml.load(stream)
|
||||||
|
|
||||||
|
required_assocs = {
|
||||||
|
'site': (Site, 'name')
|
||||||
|
}
|
||||||
|
|
||||||
|
optional_assocs = {
|
||||||
|
'role': (RackRole, 'name'),
|
||||||
|
'tenant': (Tenant, 'name'),
|
||||||
|
'group': (RackGroup, 'name')
|
||||||
|
}
|
||||||
|
|
||||||
|
if racks is not None:
|
||||||
|
for params in racks:
|
||||||
|
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)
|
||||||
|
|
||||||
|
for rack_type in RACK_TYPE_CHOICES:
|
||||||
|
if params['type'] in rack_type:
|
||||||
|
params['type'] = rack_type[0]
|
||||||
|
|
||||||
|
for rack_width in RACK_WIDTH_CHOICES:
|
||||||
|
if params['width'] in rack_width:
|
||||||
|
params['width'] = rack_width[0]
|
||||||
|
|
||||||
|
rack, created = Rack.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=rack,
|
||||||
|
value=cf_value
|
||||||
|
)
|
||||||
|
|
||||||
|
rack.custom_field_values.add(custom_field_value)
|
||||||
|
|
||||||
|
print("🔳 Created rack", rack.site, rack.name)
|
22
startup_scripts/090_device_roles.py
Normal file
22
startup_scripts/090_device_roles.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
from dcim.models import DeviceRole
|
||||||
|
from ruamel.yaml import YAML
|
||||||
|
from utilities.forms import COLOR_CHOICES
|
||||||
|
|
||||||
|
with open('/opt/netbox/initializers/device_roles.yml', 'r') as stream:
|
||||||
|
yaml=YAML(typ='safe')
|
||||||
|
device_roles = yaml.load(stream)
|
||||||
|
|
||||||
|
if device_roles is not None:
|
||||||
|
for params in device_roles:
|
||||||
|
|
||||||
|
if 'color' in params:
|
||||||
|
color = params.pop('color')
|
||||||
|
|
||||||
|
for color_tpl in COLOR_CHOICES:
|
||||||
|
if color in color_tpl:
|
||||||
|
params['color'] = color_tpl[0]
|
||||||
|
|
||||||
|
device_role, created = DeviceRole.objects.get_or_create(**params)
|
||||||
|
|
||||||
|
if created:
|
||||||
|
print("🎨 Created device role", device_role.name)
|
25
startup_scripts/100_platforms.py
Normal file
25
startup_scripts/100_platforms.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
from dcim.models import Manufacturer, Platform
|
||||||
|
from ruamel.yaml import YAML
|
||||||
|
|
||||||
|
with open('/opt/netbox/initializers/platforms.yml', 'r') as stream:
|
||||||
|
yaml = YAML(typ='safe')
|
||||||
|
platforms = yaml.load(stream)
|
||||||
|
|
||||||
|
optional_assocs = {
|
||||||
|
'manufacturer': (Manufacturer, 'name'),
|
||||||
|
}
|
||||||
|
|
||||||
|
if platforms is not None:
|
||||||
|
for params in platforms:
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
platform, created = Platform.objects.get_or_create(**params)
|
||||||
|
|
||||||
|
if created:
|
||||||
|
print("💾 Created platform", platform.name)
|
64
startup_scripts/110_devices.py
Normal file
64
startup_scripts/110_devices.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
from dcim.models import Site, Rack, DeviceRole, DeviceType, Device, Platform
|
||||||
|
from dcim.constants import RACK_FACE_CHOICES
|
||||||
|
from ipam.models import IPAddress
|
||||||
|
from virtualization.models import Cluster
|
||||||
|
from tenancy.models import Tenant
|
||||||
|
from extras.models import CustomField, CustomFieldValue
|
||||||
|
from ruamel.yaml import YAML
|
||||||
|
|
||||||
|
with open('/opt/netbox/initializers/devices.yml', 'r') as stream:
|
||||||
|
yaml = YAML(typ='safe')
|
||||||
|
devices = yaml.load(stream)
|
||||||
|
|
||||||
|
required_assocs = {
|
||||||
|
'device_role': (DeviceRole, 'name'),
|
||||||
|
'device_type': (DeviceType, 'model'),
|
||||||
|
'site': (Site, 'name')
|
||||||
|
}
|
||||||
|
|
||||||
|
optional_assocs = {
|
||||||
|
'tenant': (Tenant, 'name'),
|
||||||
|
'platform': (Platform, 'name'),
|
||||||
|
'rack': (Rack, 'name'),
|
||||||
|
'cluster': (Cluster, 'name'),
|
||||||
|
'primary_ip4': (IPAddress, 'address'),
|
||||||
|
'primary_ip6': (IPAddress, 'address')
|
||||||
|
}
|
||||||
|
|
||||||
|
if devices is not None:
|
||||||
|
for params in devices:
|
||||||
|
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 'face' in params:
|
||||||
|
for rack_face in RACK_FACE_CHOICES:
|
||||||
|
if params['face'] in rack_face:
|
||||||
|
params['face'] = rack_face[0]
|
||||||
|
|
||||||
|
device, created = Device.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=device,
|
||||||
|
value=cf_value
|
||||||
|
)
|
||||||
|
|
||||||
|
device.custom_field_values.add(custom_field_value)
|
||||||
|
|
||||||
|
print("🖥️ Created device", device.name)
|
Loading…
Reference in New Issue
Block a user