feat: Make startup scripts idempotent

This commit is contained in:
kr3ator 2022-04-05 08:34:08 +02:00
parent a6eb4fef00
commit 9be7b0e109
42 changed files with 275 additions and 95 deletions

View File

@ -4,6 +4,7 @@
# password: reader # password: reader
# writer: # writer:
# password: writer # password: writer
# api_token: # leave empty to not generate any token
# jdoe: # jdoe:
# first_name: John # first_name: John
# last_name: Doe # last_name: Doe

View File

@ -9,13 +9,17 @@ if users is None:
sys.exit() sys.exit()
for username, user_details in users.items(): for username, user_details in users.items():
if not User.objects.filter(username=username):
user = User.objects.create_user( api_token = user_details.pop("api_token", Token.generate_key())
username=username, password = user_details.pop("password", User.objects.make_random_password())
password=user_details.get("password", 0) or User.objects.make_random_password(),
) user, created = User.objects.get_or_create(username=username, defaults=user_details)
if created:
user.set_password(password)
user.save()
if api_token:
Token.objects.get_or_create(user=user, key=api_token)
print("👤 Created user", username) print("👤 Created user", username)
if user_details.get("api_token", 0):
Token.objects.create(user=user, key=user_details["api_token"])

View File

@ -14,9 +14,11 @@ for permission_name, permission_details in object_permissions.items():
object_permission, created = ObjectPermission.objects.get_or_create( object_permission, created = ObjectPermission.objects.get_or_create(
name=permission_name, name=permission_name,
description=permission_details["description"], defaults={
enabled=permission_details["enabled"], "description": permission_details["description"],
actions=permission_details["actions"], "enabled": permission_details["enabled"],
"actions": permission_details["actions"],
},
) )
if permission_details.get("object_types", 0): if permission_details.get("object_types", 0):

View File

@ -2,7 +2,7 @@ import sys
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from extras.models import CustomLink from extras.models import CustomLink
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
custom_links = load_yaml("/opt/netbox/initializers/custom_links.yml") custom_links = load_yaml("/opt/netbox/initializers/custom_links.yml")
@ -28,6 +28,8 @@ for link in custom_links:
) )
continue continue
custom_link, created = CustomLink.objects.get_or_create(**link) matching_params, defaults = split_params(link)
custom_link, created = CustomLink.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🔗 Created Custom Link '{0}'".format(custom_link.name)) print("🔗 Created Custom Link '{0}'".format(custom_link.name))

View File

@ -1,7 +1,7 @@
import sys import sys
from extras.models import Tag from extras.models import Tag
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
from utilities.choices import ColorChoices from utilities.choices import ColorChoices
tags = load_yaml("/opt/netbox/initializers/tags.yml") tags = load_yaml("/opt/netbox/initializers/tags.yml")
@ -17,7 +17,8 @@ for params in tags:
if color in color_tpl: if color in color_tpl:
params["color"] = color_tpl[0] params["color"] = color_tpl[0]
tag, created = Tag.objects.get_or_create(**params) matching_params, defaults = split_params(params)
tag, created = Tag.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🎨 Created Tag", tag.name) print("🎨 Created Tag", tag.name)

View File

@ -2,7 +2,7 @@ import sys
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from extras.models import Webhook from extras.models import Webhook
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
webhooks = load_yaml("/opt/netbox/initializers/webhooks.yml") webhooks = load_yaml("/opt/netbox/initializers/webhooks.yml")
@ -26,7 +26,9 @@ for hook in webhooks:
except ContentType.DoesNotExist: except ContentType.DoesNotExist:
continue continue
webhook, created = Webhook.objects.get_or_create(**hook) matching_params, defaults = split_params(hook)
webhook, created = Webhook.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
webhook.content_types.set(obj_type_ids) webhook.content_types.set(obj_type_ids)
webhook.save() webhook.save()

View File

@ -1,6 +1,6 @@
import sys import sys
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
from tenancy.models import TenantGroup from tenancy.models import TenantGroup
tenant_groups = load_yaml("/opt/netbox/initializers/tenant_groups.yml") tenant_groups = load_yaml("/opt/netbox/initializers/tenant_groups.yml")
@ -9,7 +9,8 @@ if tenant_groups is None:
sys.exit() sys.exit()
for params in tenant_groups: for params in tenant_groups:
tenant_group, created = TenantGroup.objects.get_or_create(**params) matching_params, defaults = split_params(params)
tenant_group, created = TenantGroup.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🔳 Created Tenant Group", tenant_group.name) print("🔳 Created Tenant Group", tenant_group.name)

