diff --git a/startup_scripts/015_object_permissions.py b/startup_scripts/015_object_permissions.py deleted file mode 100644 index 8a5ecd4..0000000 --- a/startup_scripts/015_object_permissions.py +++ /dev/null @@ -1,66 +0,0 @@ -import sys - -from django.contrib.contenttypes.models import ContentType -from startup_script_utils import load_yaml -from users.models import AdminGroup, AdminUser, ObjectPermission - -object_permissions = load_yaml("/opt/netbox/initializers/object_permissions.yml") - -if object_permissions is None: - sys.exit() - - -for permission_name, permission_details in object_permissions.items(): - - object_permission, created = ObjectPermission.objects.get_or_create( - name=permission_name, - description=permission_details["description"], - enabled=permission_details["enabled"], - actions=permission_details["actions"], - ) - - if permission_details.get("object_types", 0): - object_types = permission_details["object_types"] - - if object_types == "all": - object_permission.object_types.set(ContentType.objects.all()) - - else: - for app_label, models in object_types.items(): - if models == "all": - app_models = ContentType.objects.filter(app_label=app_label) - - for app_model in app_models: - object_permission.object_types.add(app_model.id) - else: - # There is - for model in models: - object_permission.object_types.add( - ContentType.objects.get(app_label=app_label, model=model) - ) - - print("πŸ”“ Created object permission", object_permission.name) - - if permission_details.get("groups", 0): - for groupname in permission_details["groups"]: - group = AdminGroup.objects.filter(name=groupname).first() - - if group: - object_permission.groups.add(group) - print( - " πŸ‘₯ Assigned group %s object permission of %s" - % (groupname, object_permission.name) - ) - - if permission_details.get("users", 0): - for username in permission_details["users"]: - user = AdminUser.objects.filter(username=username).first() - - if user: - object_permission.users.add(user) - print( - " πŸ‘€ Assigned user %s object permission of %s" - % (username, object_permission.name) - ) - - object_permission.save() diff --git a/startup_scripts/020_custom_fields.py b/startup_scripts/020_custom_fields.py deleted file mode 100644 index a40883c..0000000 --- a/startup_scripts/020_custom_fields.py +++ /dev/null @@ -1,67 +0,0 @@ -import sys - -from extras.models import CustomField -from startup_script_utils import load_yaml - - -def get_class_for_class_path(class_path): - import importlib - - from django.contrib.contenttypes.models import ContentType - - module_name, class_name = class_path.rsplit(".", 1) - module = importlib.import_module(module_name) - clazz = getattr(module, class_name) - return ContentType.objects.get_for_model(clazz) - - -customfields = load_yaml("/opt/netbox/initializers/custom_fields.yml") - -if customfields is None: - sys.exit() - -for cf_name, cf_details in customfields.items(): - custom_field, created = CustomField.objects.get_or_create(name=cf_name) - - if created: - if cf_details.get("default", False): - custom_field.default = cf_details["default"] - - if cf_details.get("description", False): - custom_field.description = cf_details["description"] - - if cf_details.get("label", False): - custom_field.label = cf_details["label"] - - for object_type in cf_details.get("on_objects", []): - custom_field.content_types.add(get_class_for_class_path(object_type)) - - if cf_details.get("required", False): - custom_field.required = cf_details["required"] - - if cf_details.get("type", False): - custom_field.type = cf_details["type"] - - if cf_details.get("filter_logic", False): - custom_field.filter_logic = cf_details["filter_logic"] - - if cf_details.get("weight", -1) >= 0: - 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() - - print("πŸ”§ Created custom field", cf_name) diff --git a/startup_scripts/020_object_permissions.py b/startup_scripts/020_object_permissions.py new file mode 100644 index 0000000..8a5ecd4 --- /dev/null +++ b/startup_scripts/020_object_permissions.py @@ -0,0 +1,66 @@ +import sys + +from django.contrib.contenttypes.models import ContentType +from startup_script_utils import load_yaml +from users.models import AdminGroup, AdminUser, ObjectPermission + +object_permissions = load_yaml("/opt/netbox/initializers/object_permissions.yml") + +if object_permissions is None: + sys.exit() + + +for permission_name, permission_details in object_permissions.items(): + + object_permission, created = ObjectPermission.objects.get_or_create( + name=permission_name, + description=permission_details["description"], + enabled=permission_details["enabled"], + actions=permission_details["actions"], + ) + + if permission_details.get("object_types", 0): + object_types = permission_details["object_types"] + + if object_types == "all": + object_permission.object_types.set(ContentType.objects.all()) + + else: + for app_label, models in object_types.items(): + if models == "all": + app_models = ContentType.objects.filter(app_label=app_label) + + for app_model in app_models: + object_permission.object_types.add(app_model.id) + else: + # There is + for model in models: + object_permission.object_types.add( + ContentType.objects.get(app_label=app_label, model=model) + ) + + print("πŸ”“ Created object permission", object_permission.name) + + if permission_details.get("groups", 0): + for groupname in permission_details["groups"]: + group = AdminGroup.objects.filter(name=groupname).first() + + if group: + object_permission.groups.add(group) + print( + " πŸ‘₯ Assigned group %s object permission of %s" + % (groupname, object_permission.name) + ) + + if permission_details.get("users", 0): + for username in permission_details["users"]: + user = AdminUser.objects.filter(username=username).first() + + if user: + object_permission.users.add(user) + print( + " πŸ‘€ Assigned user %s object permission of %s" + % (username, object_permission.name) + ) + + object_permission.save() diff --git a/startup_scripts/020_tags.py b/startup_scripts/020_tags.py deleted file mode 100644 index e50a000..0000000 --- a/startup_scripts/020_tags.py +++ /dev/null @@ -1,23 +0,0 @@ -import sys - -from extras.models import Tag -from startup_script_utils import load_yaml -from utilities.choices import ColorChoices - -tags = load_yaml("/opt/netbox/initializers/tags.yml") - -if tags is None: - sys.exit() - -for params in tags: - if "color" in params: - color = params.pop("color") - - for color_tpl in ColorChoices: - if color in color_tpl: - params["color"] = color_tpl[0] - - tag, created = Tag.objects.get_or_create(**params) - - if created: - print("🎨 Created Tag", tag.name) diff --git a/startup_scripts/020_tenant_groups.py b/startup_scripts/020_tenant_groups.py deleted file mode 100644 index 65cf155..0000000 --- a/startup_scripts/020_tenant_groups.py +++ /dev/null @@ -1,15 +0,0 @@ -import sys - -from startup_script_utils import load_yaml -from tenancy.models import TenantGroup - -tenant_groups = load_yaml("/opt/netbox/initializers/tenant_groups.yml") - -if tenant_groups is None: - sys.exit() - -for params in tenant_groups: - tenant_group, created = TenantGroup.objects.get_or_create(**params) - - if created: - print("πŸ”³ Created Tenant Group", tenant_group.name) diff --git a/startup_scripts/030_custom_fields.py b/startup_scripts/030_custom_fields.py new file mode 100644 index 0000000..a40883c --- /dev/null +++ b/startup_scripts/030_custom_fields.py @@ -0,0 +1,67 @@ +import sys + +from extras.models import CustomField +from startup_script_utils import load_yaml + + +def get_class_for_class_path(class_path): + import importlib + + from django.contrib.contenttypes.models import ContentType + + module_name, class_name = class_path.rsplit(".", 1) + module = importlib.import_module(module_name) + clazz = getattr(module, class_name) + return ContentType.objects.get_for_model(clazz) + + +customfields = load_yaml("/opt/netbox/initializers/custom_fields.yml") + +if customfields is None: + sys.exit() + +for cf_name, cf_details in customfields.items(): + custom_field, created = CustomField.objects.get_or_create(name=cf_name) + + if created: + if cf_details.get("default", False): + custom_field.default = cf_details["default"] + + if cf_details.get("description", False): + custom_field.description = cf_details["description"] + + if cf_details.get("label", False): + custom_field.label = cf_details["label"] + + for object_type in cf_details.get("on_objects", []): + custom_field.content_types.add(get_class_for_class_path(object_type)) + + if cf_details.get("required", False): + custom_field.required = cf_details["required"] + + if cf_details.get("type", False): + custom_field.type = cf_details["type"] + + if cf_details.get("filter_logic", False): + custom_field.filter_logic = cf_details["filter_logic"] + + if cf_details.get("weight", -1) >= 0: + 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() + + print("πŸ”§ Created custom field", cf_name) diff --git a/startup_scripts/030_regions.py b/startup_scripts/030_regions.py deleted file mode 100644 index 9d5c91f..0000000 --- a/startup_scripts/030_regions.py +++ /dev/null @@ -1,25 +0,0 @@ -import sys - -from dcim.models import Region -from startup_script_utils import load_yaml - -regions = load_yaml("/opt/netbox/initializers/regions.yml") - -if regions is None: - sys.exit() - -optional_assocs = {"parent": (Region, "name")} - -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) diff --git a/startup_scripts/030_tenants.py b/startup_scripts/030_tenants.py deleted file mode 100644 index 7b1a629..0000000 --- a/startup_scripts/030_tenants.py +++ /dev/null @@ -1,28 +0,0 @@ -import sys - -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from tenancy.models import Tenant, TenantGroup - -tenants = load_yaml("/opt/netbox/initializers/tenants.yml") - -if tenants is None: - sys.exit() - -optional_assocs = {"group": (TenantGroup, "name")} - -for params in tenants: - custom_field_data = pop_custom_fields(params) - - for assoc, details in optional_assocs.items(): - if assoc in params: - model, field = details - query = {field: params.pop(assoc)} - - params[assoc] = model.objects.get(**query) - - tenant, created = Tenant.objects.get_or_create(**params) - - if created: - set_custom_fields_values(tenant, custom_field_data) - - print("πŸ‘©β€πŸ’» Created Tenant", tenant.name) diff --git a/startup_scripts/040_custom_links.py b/startup_scripts/040_custom_links.py new file mode 100644 index 0000000..40144bd --- /dev/null +++ b/startup_scripts/040_custom_links.py @@ -0,0 +1,33 @@ +import sys + +from django.contrib.contenttypes.models import ContentType +from extras.models import CustomLink +from startup_script_utils import load_yaml + +custom_links = load_yaml("/opt/netbox/initializers/custom_links.yml") + +if custom_links is None: + sys.exit() + + +def get_content_type_id(content_type): + try: + return ContentType.objects.get(model=content_type).id + except ContentType.DoesNotExist: + pass + + +for link in custom_links: + content_type = link.pop("content_type") + link["content_type_id"] = get_content_type_id(content_type) + if link["content_type_id"] is None: + print( + "⚠️ Unable to create Custom Link '{0}': The content_type '{1}' is unknown".format( + link.get("name"), content_type + ) + ) + continue + + custom_link, created = CustomLink.objects.get_or_create(**link) + if created: + print("πŸ”— Created Custom Link '{0}'".format(custom_link.name)) diff --git a/startup_scripts/040_sites.py b/startup_scripts/040_sites.py deleted file mode 100644 index f785139..0000000 --- a/startup_scripts/040_sites.py +++ /dev/null @@ -1,29 +0,0 @@ -import sys - -from dcim.models import Region, Site -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from tenancy.models import Tenant - -sites = load_yaml("/opt/netbox/initializers/sites.yml") - -if sites is None: - sys.exit() - -optional_assocs = {"region": (Region, "name"), "tenant": (Tenant, "name")} - -for params in sites: - custom_field_data = pop_custom_fields(params) - - 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: - set_custom_fields_values(site, custom_field_data) - - print("πŸ“ Created site", site.name) diff --git a/startup_scripts/050_manufacturers.py b/startup_scripts/050_manufacturers.py deleted file mode 100644 index d11b440..0000000 --- a/startup_scripts/050_manufacturers.py +++ /dev/null @@ -1,15 +0,0 @@ -import sys - -from dcim.models import Manufacturer -from startup_script_utils import load_yaml - -manufacturers = load_yaml("/opt/netbox/initializers/manufacturers.yml") - -if manufacturers is None: - sys.exit() - -for params in manufacturers: - manufacturer, created = Manufacturer.objects.get_or_create(**params) - - if created: - print("🏭 Created Manufacturer", manufacturer.name) diff --git a/startup_scripts/050_tags.py b/startup_scripts/050_tags.py new file mode 100644 index 0000000..e50a000 --- /dev/null +++ b/startup_scripts/050_tags.py @@ -0,0 +1,23 @@ +import sys + +from extras.models import Tag +from startup_script_utils import load_yaml +from utilities.choices import ColorChoices + +tags = load_yaml("/opt/netbox/initializers/tags.yml") + +if tags is None: + sys.exit() + +for params in tags: + if "color" in params: + color = params.pop("color") + + for color_tpl in ColorChoices: + if color in color_tpl: + params["color"] = color_tpl[0] + + tag, created = Tag.objects.get_or_create(**params) + + if created: + print("🎨 Created Tag", tag.name) diff --git a/startup_scripts/060_device_types.py b/startup_scripts/060_device_types.py deleted file mode 100644 index 0d3050b..0000000 --- a/startup_scripts/060_device_types.py +++ /dev/null @@ -1,37 +0,0 @@ -import sys - -from dcim.models import DeviceType, Manufacturer, Region -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from tenancy.models import Tenant - -device_types = load_yaml("/opt/netbox/initializers/device_types.yml") - -if device_types is None: - sys.exit() - -required_assocs = {"manufacturer": (Manufacturer, "name")} - -optional_assocs = {"region": (Region, "name"), "tenant": (Tenant, "name")} - -for params in device_types: - custom_field_data = pop_custom_fields(params) - - 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: - set_custom_fields_values(device_type, custom_field_data) - - print("πŸ”‘ Created device type", device_type.manufacturer, device_type.model) diff --git a/startup_scripts/060_webhooks.py b/startup_scripts/060_webhooks.py new file mode 100644 index 0000000..8787f5f --- /dev/null +++ b/startup_scripts/060_webhooks.py @@ -0,0 +1,34 @@ +import sys + +from django.contrib.contenttypes.models import ContentType +from extras.models import Webhook +from startup_script_utils import load_yaml + +webhooks = load_yaml("/opt/netbox/initializers/webhooks.yml") + +if webhooks is None: + sys.exit() + + +def get_content_type_id(hook_name, content_type): + try: + return ContentType.objects.get(model=content_type).id + except ContentType.DoesNotExist as ex: + print("⚠️ Webhook '{0}': The object_type '{1}' is unknown.".format(hook_name, content_type)) + raise ex + + +for hook in webhooks: + obj_types = hook.pop("object_types") + + try: + obj_type_ids = [get_content_type_id(hook["name"], obj) for obj in obj_types] + except ContentType.DoesNotExist: + continue + + webhook, created = Webhook.objects.get_or_create(**hook) + if created: + webhook.content_types.set(obj_type_ids) + webhook.save() + + print("πŸͺ Created Webhook {0}".format(webhook.name)) diff --git a/startup_scripts/070_rack_roles.py b/startup_scripts/070_rack_roles.py deleted file mode 100644 index 5850405..0000000 --- a/startup_scripts/070_rack_roles.py +++ /dev/null @@ -1,23 +0,0 @@ -import sys - -from dcim.models import RackRole -from startup_script_utils import load_yaml -from utilities.choices import ColorChoices - -rack_roles = load_yaml("/opt/netbox/initializers/rack_roles.yml") - -if rack_roles is None: - sys.exit() - -for params in rack_roles: - if "color" in params: - color = params.pop("color") - - for color_tpl in ColorChoices: - 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) diff --git a/startup_scripts/070_tenant_groups.py b/startup_scripts/070_tenant_groups.py new file mode 100644 index 0000000..65cf155 --- /dev/null +++ b/startup_scripts/070_tenant_groups.py @@ -0,0 +1,15 @@ +import sys + +from startup_script_utils import load_yaml +from tenancy.models import TenantGroup + +tenant_groups = load_yaml("/opt/netbox/initializers/tenant_groups.yml") + +if tenant_groups is None: + sys.exit() + +for params in tenant_groups: + tenant_group, created = TenantGroup.objects.get_or_create(**params) + + if created: + print("πŸ”³ Created Tenant Group", tenant_group.name) diff --git a/startup_scripts/075_locations.py b/startup_scripts/075_locations.py deleted file mode 100644 index d8a2c5a..0000000 --- a/startup_scripts/075_locations.py +++ /dev/null @@ -1,23 +0,0 @@ -import sys - -from dcim.models import Location, Site -from startup_script_utils import load_yaml - -rack_groups = load_yaml("/opt/netbox/initializers/locations.yml") - -if rack_groups is None: - sys.exit() - -required_assocs = {"site": (Site, "name")} - -for params in rack_groups: - - for assoc, details in required_assocs.items(): - model, field = details - query = {field: params.pop(assoc)} - params[assoc] = model.objects.get(**query) - - location, created = Location.objects.get_or_create(**params) - - if created: - print("🎨 Created location", location.name) diff --git a/startup_scripts/080_racks.py b/startup_scripts/080_racks.py deleted file mode 100644 index b2cfc80..0000000 --- a/startup_scripts/080_racks.py +++ /dev/null @@ -1,41 +0,0 @@ -import sys - -from dcim.models import Location, Rack, RackRole, Site -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from tenancy.models import Tenant - -racks = load_yaml("/opt/netbox/initializers/racks.yml") - -if racks is None: - sys.exit() - -required_assocs = {"site": (Site, "name")} - -optional_assocs = { - "role": (RackRole, "name"), - "tenant": (Tenant, "name"), - "location": (Location, "name"), -} - -for params in racks: - custom_field_data = pop_custom_fields(params) - - 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) - - rack, created = Rack.objects.get_or_create(**params) - - if created: - set_custom_fields_values(rack, custom_field_data) - - print("πŸ”³ Created rack", rack.site, rack.name) diff --git a/startup_scripts/080_tenants.py b/startup_scripts/080_tenants.py new file mode 100644 index 0000000..7b1a629 --- /dev/null +++ b/startup_scripts/080_tenants.py @@ -0,0 +1,28 @@ +import sys + +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values +from tenancy.models import Tenant, TenantGroup + +tenants = load_yaml("/opt/netbox/initializers/tenants.yml") + +if tenants is None: + sys.exit() + +optional_assocs = {"group": (TenantGroup, "name")} + +for params in tenants: + custom_field_data = pop_custom_fields(params) + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = {field: params.pop(assoc)} + + params[assoc] = model.objects.get(**query) + + tenant, created = Tenant.objects.get_or_create(**params) + + if created: + set_custom_fields_values(tenant, custom_field_data) + + print("πŸ‘©β€πŸ’» Created Tenant", tenant.name) diff --git a/startup_scripts/090_device_roles.py b/startup_scripts/090_device_roles.py deleted file mode 100644 index 635acff..0000000 --- a/startup_scripts/090_device_roles.py +++ /dev/null @@ -1,24 +0,0 @@ -import sys - -from dcim.models import DeviceRole -from startup_script_utils import load_yaml -from utilities.choices import ColorChoices - -device_roles = load_yaml("/opt/netbox/initializers/device_roles.yml") - -if device_roles is None: - sys.exit() - -for params in device_roles: - - if "color" in params: - color = params.pop("color") - - for color_tpl in ColorChoices: - 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) diff --git a/startup_scripts/090_regions.py b/startup_scripts/090_regions.py new file mode 100644 index 0000000..9d5c91f --- /dev/null +++ b/startup_scripts/090_regions.py @@ -0,0 +1,25 @@ +import sys + +from dcim.models import Region +from startup_script_utils import load_yaml + +regions = load_yaml("/opt/netbox/initializers/regions.yml") + +if regions is None: + sys.exit() + +optional_assocs = {"parent": (Region, "name")} + +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) diff --git a/startup_scripts/100_platforms.py b/startup_scripts/100_platforms.py deleted file mode 100644 index 633b89f..0000000 --- a/startup_scripts/100_platforms.py +++ /dev/null @@ -1,27 +0,0 @@ -import sys - -from dcim.models import Manufacturer, Platform -from startup_script_utils import load_yaml - -platforms = load_yaml("/opt/netbox/initializers/platforms.yml") - -if platforms is None: - sys.exit() - -optional_assocs = { - "manufacturer": (Manufacturer, "name"), -} - -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) diff --git a/startup_scripts/110_sites.py b/startup_scripts/110_sites.py new file mode 100644 index 0000000..f785139 --- /dev/null +++ b/startup_scripts/110_sites.py @@ -0,0 +1,29 @@ +import sys + +from dcim.models import Region, Site +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values +from tenancy.models import Tenant + +sites = load_yaml("/opt/netbox/initializers/sites.yml") + +if sites is None: + sys.exit() + +optional_assocs = {"region": (Region, "name"), "tenant": (Tenant, "name")} + +for params in sites: + custom_field_data = pop_custom_fields(params) + + 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: + set_custom_fields_values(site, custom_field_data) + + print("πŸ“ Created site", site.name) diff --git a/startup_scripts/120_locations.py b/startup_scripts/120_locations.py new file mode 100644 index 0000000..d8a2c5a --- /dev/null +++ b/startup_scripts/120_locations.py @@ -0,0 +1,23 @@ +import sys + +from dcim.models import Location, Site +from startup_script_utils import load_yaml + +rack_groups = load_yaml("/opt/netbox/initializers/locations.yml") + +if rack_groups is None: + sys.exit() + +required_assocs = {"site": (Site, "name")} + +for params in rack_groups: + + for assoc, details in required_assocs.items(): + model, field = details + query = {field: params.pop(assoc)} + params[assoc] = model.objects.get(**query) + + location, created = Location.objects.get_or_create(**params) + + if created: + print("🎨 Created location", location.name) diff --git a/startup_scripts/130_cluster_types.py b/startup_scripts/130_cluster_types.py deleted file mode 100644 index 9f361b1..0000000 --- a/startup_scripts/130_cluster_types.py +++ /dev/null @@ -1,15 +0,0 @@ -import sys - -from startup_script_utils import load_yaml -from virtualization.models import ClusterType - -cluster_types = load_yaml("/opt/netbox/initializers/cluster_types.yml") - -if cluster_types is None: - sys.exit() - -for params in cluster_types: - cluster_type, created = ClusterType.objects.get_or_create(**params) - - if created: - print("🧰 Created Cluster Type", cluster_type.name) diff --git a/startup_scripts/130_rack_roles.py b/startup_scripts/130_rack_roles.py new file mode 100644 index 0000000..5850405 --- /dev/null +++ b/startup_scripts/130_rack_roles.py @@ -0,0 +1,23 @@ +import sys + +from dcim.models import RackRole +from startup_script_utils import load_yaml +from utilities.choices import ColorChoices + +rack_roles = load_yaml("/opt/netbox/initializers/rack_roles.yml") + +if rack_roles is None: + sys.exit() + +for params in rack_roles: + if "color" in params: + color = params.pop("color") + + for color_tpl in ColorChoices: + 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) diff --git a/startup_scripts/135_cluster_groups.py b/startup_scripts/135_cluster_groups.py deleted file mode 100644 index fedd292..0000000 --- a/startup_scripts/135_cluster_groups.py +++ /dev/null @@ -1,15 +0,0 @@ -import sys - -from startup_script_utils import load_yaml -from virtualization.models import ClusterGroup - -cluster_groups = load_yaml("/opt/netbox/initializers/cluster_groups.yml") - -if cluster_groups is None: - sys.exit() - -for params in cluster_groups: - cluster_group, created = ClusterGroup.objects.get_or_create(**params) - - if created: - print("πŸ—„οΈ Created Cluster Group", cluster_group.name) diff --git a/startup_scripts/135_clusters.py b/startup_scripts/135_clusters.py deleted file mode 100644 index 2748f20..0000000 --- a/startup_scripts/135_clusters.py +++ /dev/null @@ -1,42 +0,0 @@ -import sys - -from dcim.models import Site -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from tenancy.models import Tenant -from virtualization.models import Cluster, ClusterGroup, ClusterType - -clusters = load_yaml("/opt/netbox/initializers/clusters.yml") - -if clusters is None: - sys.exit() - -required_assocs = {"type": (ClusterType, "name")} - -optional_assocs = { - "site": (Site, "name"), - "group": (ClusterGroup, "name"), - "tenant": (Tenant, "name"), -} - -for params in clusters: - custom_field_data = pop_custom_fields(params) - - for assoc, details in required_assocs.items(): - model, field = details - query = {field: params.pop(assoc)} - - params[assoc] = model.objects.get(**query) - - for assoc, details in optional_assocs.items(): - if assoc in params: - model, field = details - query = {field: params.pop(assoc)} - - params[assoc] = model.objects.get(**query) - - cluster, created = Cluster.objects.get_or_create(**params) - - if created: - set_custom_fields_values(cluster, custom_field_data) - - print("πŸ—„οΈ Created cluster", cluster.name) diff --git a/startup_scripts/140_clusters.py b/startup_scripts/140_clusters.py deleted file mode 100644 index 2748f20..0000000 --- a/startup_scripts/140_clusters.py +++ /dev/null @@ -1,42 +0,0 @@ -import sys - -from dcim.models import Site -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from tenancy.models import Tenant -from virtualization.models import Cluster, ClusterGroup, ClusterType - -clusters = load_yaml("/opt/netbox/initializers/clusters.yml") - -if clusters is None: - sys.exit() - -required_assocs = {"type": (ClusterType, "name")} - -optional_assocs = { - "site": (Site, "name"), - "group": (ClusterGroup, "name"), - "tenant": (Tenant, "name"), -} - -for params in clusters: - custom_field_data = pop_custom_fields(params) - - for assoc, details in required_assocs.items(): - model, field = details - query = {field: params.pop(assoc)} - - params[assoc] = model.objects.get(**query) - - for assoc, details in optional_assocs.items(): - if assoc in params: - model, field = details - query = {field: params.pop(assoc)} - - params[assoc] = model.objects.get(**query) - - cluster, created = Cluster.objects.get_or_create(**params) - - if created: - set_custom_fields_values(cluster, custom_field_data) - - print("πŸ—„οΈ Created cluster", cluster.name) diff --git a/startup_scripts/140_devices.py b/startup_scripts/140_devices.py deleted file mode 100644 index 423b7c9..0000000 --- a/startup_scripts/140_devices.py +++ /dev/null @@ -1,52 +0,0 @@ -import sys - -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 tenancy.models import Tenant -from virtualization.models import Cluster - -devices = load_yaml("/opt/netbox/initializers/devices.yml") - -if devices is None: - sys.exit() - -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"), - "location": (Location, "name"), -} - -for params in devices: - custom_field_data = pop_custom_fields(params) - - # primary ips are handled later in `270_primary_ips.py` - params.pop("primary_ip4", None) - params.pop("primary_ip6", 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, created = Device.objects.get_or_create(**params) - - if created: - set_custom_fields_values(device, custom_field_data) - - print("πŸ–₯️ Created device", device.name) diff --git a/startup_scripts/140_racks.py b/startup_scripts/140_racks.py new file mode 100644 index 0000000..b2cfc80 --- /dev/null +++ b/startup_scripts/140_racks.py @@ -0,0 +1,41 @@ +import sys + +from dcim.models import Location, Rack, RackRole, Site +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values +from tenancy.models import Tenant + +racks = load_yaml("/opt/netbox/initializers/racks.yml") + +if racks is None: + sys.exit() + +required_assocs = {"site": (Site, "name")} + +optional_assocs = { + "role": (RackRole, "name"), + "tenant": (Tenant, "name"), + "location": (Location, "name"), +} + +for params in racks: + custom_field_data = pop_custom_fields(params) + + 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) + + rack, created = Rack.objects.get_or_create(**params) + + if created: + set_custom_fields_values(rack, custom_field_data) + + print("πŸ”³ Created rack", rack.site, rack.name) diff --git a/startup_scripts/150_power_panels.py b/startup_scripts/150_power_panels.py new file mode 100644 index 0000000..8542435 --- /dev/null +++ b/startup_scripts/150_power_panels.py @@ -0,0 +1,36 @@ +import sys + +from dcim.models import Location, PowerPanel, Site +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values + +power_panels = load_yaml("/opt/netbox/initializers/power_panels.yml") + +if power_panels is None: + sys.exit() + +required_assocs = {"site": (Site, "name")} + +optional_assocs = {"location": (Location, "name")} + +for params in power_panels: + custom_field_data = pop_custom_fields(params) + + 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) + + power_panel, created = PowerPanel.objects.get_or_create(**params) + + if created: + set_custom_fields_values(power_panel, custom_field_data) + + print("⚑ Created Power Panel", power_panel.site, power_panel.name) diff --git a/startup_scripts/150_rirs.py b/startup_scripts/150_rirs.py deleted file mode 100644 index 0e0df20..0000000 --- a/startup_scripts/150_rirs.py +++ /dev/null @@ -1,15 +0,0 @@ -import sys - -from ipam.models import RIR -from startup_script_utils import load_yaml - -rirs = load_yaml("/opt/netbox/initializers/rirs.yml") - -if rirs is None: - sys.exit() - -for params in rirs: - rir, created = RIR.objects.get_or_create(**params) - - if created: - print("πŸ—ΊοΈ Created RIR", rir.name) diff --git a/startup_scripts/155_asns.py b/startup_scripts/155_asns.py deleted file mode 100644 index 893f3ba..0000000 --- a/startup_scripts/155_asns.py +++ /dev/null @@ -1,33 +0,0 @@ -import sys - -from ipam.models import ASN, RIR -from startup_script_utils import load_yaml -from tenancy.models import Tenant - -asns = load_yaml("/opt/netbox/initializers/asns.yml") - -if asns is None: - sys.exit() - -required_assocs = {"rir": (RIR, "name")} - -optional_assocs = {"tenant": (Tenant, "name")} - -for params in asns: - 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) - - asn, created = ASN.objects.get_or_create(**params) - - if created: - print(f"πŸ”‘ Created ASN {asn.asn}") diff --git a/startup_scripts/160_aggregates.py b/startup_scripts/160_aggregates.py deleted file mode 100644 index c638e6f..0000000 --- a/startup_scripts/160_aggregates.py +++ /dev/null @@ -1,42 +0,0 @@ -import sys - -from ipam.models import RIR, Aggregate -from netaddr import IPNetwork -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from tenancy.models import Tenant - -aggregates = load_yaml("/opt/netbox/initializers/aggregates.yml") - -if aggregates is None: - sys.exit() - -required_assocs = {"rir": (RIR, "name")} - -optional_assocs = { - "tenant": (Tenant, "name"), -} - -for params in aggregates: - custom_field_data = pop_custom_fields(params) - - params["prefix"] = IPNetwork(params["prefix"]) - - for assoc, details in required_assocs.items(): - model, field = details - query = {field: params.pop(assoc)} - - params[assoc] = model.objects.get(**query) - - 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) - - aggregate, created = Aggregate.objects.get_or_create(**params) - - if created: - set_custom_fields_values(aggregate, custom_field_data) - - print("πŸ—žοΈ Created Aggregate", aggregate.prefix) diff --git a/startup_scripts/160_power_feeds.py b/startup_scripts/160_power_feeds.py new file mode 100644 index 0000000..f5aa5b5 --- /dev/null +++ b/startup_scripts/160_power_feeds.py @@ -0,0 +1,36 @@ +import sys + +from dcim.models import PowerFeed, PowerPanel, Rack +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values + +power_feeds = load_yaml("/opt/netbox/initializers/power_feeds.yml") + +if power_feeds is None: + sys.exit() + +required_assocs = {"power_panel": (PowerPanel, "name")} + +optional_assocs = {"rack": (Rack, "name")} + +for params in power_feeds: + custom_field_data = pop_custom_fields(params) + + 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) + + power_feed, created = PowerFeed.objects.get_or_create(**params) + + if created: + set_custom_fields_values(power_feed, custom_field_data) + + print("⚑ Created Power Feed", power_feed.name) diff --git a/startup_scripts/165_cluster_groups.py b/startup_scripts/165_cluster_groups.py deleted file mode 100644 index fedd292..0000000 --- a/startup_scripts/165_cluster_groups.py +++ /dev/null @@ -1,15 +0,0 @@ -import sys - -from startup_script_utils import load_yaml -from virtualization.models import ClusterGroup - -cluster_groups = load_yaml("/opt/netbox/initializers/cluster_groups.yml") - -if cluster_groups is None: - sys.exit() - -for params in cluster_groups: - cluster_group, created = ClusterGroup.objects.get_or_create(**params) - - if created: - print("πŸ—„οΈ Created Cluster Group", cluster_group.name) diff --git a/startup_scripts/170_manufacturers.py b/startup_scripts/170_manufacturers.py new file mode 100644 index 0000000..d11b440 --- /dev/null +++ b/startup_scripts/170_manufacturers.py @@ -0,0 +1,15 @@ +import sys + +from dcim.models import Manufacturer +from startup_script_utils import load_yaml + +manufacturers = load_yaml("/opt/netbox/initializers/manufacturers.yml") + +if manufacturers is None: + sys.exit() + +for params in manufacturers: + manufacturer, created = Manufacturer.objects.get_or_create(**params) + + if created: + print("🏭 Created Manufacturer", manufacturer.name) diff --git a/startup_scripts/175_route_targets.py b/startup_scripts/175_route_targets.py deleted file mode 100644 index e1c8221..0000000 --- a/startup_scripts/175_route_targets.py +++ /dev/null @@ -1,29 +0,0 @@ -import sys - -from ipam.models import RouteTarget -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from tenancy.models import Tenant - -route_targets = load_yaml("/opt/netbox/initializers/route_targets.yml") - -if route_targets is None: - sys.exit() - -optional_assocs = {"tenant": (Tenant, "name")} - -for params in route_targets: - custom_field_data = pop_custom_fields(params) - - 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) - - route_target, created = RouteTarget.objects.get_or_create(**params) - - if created: - set_custom_fields_values(route_target, custom_field_data) - - print("🎯 Created Route Target", route_target.name) diff --git a/startup_scripts/180_device_roles.py b/startup_scripts/180_device_roles.py new file mode 100644 index 0000000..635acff --- /dev/null +++ b/startup_scripts/180_device_roles.py @@ -0,0 +1,24 @@ +import sys + +from dcim.models import DeviceRole +from startup_script_utils import load_yaml +from utilities.choices import ColorChoices + +device_roles = load_yaml("/opt/netbox/initializers/device_roles.yml") + +if device_roles is None: + sys.exit() + +for params in device_roles: + + if "color" in params: + color = params.pop("color") + + for color_tpl in ColorChoices: + 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) diff --git a/startup_scripts/180_vrfs.py b/startup_scripts/180_vrfs.py deleted file mode 100644 index a67c8c8..0000000 --- a/startup_scripts/180_vrfs.py +++ /dev/null @@ -1,29 +0,0 @@ -import sys - -from ipam.models import VRF -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from tenancy.models import Tenant - -vrfs = load_yaml("/opt/netbox/initializers/vrfs.yml") - -if vrfs is None: - sys.exit() - -optional_assocs = {"tenant": (Tenant, "name")} - -for params in vrfs: - custom_field_data = pop_custom_fields(params) - - for assoc, details in optional_assocs.items(): - if assoc in params: - model, field = details - query = {field: params.pop(assoc)} - - params[assoc] = model.objects.get(**query) - - vrf, created = VRF.objects.get_or_create(**params) - - if created: - set_custom_fields_values(vrf, custom_field_data) - - print("πŸ“¦ Created VRF", vrf.name) diff --git a/startup_scripts/190_device_types.py b/startup_scripts/190_device_types.py new file mode 100644 index 0000000..0d3050b --- /dev/null +++ b/startup_scripts/190_device_types.py @@ -0,0 +1,37 @@ +import sys + +from dcim.models import DeviceType, Manufacturer, Region +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values +from tenancy.models import Tenant + +device_types = load_yaml("/opt/netbox/initializers/device_types.yml") + +if device_types is None: + sys.exit() + +required_assocs = {"manufacturer": (Manufacturer, "name")} + +optional_assocs = {"region": (Region, "name"), "tenant": (Tenant, "name")} + +for params in device_types: + custom_field_data = pop_custom_fields(params) + + 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: + set_custom_fields_values(device_type, custom_field_data) + + print("πŸ”‘ Created device type", device_type.manufacturer, device_type.model) diff --git a/startup_scripts/190_prefix_vlan_roles.py b/startup_scripts/190_prefix_vlan_roles.py deleted file mode 100644 index ec359fb..0000000 --- a/startup_scripts/190_prefix_vlan_roles.py +++ /dev/null @@ -1,15 +0,0 @@ -import sys - -from ipam.models import Role -from startup_script_utils import load_yaml - -roles = load_yaml("/opt/netbox/initializers/prefix_vlan_roles.yml") - -if roles is None: - sys.exit() - -for params in roles: - role, created = Role.objects.get_or_create(**params) - - if created: - print("⛹️‍ Created Prefix/VLAN Role", role.name) diff --git a/startup_scripts/200_devices.py b/startup_scripts/200_devices.py new file mode 100644 index 0000000..423b7c9 --- /dev/null +++ b/startup_scripts/200_devices.py @@ -0,0 +1,52 @@ +import sys + +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 tenancy.models import Tenant +from virtualization.models import Cluster + +devices = load_yaml("/opt/netbox/initializers/devices.yml") + +if devices is None: + sys.exit() + +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"), + "location": (Location, "name"), +} + +for params in devices: + custom_field_data = pop_custom_fields(params) + + # primary ips are handled later in `270_primary_ips.py` + params.pop("primary_ip4", None) + params.pop("primary_ip6", 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, created = Device.objects.get_or_create(**params) + + if created: + set_custom_fields_values(device, custom_field_data) + + print("πŸ–₯️ Created device", device.name) diff --git a/startup_scripts/200_vlan_groups.py b/startup_scripts/200_vlan_groups.py deleted file mode 100644 index 2a4a33d..0000000 --- a/startup_scripts/200_vlan_groups.py +++ /dev/null @@ -1,40 +0,0 @@ -import sys - -from django.contrib.contenttypes.models import ContentType -from ipam.models import VLANGroup -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values - -vlan_groups = load_yaml("/opt/netbox/initializers/vlan_groups.yml") - -if vlan_groups is None: - sys.exit() - -optional_assocs = {"scope": (None, "name")} - -for params in vlan_groups: - custom_field_data = pop_custom_fields(params) - - for assoc, details in optional_assocs.items(): - if assoc in params: - model, field = details - query = {field: params.pop(assoc)} - # Get model from Contenttype - scope_type = params.pop("scope_type", None) - if not scope_type: - print(f"VLAN Group '{params['name']}': scope_type is missing from VLAN Group") - continue - app_label, model = str(scope_type).split(".") - ct = ContentType.objects.filter(app_label=app_label, model=model).first() - if not ct: - print( - f"VLAN Group '{params['name']}': ContentType for " - + f"app_label = '{app_label}' and model = '{model}' not found" - ) - continue - params["scope_id"] = ct.model_class().objects.get(**query).id - vlan_group, created = VLANGroup.objects.get_or_create(**params) - - if created: - set_custom_fields_values(vlan_group, custom_field_data) - - print("🏘️ Created VLAN Group", vlan_group.name) diff --git a/startup_scripts/210_dcim_interfaces.py b/startup_scripts/210_dcim_interfaces.py new file mode 100644 index 0000000..a802628 --- /dev/null +++ b/startup_scripts/210_dcim_interfaces.py @@ -0,0 +1,27 @@ +import sys + +from dcim.models import Device, Interface +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values + +interfaces = load_yaml("/opt/netbox/initializers/dcim_interfaces.yml") + +if interfaces is None: + sys.exit() + +required_assocs = {"device": (Device, "name")} + +for params in interfaces: + custom_field_data = pop_custom_fields(params) + + for assoc, details in required_assocs.items(): + model, field = details + query = {field: params.pop(assoc)} + + params[assoc] = model.objects.get(**query) + + interface, created = Interface.objects.get_or_create(**params) + + if created: + set_custom_fields_values(interface, custom_field_data) + + print("🧷 Created interface", interface.name, interface.device.name) diff --git a/startup_scripts/210_vlans.py b/startup_scripts/210_vlans.py deleted file mode 100644 index e8ebb94..0000000 --- a/startup_scripts/210_vlans.py +++ /dev/null @@ -1,36 +0,0 @@ -import sys - -from dcim.models import Site -from ipam.models import VLAN, Role, VLANGroup -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from tenancy.models import Tenant, TenantGroup - -vlans = load_yaml("/opt/netbox/initializers/vlans.yml") - -if vlans is None: - sys.exit() - -optional_assocs = { - "site": (Site, "name"), - "tenant": (Tenant, "name"), - "tenant_group": (TenantGroup, "name"), - "group": (VLANGroup, "name"), - "role": (Role, "name"), -} - -for params in vlans: - custom_field_data = pop_custom_fields(params) - - for assoc, details in optional_assocs.items(): - if assoc in params: - model, field = details - query = {field: params.pop(assoc)} - - params[assoc] = model.objects.get(**query) - - vlan, created = VLAN.objects.get_or_create(**params) - - if created: - set_custom_fields_values(vlan, custom_field_data) - - print("🏠 Created VLAN", vlan.name) diff --git a/startup_scripts/220_platforms.py b/startup_scripts/220_platforms.py new file mode 100644 index 0000000..633b89f --- /dev/null +++ b/startup_scripts/220_platforms.py @@ -0,0 +1,27 @@ +import sys + +from dcim.models import Manufacturer, Platform +from startup_script_utils import load_yaml + +platforms = load_yaml("/opt/netbox/initializers/platforms.yml") + +if platforms is None: + sys.exit() + +optional_assocs = { + "manufacturer": (Manufacturer, "name"), +} + +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) diff --git a/startup_scripts/220_prefixes.py b/startup_scripts/220_prefixes.py deleted file mode 100644 index 4e2b0d0..0000000 --- a/startup_scripts/220_prefixes.py +++ /dev/null @@ -1,39 +0,0 @@ -import sys - -from dcim.models import Site -from ipam.models import VLAN, VRF, Prefix, Role -from netaddr import IPNetwork -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from tenancy.models import Tenant, TenantGroup - -prefixes = load_yaml("/opt/netbox/initializers/prefixes.yml") - -if prefixes is None: - sys.exit() - -optional_assocs = { - "site": (Site, "name"), - "tenant": (Tenant, "name"), - "tenant_group": (TenantGroup, "name"), - "vlan": (VLAN, "name"), - "role": (Role, "name"), - "vrf": (VRF, "name"), -} - -for params in prefixes: - custom_field_data = pop_custom_fields(params) - - params["prefix"] = IPNetwork(params["prefix"]) - - for assoc, details in optional_assocs.items(): - if assoc in params: - model, field = details - query = {field: params.pop(assoc)} - params[assoc] = model.objects.get(**query) - - prefix, created = Prefix.objects.get_or_create(**params) - - if created: - set_custom_fields_values(prefix, custom_field_data) - - print("πŸ“Œ Created Prefix", prefix.prefix) diff --git a/startup_scripts/230_route_targets.py b/startup_scripts/230_route_targets.py new file mode 100644 index 0000000..e1c8221 --- /dev/null +++ b/startup_scripts/230_route_targets.py @@ -0,0 +1,29 @@ +import sys + +from ipam.models import RouteTarget +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values +from tenancy.models import Tenant + +route_targets = load_yaml("/opt/netbox/initializers/route_targets.yml") + +if route_targets is None: + sys.exit() + +optional_assocs = {"tenant": (Tenant, "name")} + +for params in route_targets: + custom_field_data = pop_custom_fields(params) + + 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) + + route_target, created = RouteTarget.objects.get_or_create(**params) + + if created: + set_custom_fields_values(route_target, custom_field_data) + + print("🎯 Created Route Target", route_target.name) diff --git a/startup_scripts/230_virtual_machines.py b/startup_scripts/230_virtual_machines.py deleted file mode 100644 index 2e3f428..0000000 --- a/startup_scripts/230_virtual_machines.py +++ /dev/null @@ -1,46 +0,0 @@ -import sys - -from dcim.models import DeviceRole, Platform -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from tenancy.models import Tenant -from virtualization.models import Cluster, VirtualMachine - -virtual_machines = load_yaml("/opt/netbox/initializers/virtual_machines.yml") - -if virtual_machines is None: - sys.exit() - -required_assocs = {"cluster": (Cluster, "name")} - -optional_assocs = { - "tenant": (Tenant, "name"), - "platform": (Platform, "name"), - "role": (DeviceRole, "name"), -} - -for params in virtual_machines: - custom_field_data = pop_custom_fields(params) - - # primary ips are handled later in `270_primary_ips.py` - params.pop("primary_ip4", None) - params.pop("primary_ip6", 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) - - virtual_machine, created = VirtualMachine.objects.get_or_create(**params) - - if created: - set_custom_fields_values(virtual_machine, custom_field_data) - - print("πŸ–₯️ Created virtual machine", virtual_machine.name) diff --git a/startup_scripts/240_virtualization_interfaces.py b/startup_scripts/240_virtualization_interfaces.py deleted file mode 100644 index 6ee6347..0000000 --- a/startup_scripts/240_virtualization_interfaces.py +++ /dev/null @@ -1,27 +0,0 @@ -import sys - -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from virtualization.models import VirtualMachine, VMInterface - -interfaces = load_yaml("/opt/netbox/initializers/virtualization_interfaces.yml") - -if interfaces is None: - sys.exit() - -required_assocs = {"virtual_machine": (VirtualMachine, "name")} - -for params in interfaces: - custom_field_data = pop_custom_fields(params) - - for assoc, details in required_assocs.items(): - model, field = details - query = {field: params.pop(assoc)} - - params[assoc] = model.objects.get(**query) - - interface, created = VMInterface.objects.get_or_create(**params) - - if created: - set_custom_fields_values(interface, custom_field_data) - - print("🧷 Created interface", interface.name, interface.virtual_machine.name) diff --git a/startup_scripts/240_vrfs.py b/startup_scripts/240_vrfs.py new file mode 100644 index 0000000..a67c8c8 --- /dev/null +++ b/startup_scripts/240_vrfs.py @@ -0,0 +1,29 @@ +import sys + +from ipam.models import VRF +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values +from tenancy.models import Tenant + +vrfs = load_yaml("/opt/netbox/initializers/vrfs.yml") + +if vrfs is None: + sys.exit() + +optional_assocs = {"tenant": (Tenant, "name")} + +for params in vrfs: + custom_field_data = pop_custom_fields(params) + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = {field: params.pop(assoc)} + + params[assoc] = model.objects.get(**query) + + vrf, created = VRF.objects.get_or_create(**params) + + if created: + set_custom_fields_values(vrf, custom_field_data) + + print("πŸ“¦ Created VRF", vrf.name) diff --git a/startup_scripts/250_dcim_interfaces.py b/startup_scripts/250_dcim_interfaces.py deleted file mode 100644 index a802628..0000000 --- a/startup_scripts/250_dcim_interfaces.py +++ /dev/null @@ -1,27 +0,0 @@ -import sys - -from dcim.models import Device, Interface -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values - -interfaces = load_yaml("/opt/netbox/initializers/dcim_interfaces.yml") - -if interfaces is None: - sys.exit() - -required_assocs = {"device": (Device, "name")} - -for params in interfaces: - custom_field_data = pop_custom_fields(params) - - for assoc, details in required_assocs.items(): - model, field = details - query = {field: params.pop(assoc)} - - params[assoc] = model.objects.get(**query) - - interface, created = Interface.objects.get_or_create(**params) - - if created: - set_custom_fields_values(interface, custom_field_data) - - print("🧷 Created interface", interface.name, interface.device.name) diff --git a/startup_scripts/250_rirs.py b/startup_scripts/250_rirs.py new file mode 100644 index 0000000..0e0df20 --- /dev/null +++ b/startup_scripts/250_rirs.py @@ -0,0 +1,15 @@ +import sys + +from ipam.models import RIR +from startup_script_utils import load_yaml + +rirs = load_yaml("/opt/netbox/initializers/rirs.yml") + +if rirs is None: + sys.exit() + +for params in rirs: + rir, created = RIR.objects.get_or_create(**params) + + if created: + print("πŸ—ΊοΈ Created RIR", rir.name) diff --git a/startup_scripts/260_asns.py b/startup_scripts/260_asns.py new file mode 100644 index 0000000..893f3ba --- /dev/null +++ b/startup_scripts/260_asns.py @@ -0,0 +1,33 @@ +import sys + +from ipam.models import ASN, RIR +from startup_script_utils import load_yaml +from tenancy.models import Tenant + +asns = load_yaml("/opt/netbox/initializers/asns.yml") + +if asns is None: + sys.exit() + +required_assocs = {"rir": (RIR, "name")} + +optional_assocs = {"tenant": (Tenant, "name")} + +for params in asns: + 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) + + asn, created = ASN.objects.get_or_create(**params) + + if created: + print(f"πŸ”‘ Created ASN {asn.asn}") diff --git a/startup_scripts/260_ip_addresses.py b/startup_scripts/260_ip_addresses.py deleted file mode 100644 index 3f0aed0..0000000 --- a/startup_scripts/260_ip_addresses.py +++ /dev/null @@ -1,62 +0,0 @@ -import sys - -from dcim.models import Device, Interface -from django.contrib.contenttypes.models import ContentType -from django.db.models import Q -from ipam.models import VRF, IPAddress -from netaddr import IPNetwork -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from tenancy.models import Tenant -from virtualization.models import VirtualMachine, VMInterface - -ip_addresses = load_yaml("/opt/netbox/initializers/ip_addresses.yml") - -if ip_addresses is None: - sys.exit() - -optional_assocs = { - "tenant": (Tenant, "name"), - "vrf": (VRF, "name"), - "interface": (None, None), -} - -vm_interface_ct = ContentType.objects.filter( - Q(app_label="virtualization", model="vminterface") -).first() -interface_ct = ContentType.objects.filter(Q(app_label="dcim", model="interface")).first() - -for params in ip_addresses: - custom_field_data = pop_custom_fields(params) - - vm = params.pop("virtual_machine", None) - device = params.pop("device", None) - params["address"] = IPNetwork(params["address"]) - - if vm and device: - print("IP Address can only specify one of the following: virtual_machine or device.") - sys.exit() - - for assoc, details in optional_assocs.items(): - if assoc in params: - model, field = details - if assoc == "interface": - if vm: - vm_id = VirtualMachine.objects.get(name=vm).id - query = {"name": params.pop(assoc), "virtual_machine_id": vm_id} - params["assigned_object_type"] = vm_interface_ct - params["assigned_object_id"] = VMInterface.objects.get(**query).id - elif device: - dev_id = Device.objects.get(name=device).id - query = {"name": params.pop(assoc), "device_id": dev_id} - params["assigned_object_type"] = interface_ct - params["assigned_object_id"] = Interface.objects.get(**query).id - else: - query = {field: params.pop(assoc)} - params[assoc] = model.objects.get(**query) - - ip_address, created = IPAddress.objects.get_or_create(**params) - - if created: - set_custom_fields_values(ip_address, custom_field_data) - - print("🧬 Created IP Address", ip_address.address) diff --git a/startup_scripts/270_aggregates.py b/startup_scripts/270_aggregates.py new file mode 100644 index 0000000..c638e6f --- /dev/null +++ b/startup_scripts/270_aggregates.py @@ -0,0 +1,42 @@ +import sys + +from ipam.models import RIR, Aggregate +from netaddr import IPNetwork +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values +from tenancy.models import Tenant + +aggregates = load_yaml("/opt/netbox/initializers/aggregates.yml") + +if aggregates is None: + sys.exit() + +required_assocs = {"rir": (RIR, "name")} + +optional_assocs = { + "tenant": (Tenant, "name"), +} + +for params in aggregates: + custom_field_data = pop_custom_fields(params) + + params["prefix"] = IPNetwork(params["prefix"]) + + for assoc, details in required_assocs.items(): + model, field = details + query = {field: params.pop(assoc)} + + params[assoc] = model.objects.get(**query) + + 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) + + aggregate, created = Aggregate.objects.get_or_create(**params) + + if created: + set_custom_fields_values(aggregate, custom_field_data) + + print("πŸ—žοΈ Created Aggregate", aggregate.prefix) diff --git a/startup_scripts/270_primary_ips.py b/startup_scripts/270_primary_ips.py deleted file mode 100644 index 11c3179..0000000 --- a/startup_scripts/270_primary_ips.py +++ /dev/null @@ -1,47 +0,0 @@ -import sys - -from dcim.models import Device -from ipam.models import IPAddress -from startup_script_utils import load_yaml -from virtualization.models import VirtualMachine - - -def link_primary_ip(assets, asset_model): - for params in assets: - primary_ip_fields = set(params) & {"primary_ip4", "primary_ip6"} - if not primary_ip_fields: - continue - - for assoc, details in optional_assocs.items(): - if assoc in params: - model, field = details - query = {field: params.pop(assoc)} - - try: - params[assoc] = model.objects.get(**query) - except model.DoesNotExist: - primary_ip_fields -= {assoc} - print(f"⚠️ IP Address '{query[field]}' not found") - - asset = asset_model.objects.get(name=params["name"]) - for field in primary_ip_fields: - if getattr(asset, field) != params[field]: - setattr(asset, field, params[field]) - print(f"πŸ”— Define primary IP '{params[field].address}' on '{asset.name}'") - asset.save() - - -devices = load_yaml("/opt/netbox/initializers/devices.yml") -virtual_machines = load_yaml("/opt/netbox/initializers/virtual_machines.yml") - -optional_assocs = { - "primary_ip4": (IPAddress, "address"), - "primary_ip6": (IPAddress, "address"), -} - -if devices is None and virtual_machines is None: - sys.exit() -if devices is not None: - link_primary_ip(devices, Device) -if virtual_machines is not None: - link_primary_ip(virtual_machines, VirtualMachine) diff --git a/startup_scripts/280_custom_links.py b/startup_scripts/280_custom_links.py deleted file mode 100644 index 40144bd..0000000 --- a/startup_scripts/280_custom_links.py +++ /dev/null @@ -1,33 +0,0 @@ -import sys - -from django.contrib.contenttypes.models import ContentType -from extras.models import CustomLink -from startup_script_utils import load_yaml - -custom_links = load_yaml("/opt/netbox/initializers/custom_links.yml") - -if custom_links is None: - sys.exit() - - -def get_content_type_id(content_type): - try: - return ContentType.objects.get(model=content_type).id - except ContentType.DoesNotExist: - pass - - -for link in custom_links: - content_type = link.pop("content_type") - link["content_type_id"] = get_content_type_id(content_type) - if link["content_type_id"] is None: - print( - "⚠️ Unable to create Custom Link '{0}': The content_type '{1}' is unknown".format( - link.get("name"), content_type - ) - ) - continue - - custom_link, created = CustomLink.objects.get_or_create(**link) - if created: - print("πŸ”— Created Custom Link '{0}'".format(custom_link.name)) diff --git a/startup_scripts/280_prefix_vlan_roles.py b/startup_scripts/280_prefix_vlan_roles.py new file mode 100644 index 0000000..ec359fb --- /dev/null +++ b/startup_scripts/280_prefix_vlan_roles.py @@ -0,0 +1,15 @@ +import sys + +from ipam.models import Role +from startup_script_utils import load_yaml + +roles = load_yaml("/opt/netbox/initializers/prefix_vlan_roles.yml") + +if roles is None: + sys.exit() + +for params in roles: + role, created = Role.objects.get_or_create(**params) + + if created: + print("⛹️‍ Created Prefix/VLAN Role", role.name) diff --git a/startup_scripts/280_providers.py b/startup_scripts/280_providers.py deleted file mode 100644 index 5c4330a..0000000 --- a/startup_scripts/280_providers.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys - -from circuits.models import Provider -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values - -providers = load_yaml("/opt/netbox/initializers/providers.yml") - -if providers is None: - sys.exit() - -for params in providers: - custom_field_data = pop_custom_fields(params) - - provider, created = Provider.objects.get_or_create(**params) - - if created: - set_custom_fields_values(provider, custom_field_data) - - print("πŸ“‘ Created provider", provider.name) diff --git a/startup_scripts/290_circuit_types.py b/startup_scripts/290_circuit_types.py deleted file mode 100644 index 071793c..0000000 --- a/startup_scripts/290_circuit_types.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys - -from circuits.models import CircuitType -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values - -circuit_types = load_yaml("/opt/netbox/initializers/circuit_types.yml") - -if circuit_types is None: - sys.exit() - -for params in circuit_types: - custom_field_data = pop_custom_fields(params) - - circuit_type, created = CircuitType.objects.get_or_create(**params) - - if created: - set_custom_fields_values(circuit_type, custom_field_data) - - print("⚑ Created Circuit Type", circuit_type.name) diff --git a/startup_scripts/290_cluster_types.py b/startup_scripts/290_cluster_types.py new file mode 100644 index 0000000..9f361b1 --- /dev/null +++ b/startup_scripts/290_cluster_types.py @@ -0,0 +1,15 @@ +import sys + +from startup_script_utils import load_yaml +from virtualization.models import ClusterType + +cluster_types = load_yaml("/opt/netbox/initializers/cluster_types.yml") + +if cluster_types is None: + sys.exit() + +for params in cluster_types: + cluster_type, created = ClusterType.objects.get_or_create(**params) + + if created: + print("🧰 Created Cluster Type", cluster_type.name) diff --git a/startup_scripts/290_webhooks.py b/startup_scripts/290_webhooks.py deleted file mode 100644 index 8787f5f..0000000 --- a/startup_scripts/290_webhooks.py +++ /dev/null @@ -1,34 +0,0 @@ -import sys - -from django.contrib.contenttypes.models import ContentType -from extras.models import Webhook -from startup_script_utils import load_yaml - -webhooks = load_yaml("/opt/netbox/initializers/webhooks.yml") - -if webhooks is None: - sys.exit() - - -def get_content_type_id(hook_name, content_type): - try: - return ContentType.objects.get(model=content_type).id - except ContentType.DoesNotExist as ex: - print("⚠️ Webhook '{0}': The object_type '{1}' is unknown.".format(hook_name, content_type)) - raise ex - - -for hook in webhooks: - obj_types = hook.pop("object_types") - - try: - obj_type_ids = [get_content_type_id(hook["name"], obj) for obj in obj_types] - except ContentType.DoesNotExist: - continue - - webhook, created = Webhook.objects.get_or_create(**hook) - if created: - webhook.content_types.set(obj_type_ids) - webhook.save() - - print("πŸͺ Created Webhook {0}".format(webhook.name)) diff --git a/startup_scripts/300_circuits.py b/startup_scripts/300_circuits.py deleted file mode 100644 index f82d3b7..0000000 --- a/startup_scripts/300_circuits.py +++ /dev/null @@ -1,37 +0,0 @@ -import sys - -from circuits.models import Circuit, CircuitType, Provider -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values -from tenancy.models import Tenant - -circuits = load_yaml("/opt/netbox/initializers/circuits.yml") - -if circuits is None: - sys.exit() - -required_assocs = {"provider": (Provider, "name"), "type": (CircuitType, "name")} - -optional_assocs = {"tenant": (Tenant, "name")} - -for params in circuits: - custom_field_data = pop_custom_fields(params) - - 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) - - circuit, created = Circuit.objects.get_or_create(**params) - - if created: - set_custom_fields_values(circuit, custom_field_data) - - print("⚑ Created Circuit", circuit.cid) diff --git a/startup_scripts/300_cluster_groups.py b/startup_scripts/300_cluster_groups.py new file mode 100644 index 0000000..fedd292 --- /dev/null +++ b/startup_scripts/300_cluster_groups.py @@ -0,0 +1,15 @@ +import sys + +from startup_script_utils import load_yaml +from virtualization.models import ClusterGroup + +cluster_groups = load_yaml("/opt/netbox/initializers/cluster_groups.yml") + +if cluster_groups is None: + sys.exit() + +for params in cluster_groups: + cluster_group, created = ClusterGroup.objects.get_or_create(**params) + + if created: + print("πŸ—„οΈ Created Cluster Group", cluster_group.name) diff --git a/startup_scripts/310_clusters.py b/startup_scripts/310_clusters.py new file mode 100644 index 0000000..2748f20 --- /dev/null +++ b/startup_scripts/310_clusters.py @@ -0,0 +1,42 @@ +import sys + +from dcim.models import Site +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values +from tenancy.models import Tenant +from virtualization.models import Cluster, ClusterGroup, ClusterType + +clusters = load_yaml("/opt/netbox/initializers/clusters.yml") + +if clusters is None: + sys.exit() + +required_assocs = {"type": (ClusterType, "name")} + +optional_assocs = { + "site": (Site, "name"), + "group": (ClusterGroup, "name"), + "tenant": (Tenant, "name"), +} + +for params in clusters: + custom_field_data = pop_custom_fields(params) + + for assoc, details in required_assocs.items(): + model, field = details + query = {field: params.pop(assoc)} + + params[assoc] = model.objects.get(**query) + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = {field: params.pop(assoc)} + + params[assoc] = model.objects.get(**query) + + cluster, created = Cluster.objects.get_or_create(**params) + + if created: + set_custom_fields_values(cluster, custom_field_data) + + print("πŸ—„οΈ Created cluster", cluster.name) diff --git a/startup_scripts/320_services.py b/startup_scripts/320_services.py deleted file mode 100644 index a28eb09..0000000 --- a/startup_scripts/320_services.py +++ /dev/null @@ -1,30 +0,0 @@ -import sys - -from dcim.models import Device -from ipam.models import Service -from startup_script_utils import load_yaml -from virtualization.models import VirtualMachine - -services = load_yaml("/opt/netbox/initializers/services.yml") - -if services is None: - sys.exit() - -optional_assocs = { - "device": (Device, "name"), - "virtual_machine": (VirtualMachine, "name"), -} - -for params in services: - - 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) - - service, created = Service.objects.get_or_create(**params) - - if created: - print("🧰 Created Service", service.name) diff --git a/startup_scripts/320_vlan_groups.py b/startup_scripts/320_vlan_groups.py new file mode 100644 index 0000000..2a4a33d --- /dev/null +++ b/startup_scripts/320_vlan_groups.py @@ -0,0 +1,40 @@ +import sys + +from django.contrib.contenttypes.models import ContentType +from ipam.models import VLANGroup +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values + +vlan_groups = load_yaml("/opt/netbox/initializers/vlan_groups.yml") + +if vlan_groups is None: + sys.exit() + +optional_assocs = {"scope": (None, "name")} + +for params in vlan_groups: + custom_field_data = pop_custom_fields(params) + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = {field: params.pop(assoc)} + # Get model from Contenttype + scope_type = params.pop("scope_type", None) + if not scope_type: + print(f"VLAN Group '{params['name']}': scope_type is missing from VLAN Group") + continue + app_label, model = str(scope_type).split(".") + ct = ContentType.objects.filter(app_label=app_label, model=model).first() + if not ct: + print( + f"VLAN Group '{params['name']}': ContentType for " + + f"app_label = '{app_label}' and model = '{model}' not found" + ) + continue + params["scope_id"] = ct.model_class().objects.get(**query).id + vlan_group, created = VLANGroup.objects.get_or_create(**params) + + if created: + set_custom_fields_values(vlan_group, custom_field_data) + + print("🏘️ Created VLAN Group", vlan_group.name) diff --git a/startup_scripts/330_power_panels.py b/startup_scripts/330_power_panels.py deleted file mode 100644 index 8542435..0000000 --- a/startup_scripts/330_power_panels.py +++ /dev/null @@ -1,36 +0,0 @@ -import sys - -from dcim.models import Location, PowerPanel, Site -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values - -power_panels = load_yaml("/opt/netbox/initializers/power_panels.yml") - -if power_panels is None: - sys.exit() - -required_assocs = {"site": (Site, "name")} - -optional_assocs = {"location": (Location, "name")} - -for params in power_panels: - custom_field_data = pop_custom_fields(params) - - 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) - - power_panel, created = PowerPanel.objects.get_or_create(**params) - - if created: - set_custom_fields_values(power_panel, custom_field_data) - - print("⚑ Created Power Panel", power_panel.site, power_panel.name) diff --git a/startup_scripts/330_vlans.py b/startup_scripts/330_vlans.py new file mode 100644 index 0000000..e8ebb94 --- /dev/null +++ b/startup_scripts/330_vlans.py @@ -0,0 +1,36 @@ +import sys + +from dcim.models import Site +from ipam.models import VLAN, Role, VLANGroup +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values +from tenancy.models import Tenant, TenantGroup + +vlans = load_yaml("/opt/netbox/initializers/vlans.yml") + +if vlans is None: + sys.exit() + +optional_assocs = { + "site": (Site, "name"), + "tenant": (Tenant, "name"), + "tenant_group": (TenantGroup, "name"), + "group": (VLANGroup, "name"), + "role": (Role, "name"), +} + +for params in vlans: + custom_field_data = pop_custom_fields(params) + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = {field: params.pop(assoc)} + + params[assoc] = model.objects.get(**query) + + vlan, created = VLAN.objects.get_or_create(**params) + + if created: + set_custom_fields_values(vlan, custom_field_data) + + print("🏠 Created VLAN", vlan.name) diff --git a/startup_scripts/340_power_feeds.py b/startup_scripts/340_power_feeds.py deleted file mode 100644 index f5aa5b5..0000000 --- a/startup_scripts/340_power_feeds.py +++ /dev/null @@ -1,36 +0,0 @@ -import sys - -from dcim.models import PowerFeed, PowerPanel, Rack -from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values - -power_feeds = load_yaml("/opt/netbox/initializers/power_feeds.yml") - -if power_feeds is None: - sys.exit() - -required_assocs = {"power_panel": (PowerPanel, "name")} - -optional_assocs = {"rack": (Rack, "name")} - -for params in power_feeds: - custom_field_data = pop_custom_fields(params) - - 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) - - power_feed, created = PowerFeed.objects.get_or_create(**params) - - if created: - set_custom_fields_values(power_feed, custom_field_data) - - print("⚑ Created Power Feed", power_feed.name) diff --git a/startup_scripts/340_virtual_machines.py b/startup_scripts/340_virtual_machines.py new file mode 100644 index 0000000..2e3f428 --- /dev/null +++ b/startup_scripts/340_virtual_machines.py @@ -0,0 +1,46 @@ +import sys + +from dcim.models import DeviceRole, Platform +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values +from tenancy.models import Tenant +from virtualization.models import Cluster, VirtualMachine + +virtual_machines = load_yaml("/opt/netbox/initializers/virtual_machines.yml") + +if virtual_machines is None: + sys.exit() + +required_assocs = {"cluster": (Cluster, "name")} + +optional_assocs = { + "tenant": (Tenant, "name"), + "platform": (Platform, "name"), + "role": (DeviceRole, "name"), +} + +for params in virtual_machines: + custom_field_data = pop_custom_fields(params) + + # primary ips are handled later in `270_primary_ips.py` + params.pop("primary_ip4", None) + params.pop("primary_ip6", 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) + + virtual_machine, created = VirtualMachine.objects.get_or_create(**params) + + if created: + set_custom_fields_values(virtual_machine, custom_field_data) + + print("πŸ–₯️ Created virtual machine", virtual_machine.name) diff --git a/startup_scripts/350_virtualization_interfaces.py b/startup_scripts/350_virtualization_interfaces.py new file mode 100644 index 0000000..6ee6347 --- /dev/null +++ b/startup_scripts/350_virtualization_interfaces.py @@ -0,0 +1,27 @@ +import sys + +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values +from virtualization.models import VirtualMachine, VMInterface + +interfaces = load_yaml("/opt/netbox/initializers/virtualization_interfaces.yml") + +if interfaces is None: + sys.exit() + +required_assocs = {"virtual_machine": (VirtualMachine, "name")} + +for params in interfaces: + custom_field_data = pop_custom_fields(params) + + for assoc, details in required_assocs.items(): + model, field = details + query = {field: params.pop(assoc)} + + params[assoc] = model.objects.get(**query) + + interface, created = VMInterface.objects.get_or_create(**params) + + if created: + set_custom_fields_values(interface, custom_field_data) + + print("🧷 Created interface", interface.name, interface.virtual_machine.name) diff --git a/startup_scripts/360_prefixes.py b/startup_scripts/360_prefixes.py new file mode 100644 index 0000000..4e2b0d0 --- /dev/null +++ b/startup_scripts/360_prefixes.py @@ -0,0 +1,39 @@ +import sys + +from dcim.models import Site +from ipam.models import VLAN, VRF, Prefix, Role +from netaddr import IPNetwork +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values +from tenancy.models import Tenant, TenantGroup + +prefixes = load_yaml("/opt/netbox/initializers/prefixes.yml") + +if prefixes is None: + sys.exit() + +optional_assocs = { + "site": (Site, "name"), + "tenant": (Tenant, "name"), + "tenant_group": (TenantGroup, "name"), + "vlan": (VLAN, "name"), + "role": (Role, "name"), + "vrf": (VRF, "name"), +} + +for params in prefixes: + custom_field_data = pop_custom_fields(params) + + params["prefix"] = IPNetwork(params["prefix"]) + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = {field: params.pop(assoc)} + params[assoc] = model.objects.get(**query) + + prefix, created = Prefix.objects.get_or_create(**params) + + if created: + set_custom_fields_values(prefix, custom_field_data) + + print("πŸ“Œ Created Prefix", prefix.prefix) diff --git a/startup_scripts/370_ip_addresses.py b/startup_scripts/370_ip_addresses.py new file mode 100644 index 0000000..7f166f0 --- /dev/null +++ b/startup_scripts/370_ip_addresses.py @@ -0,0 +1,63 @@ +import sys + +from dcim.models import Device, Interface +from django.contrib.contenttypes.models import ContentType +from django.db.models import Q +from ipam.models import VRF, IPAddress +from netaddr import IPNetwork +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values +from tenancy.models import Tenant +from virtualization.models import VirtualMachine, VMInterface + +ip_addresses = load_yaml("/opt/netbox/initializers/ip_addresses.yml") + +if ip_addresses is None: + sys.exit() + +optional_assocs = { + "tenant": (Tenant, "name"), + "vrf": (VRF, "name"), + "interface": (None, None), +} + +vm_interface_ct = ContentType.objects.filter( + Q(app_label="virtualization", model="vminterface") +).first() +interface_ct = ContentType.objects.filter(Q(app_label="dcim", model="interface")).first() + +for params in ip_addresses: + custom_field_data = pop_custom_fields(params) + + vm = params.pop("virtual_machine", None) + device = params.pop("device", None) + params["address"] = IPNetwork(params["address"]) + + if vm and device: + print("IP Address can only specify one of the following: virtual_machine or device.") + sys.exit() + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + if assoc == "interface": + if vm: + vm_id = VirtualMachine.objects.get(name=vm).id + query = {"name": params.pop(assoc), "virtual_machine_id": vm_id} + params["assigned_object_type"] = vm_interface_ct + params["assigned_object_id"] = VMInterface.objects.get(**query).id + elif device: + dev_id = Device.objects.get(name=device).id + query = {"name": params.pop(assoc), "device_id": dev_id} + params["assigned_object_type"] = interface_ct + params["assigned_object_id"] = Interface.objects.get(**query).id + else: + query = {field: params.pop(assoc)} + + params[assoc] = model.objects.get(**query) + + ip_address, created = IPAddress.objects.get_or_create(**params) + + if created: + set_custom_fields_values(ip_address, custom_field_data) + + print("🧬 Created IP Address", ip_address.address) diff --git a/startup_scripts/380_primary_ips.py b/startup_scripts/380_primary_ips.py new file mode 100644 index 0000000..11c3179 --- /dev/null +++ b/startup_scripts/380_primary_ips.py @@ -0,0 +1,47 @@ +import sys + +from dcim.models import Device +from ipam.models import IPAddress +from startup_script_utils import load_yaml +from virtualization.models import VirtualMachine + + +def link_primary_ip(assets, asset_model): + for params in assets: + primary_ip_fields = set(params) & {"primary_ip4", "primary_ip6"} + if not primary_ip_fields: + continue + + for assoc, details in optional_assocs.items(): + if assoc in params: + model, field = details + query = {field: params.pop(assoc)} + + try: + params[assoc] = model.objects.get(**query) + except model.DoesNotExist: + primary_ip_fields -= {assoc} + print(f"⚠️ IP Address '{query[field]}' not found") + + asset = asset_model.objects.get(name=params["name"]) + for field in primary_ip_fields: + if getattr(asset, field) != params[field]: + setattr(asset, field, params[field]) + print(f"πŸ”— Define primary IP '{params[field].address}' on '{asset.name}'") + asset.save() + + +devices = load_yaml("/opt/netbox/initializers/devices.yml") +virtual_machines = load_yaml("/opt/netbox/initializers/virtual_machines.yml") + +optional_assocs = { + "primary_ip4": (IPAddress, "address"), + "primary_ip6": (IPAddress, "address"), +} + +if devices is None and virtual_machines is None: + sys.exit() +if devices is not None: + link_primary_ip(devices, Device) +if virtual_machines is not None: + link_primary_ip(virtual_machines, VirtualMachine) diff --git a/startup_scripts/400_services.py b/startup_scripts/400_services.py new file mode 100644 index 0000000..a28eb09 --- /dev/null +++ b/startup_scripts/400_services.py @@ -0,0 +1,30 @@ +import sys + +from dcim.models import Device +from ipam.models import Service +from startup_script_utils import load_yaml +from virtualization.models import VirtualMachine + +services = load_yaml("/opt/netbox/initializers/services.yml") + +if services is None: + sys.exit() + +optional_assocs = { + "device": (Device, "name"), + "virtual_machine": (VirtualMachine, "name"), +} + +for params in services: + + 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) + + service, created = Service.objects.get_or_create(**params) + + if created: + print("🧰 Created Service", service.name) diff --git a/startup_scripts/420_providers.py b/startup_scripts/420_providers.py new file mode 100644 index 0000000..5c4330a --- /dev/null +++ b/startup_scripts/420_providers.py @@ -0,0 +1,19 @@ +import sys + +from circuits.models import Provider +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values + +providers = load_yaml("/opt/netbox/initializers/providers.yml") + +if providers is None: + sys.exit() + +for params in providers: + custom_field_data = pop_custom_fields(params) + + provider, created = Provider.objects.get_or_create(**params) + + if created: + set_custom_fields_values(provider, custom_field_data) + + print("πŸ“‘ Created provider", provider.name) diff --git a/startup_scripts/440_circuit_types.py b/startup_scripts/440_circuit_types.py new file mode 100644 index 0000000..071793c --- /dev/null +++ b/startup_scripts/440_circuit_types.py @@ -0,0 +1,19 @@ +import sys + +from circuits.models import CircuitType +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values + +circuit_types = load_yaml("/opt/netbox/initializers/circuit_types.yml") + +if circuit_types is None: + sys.exit() + +for params in circuit_types: + custom_field_data = pop_custom_fields(params) + + circuit_type, created = CircuitType.objects.get_or_create(**params) + + if created: + set_custom_fields_values(circuit_type, custom_field_data) + + print("⚑ Created Circuit Type", circuit_type.name) diff --git a/startup_scripts/450_circuits.py b/startup_scripts/450_circuits.py new file mode 100644 index 0000000..f82d3b7 --- /dev/null +++ b/startup_scripts/450_circuits.py @@ -0,0 +1,37 @@ +import sys + +from circuits.models import Circuit, CircuitType, Provider +from startup_script_utils import load_yaml, pop_custom_fields, set_custom_fields_values +from tenancy.models import Tenant + +circuits = load_yaml("/opt/netbox/initializers/circuits.yml") + +if circuits is None: + sys.exit() + +required_assocs = {"provider": (Provider, "name"), "type": (CircuitType, "name")} + +optional_assocs = {"tenant": (Tenant, "name")} + +for params in circuits: + custom_field_data = pop_custom_fields(params) + + 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) + + circuit, created = Circuit.objects.get_or_create(**params) + + if created: + set_custom_fields_values(circuit, custom_field_data) + + print("⚑ Created Circuit", circuit.cid)