View File

@ -1,6 +1,11 @@
import sys import sys
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup
tenants = load_yaml("/opt/netbox/initializers/tenants.yml") tenants = load_yaml("/opt/netbox/initializers/tenants.yml")
@ -20,7 +25,8 @@ for params in tenants:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
tenant, created = Tenant.objects.get_or_create(**params) matching_params, defaults = split_params(params)
tenant, created = Tenant.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("👩‍💻 Created Tenant", tenant.name) print("👩‍💻 Created Tenant", tenant.name)

View File

@ -1,7 +1,7 @@
import sys import sys
from dcim.models import Region from dcim.models import Region
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
regions = load_yaml("/opt/netbox/initializers/regions.yml") regions = load_yaml("/opt/netbox/initializers/regions.yml")
@ -19,7 +19,8 @@ for params in regions:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
region, created = Region.objects.get_or_create(**params) matching_params, defaults = split_params(params)
region, created = Region.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🌐 Created region", region.name) print("🌐 Created region", region.name)

View File

@ -1,7 +1,12 @@
import sys import sys
from dcim.models import Region, Site from dcim.models import Region, Site
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from tenancy.models import Tenant from tenancy.models import Tenant
sites = load_yaml("/opt/netbox/initializers/sites.yml") sites = load_yaml("/opt/netbox/initializers/sites.yml")
@ -21,7 +26,8 @@ for params in sites:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
site, created = Site.objects.get_or_create(**params) matching_params, defaults = split_params(params)
site, created = Site.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("📍 Created site", site.name) print("📍 Created site", site.name)

View File

@ -1,13 +1,14 @@
import sys import sys
from dcim.models import Location, Site from dcim.models import Location, Site
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
rack_groups = load_yaml("/opt/netbox/initializers/locations.yml") rack_groups = load_yaml("/opt/netbox/initializers/locations.yml")
if rack_groups is None: if rack_groups is None:
sys.exit() sys.exit()
match_params = ["name", "slug", "site"]
required_assocs = {"site": (Site, "name")} required_assocs = {"site": (Site, "name")}
for params in rack_groups: for params in rack_groups:
@ -17,7 +18,8 @@ for params in rack_groups:
query = {field: params.pop(assoc)} query = {field: params.pop(assoc)}
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
location, created = Location.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
location, created = Location.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🎨 Created location", location.name) print("🎨 Created location", location.name)

View File

@ -1,7 +1,7 @@
import sys import sys
from dcim.models import RackRole from dcim.models import RackRole
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
from utilities.choices import ColorChoices from utilities.choices import ColorChoices
rack_roles = load_yaml("/opt/netbox/initializers/rack_roles.yml") rack_roles = load_yaml("/opt/netbox/initializers/rack_roles.yml")
@ -17,7 +17,8 @@ for params in rack_roles:
if color in color_tpl: if color in color_tpl:
params["color"] = color_tpl[0] params["color"] = color_tpl[0]
rack_role, created = RackRole.objects.get_or_create(**params) matching_params, defaults = split_params(params)
rack_role, created = RackRole.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🎨 Created rack role", rack_role.name) print("🎨 Created rack role", rack_role.name)

View File

@ -1,7 +1,12 @@
import sys import sys
from dcim.models import Location, Rack, RackRole, Site from dcim.models import Location, Rack, RackRole, Site
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from tenancy.models import Tenant from tenancy.models import Tenant
racks = load_yaml("/opt/netbox/initializers/racks.yml") racks = load_yaml("/opt/netbox/initializers/racks.yml")
@ -9,8 +14,8 @@ racks = load_yaml("/opt/netbox/initializers/racks.yml")
if racks is None: if racks is None:
sys.exit() sys.exit()
match_params = ["name", "site"]
required_assocs = {"site": (Site, "name")} required_assocs = {"site": (Site, "name")}
optional_assocs = { optional_assocs = {
"role": (RackRole, "name"), "role": (RackRole, "name"),
"tenant": (Tenant, "name"), "tenant": (Tenant, "name"),
@ -33,7 +38,8 @@ for params in racks:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
rack, created = Rack.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
rack, created = Rack.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🔳 Created rack", rack.site, rack.name) print("🔳 Created rack", rack.site, rack.name)

View File

@ -1,15 +1,20 @@
import sys import sys
from dcim.models import Location, PowerPanel, Site from dcim.models import Location, PowerPanel, Site
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
power_panels = load_yaml("/opt/netbox/initializers/power_panels.yml") power_panels = load_yaml("/opt/netbox/initializers/power_panels.yml")
if power_panels is None: if power_panels is None:
sys.exit() sys.exit()
match_params = ["name", "site"]
required_assocs = {"site": (Site, "name")} required_assocs = {"site": (Site, "name")}
optional_assocs = {"location": (Location, "name")} optional_assocs = {"location": (Location, "name")}
for params in power_panels: for params in power_panels:
@ -28,7 +33,8 @@ for params in power_panels:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
power_panel, created = PowerPanel.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
power_panel, created = PowerPanel.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("⚡ Created Power Panel", power_panel.site, power_panel.name) print("⚡ Created Power Panel", power_panel.site, power_panel.name)

View File

@ -1,15 +1,20 @@
import sys import sys
from dcim.models import PowerFeed, PowerPanel, Rack from dcim.models import PowerFeed, PowerPanel, Rack
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
power_feeds = load_yaml("/opt/netbox/initializers/power_feeds.yml") power_feeds = load_yaml("/opt/netbox/initializers/power_feeds.yml")
if power_feeds is None: if power_feeds is None:
sys.exit() sys.exit()
match_params = ["name", "power_panel"]
required_assocs = {"power_panel": (PowerPanel, "name")} required_assocs = {"power_panel": (PowerPanel, "name")}
optional_assocs = {"rack": (Rack, "name")} optional_assocs = {"rack": (Rack, "name")}
for params in power_feeds: for params in power_feeds:
@ -28,7 +33,8 @@ for params in power_feeds:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
power_feed, created = PowerFeed.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
power_feed, created = PowerFeed.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("⚡ Created Power Feed", power_feed.name) print("⚡ Created Power Feed", power_feed.name)

View File

@ -1,7 +1,7 @@
import sys import sys
from dcim.models import Manufacturer from dcim.models import Manufacturer
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
manufacturers = load_yaml("/opt/netbox/initializers/manufacturers.yml") manufacturers = load_yaml("/opt/netbox/initializers/manufacturers.yml")
@ -9,7 +9,8 @@ if manufacturers is None:
sys.exit() sys.exit()
for params in manufacturers: for params in manufacturers:
manufacturer, created = Manufacturer.objects.get_or_create(**params) matching_params, defaults = split_params(params)
manufacturer, created = Manufacturer.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🏭 Created Manufacturer", manufacturer.name) print("🏭 Created Manufacturer", manufacturer.name)

View File

@ -1,7 +1,7 @@
import sys import sys
from dcim.models import DeviceRole from dcim.models import DeviceRole
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
from utilities.choices import ColorChoices from utilities.choices import ColorChoices
device_roles = load_yaml("/opt/netbox/initializers/device_roles.yml") device_roles = load_yaml("/opt/netbox/initializers/device_roles.yml")
@ -18,7 +18,8 @@ for params in device_roles:
if color in color_tpl: if color in color_tpl:
params["color"] = color_tpl[0] params["color"] = color_tpl[0]
device_role, created = DeviceRole.objects.get_or_create(**params) matching_params, defaults = split_params(params)
device_role, created = DeviceRole.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🎨 Created device role", device_role.name) print("🎨 Created device role", device_role.name)

View File

@ -1,7 +1,12 @@
import sys import sys
from dcim.models import DeviceType, Manufacturer, Region from dcim.models import DeviceType, Manufacturer, Region
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from tenancy.models import Tenant 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")
@ -9,8 +14,8 @@ device_types = load_yaml("/opt/netbox/initializers/device_types.yml")
if device_types is None: if device_types is None:
sys.exit() sys.exit()
match_params = ["manufacturer", "model", "slug"]
required_assocs = {"manufacturer": (Manufacturer, "name")} required_assocs = {"manufacturer": (Manufacturer, "name")}
optional_assocs = {"region": (Region, "name"), "tenant": (Tenant, "name")} optional_assocs = {"region": (Region, "name"), "tenant": (Tenant, "name")}
for params in device_types: for params in device_types:
@ -29,7 +34,8 @@ for params in device_types:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
device_type, created = DeviceType.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
device_type, created = DeviceType.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🔡 Created device type", device_type.manufacturer, device_type.model) print("🔡 Created device type", device_type.manufacturer, device_type.model)

View File

@ -1,7 +1,12 @@
import sys import sys
from dcim.models import Device, DeviceRole, DeviceType, Location, Platform, Rack, Site from dcim.models import Device, DeviceRole, DeviceType, Location, Platform, Rack, Site
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from tenancy.models import Tenant from tenancy.models import Tenant
from virtualization.models import Cluster from virtualization.models import Cluster
@ -10,12 +15,12 @@ devices = load_yaml("/opt/netbox/initializers/devices.yml")
if devices is None: if devices is None:
sys.exit() sys.exit()
match_params = ["device_type", "name", "site"]
required_assocs = { required_assocs = {
"device_role": (DeviceRole, "name"), "device_role": (DeviceRole, "name"),
"device_type": (DeviceType, "model"), "device_type": (DeviceType, "model"),
"site": (Site, "name"), "site": (Site, "name"),
} }
optional_assocs = { optional_assocs = {
"tenant": (Tenant, "name"), "tenant": (Tenant, "name"),
"platform": (Platform, "name"), "platform": (Platform, "name"),
@ -27,7 +32,7 @@ optional_assocs = {
for params in devices: for params in devices:
custom_field_data = pop_custom_fields(params) custom_field_data = pop_custom_fields(params)
# primary ips are handled later in `270_primary_ips.py` # primary ips are handled later in `380_primary_ips.py`
params.pop("primary_ip4", None) params.pop("primary_ip4", None)
params.pop("primary_ip6", None) params.pop("primary_ip6", None)
@ -44,7 +49,8 @@ for params in devices:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
device, created = Device.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
device, created = Device.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🖥️ Created device", device.name) print("🖥️ Created device", device.name)

View File

@ -1,13 +1,19 @@
import sys import sys
from dcim.models import Device, Interface from dcim.models import Device, Interface
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
interfaces = load_yaml("/opt/netbox/initializers/dcim_interfaces.yml") interfaces = load_yaml("/opt/netbox/initializers/dcim_interfaces.yml")
if interfaces is None: if interfaces is None:
sys.exit() sys.exit()
match_params = ["device", "name"]
required_assocs = {"device": (Device, "name")} required_assocs = {"device": (Device, "name")}
for params in interfaces: for params in interfaces:
@ -19,7 +25,8 @@ for params in interfaces:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
interface, created = Interface.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
interface, created = Interface.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🧷 Created interface", interface.name, interface.device.name) print("🧷 Created interface", interface.name, interface.device.name)

View File

@ -1,7 +1,7 @@
import sys import sys
from dcim.models import Manufacturer, Platform from dcim.models import Manufacturer, Platform
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
platforms = load_yaml("/opt/netbox/initializers/platforms.yml") platforms = load_yaml("/opt/netbox/initializers/platforms.yml")
@ -21,7 +21,8 @@ for params in platforms:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
platform, created = Platform.objects.get_or_create(**params) matching_params, defaults = split_params(params)
platform, created = Platform.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("💾 Created platform", platform.name) print("💾 Created platform", platform.name)

View File

@ -1,7 +1,12 @@
import sys import sys
from ipam.models import RouteTarget from ipam.models import RouteTarget
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from tenancy.models import Tenant from tenancy.models import Tenant
route_targets = load_yaml("/opt/netbox/initializers/route_targets.yml") route_targets = load_yaml("/opt/netbox/initializers/route_targets.yml")
@ -21,7 +26,8 @@ for params in route_targets:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
route_target, created = RouteTarget.objects.get_or_create(**params) matching_params, defaults = split_params(params)
route_target, created = RouteTarget.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🎯 Created Route Target", route_target.name) print("🎯 Created Route Target", route_target.name)

View File

@ -1,7 +1,12 @@
import sys import sys
from ipam.models import VRF from ipam.models import VRF
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from tenancy.models import Tenant from tenancy.models import Tenant
vrfs = load_yaml("/opt/netbox/initializers/vrfs.yml") vrfs = load_yaml("/opt/netbox/initializers/vrfs.yml")
@ -9,6 +14,7 @@ vrfs = load_yaml("/opt/netbox/initializers/vrfs.yml")
if vrfs is None: if vrfs is None:
sys.exit() sys.exit()
match_params = ["name", "rd"]
optional_assocs = {"tenant": (Tenant, "name")} optional_assocs = {"tenant": (Tenant, "name")}
for params in vrfs: for params in vrfs:
@ -21,7 +27,8 @@ for params in vrfs:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
vrf, created = VRF.objects.get_or_create(**params) matching_params, defaults = split_params(params)
vrf, created = VRF.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("📦 Created VRF", vrf.name) print("📦 Created VRF", vrf.name)

View File

@ -1,7 +1,7 @@
import sys import sys
from ipam.models import RIR from ipam.models import RIR
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
rirs = load_yaml("/opt/netbox/initializers/rirs.yml") rirs = load_yaml("/opt/netbox/initializers/rirs.yml")
@ -9,7 +9,8 @@ if rirs is None:
sys.exit() sys.exit()
for params in rirs: for params in rirs:
rir, created = RIR.objects.get_or_create(**params) matching_params, defaults = split_params(params)
rir, created = RIR.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🗺️ Created RIR", rir.name) print("🗺️ Created RIR", rir.name)

View File

@ -1,7 +1,7 @@
import sys import sys
from ipam.models import ASN, RIR from ipam.models import ASN, RIR
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
from tenancy.models import Tenant from tenancy.models import Tenant
asns = load_yaml("/opt/netbox/initializers/asns.yml") asns = load_yaml("/opt/netbox/initializers/asns.yml")
@ -9,8 +9,8 @@ asns = load_yaml("/opt/netbox/initializers/asns.yml")
if asns is None: if asns is None:
sys.exit() sys.exit()
match_params = ["asn", "rir"]
required_assocs = {"rir": (RIR, "name")} required_assocs = {"rir": (RIR, "name")}
optional_assocs = {"tenant": (Tenant, "name")} optional_assocs = {"tenant": (Tenant, "name")}
for params in asns: for params in asns:
@ -27,7 +27,8 @@ for params in asns:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
asn, created = ASN.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
asn, created = ASN.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print(f"🔡 Created ASN {asn.asn}") print(f"🔡 Created ASN {asn.asn}")

View File

@ -2,7 +2,12 @@ import sys
from ipam.models import RIR, Aggregate from ipam.models import RIR, Aggregate
from netaddr import IPNetwork from netaddr import IPNetwork
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from tenancy.models import Tenant from tenancy.models import Tenant
aggregates = load_yaml("/opt/netbox/initializers/aggregates.yml") aggregates = load_yaml("/opt/netbox/initializers/aggregates.yml")
@ -10,8 +15,8 @@ aggregates = load_yaml("/opt/netbox/initializers/aggregates.yml")
if aggregates is None: if aggregates is None:
sys.exit() sys.exit()
match_params = ["prefix", "rir"]
required_assocs = {"rir": (RIR, "name")} required_assocs = {"rir": (RIR, "name")}
optional_assocs = { optional_assocs = {
"tenant": (Tenant, "name"), "tenant": (Tenant, "name"),
} }
@ -34,7 +39,8 @@ for params in aggregates:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
aggregate, created = Aggregate.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
aggregate, created = Aggregate.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🗞️ Created Aggregate", aggregate.prefix) print("🗞️ Created Aggregate", aggregate.prefix)

View File

@ -1,7 +1,7 @@
import sys import sys
from ipam.models import Role from ipam.models import Role
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
roles = load_yaml("/opt/netbox/initializers/prefix_vlan_roles.yml") roles = load_yaml("/opt/netbox/initializers/prefix_vlan_roles.yml")
@ -9,7 +9,8 @@ if roles is None:
sys.exit() sys.exit()
for params in roles: for params in roles:
role, created = Role.objects.get_or_create(**params) matching_params, defaults = split_params(params)
role, created = Role.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("⛹️‍ Created Prefix/VLAN Role", role.name) print("⛹️‍ Created Prefix/VLAN Role", role.name)

View File

@ -1,6 +1,6 @@
import sys import sys
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
from virtualization.models import ClusterType from virtualization.models import ClusterType
cluster_types = load_yaml("/opt/netbox/initializers/cluster_types.yml") cluster_types = load_yaml("/opt/netbox/initializers/cluster_types.yml")
@ -9,7 +9,8 @@ if cluster_types is None:
sys.exit() sys.exit()
for params in cluster_types: for params in cluster_types:
cluster_type, created = ClusterType.objects.get_or_create(**params) matching_params, defaults = split_params(params)
cluster_type, created = ClusterType.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🧰 Created Cluster Type", cluster_type.name) print("🧰 Created Cluster Type", cluster_type.name)

View File

@ -1,6 +1,6 @@
import sys import sys
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
from virtualization.models import ClusterGroup from virtualization.models import ClusterGroup
cluster_groups = load_yaml("/opt/netbox/initializers/cluster_groups.yml") cluster_groups = load_yaml("/opt/netbox/initializers/cluster_groups.yml")
@ -9,7 +9,10 @@ if cluster_groups is None:
sys.exit() sys.exit()
for params in cluster_groups: for params in cluster_groups:
cluster_group, created = ClusterGroup.objects.get_or_create(**params) matching_params, defaults = split_params(params)
cluster_group, created = ClusterGroup.objects.get_or_create(
**matching_params, defaults=defaults
)
if created: if created:
print("🗄️ Created Cluster Group", cluster_group.name) print("🗄️ Created Cluster Group", cluster_group.name)

View File

@ -1,7 +1,12 @@
import sys import sys
from dcim.models import Site from dcim.models import Site
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from tenancy.models import Tenant from tenancy.models import Tenant
from virtualization.models import Cluster, ClusterGroup, ClusterType from virtualization.models import Cluster, ClusterGroup, ClusterType
@ -10,8 +15,8 @@ clusters = load_yaml("/opt/netbox/initializers/clusters.yml")
if clusters is None: if clusters is None:
sys.exit() sys.exit()
match_params = ["name", "type"]
required_assocs = {"type": (ClusterType, "name")} required_assocs = {"type": (ClusterType, "name")}
optional_assocs = { optional_assocs = {
"site": (Site, "name"), "site": (Site, "name"),
"group": (ClusterGroup, "name"), "group": (ClusterGroup, "name"),
@ -34,7 +39,8 @@ for params in clusters:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
cluster, created = Cluster.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
cluster, created = Cluster.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🗄️ Created cluster", cluster.name) print("🗄️ Created cluster", cluster.name)

View File

@ -2,7 +2,12 @@ import sys
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from ipam.models import VLANGroup from ipam.models import VLANGroup
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
vlan_groups = load_yaml("/opt/netbox/initializers/vlan_groups.yml") vlan_groups = load_yaml("/opt/netbox/initializers/vlan_groups.yml")
@ -32,7 +37,9 @@ for params in vlan_groups:
) )
continue continue
params["scope_id"] = ct.model_class().objects.get(**query).id params["scope_id"] = ct.model_class().objects.get(**query).id
vlan_group, created = VLANGroup.objects.get_or_create(**params)
matching_params, defaults = split_params(params)
vlan_group, created = VLANGroup.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🏘️ Created VLAN Group", vlan_group.name) print("🏘️ Created VLAN Group", vlan_group.name)

View File

@ -2,7 +2,12 @@ import sys
from dcim.models import Site from dcim.models import Site
from ipam.models import VLAN, Role, VLANGroup from ipam.models import VLAN, Role, VLANGroup
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup
vlans = load_yaml("/opt/netbox/initializers/vlans.yml") vlans = load_yaml("/opt/netbox/initializers/vlans.yml")
@ -10,6 +15,7 @@ vlans = load_yaml("/opt/netbox/initializers/vlans.yml")
if vlans is None: if vlans is None:
sys.exit() sys.exit()
match_params = ["name", "vid"]
optional_assocs = { optional_assocs = {
"site": (Site, "name"), "site": (Site, "name"),
"tenant": (Tenant, "name"), "tenant": (Tenant, "name"),
@ -28,7 +34,8 @@ for params in vlans:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
vlan, created = VLAN.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
vlan, created = VLAN.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🏠 Created VLAN", vlan.name) print("🏠 Created VLAN", vlan.name)

View File

@ -1,7 +1,12 @@
import sys import sys
from dcim.models import DeviceRole, Platform from dcim.models import DeviceRole, Platform
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from tenancy.models import Tenant from tenancy.models import Tenant
from virtualization.models import Cluster, VirtualMachine from virtualization.models import Cluster, VirtualMachine
@ -10,8 +15,8 @@ virtual_machines = load_yaml("/opt/netbox/initializers/virtual_machines.yml")
if virtual_machines is None: if virtual_machines is None:
sys.exit() sys.exit()
match_params = ["cluster", "name"]
required_assocs = {"cluster": (Cluster, "name")} required_assocs = {"cluster": (Cluster, "name")}
optional_assocs = { optional_assocs = {
"tenant": (Tenant, "name"), "tenant": (Tenant, "name"),
"platform": (Platform, "name"), "platform": (Platform, "name"),
@ -38,7 +43,10 @@ for params in virtual_machines:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
virtual_machine, created = VirtualMachine.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
virtual_machine, created = VirtualMachine.objects.get_or_create(
**matching_params, defaults=defaults
)
if created: if created:
print("🖥️ Created virtual machine", virtual_machine.name) print("🖥️ Created virtual machine", virtual_machine.name)

View File

@ -1,6 +1,11 @@
import sys import sys
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from virtualization.models import VirtualMachine, VMInterface from virtualization.models import VirtualMachine, VMInterface
interfaces = load_yaml("/opt/netbox/initializers/virtualization_interfaces.yml") interfaces = load_yaml("/opt/netbox/initializers/virtualization_interfaces.yml")
@ -8,6 +13,7 @@ interfaces = load_yaml("/opt/netbox/initializers/virtualization_interfaces.yml")
if interfaces is None: if interfaces is None:
sys.exit() sys.exit()
match_params = ["name", "virtual_machine"]
required_assocs = {"virtual_machine": (VirtualMachine, "name")} required_assocs = {"virtual_machine": (VirtualMachine, "name")}
for params in interfaces: for params in interfaces:
@ -19,7 +25,8 @@ for params in interfaces:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
interface, created = VMInterface.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
interface, created = VMInterface.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🧷 Created interface", interface.name, interface.virtual_machine.name) print("🧷 Created interface", interface.name, interface.virtual_machine.name)

View File

@ -3,7 +3,12 @@ import sys
from dcim.models import Site from dcim.models import Site
from ipam.models import VLAN, VRF, Prefix, Role from ipam.models import VLAN, VRF, Prefix, Role
from netaddr import IPNetwork from netaddr import IPNetwork
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup
prefixes = load_yaml("/opt/netbox/initializers/prefixes.yml") prefixes = load_yaml("/opt/netbox/initializers/prefixes.yml")
@ -11,6 +16,7 @@ prefixes = load_yaml("/opt/netbox/initializers/prefixes.yml")
if prefixes is None: if prefixes is None:
sys.exit() sys.exit()
match_params = ["prefix", "site", "vrf", "vlan"]
optional_assocs = { optional_assocs = {
"site": (Site, "name"), "site": (Site, "name"),
"tenant": (Tenant, "name"), "tenant": (Tenant, "name"),
@ -31,7 +37,8 @@ for params in prefixes:
query = {field: params.pop(assoc)} query = {field: params.pop(assoc)}
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
prefix, created = Prefix.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
prefix, created = Prefix.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("📌 Created Prefix", prefix.prefix) print("📌 Created Prefix", prefix.prefix)

View File

@ -5,7 +5,12 @@ from django.contrib.contenttypes.models import ContentType
from django.db.models import Q from django.db.models import Q
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, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from tenancy.models import Tenant from tenancy.models import Tenant
from virtualization.models import VirtualMachine, VMInterface from virtualization.models import VirtualMachine, VMInterface
@ -14,6 +19,7 @@ ip_addresses = load_yaml("/opt/netbox/initializers/ip_addresses.yml")
if ip_addresses is None: if ip_addresses is None:
sys.exit() sys.exit()
match_params = ["address", "vrf"]
optional_assocs = { optional_assocs = {
"tenant": (Tenant, "name"), "tenant": (Tenant, "name"),
"vrf": (VRF, "name"), "vrf": (VRF, "name"),
@ -55,7 +61,8 @@ for params in ip_addresses:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
ip_address, created = IPAddress.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
ip_address, created = IPAddress.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("🧬 Created IP Address", ip_address.address) print("🧬 Created IP Address", ip_address.address)

View File

@ -2,7 +2,7 @@ import sys
from dcim.models import Device from dcim.models import Device
from ipam.models import Service from ipam.models import Service
from startup_script_utils import load_yaml from startup_script_utils import load_yaml, split_params
from virtualization.models import VirtualMachine from virtualization.models import VirtualMachine
services = load_yaml("/opt/netbox/initializers/services.yml") services = load_yaml("/opt/netbox/initializers/services.yml")
@ -10,6 +10,7 @@ services = load_yaml("/opt/netbox/initializers/services.yml")
if services is None: if services is None:
sys.exit() sys.exit()
match_params = ["name", "device", "virtual_machine"]
optional_assocs = { optional_assocs = {
"device": (Device, "name"), "device": (Device, "name"),
"virtual_machine": (VirtualMachine, "name"), "virtual_machine": (VirtualMachine, "name"),
@ -24,6 +25,7 @@ for params in services:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
matching_params, defaults = split_params(params, match_params)
service, created = Service.objects.get_or_create(**params) service, created = Service.objects.get_or_create(**params)
if created: if created:

View File

@ -1,7 +1,12 @@
import sys import sys
from circuits.models import Provider from circuits.models import Provider
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
providers = load_yaml("/opt/netbox/initializers/providers.yml") providers = load_yaml("/opt/netbox/initializers/providers.yml")
@ -11,7 +16,8 @@ if providers is None:
for params in providers: for params in providers:
custom_field_data = pop_custom_fields(params) custom_field_data = pop_custom_fields(params)
provider, created = Provider.objects.get_or_create(**params) matching_params, defaults = split_params(params)
provider, created = Provider.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("📡 Created provider", provider.name) print("📡 Created provider", provider.name)

View File

@ -1,7 +1,12 @@
import sys import sys
from circuits.models import CircuitType from circuits.models import CircuitType
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
circuit_types = load_yaml("/opt/netbox/initializers/circuit_types.yml") circuit_types = load_yaml("/opt/netbox/initializers/circuit_types.yml")
@ -11,7 +16,8 @@ if circuit_types is None:
for params in circuit_types: for params in circuit_types:
custom_field_data = pop_custom_fields(params) custom_field_data = pop_custom_fields(params)
circuit_type, created = CircuitType.objects.get_or_create(**params) matching_params, defaults = split_params(params)
circuit_type, created = CircuitType.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("⚡ Created Circuit Type", circuit_type.name) print("⚡ Created Circuit Type", circuit_type.name)

View File

@ -1,7 +1,12 @@
import sys import sys
from circuits.models import Circuit, CircuitType, Provider from circuits.models import Circuit, CircuitType, Provider
from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values from startup_script_utils import (
load_yaml,
pop_custom_fields,
set_custom_fields_values,
split_params,
)
from tenancy.models import Tenant from tenancy.models import Tenant
circuits = load_yaml("/opt/netbox/initializers/circuits.yml") circuits = load_yaml("/opt/netbox/initializers/circuits.yml")
@ -9,8 +14,8 @@ circuits = load_yaml("/opt/netbox/initializers/circuits.yml")
if circuits is None: if circuits is None:
sys.exit() sys.exit()
match_params = ["cid", "provider", "type"]
required_assocs = {"provider": (Provider, "name"), "type": (CircuitType, "name")} required_assocs = {"provider": (Provider, "name"), "type": (CircuitType, "name")}
optional_assocs = {"tenant": (Tenant, "name")} optional_assocs = {"tenant": (Tenant, "name")}
for params in circuits: for params in circuits:
@ -29,7 +34,8 @@ for params in circuits:
params[assoc] = model.objects.get(**query) params[assoc] = model.objects.get(**query)
circuit, created = Circuit.objects.get_or_create(**params) matching_params, defaults = split_params(params, match_params)
circuit, created = Circuit.objects.get_or_create(**matching_params, defaults=defaults)
if created: if created:
print("⚡ Created Circuit", circuit.cid) print("⚡ Created Circuit", circuit.cid)

View File

@ -1,2 +1,3 @@
from .custom_fields import pop_custom_fields, set_custom_fields_values from .custom_fields import pop_custom_fields, set_custom_fields_values
from .load_yaml import load_yaml from .load_yaml import load_yaml
from .utils import split_params

View File

@ -0,0 +1,15 @@
from typing import Tuple
def split_params(params: dict, unique_params: list = None) -> Tuple[dict, dict]:
"""Split params dict into dict with matching params and a dict with default values"""
if unique_params is None:
unique_params = ["name", "slug"]
matching_params = {}
for unique_param in unique_params:
param = params.pop(unique_param, None)
if param:
matching_params[unique_param] = param
return matching_params, params