From 67dcd4cde9b7774fda2e74e86973b3fe50428ebc Mon Sep 17 00:00:00 2001 From: Ryan Merolle Date: Thu, 14 Mar 2024 04:09:02 +0000 Subject: [PATCH 01/20] add site_group support --- .../initializers/__init__.py | 2 ++ .../initializers/site_groups.py | 36 +++++++++++++++++++ src/netbox_initializers/initializers/sites.py | 8 +++-- .../initializers/yaml/site_groups.yml | 7 ++++ .../initializers/yaml/sites.yml | 1 + 5 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 src/netbox_initializers/initializers/site_groups.py create mode 100644 src/netbox_initializers/initializers/yaml/site_groups.yml diff --git a/src/netbox_initializers/initializers/__init__.py b/src/netbox_initializers/initializers/__init__.py index 677d210..1133e62 100644 --- a/src/netbox_initializers/initializers/__init__.py +++ b/src/netbox_initializers/initializers/__init__.py @@ -17,6 +17,7 @@ "webhooks", "tenant_groups", "tenants", + "site_groups", "regions", "rirs", "asns", @@ -205,6 +206,7 @@ def register_initializer(name: str, initializer): from .route_targets import RouteTargetInitializer from .service_templates import ServiceTemplateInitializer from .services import ServiceInitializer +from .site_groups import SiteGroupInitializer from .sites import SiteInitializer from .tags import TagInitializer from .tenant_groups import TenantGroupInitializer diff --git a/src/netbox_initializers/initializers/site_groups.py b/src/netbox_initializers/initializers/site_groups.py new file mode 100644 index 0000000..17bc95b --- /dev/null +++ b/src/netbox_initializers/initializers/site_groups.py @@ -0,0 +1,36 @@ +from dcim.models import SiteGroup + +from . import BaseInitializer, register_initializer + +OPTIONAL_ASSOCS = {"parent": (SiteGroup, "name")} + + +class SiteGroupInitializer(BaseInitializer): + data_file_name = "site_groups.yml" + + def load_data(self): + site_groups = self.load_yaml() + if site_groups is None: + return + for params in site_groups: + tags = params.pop("tags", None) + + for assoc, details in OPTIONAL_ASSOCS.items(): + if assoc in params: + model, field = details + query = {field: params.pop(assoc)} + + params[assoc] = model.objects.get(**query) + + matching_params, defaults = self.split_params(params) + site_group, created = SiteGroup.objects.get_or_create( + **matching_params, defaults=defaults + ) + + if created: + print("๐ŸŒ Created Site Group", site_group.name) + + self.set_tags(site_group, tags) + + +register_initializer("site_groups", SiteGroupInitializer) diff --git a/src/netbox_initializers/initializers/sites.py b/src/netbox_initializers/initializers/sites.py index 09a4386..0aac182 100644 --- a/src/netbox_initializers/initializers/sites.py +++ b/src/netbox_initializers/initializers/sites.py @@ -1,10 +1,14 @@ -from dcim.models import Region, Site +from dcim.models import Region, Site, SiteGroup from ipam.models import ASN from tenancy.models import Tenant from . import BaseInitializer, register_initializer -OPTIONAL_ASSOCS = {"region": (Region, "name"), "tenant": (Tenant, "name")} +OPTIONAL_ASSOCS = { + "region": (Region, "name"), + "group": (SiteGroup, "name"), + "tenant": (Tenant, "name"), +} class SiteInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/yaml/site_groups.yml b/src/netbox_initializers/initializers/yaml/site_groups.yml new file mode 100644 index 0000000..497316c --- /dev/null +++ b/src/netbox_initializers/initializers/yaml/site_groups.yml @@ -0,0 +1,7 @@ +# - name: Datacenter +# slug: datacenter +# - name: Office +# slug: office +# - name: Headquaters +# slug: headquarters +# parent: Office diff --git a/src/netbox_initializers/initializers/yaml/sites.yml b/src/netbox_initializers/initializers/yaml/sites.yml index c68c9ba..522bd3d 100644 --- a/src/netbox_initializers/initializers/yaml/sites.yml +++ b/src/netbox_initializers/initializers/yaml/sites.yml @@ -3,6 +3,7 @@ # region: Downtown # status: active # facility: Amsterdam 1 +#. group: Office # custom_field_data: # text_field: Description for AMS1 # - name: AMS 2 From 5d3bc30f9bfa17c3520686ac96f4df91d6a56466 Mon Sep 17 00:00:00 2001 From: Olivier BEDOUET <18343642+obedouet@users.noreply.github.com> Date: Fri, 29 Mar 2024 19:15:57 +0100 Subject: [PATCH 02/20] set attr from interfaces.yml (#96) * set attr from interfaces.yml * add examples in yml * fixing manufacturer name * fixes --------- Co-authored-by: obedouet --- src/netbox_initializers/initializers/interfaces.py | 4 ++++ .../initializers/yaml/device_types.yml | 8 ++++++++ src/netbox_initializers/initializers/yaml/devices.yml | 6 ++++++ src/netbox_initializers/initializers/yaml/interfaces.yml | 5 +++++ 4 files changed, 23 insertions(+) diff --git a/src/netbox_initializers/initializers/interfaces.py b/src/netbox_initializers/initializers/interfaces.py index fc5f9b5..81f226a 100644 --- a/src/netbox_initializers/initializers/interfaces.py +++ b/src/netbox_initializers/initializers/interfaces.py @@ -48,6 +48,10 @@ def load_data(self): if created: print(f"๐Ÿงท Created interface {interface} on {interface.device}") + else: + for name in defaults: + setattr(interface, name, defaults[name]) + interface.save() self.set_custom_fields_values(interface, custom_field_data) self.set_tags(interface, tags) diff --git a/src/netbox_initializers/initializers/yaml/device_types.yml b/src/netbox_initializers/initializers/yaml/device_types.yml index 3ee6186..c8842b9 100644 --- a/src/netbox_initializers/initializers/yaml/device_types.yml +++ b/src/netbox_initializers/initializers/yaml/device_types.yml @@ -16,6 +16,14 @@ # u_height: 0 # custom_field_data: # text_field: Description +# - model: TOR-8P +# manufacturer: No Name +# part_number: vlab-eos +# slug: tor-8p +# interfaces: +# - name: Ethernet1 +# type: 1000base-t +# description: UPLINK # - model: Other # manufacturer: No Name # slug: other diff --git a/src/netbox_initializers/initializers/yaml/devices.yml b/src/netbox_initializers/initializers/yaml/devices.yml index 953ad36..32ae82e 100644 --- a/src/netbox_initializers/initializers/yaml/devices.yml +++ b/src/netbox_initializers/initializers/yaml/devices.yml @@ -55,3 +55,9 @@ # custom_field_data: # text_field: Description # +## Templated device +# - name: gns3-tor +# device_role: switch +# device_type: TOR-8P +# site: SING 1 +# rack: rack-03 diff --git a/src/netbox_initializers/initializers/yaml/interfaces.yml b/src/netbox_initializers/initializers/yaml/interfaces.yml index 5c24875..891b3f0 100644 --- a/src/netbox_initializers/initializers/yaml/interfaces.yml +++ b/src/netbox_initializers/initializers/yaml/interfaces.yml @@ -34,3 +34,8 @@ # enabled: true # type: virtual # name: loopback + +## Example to add attributes on a templated interface +# - name: Ethernet1 +# mtu: 9100 +# device: gns3-tor From 2067b02202b8e46999a44b3d7721eba26f35e8a2 Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Mon, 15 Apr 2024 11:01:38 +0200 Subject: [PATCH 03/20] Prepare for Netbox 4.0 --- README.md | 6 +++--- pyproject.toml | 2 +- src/netbox_initializers/__init__.py | 6 +++--- src/netbox_initializers/initializers/__init__.py | 8 ++++---- .../initializers/custom_fields.py | 6 +++--- .../initializers/custom_links.py | 8 ++++---- .../initializers/device_roles.py | 2 +- src/netbox_initializers/initializers/devices.py | 2 +- src/netbox_initializers/initializers/groups.py | 8 ++++---- .../initializers/object_permissions.py | 14 +++++++------- src/netbox_initializers/initializers/rack_roles.py | 2 +- src/netbox_initializers/initializers/tags.py | 6 +++--- src/netbox_initializers/initializers/users.py | 8 +++----- .../initializers/yaml/devices.yml | 10 +++++----- test/Dockerfile | 2 +- test/env/netbox.env | 1 + 16 files changed, 45 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 80b7b37..e4e1841 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Load data from YAML files into Netbox First activate your virtual environment where Netbox is installed, the install the plugin version correspondig to your Netbox version. ```bash -pip install "netbox-initializers==3.7.*" +pip install "netbox-initializers==4.0.*" ``` Then you need to add the plugin to the `PLUGINS` array in the Netbox configuration. ```python @@ -36,6 +36,6 @@ The initializers where a part of the Docker image and where then extracted into To use the new plugin in a the Netbox Docker image, it musst be installad into the image. To this, the following example can be used as a starting point: ```dockerfile -FROM netboxcommunity/netbox:v3.7 -RUN /opt/netbox/venv/bin/pip install "netbox-initializers==3.7.*" +FROM netboxcommunity/netbox:v4.0 +RUN /opt/netbox/venv/bin/pip install "netbox-initializers==4.0.*" ``` diff --git a/pyproject.toml b/pyproject.toml index 89e8703..de16a09 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ license = "Apache-2.0" name = "netbox-initializers" readme = "README.md" repository = "https://github.com/tobiasge/netbox-initializers" -version = "3.7.2" +version = "4.0.0" [tool.poetry.dependencies] python = "^3.8" diff --git a/src/netbox_initializers/__init__.py b/src/netbox_initializers/__init__.py index aab7519..2099aa0 100644 --- a/src/netbox_initializers/__init__.py +++ b/src/netbox_initializers/__init__.py @@ -5,10 +5,10 @@ class NetBoxInitializersConfig(PluginConfig): name = "netbox_initializers" verbose_name = "NetBox Initializers" description = "Load initial data into Netbox" - version = "3.7.2" + version = "4.0.0" base_url = "initializers" - min_version = "3.7.0" - max_version = "3.7.99" + min_version = "4.0-beta1" + max_version = "4.0.99" config = NetBoxInitializersConfig diff --git a/src/netbox_initializers/initializers/__init__.py b/src/netbox_initializers/initializers/__init__.py index 1133e62..b7a2499 100644 --- a/src/netbox_initializers/initializers/__init__.py +++ b/src/netbox_initializers/initializers/__init__.py @@ -1,7 +1,7 @@ from pathlib import Path from typing import Tuple -from django.contrib.contenttypes.models import ContentType +from core.models import ObjectType from django.core.exceptions import ObjectDoesNotExist from extras.models import CustomField, Tag from ruamel.yaml import YAML @@ -105,8 +105,8 @@ def set_custom_fields_values(self, entity, custom_field_data): except ObjectDoesNotExist: missing_cfs.append(key) else: - ct = ContentType.objects.get_for_model(entity) - if ct not in cf.content_types.all(): + ct = ObjectType.objects.get_for_model(entity) + if ct not in cf.object_types.all(): print( f"โš ๏ธ Custom field {key} is not enabled for {entity}'s model!" "Please check the 'on_objects' for that custom field in custom_fields.yml" @@ -131,7 +131,7 @@ def set_tags(self, entity, tags): if not hasattr(entity, "tags"): raise Exception(f"โš ๏ธ Tags cannot be applied to {entity}'s model") - ct = ContentType.objects.get_for_model(entity) + ct = ObjectType.objects.get_for_model(entity) save = False for tag in Tag.objects.filter(name__in=tags): diff --git a/src/netbox_initializers/initializers/custom_fields.py b/src/netbox_initializers/initializers/custom_fields.py index ac0c10f..4a51314 100644 --- a/src/netbox_initializers/initializers/custom_fields.py +++ b/src/netbox_initializers/initializers/custom_fields.py @@ -6,12 +6,12 @@ def get_class_for_class_path(class_path): import importlib - from django.contrib.contenttypes.models import ContentType + from core.models import ObjectType 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) + return ObjectType.objects.get_for_model(clazz) class CustomFieldInitializer(BaseInitializer): @@ -35,7 +35,7 @@ def load_data(self): 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)) + custom_field.object_types.add(get_class_for_class_path(object_type)) if cf_details.get("required", False): custom_field.required = cf_details["required"] diff --git a/src/netbox_initializers/initializers/custom_links.py b/src/netbox_initializers/initializers/custom_links.py index 1024334..7b149f1 100644 --- a/src/netbox_initializers/initializers/custom_links.py +++ b/src/netbox_initializers/initializers/custom_links.py @@ -1,4 +1,4 @@ -from django.contrib.contenttypes.models import ContentType +from core.models import ObjectType from extras.models import CustomLink from . import BaseInitializer, register_initializer @@ -6,8 +6,8 @@ def get_content_type(content_type): try: - return ContentType.objects.get(model=content_type) - except ContentType.DoesNotExist: + return ObjectType.objects.get(model=content_type) + except ObjectType.DoesNotExist: pass return None @@ -36,7 +36,7 @@ def load_data(self): ) if created: - custom_link.content_types.add(content_type) + custom_link.object_types.add(content_type) custom_link.save() print("๐Ÿ”— Created Custom Link '{0}'".format(custom_link.name)) diff --git a/src/netbox_initializers/initializers/device_roles.py b/src/netbox_initializers/initializers/device_roles.py index c6cc1d1..544b49a 100644 --- a/src/netbox_initializers/initializers/device_roles.py +++ b/src/netbox_initializers/initializers/device_roles.py @@ -1,5 +1,5 @@ from dcim.models import DeviceRole -from utilities.choices import ColorChoices +from netbox.choices import ColorChoices from . import BaseInitializer, register_initializer diff --git a/src/netbox_initializers/initializers/devices.py b/src/netbox_initializers/initializers/devices.py index c549b42..c73a925 100644 --- a/src/netbox_initializers/initializers/devices.py +++ b/src/netbox_initializers/initializers/devices.py @@ -7,7 +7,7 @@ MATCH_PARAMS = ["device_type", "name", "site"] REQUIRED_ASSOCS = { - "device_role": (DeviceRole, "name"), + "role": (DeviceRole, "name"), "device_type": (DeviceType, "model"), "site": (Site, "name"), } diff --git a/src/netbox_initializers/initializers/groups.py b/src/netbox_initializers/initializers/groups.py index 136f1c6..7280d66 100644 --- a/src/netbox_initializers/initializers/groups.py +++ b/src/netbox_initializers/initializers/groups.py @@ -1,4 +1,4 @@ -from users.models import NetBoxGroup, NetBoxUser +from users.models import Group, User from . import BaseInitializer, register_initializer @@ -12,13 +12,13 @@ def load_data(self): return for groupname, group_details in groups.items(): - group, created = NetBoxGroup.objects.get_or_create(name=groupname) + group, created = Group.objects.get_or_create(name=groupname) if created: print("๐Ÿ‘ฅ Created group", groupname) for username in group_details.get("users", []): - user = NetBoxUser.objects.get(username=username) + user = User.objects.get(username=username) if user: - group.user_set.add(user) + group.users.add(user) print(" ๐Ÿ‘ค Assigned user %s to group %s" % (username, group.name)) group.save() diff --git a/src/netbox_initializers/initializers/object_permissions.py b/src/netbox_initializers/initializers/object_permissions.py index 4878295..3ad2a5b 100644 --- a/src/netbox_initializers/initializers/object_permissions.py +++ b/src/netbox_initializers/initializers/object_permissions.py @@ -1,5 +1,5 @@ -from django.contrib.contenttypes.models import ContentType -from users.models import NetBoxGroup, NetBoxUser, ObjectPermission +from core.models import ObjectType +from users.models import Group, ObjectPermission, User from . import BaseInitializer, register_initializer @@ -28,12 +28,12 @@ def load_data(self): object_types = permission_details["object_types"] if object_types == "all": - object_permission.object_types.set(ContentType.objects.all()) + object_permission.object_types.set(ObjectType.objects.all()) else: for app_label, models in object_types.items(): if models == "all": - app_models = ContentType.objects.filter(app_label=app_label) + app_models = ObjectType.objects.filter(app_label=app_label) for app_model in app_models: object_permission.object_types.add(app_model.id) @@ -41,14 +41,14 @@ def load_data(self): # There is for model in models: object_permission.object_types.add( - ContentType.objects.get(app_label=app_label, model=model) + ObjectType.objects.get(app_label=app_label, model=model) ) if created: print("๐Ÿ”“ Created object permission", object_permission.name) if permission_details.get("groups", 0): for groupname in permission_details["groups"]: - group = NetBoxGroup.objects.filter(name=groupname).first() + group = Group.objects.filter(name=groupname).first() if group: object_permission.groups.add(group) @@ -59,7 +59,7 @@ def load_data(self): if permission_details.get("users", 0): for username in permission_details["users"]: - user = NetBoxUser.objects.filter(username=username).first() + user = User.objects.filter(username=username).first() if user: object_permission.users.add(user) diff --git a/src/netbox_initializers/initializers/rack_roles.py b/src/netbox_initializers/initializers/rack_roles.py index ab4d9f2..bdbbc6d 100644 --- a/src/netbox_initializers/initializers/rack_roles.py +++ b/src/netbox_initializers/initializers/rack_roles.py @@ -1,5 +1,5 @@ from dcim.models import RackRole -from utilities.choices import ColorChoices +from netbox.choices import ColorChoices from . import BaseInitializer, register_initializer diff --git a/src/netbox_initializers/initializers/tags.py b/src/netbox_initializers/initializers/tags.py index 3650c03..72e1894 100644 --- a/src/netbox_initializers/initializers/tags.py +++ b/src/netbox_initializers/initializers/tags.py @@ -1,6 +1,6 @@ -from django.contrib.contenttypes.models import ContentType +from core.models import ObjectType from extras.models import Tag -from utilities.choices import ColorChoices +from netbox.choices import ColorChoices from . import BaseInitializer, register_initializer @@ -29,7 +29,7 @@ def load_data(self): if object_types: for ot in object_types: - ct = ContentType.objects.get( + ct = ObjectType.objects.get( app_label=ot["app"], model=ot["model"], ) diff --git a/src/netbox_initializers/initializers/users.py b/src/netbox_initializers/initializers/users.py index 2e3d771..895bed3 100644 --- a/src/netbox_initializers/initializers/users.py +++ b/src/netbox_initializers/initializers/users.py @@ -1,4 +1,4 @@ -from users.models import NetBoxUser, Token +from users.models import Token, User from . import BaseInitializer, register_initializer @@ -13,10 +13,8 @@ def load_data(self): for username, user_details in users.items(): api_token = user_details.pop("api_token", Token.generate_key()) - password = user_details.pop("password", NetBoxUser.objects.make_random_password()) - user, created = NetBoxUser.objects.get_or_create( - username=username, defaults=user_details - ) + password = user_details.pop("password", 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() diff --git a/src/netbox_initializers/initializers/yaml/devices.yml b/src/netbox_initializers/initializers/yaml/devices.yml index 32ae82e..4e7155d 100644 --- a/src/netbox_initializers/initializers/yaml/devices.yml +++ b/src/netbox_initializers/initializers/yaml/devices.yml @@ -14,7 +14,7 @@ ## Examples: # - name: server01 -# device_role: server +# role: server # device_type: Other # site: AMS 1 # rack: rack-01 @@ -23,7 +23,7 @@ # custom_field_data: # text_field: Description # - name: server02 -# device_role: server +# role: server # device_type: Other # site: AMS 2 # rack: rack-02 @@ -36,7 +36,7 @@ # custom_field_data: # text_field: Description # - name: server03 -# device_role: server +# role: server # device_type: Other # site: SING 1 # rack: rack-03 @@ -45,7 +45,7 @@ # custom_field_data: # text_field: Description # - name: server04 -# device_role: server +# role: server # device_type: Other # site: SING 1 # location: cage 101 @@ -57,7 +57,7 @@ # ## Templated device # - name: gns3-tor -# device_role: switch +# role: switch # device_type: TOR-8P # site: SING 1 # rack: rack-03 diff --git a/test/Dockerfile b/test/Dockerfile index 5840f97..ba25a73 100644 --- a/test/Dockerfile +++ b/test/Dockerfile @@ -1,4 +1,4 @@ -FROM netboxcommunity/netbox:v3.7 +FROM netboxcommunity/netbox:feature COPY ../ /opt/netbox-initializers/ COPY ./test/config/plugins.py /etc/netbox/config/ diff --git a/test/env/netbox.env b/test/env/netbox.env index 47a77cc..81df20a 100644 --- a/test/env/netbox.env +++ b/test/env/netbox.env @@ -14,4 +14,5 @@ REDIS_INSECURE_SKIP_TLS_VERIFY=false REDIS_PASSWORD=aC4eic9if9de4eHi@kah REDIS_SSL=false SECRET_KEY=yam+ie6Uhou5ciGaez7Psheihae*Nga3wohz9ietsae8Hu:chung:aeGeat9 +SKIP_SUPERUSER=true WEBHOOKS_ENABLED=true From aa4794ddcbf1da690bb7bd2d94e1db6a5b30afb0 Mon Sep 17 00:00:00 2001 From: Matej Vadnjal Date: Fri, 7 Jun 2024 11:05:33 +0200 Subject: [PATCH 04/20] custom_field object_type was renamed to related_object_type in netbox 4.0 --- .../initializers/custom_fields.py | 17 ++++++++++++++--- .../initializers/yaml/custom_fields.yml | 4 ++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/netbox_initializers/initializers/custom_fields.py b/src/netbox_initializers/initializers/custom_fields.py index 4a51314..7fa8307 100644 --- a/src/netbox_initializers/initializers/custom_fields.py +++ b/src/netbox_initializers/initializers/custom_fields.py @@ -61,19 +61,30 @@ def load_data(self): if cf_details.get("is_cloneable", None) is not None: custom_field.is_cloneable = cf_details["is_cloneable"] - # object_type should only be applied when type is object, multiobject + # object_type was renamed to related_object_type in netbox 4.0 if cf_details.get("object_type"): + print( + f"โš ๏ธ Unable to create Custom Field '{cf_name}': please rename object_type " + + "to related_object_type" + ) + custom_field.delete() + continue + + # related_object_type should only be applied when type is object, multiobject + if cf_details.get("related_object_type"): if cf_details.get("type") not in ( "object", "multiobject", ): print( - f"โš ๏ธ Unable to create Custom Field '{cf_name}': object_type is " + f"โš ๏ธ Unable to create Custom Field '{cf_name}': related_object_type is " + "supported only for object and multiobject types" ) custom_field.delete() continue - custom_field.object_type = get_class_for_class_path(cf_details["object_type"]) + custom_field.related_object_type = get_class_for_class_path( + cf_details["related_object_type"] + ) # validation_regex should only be applied when type is text, longtext, url if cf_details.get("validation_regex"): diff --git a/src/netbox_initializers/initializers/yaml/custom_fields.yml b/src/netbox_initializers/initializers/yaml/custom_fields.yml index b53b303..e2b471d 100644 --- a/src/netbox_initializers/initializers/yaml/custom_fields.yml +++ b/src/netbox_initializers/initializers/yaml/custom_fields.yml @@ -100,7 +100,7 @@ # filter_logic: loose # on_objects: # - dcim.models.Location -# object_type: ipam.models.IPAddress +# related_object_type: ipam.models.IPAddress # object_field: # type: object # label: ASN @@ -109,4 +109,4 @@ # filter_logic: loose # on_objects: # - dcim.models.Device -# object_type: ipam.models.ASN +# related_object_type: ipam.models.ASN From c0f3de15124d3779998d83354559354b3625cf04 Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Sun, 1 Sep 2024 11:46:30 +0200 Subject: [PATCH 05/20] Prepare for Netbox 4.1 --- README.md | 6 +- pyproject.toml | 2 +- src/netbox_initializers/__init__.py | 6 +- .../initializers/__init__.py | 4 +- .../initializers/rack_types.py | 31 +++++++++++ src/netbox_initializers/initializers/racks.py | 3 +- .../initializers/yaml/custom_fields.yml | 1 + .../initializers/yaml/rack_types.yml | 55 +++++++++++++++++++ .../initializers/yaml/racks.yml | 12 +--- test/docker-compose.yml | 1 - 10 files changed, 102 insertions(+), 19 deletions(-) create mode 100644 src/netbox_initializers/initializers/rack_types.py create mode 100644 src/netbox_initializers/initializers/yaml/rack_types.yml diff --git a/README.md b/README.md index e4e1841..70a1680 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Load data from YAML files into Netbox First activate your virtual environment where Netbox is installed, the install the plugin version correspondig to your Netbox version. ```bash -pip install "netbox-initializers==4.0.*" +pip install "netbox-initializers==4.1.*" ``` Then you need to add the plugin to the `PLUGINS` array in the Netbox configuration. ```python @@ -36,6 +36,6 @@ The initializers where a part of the Docker image and where then extracted into To use the new plugin in a the Netbox Docker image, it musst be installad into the image. To this, the following example can be used as a starting point: ```dockerfile -FROM netboxcommunity/netbox:v4.0 -RUN /opt/netbox/venv/bin/pip install "netbox-initializers==4.0.*" +FROM netboxcommunity/netbox:v4.1 +RUN /opt/netbox/venv/bin/pip install "netbox-initializers==4.1.*" ``` diff --git a/pyproject.toml b/pyproject.toml index de16a09..85b9039 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ license = "Apache-2.0" name = "netbox-initializers" readme = "README.md" repository = "https://github.com/tobiasge/netbox-initializers" -version = "4.0.0" +version = "4.1.0" [tool.poetry.dependencies] python = "^3.8" diff --git a/src/netbox_initializers/__init__.py b/src/netbox_initializers/__init__.py index 2099aa0..a6e9763 100644 --- a/src/netbox_initializers/__init__.py +++ b/src/netbox_initializers/__init__.py @@ -5,10 +5,10 @@ class NetBoxInitializersConfig(PluginConfig): name = "netbox_initializers" verbose_name = "NetBox Initializers" description = "Load initial data into Netbox" - version = "4.0.0" + version = "4.1.0" base_url = "initializers" - min_version = "4.0-beta1" - max_version = "4.0.99" + min_version = "4.1-beta1" + max_version = "4.1.99" config = NetBoxInitializersConfig diff --git a/src/netbox_initializers/initializers/__init__.py b/src/netbox_initializers/initializers/__init__.py index b7a2499..1c7f664 100644 --- a/src/netbox_initializers/initializers/__init__.py +++ b/src/netbox_initializers/initializers/__init__.py @@ -23,11 +23,12 @@ "asns", "sites", "locations", + "manufacturers", "rack_roles", + "rack_types", "racks", "power_panels", "power_feeds", - "manufacturers", "platforms", "device_roles", "device_types", @@ -201,6 +202,7 @@ def register_initializer(name: str, initializer): from .providers import ProviderInitializer from .rack_roles import RackRoleInitializer from .racks import RackInitializer +from .rack_types import RackTypeInitializer from .regions import RegionInitializer from .rirs import RIRInitializer from .route_targets import RouteTargetInitializer diff --git a/src/netbox_initializers/initializers/rack_types.py b/src/netbox_initializers/initializers/rack_types.py new file mode 100644 index 0000000..90251e6 --- /dev/null +++ b/src/netbox_initializers/initializers/rack_types.py @@ -0,0 +1,31 @@ +from dcim.models import RackType +from dcim.models import Manufacturer + +from . import BaseInitializer, register_initializer + +MATCH_PARAMS = ["slug"] +REQUIRED_ASSOCS = {"manufacturer": (Manufacturer, "slug")} + +class RackTypeInitializer(BaseInitializer): + data_file_name = "rack_types.yml" + + def load_data(self): + rack_types = self.load_yaml() + if rack_types is None: + return + for params in rack_types: + + for assoc, details in REQUIRED_ASSOCS.items(): + model, field = details + query = {field: params.pop(assoc)} + + params[assoc] = model.objects.get(**query) + + matching_params, defaults = self.split_params(params, MATCH_PARAMS) + rack_type, created = RackType.objects.get_or_create(**matching_params, defaults=defaults) + + if created: + print("๐Ÿ”ณ Created rack type", rack_type.model) + + +register_initializer("rack_types", RackTypeInitializer) diff --git a/src/netbox_initializers/initializers/racks.py b/src/netbox_initializers/initializers/racks.py index 3cb3ae3..3d37e2a 100644 --- a/src/netbox_initializers/initializers/racks.py +++ b/src/netbox_initializers/initializers/racks.py @@ -1,4 +1,4 @@ -from dcim.models import Location, Rack, RackRole, Site +from dcim.models import Location, Rack, RackRole, Site, RackType from tenancy.models import Tenant from . import BaseInitializer, register_initializer @@ -9,6 +9,7 @@ "role": (RackRole, "name"), "tenant": (Tenant, "name"), "location": (Location, "name"), + "rack_type": (RackType, "slug"), } diff --git a/src/netbox_initializers/initializers/yaml/custom_fields.yml b/src/netbox_initializers/initializers/yaml/custom_fields.yml index e2b471d..961a7bc 100644 --- a/src/netbox_initializers/initializers/yaml/custom_fields.yml +++ b/src/netbox_initializers/initializers/yaml/custom_fields.yml @@ -32,6 +32,7 @@ # on_objects: # - dcim.models.Device # - dcim.models.Rack +# - dcim.models.RackType # - dcim.models.Site # - dcim.models.DeviceType # - ipam.models.IPAddress diff --git a/src/netbox_initializers/initializers/yaml/rack_types.yml b/src/netbox_initializers/initializers/yaml/rack_types.yml new file mode 100644 index 0000000..a898773 --- /dev/null +++ b/src/netbox_initializers/initializers/yaml/rack_types.yml @@ -0,0 +1,55 @@ +# # Examples: +# - model: Rack Type 1 +# manufacturer: manufacturer-1 +# slug: rack-type-1 +# form_factor: 4-post-cabinet +# width: 19 +# u_height: 47 +# custom_field_data: +# text_field: Description +# starting_unit: 2 +# desc_units: true +# outer_width: 600 +# outer_depth: 1000 +# outer_unit: mm +# mounting_depth: 800 +# weight: 100.3 +# weight_unit: kg +# description: Description for Rack Type 1 +# comments: Comments for Rack Type 1 +# - model: Rack Type 2 +# manufacturer: manufacturer-2 +# slug: rack-type-2 +# form_factor: 2-post-frame +# width: 23 +# u_height: 24 +# custom_field_data: +# text_field: Description +# starting_unit: 1 +# desc_units: false +# outer_width: 800 +# outer_depth: 1200 +# outer_unit: mm +# mounting_depth: 1000 +# weight: 80.5 +# weight_unit: kg +# description: Description for Rack Type 2 +# comments: Comments for Rack Type 2 +# - model: Rack Type 3 +# manufacturer: no-name +# slug: rack-type-3 +# form_factor: wall-mount +# width: 10 +# u_height: 12 +# custom_field_data: +# text_field: Description +# starting_unit: 1 +# desc_units: true +# outer_width: 500 +# outer_depth: 300 +# outer_unit: mm +# mounting_depth: 250 +# weight: 30.2 +# weight_unit: kg +# description: Description for Rack Type 3 +# comments: Comments for Rack Type 3 diff --git a/src/netbox_initializers/initializers/yaml/racks.yml b/src/netbox_initializers/initializers/yaml/racks.yml index 9071e19..48f44de 100644 --- a/src/netbox_initializers/initializers/yaml/racks.yml +++ b/src/netbox_initializers/initializers/yaml/racks.yml @@ -2,12 +2,6 @@ ## width: ## - 19 ## - 23 -## types: -## - 2-post-frame -## - 4-post-frame -## - 4-post-cabinet -## - wall-frame -## - wall-cabinet ## outer_unit: ## - mm ## - in @@ -17,7 +11,7 @@ # - site: AMS 1 # name: rack-01 # role: Role 1 -# type: 4-post-cabinet +# rack_type: rack-type-1 # width: 19 # u_height: 47 # custom_field_data: @@ -25,7 +19,7 @@ # - site: AMS 2 # name: rack-02 # role: Role 2 -# type: 4-post-cabinet +# rack_type: rack-type-2 # width: 19 # u_height: 47 # custom_field_data: @@ -34,7 +28,7 @@ # name: rack-03 # location: cage 101 # role: Role 3 -# type: 4-post-cabinet +# rack_type: rack-type-3 # width: 19 # u_height: 47 # custom_field_data: diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 153c478..582d4f2 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -1,5 +1,4 @@ --- -version: '3.4' services: netbox: depends_on: From 7398f6130def60c8759201ca844de5cf3d739f69 Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Sun, 1 Sep 2024 13:35:33 +0200 Subject: [PATCH 06/20] Prepare for Netbox 4.1 --- .github/workflows/linter.yml | 5 +- poetry.lock | 239 ++++++++++++++++++ pyproject.toml | 4 + .../initializers/__init__.py | 2 +- .../initializers/rack_types.py | 8 +- src/netbox_initializers/initializers/racks.py | 2 +- .../initializers/yaml/power_panels.yml | 4 +- .../initializers/yaml/service_templates.yml | 2 +- .../initializers/yaml/services.yml | 2 +- 9 files changed, 258 insertions(+), 10 deletions(-) create mode 100644 poetry.lock diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 39ed617..f51f992 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -17,12 +17,14 @@ jobs: # list of changed files within `super-linter` fetch-depth: 0 - name: Lint Code Base - uses: github/super-linter@v5 + uses: github/super-linter@v7 env: DEFAULT_BRANCH: main GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SUPPRESS_POSSUM: true VALIDATE_ALL_CODEBASE: false + VALIDATE_CHECKOV: false + VALIDATE_JSCPD: false VALIDATE_PYTHON_MYPY: false LINTER_RULES_PATH: / PYTHON_BLACK_CONFIG_FILE: pyproject.toml @@ -30,3 +32,4 @@ jobs: YAML_CONFIG_FILE: .yamllint.yaml PYTHON_FLAKE8_CONFIG_FILE: .flake8 PYTHON_ISORT_CONFIG_FILE: pyproject.toml + diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..1aeaf23 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,239 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. + +[[package]] +name = "black" +version = "24.8.0" +description = "The uncompromising code formatter." +optional = false +python-versions = ">=3.8" +files = [ + {file = "black-24.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09cdeb74d494ec023ded657f7092ba518e8cf78fa8386155e4a03fdcc44679e6"}, + {file = "black-24.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81c6742da39f33b08e791da38410f32e27d632260e599df7245cccee2064afeb"}, + {file = "black-24.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:707a1ca89221bc8a1a64fb5e15ef39cd755633daa672a9db7498d1c19de66a42"}, + {file = "black-24.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d6417535d99c37cee4091a2f24eb2b6d5ec42b144d50f1f2e436d9fe1916fe1a"}, + {file = "black-24.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fb6e2c0b86bbd43dee042e48059c9ad7830abd5c94b0bc518c0eeec57c3eddc1"}, + {file = "black-24.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:837fd281f1908d0076844bc2b801ad2d369c78c45cf800cad7b61686051041af"}, + {file = "black-24.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62e8730977f0b77998029da7971fa896ceefa2c4c4933fcd593fa599ecbf97a4"}, + {file = "black-24.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:72901b4913cbac8972ad911dc4098d5753704d1f3c56e44ae8dce99eecb0e3af"}, + {file = "black-24.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7c046c1d1eeb7aea9335da62472481d3bbf3fd986e093cffd35f4385c94ae368"}, + {file = "black-24.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:649f6d84ccbae73ab767e206772cc2d7a393a001070a4c814a546afd0d423aed"}, + {file = "black-24.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b59b250fdba5f9a9cd9d0ece6e6d993d91ce877d121d161e4698af3eb9c1018"}, + {file = "black-24.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:6e55d30d44bed36593c3163b9bc63bf58b3b30e4611e4d88a0c3c239930ed5b2"}, + {file = "black-24.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:505289f17ceda596658ae81b61ebbe2d9b25aa78067035184ed0a9d855d18afd"}, + {file = "black-24.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b19c9ad992c7883ad84c9b22aaa73562a16b819c1d8db7a1a1a49fb7ec13c7d2"}, + {file = "black-24.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f13f7f386f86f8121d76599114bb8c17b69d962137fc70efe56137727c7047e"}, + {file = "black-24.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:f490dbd59680d809ca31efdae20e634f3fae27fba3ce0ba3208333b713bc3920"}, + {file = "black-24.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eab4dd44ce80dea27dc69db40dab62d4ca96112f87996bca68cd75639aeb2e4c"}, + {file = "black-24.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3c4285573d4897a7610054af5a890bde7c65cb466040c5f0c8b732812d7f0e5e"}, + {file = "black-24.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e84e33b37be070ba135176c123ae52a51f82306def9f7d063ee302ecab2cf47"}, + {file = "black-24.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:73bbf84ed136e45d451a260c6b73ed674652f90a2b3211d6a35e78054563a9bb"}, + {file = "black-24.8.0-py3-none-any.whl", hash = "sha256:972085c618ee94f402da1af548a4f218c754ea7e5dc70acb168bfaca4c2542ed"}, + {file = "black-24.8.0.tar.gz", hash = "sha256:2500945420b6784c38b9ee885af039f5e7471ef284ab03fa35ecdde4688cd83f"}, +] + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "isort" +version = "5.13.2" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, +] + +[package.extras] +colors = ["colorama (>=0.4.6)"] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "packaging" +version = "24.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + +[[package]] +name = "platformdirs" +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] + +[[package]] +name = "ruamel-yaml" +version = "0.18.6" +description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636"}, + {file = "ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b"}, +] + +[package.dependencies] +"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""} + +[package.extras] +docs = ["mercurial (>5.7)", "ryd"] +jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] + +[[package]] +name = "ruamel-yaml-clib" +version = "0.2.8" +description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" +optional = false +python-versions = ">=3.6" +files = [ + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b"}, + {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"}, + {file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"}, +] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.8" +content-hash = "f96359cba6be4885f3531d536e56a3a28684a39f288b2d9a86ba819f3e1161e7" diff --git a/pyproject.toml b/pyproject.toml index 85b9039..335946d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,10 @@ version = "4.1.0" python = "^3.8" "ruamel.yaml" = "0.18.6" +[tool.poetry.group.dev.dependencies] +black = "^24.8.0" +isort = "^5.13.2" + [build-system] build-backend = "poetry.core.masonry.api" requires = ["poetry-core"] diff --git a/src/netbox_initializers/initializers/__init__.py b/src/netbox_initializers/initializers/__init__.py index 1c7f664..4789772 100644 --- a/src/netbox_initializers/initializers/__init__.py +++ b/src/netbox_initializers/initializers/__init__.py @@ -201,8 +201,8 @@ def register_initializer(name: str, initializer): from .primary_ips import PrimaryIPInitializer from .providers import ProviderInitializer from .rack_roles import RackRoleInitializer -from .racks import RackInitializer from .rack_types import RackTypeInitializer +from .racks import RackInitializer from .regions import RegionInitializer from .rirs import RIRInitializer from .route_targets import RouteTargetInitializer diff --git a/src/netbox_initializers/initializers/rack_types.py b/src/netbox_initializers/initializers/rack_types.py index 90251e6..53f3d11 100644 --- a/src/netbox_initializers/initializers/rack_types.py +++ b/src/netbox_initializers/initializers/rack_types.py @@ -1,11 +1,11 @@ -from dcim.models import RackType -from dcim.models import Manufacturer +from dcim.models import Manufacturer, RackType from . import BaseInitializer, register_initializer MATCH_PARAMS = ["slug"] REQUIRED_ASSOCS = {"manufacturer": (Manufacturer, "slug")} + class RackTypeInitializer(BaseInitializer): data_file_name = "rack_types.yml" @@ -22,7 +22,9 @@ def load_data(self): params[assoc] = model.objects.get(**query) matching_params, defaults = self.split_params(params, MATCH_PARAMS) - rack_type, created = RackType.objects.get_or_create(**matching_params, defaults=defaults) + rack_type, created = RackType.objects.get_or_create( + **matching_params, defaults=defaults + ) if created: print("๐Ÿ”ณ Created rack type", rack_type.model) diff --git a/src/netbox_initializers/initializers/racks.py b/src/netbox_initializers/initializers/racks.py index 3d37e2a..a0cb806 100644 --- a/src/netbox_initializers/initializers/racks.py +++ b/src/netbox_initializers/initializers/racks.py @@ -1,4 +1,4 @@ -from dcim.models import Location, Rack, RackRole, Site, RackType +from dcim.models import Location, Rack, RackRole, RackType, Site from tenancy.models import Tenant from . import BaseInitializer, register_initializer diff --git a/src/netbox_initializers/initializers/yaml/power_panels.yml b/src/netbox_initializers/initializers/yaml/power_panels.yml index a670ba7..80500fc 100644 --- a/src/netbox_initializers/initializers/yaml/power_panels.yml +++ b/src/netbox_initializers/initializers/yaml/power_panels.yml @@ -1,5 +1,5 @@ # - name: power panel AMS 1 -# site: AMS 1 +# site: AMS 1 # - name: power panel SING 1 -# site: SING 1 +# site: SING 1 # location: cage 101 diff --git a/src/netbox_initializers/initializers/yaml/service_templates.yml b/src/netbox_initializers/initializers/yaml/service_templates.yml index fdd0562..1a1ab73 100644 --- a/src/netbox_initializers/initializers/yaml/service_templates.yml +++ b/src/netbox_initializers/initializers/yaml/service_templates.yml @@ -8,5 +8,5 @@ # - 53 # - name: MISC # protocol: UDP -# ports: +# ports: # - 4000 diff --git a/src/netbox_initializers/initializers/yaml/services.yml b/src/netbox_initializers/initializers/yaml/services.yml index 8d4441c..b86fdd9 100644 --- a/src/netbox_initializers/initializers/yaml/services.yml +++ b/src/netbox_initializers/initializers/yaml/services.yml @@ -10,6 +10,6 @@ # virtual_machine: virtual machine 1 # - name: MISC # protocol: UDP -# ports: +# ports: # - 4000 # device: server01 From 7ade6a70b6d7a44dcd949116c6e902125e633387 Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Sun, 1 Sep 2024 13:41:30 +0200 Subject: [PATCH 07/20] Prepare for Netbox 4.1 --- .github/workflows/linter.yml | 3 ++- README.md | 4 +++- test/docker-compose.yml | 26 +++++++++++++------------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index f51f992..33533fd 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -26,10 +26,11 @@ jobs: VALIDATE_CHECKOV: false VALIDATE_JSCPD: false VALIDATE_PYTHON_MYPY: false + VALIDATE_PYTHON_PYINK: false + VALIDATE_PYTHON_RUFF: false LINTER_RULES_PATH: / PYTHON_BLACK_CONFIG_FILE: pyproject.toml FILTER_REGEX_EXCLUDE: (.*/)?(LICENSE) YAML_CONFIG_FILE: .yamllint.yaml PYTHON_FLAKE8_CONFIG_FILE: .flake8 PYTHON_ISORT_CONFIG_FILE: pyproject.toml - diff --git a/README.md b/README.md index 70a1680..8565255 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,13 @@ Load data from YAML files into Netbox ## Installation First activate your virtual environment where Netbox is installed, the install the plugin version correspondig to your Netbox version. + ```bash pip install "netbox-initializers==4.1.*" ``` + Then you need to add the plugin to the `PLUGINS` array in the Netbox configuration. + ```python PLUGINS = [ 'netbox_initializers', @@ -29,7 +32,6 @@ After you filled in the data you want to import, the import can be started with ./manage.py load_initializer_data --path /path/for/example/files ``` - ## Netbox Docker image The initializers where a part of the Docker image and where then extracted into a Netbox plugin. This was done to split the release cycle of the initializers and the image. diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 582d4f2..506d0a7 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -2,13 +2,13 @@ services: netbox: depends_on: - - postgres - - redis - - redis-cache - user: 'unit:root' + - postgres + - redis + - redis-cache + user: "unit:root" env_file: env/netbox.env volumes: - - ./initializer-data:/etc/netbox/initializer-data:z,ro + - ./initializer-data:/etc/netbox/initializer-data:z,ro build: context: .. dockerfile: test/Dockerfile @@ -17,24 +17,24 @@ services: image: postgres:15-alpine env_file: env/postgres.env volumes: - - netbox-postgres-data:/var/lib/postgresql/data + - netbox-postgres-data:/var/lib/postgresql/data # redis redis: image: redis:7-alpine command: - - sh - - -c # this is to evaluate the $REDIS_PASSWORD from the env - - redis-server --appendonly yes --requirepass $$REDIS_PASSWORD ## $$ because of docker-compose + - sh + - -c # this is to evaluate the $REDIS_PASSWORD from the env + - redis-server --appendonly yes --requirepass $$REDIS_PASSWORD ## $$ because of docker-compose env_file: env/redis.env volumes: - - netbox-redis-data:/data + - netbox-redis-data:/data redis-cache: image: redis:7-alpine command: - - sh - - -c # this is to evaluate the $REDIS_PASSWORD from the env - - redis-server --requirepass $$REDIS_PASSWORD ## $$ because of docker-compose + - sh + - -c # this is to evaluate the $REDIS_PASSWORD from the env + - redis-server --requirepass $$REDIS_PASSWORD ## $$ because of docker-compose env_file: env/redis-cache.env volumes: From ff962930b838739a3ba44b83cee0827f28dbb689 Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Sun, 1 Sep 2024 13:57:09 +0200 Subject: [PATCH 08/20] Prepare for Netbox 4.1 --- .../initializers/__init__.py | 170 ------------------ .../initializers/aggregates.py | 2 +- src/netbox_initializers/initializers/asns.py | 2 +- src/netbox_initializers/initializers/base.py | 170 ++++++++++++++++++ .../initializers/cables.py | 2 +- .../initializers/circuit_types.py | 2 +- .../initializers/circuits.py | 2 +- .../initializers/cluster_groups.py | 2 +- .../initializers/cluster_types.py | 2 +- .../initializers/clusters.py | 2 +- .../initializers/config_contexts.py | 2 +- .../initializers/config_templates.py | 2 +- .../initializers/contact_groups.py | 2 +- .../initializers/contact_roles.py | 2 +- .../initializers/contacts.py | 2 +- .../initializers/custom_fields.py | 2 +- .../initializers/custom_links.py | 2 +- .../initializers/device_roles.py | 2 +- .../initializers/device_types.py | 2 +- .../initializers/devices.py | 2 +- .../initializers/groups.py | 2 +- .../initializers/interfaces.py | 2 +- .../initializers/ip_addresses.py | 6 +- .../initializers/locations.py | 2 +- .../initializers/manufacturers.py | 2 +- .../initializers/object_permissions.py | 2 +- .../initializers/platforms.py | 2 +- .../initializers/power_feeds.py | 2 +- .../initializers/power_panels.py | 2 +- .../initializers/prefix_vlan_roles.py | 2 +- .../initializers/prefixes.py | 2 +- .../initializers/primary_ips.py | 2 +- .../initializers/providers.py | 2 +- .../initializers/rack_roles.py | 2 +- .../initializers/rack_types.py | 2 +- src/netbox_initializers/initializers/racks.py | 2 +- .../initializers/regions.py | 2 +- src/netbox_initializers/initializers/rirs.py | 2 +- .../initializers/route_targets.py | 2 +- .../initializers/service_templates.py | 2 +- .../initializers/services.py | 2 +- .../initializers/site_groups.py | 2 +- src/netbox_initializers/initializers/sites.py | 2 +- src/netbox_initializers/initializers/tags.py | 2 +- .../initializers/tenant_groups.py | 2 +- .../initializers/tenants.py | 2 +- src/netbox_initializers/initializers/users.py | 2 +- .../initializers/virtual_machines.py | 2 +- .../initializers/virtualization_interfaces.py | 2 +- .../initializers/vlan_groups.py | 2 +- src/netbox_initializers/initializers/vlans.py | 2 +- src/netbox_initializers/initializers/vrfs.py | 2 +- .../initializers/webhooks.py | 2 +- .../commands/load_initializer_data.py | 2 +- 54 files changed, 226 insertions(+), 222 deletions(-) create mode 100644 src/netbox_initializers/initializers/base.py diff --git a/src/netbox_initializers/initializers/__init__.py b/src/netbox_initializers/initializers/__init__.py index 4789772..bae56c2 100644 --- a/src/netbox_initializers/initializers/__init__.py +++ b/src/netbox_initializers/initializers/__init__.py @@ -1,173 +1,3 @@ -from pathlib import Path -from typing import Tuple - -from core.models import ObjectType -from django.core.exceptions import ObjectDoesNotExist -from extras.models import CustomField, Tag -from ruamel.yaml import YAML - -INITIALIZER_ORDER = ( - "users", - "groups", - "object_permissions", - "custom_fields", - "custom_links", - "tags", - "config_templates", - "webhooks", - "tenant_groups", - "tenants", - "site_groups", - "regions", - "rirs", - "asns", - "sites", - "locations", - "manufacturers", - "rack_roles", - "rack_types", - "racks", - "power_panels", - "power_feeds", - "platforms", - "device_roles", - "device_types", - "cluster_types", - "cluster_groups", - "clusters", - "prefix_vlan_roles", - "vlan_groups", - "vlans", - "devices", - "interfaces", - "route_targets", - "vrfs", - "aggregates", - "virtual_machines", - "virtualization_interfaces", - "prefixes", - "ip_addresses", - "primary_ips", - "services", - "service_templates", - "providers", - "circuit_types", - "circuits", - "cables", - "config_contexts", - "contact_groups", - "contact_roles", - "contacts", -) - -INITIALIZER_REGISTRY = dict() - - -class BaseInitializer: - # File name for import; Musst be set in subclass - data_file_name = "" - - def __init__(self, data_file_path: str) -> None: - self.data_file_path = data_file_path - - def load_data(self): - # Must be implemented by specific subclass - pass - - def load_yaml(self, data_file_name=None): - if data_file_name: - yf = Path(f"{self.data_file_path}/{data_file_name}") - else: - yf = Path(f"{self.data_file_path}/{self.data_file_name}") - if not yf.is_file(): - return None - with yf.open("r") as stream: - yaml = YAML(typ="safe") - return yaml.load(stream) - - def pop_custom_fields(self, params): - if "custom_field_data" in params: - return params.pop("custom_field_data") - elif "custom_fields" in params: - print("โš ๏ธ Please rename 'custom_fields' to 'custom_field_data'!") - return params.pop("custom_fields") - - return None - - def set_custom_fields_values(self, entity, custom_field_data): - if not custom_field_data: - return - - missing_cfs = [] - save = False - for key, value in custom_field_data.items(): - try: - cf = CustomField.objects.get(name=key) - except ObjectDoesNotExist: - missing_cfs.append(key) - else: - ct = ObjectType.objects.get_for_model(entity) - if ct not in cf.object_types.all(): - print( - f"โš ๏ธ Custom field {key} is not enabled for {entity}'s model!" - "Please check the 'on_objects' for that custom field in custom_fields.yml" - ) - elif key not in entity.custom_field_data: - entity.custom_field_data[key] = value - save = True - - if missing_cfs: - raise Exception( - f"โš ๏ธ Custom field(s) '{missing_cfs}' requested for {entity} but not found in Netbox!" - "Please chceck the custom_fields.yml" - ) - - if save: - entity.save() - - def set_tags(self, entity, tags): - if not tags: - return - - if not hasattr(entity, "tags"): - raise Exception(f"โš ๏ธ Tags cannot be applied to {entity}'s model") - - ct = ObjectType.objects.get_for_model(entity) - - save = False - for tag in Tag.objects.filter(name__in=tags): - restricted_cts = tag.object_types.all() - if restricted_cts and ct not in restricted_cts: - raise Exception(f"โš ๏ธ Tag {tag} cannot be applied to {entity}'s model") - - entity.tags.add(tag) - save = True - - if save: - entity.save() - - def split_params(self, 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, "__not_set__") - if param != "__not_set__": - matching_params[unique_param] = param - return matching_params, params - - -class InitializationError(Exception): - pass - - -def register_initializer(name: str, initializer): - INITIALIZER_REGISTRY[name] = initializer - - # All initializers must be imported here, to be registered from .aggregates import AggregateInitializer from .asns import ASNInitializer diff --git a/src/netbox_initializers/initializers/aggregates.py b/src/netbox_initializers/initializers/aggregates.py index 76d33c3..b9dc53b 100644 --- a/src/netbox_initializers/initializers/aggregates.py +++ b/src/netbox_initializers/initializers/aggregates.py @@ -2,7 +2,7 @@ from netaddr import IPNetwork from tenancy.models import Tenant -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["prefix", "rir"] REQUIRED_ASSOCS = {"rir": (RIR, "name")} diff --git a/src/netbox_initializers/initializers/asns.py b/src/netbox_initializers/initializers/asns.py index 02350e3..4442a04 100644 --- a/src/netbox_initializers/initializers/asns.py +++ b/src/netbox_initializers/initializers/asns.py @@ -1,7 +1,7 @@ from ipam.models import ASN, RIR from tenancy.models import Tenant -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["asn", "rir"] REQUIRED_ASSOCS = {"rir": (RIR, "name")} diff --git a/src/netbox_initializers/initializers/base.py b/src/netbox_initializers/initializers/base.py new file mode 100644 index 0000000..d7d659c --- /dev/null +++ b/src/netbox_initializers/initializers/base.py @@ -0,0 +1,170 @@ +from pathlib import Path +from typing import Tuple + +from core.models import ObjectType +from django.core.exceptions import ObjectDoesNotExist +from extras.models import CustomField, Tag +from ruamel.yaml import YAML + + +class BaseInitializer: + # File name for import; Musst be set in subclass + data_file_name = "" + + def __init__(self, data_file_path: str) -> None: + self.data_file_path = data_file_path + + def load_data(self): + # Must be implemented by specific subclass + pass + + def load_yaml(self, data_file_name=None): + if data_file_name: + yf = Path(f"{self.data_file_path}/{data_file_name}") + else: + yf = Path(f"{self.data_file_path}/{self.data_file_name}") + if not yf.is_file(): + return None + with yf.open("r") as stream: + yaml = YAML(typ="safe") + return yaml.load(stream) + + def pop_custom_fields(self, params): + if "custom_field_data" in params: + return params.pop("custom_field_data") + elif "custom_fields" in params: + print("โš ๏ธ Please rename 'custom_fields' to 'custom_field_data'!") + return params.pop("custom_fields") + + return None + + def set_custom_fields_values(self, entity, custom_field_data): + if not custom_field_data: + return + + missing_cfs = [] + save = False + for key, value in custom_field_data.items(): + try: + cf = CustomField.objects.get(name=key) + except ObjectDoesNotExist: + missing_cfs.append(key) + else: + ct = ObjectType.objects.get_for_model(entity) + if ct not in cf.object_types.all(): + print( + f"โš ๏ธ Custom field {key} is not enabled for {entity}'s model!" + "Please check the 'on_objects' for that custom field in custom_fields.yml" + ) + elif key not in entity.custom_field_data: + entity.custom_field_data[key] = value + save = True + + if missing_cfs: + raise Exception( + f"โš ๏ธ Custom field(s) '{missing_cfs}' requested for {entity} but not found in Netbox!" + "Please chceck the custom_fields.yml" + ) + + if save: + entity.save() + + def set_tags(self, entity, tags): + if not tags: + return + + if not hasattr(entity, "tags"): + raise Exception(f"โš ๏ธ Tags cannot be applied to {entity}'s model") + + ct = ObjectType.objects.get_for_model(entity) + + save = False + for tag in Tag.objects.filter(name__in=tags): + restricted_cts = tag.object_types.all() + if restricted_cts and ct not in restricted_cts: + raise Exception(f"โš ๏ธ Tag {tag} cannot be applied to {entity}'s model") + + entity.tags.add(tag) + save = True + + if save: + entity.save() + + def split_params(self, 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, "__not_set__") + if param != "__not_set__": + matching_params[unique_param] = param + return matching_params, params + + +class InitializationError(Exception): + pass + + +INITIALIZER_ORDER = ( + "users", + "groups", + "object_permissions", + "custom_fields", + "custom_links", + "tags", + "config_templates", + "webhooks", + "tenant_groups", + "tenants", + "site_groups", + "regions", + "rirs", + "asns", + "sites", + "locations", + "manufacturers", + "rack_roles", + "rack_types", + "racks", + "power_panels", + "power_feeds", + "platforms", + "device_roles", + "device_types", + "cluster_types", + "cluster_groups", + "clusters", + "prefix_vlan_roles", + "vlan_groups", + "vlans", + "devices", + "interfaces", + "route_targets", + "vrfs", + "aggregates", + "virtual_machines", + "virtualization_interfaces", + "prefixes", + "ip_addresses", + "primary_ips", + "services", + "service_templates", + "providers", + "circuit_types", + "circuits", + "cables", + "config_contexts", + "contact_groups", + "contact_roles", + "contacts", +) + + +INITIALIZER_REGISTRY = dict() + + +def register_initializer(name: str, initializer): + INITIALIZER_REGISTRY[name] = initializer diff --git a/src/netbox_initializers/initializers/cables.py b/src/netbox_initializers/initializers/cables.py index ef4f32e..5053a69 100644 --- a/src/netbox_initializers/initializers/cables.py +++ b/src/netbox_initializers/initializers/cables.py @@ -18,7 +18,7 @@ from django.contrib.contenttypes.models import ContentType from django.db.models import Q -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer CONSOLE_PORT_TERMINATION = ContentType.objects.get_for_model(ConsolePort) CONSOLE_SERVER_PORT_TERMINATION = ContentType.objects.get_for_model(ConsoleServerPort) diff --git a/src/netbox_initializers/initializers/circuit_types.py b/src/netbox_initializers/initializers/circuit_types.py index 2e1aa3b..bdc5ef0 100644 --- a/src/netbox_initializers/initializers/circuit_types.py +++ b/src/netbox_initializers/initializers/circuit_types.py @@ -1,6 +1,6 @@ from circuits.models import CircuitType -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class CircuitTypeInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/circuits.py b/src/netbox_initializers/initializers/circuits.py index 125f17c..fa7f53c 100644 --- a/src/netbox_initializers/initializers/circuits.py +++ b/src/netbox_initializers/initializers/circuits.py @@ -1,7 +1,7 @@ from circuits.models import Circuit, CircuitType, Provider from tenancy.models import Tenant -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["cid", "provider", "type"] REQUIRED_ASSOCS = {"provider": (Provider, "name"), "type": (CircuitType, "name")} diff --git a/src/netbox_initializers/initializers/cluster_groups.py b/src/netbox_initializers/initializers/cluster_groups.py index f56490a..21b8f2a 100644 --- a/src/netbox_initializers/initializers/cluster_groups.py +++ b/src/netbox_initializers/initializers/cluster_groups.py @@ -1,6 +1,6 @@ from virtualization.models import ClusterGroup -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class ClusterGroupInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/cluster_types.py b/src/netbox_initializers/initializers/cluster_types.py index cd9d811..d66edba 100644 --- a/src/netbox_initializers/initializers/cluster_types.py +++ b/src/netbox_initializers/initializers/cluster_types.py @@ -1,6 +1,6 @@ from virtualization.models import ClusterType -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class ClusterTypesInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/clusters.py b/src/netbox_initializers/initializers/clusters.py index 46d9df9..328ffc0 100644 --- a/src/netbox_initializers/initializers/clusters.py +++ b/src/netbox_initializers/initializers/clusters.py @@ -2,7 +2,7 @@ from tenancy.models import Tenant from virtualization.models import Cluster, ClusterGroup, ClusterType -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["name", "type"] REQUIRED_ASSOCS = {"type": (ClusterType, "name")} diff --git a/src/netbox_initializers/initializers/config_contexts.py b/src/netbox_initializers/initializers/config_contexts.py index 36eacde..30b90f4 100644 --- a/src/netbox_initializers/initializers/config_contexts.py +++ b/src/netbox_initializers/initializers/config_contexts.py @@ -3,7 +3,7 @@ from tenancy import models as tenancy from virtualization import models as virtualization -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["name"] OPTIONAL_MANY_ASSOCS = { diff --git a/src/netbox_initializers/initializers/config_templates.py b/src/netbox_initializers/initializers/config_templates.py index b82c237..1c25058 100644 --- a/src/netbox_initializers/initializers/config_templates.py +++ b/src/netbox_initializers/initializers/config_templates.py @@ -1,7 +1,7 @@ from django.contrib.contenttypes.models import ContentType from extras.models import ConfigTemplate -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["name", "description", "template_code", "environment_params"] diff --git a/src/netbox_initializers/initializers/contact_groups.py b/src/netbox_initializers/initializers/contact_groups.py index fc0a88a..4433c8a 100644 --- a/src/netbox_initializers/initializers/contact_groups.py +++ b/src/netbox_initializers/initializers/contact_groups.py @@ -1,6 +1,6 @@ from tenancy.models import ContactGroup -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer OPTIONAL_ASSOCS = {"parent": (ContactGroup, "name")} diff --git a/src/netbox_initializers/initializers/contact_roles.py b/src/netbox_initializers/initializers/contact_roles.py index a43316f..314c5a5 100644 --- a/src/netbox_initializers/initializers/contact_roles.py +++ b/src/netbox_initializers/initializers/contact_roles.py @@ -1,6 +1,6 @@ from tenancy.models import ContactRole -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class ContactRoleInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/contacts.py b/src/netbox_initializers/initializers/contacts.py index 64ce5c1..fa71bd4 100644 --- a/src/netbox_initializers/initializers/contacts.py +++ b/src/netbox_initializers/initializers/contacts.py @@ -1,6 +1,6 @@ from tenancy.models import Contact, ContactGroup -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer OPTIONAL_ASSOCS = {"group": (ContactGroup, "name")} diff --git a/src/netbox_initializers/initializers/custom_fields.py b/src/netbox_initializers/initializers/custom_fields.py index 7fa8307..4bc8724 100644 --- a/src/netbox_initializers/initializers/custom_fields.py +++ b/src/netbox_initializers/initializers/custom_fields.py @@ -1,6 +1,6 @@ from extras.models import CustomField, CustomFieldChoiceSet -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer def get_class_for_class_path(class_path): diff --git a/src/netbox_initializers/initializers/custom_links.py b/src/netbox_initializers/initializers/custom_links.py index 7b149f1..d9795fd 100644 --- a/src/netbox_initializers/initializers/custom_links.py +++ b/src/netbox_initializers/initializers/custom_links.py @@ -1,7 +1,7 @@ from core.models import ObjectType from extras.models import CustomLink -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer def get_content_type(content_type): diff --git a/src/netbox_initializers/initializers/device_roles.py b/src/netbox_initializers/initializers/device_roles.py index 544b49a..af961a5 100644 --- a/src/netbox_initializers/initializers/device_roles.py +++ b/src/netbox_initializers/initializers/device_roles.py @@ -1,7 +1,7 @@ from dcim.models import DeviceRole from netbox.choices import ColorChoices -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class DeviceRoleInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/device_types.py b/src/netbox_initializers/initializers/device_types.py index 7ea87d5..c946058 100644 --- a/src/netbox_initializers/initializers/device_types.py +++ b/src/netbox_initializers/initializers/device_types.py @@ -14,7 +14,7 @@ from tenancy.models import Tenant from utilities.forms.utils import expand_alphanumeric_pattern -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["manufacturer", "model", "slug"] REQUIRED_ASSOCS = {"manufacturer": (Manufacturer, "name")} diff --git a/src/netbox_initializers/initializers/devices.py b/src/netbox_initializers/initializers/devices.py index c73a925..40025dd 100644 --- a/src/netbox_initializers/initializers/devices.py +++ b/src/netbox_initializers/initializers/devices.py @@ -3,7 +3,7 @@ from tenancy.models import Tenant from virtualization.models import Cluster -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["device_type", "name", "site"] REQUIRED_ASSOCS = { diff --git a/src/netbox_initializers/initializers/groups.py b/src/netbox_initializers/initializers/groups.py index 7280d66..d70363c 100644 --- a/src/netbox_initializers/initializers/groups.py +++ b/src/netbox_initializers/initializers/groups.py @@ -1,6 +1,6 @@ from users.models import Group, User -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class GroupInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/interfaces.py b/src/netbox_initializers/initializers/interfaces.py index 81f226a..c3fcb36 100644 --- a/src/netbox_initializers/initializers/interfaces.py +++ b/src/netbox_initializers/initializers/interfaces.py @@ -1,7 +1,7 @@ from dcim.models import Device, Interface from ipam.models import VLAN -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["device", "name"] REQUIRED_ASSOCS = {"device": (Device, "name")} diff --git a/src/netbox_initializers/initializers/ip_addresses.py b/src/netbox_initializers/initializers/ip_addresses.py index db67b8f..6be8a23 100644 --- a/src/netbox_initializers/initializers/ip_addresses.py +++ b/src/netbox_initializers/initializers/ip_addresses.py @@ -6,7 +6,11 @@ from tenancy.models import Tenant from virtualization.models import VirtualMachine, VMInterface -from . import BaseInitializer, InitializationError, register_initializer +from netbox_initializers.initializers.base import ( + BaseInitializer, + InitializationError, + register_initializer, +) MATCH_PARAMS = ["address", "vrf", "vrf_id", "assigned_object_id", "assigned_object_type"] OPTIONAL_ASSOCS = { diff --git a/src/netbox_initializers/initializers/locations.py b/src/netbox_initializers/initializers/locations.py index 30ffce6..f35c050 100644 --- a/src/netbox_initializers/initializers/locations.py +++ b/src/netbox_initializers/initializers/locations.py @@ -1,6 +1,6 @@ from dcim.models import Location, Site -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer OPTIONAL_ASSOCS = {"site": (Site, "name"), "parent": (Location, "name")} diff --git a/src/netbox_initializers/initializers/manufacturers.py b/src/netbox_initializers/initializers/manufacturers.py index 820ee9f..394e3a6 100644 --- a/src/netbox_initializers/initializers/manufacturers.py +++ b/src/netbox_initializers/initializers/manufacturers.py @@ -1,6 +1,6 @@ from dcim.models import Manufacturer -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class ManufacturerInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/object_permissions.py b/src/netbox_initializers/initializers/object_permissions.py index 3ad2a5b..606c0aa 100644 --- a/src/netbox_initializers/initializers/object_permissions.py +++ b/src/netbox_initializers/initializers/object_permissions.py @@ -1,7 +1,7 @@ from core.models import ObjectType from users.models import Group, ObjectPermission, User -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class ObjectPermissionInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/platforms.py b/src/netbox_initializers/initializers/platforms.py index 092c29b..6bcb069 100644 --- a/src/netbox_initializers/initializers/platforms.py +++ b/src/netbox_initializers/initializers/platforms.py @@ -1,7 +1,7 @@ from dcim.models import Manufacturer, Platform from extras.models import ConfigTemplate -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer OPTIONAL_ASSOCS = { "manufacturer": (Manufacturer, "name"), diff --git a/src/netbox_initializers/initializers/power_feeds.py b/src/netbox_initializers/initializers/power_feeds.py index 6badd0e..e85018f 100644 --- a/src/netbox_initializers/initializers/power_feeds.py +++ b/src/netbox_initializers/initializers/power_feeds.py @@ -1,6 +1,6 @@ from dcim.models import PowerFeed, PowerPanel, Rack -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["name", "power_panel"] OPTIONAL_ASSOCS = {"rack": (Rack, "name")} diff --git a/src/netbox_initializers/initializers/power_panels.py b/src/netbox_initializers/initializers/power_panels.py index 89b92e7..60119a0 100644 --- a/src/netbox_initializers/initializers/power_panels.py +++ b/src/netbox_initializers/initializers/power_panels.py @@ -1,6 +1,6 @@ from dcim.models import Location, PowerPanel, Site -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["name", "site"] REQUIRED_ASSOCS = {"site": (Site, "name")} diff --git a/src/netbox_initializers/initializers/prefix_vlan_roles.py b/src/netbox_initializers/initializers/prefix_vlan_roles.py index 9bf0470..46be77f 100644 --- a/src/netbox_initializers/initializers/prefix_vlan_roles.py +++ b/src/netbox_initializers/initializers/prefix_vlan_roles.py @@ -1,6 +1,6 @@ from ipam.models import Role -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class RoleInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/prefixes.py b/src/netbox_initializers/initializers/prefixes.py index b4a435f..cdbada2 100644 --- a/src/netbox_initializers/initializers/prefixes.py +++ b/src/netbox_initializers/initializers/prefixes.py @@ -3,7 +3,7 @@ from netaddr import IPNetwork from tenancy.models import Tenant, TenantGroup -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["prefix", "site", "vrf", "vlan"] OPTIONAL_ASSOCS = { diff --git a/src/netbox_initializers/initializers/primary_ips.py b/src/netbox_initializers/initializers/primary_ips.py index 8f576bc..e9f6c40 100644 --- a/src/netbox_initializers/initializers/primary_ips.py +++ b/src/netbox_initializers/initializers/primary_ips.py @@ -2,7 +2,7 @@ from ipam.models import VRF, IPAddress from virtualization.models import VirtualMachine -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer OPTIONAL_ASSOCS = { "primary_ip4": (IPAddress, "address"), diff --git a/src/netbox_initializers/initializers/providers.py b/src/netbox_initializers/initializers/providers.py index 31245f9..bcc050d 100644 --- a/src/netbox_initializers/initializers/providers.py +++ b/src/netbox_initializers/initializers/providers.py @@ -1,7 +1,7 @@ from circuits.models import Provider from ipam.models import ASN -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class ProviderInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/rack_roles.py b/src/netbox_initializers/initializers/rack_roles.py index bdbbc6d..d35f7a5 100644 --- a/src/netbox_initializers/initializers/rack_roles.py +++ b/src/netbox_initializers/initializers/rack_roles.py @@ -1,7 +1,7 @@ from dcim.models import RackRole from netbox.choices import ColorChoices -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class RackRoleInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/rack_types.py b/src/netbox_initializers/initializers/rack_types.py index 53f3d11..8439474 100644 --- a/src/netbox_initializers/initializers/rack_types.py +++ b/src/netbox_initializers/initializers/rack_types.py @@ -1,6 +1,6 @@ from dcim.models import Manufacturer, RackType -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["slug"] REQUIRED_ASSOCS = {"manufacturer": (Manufacturer, "slug")} diff --git a/src/netbox_initializers/initializers/racks.py b/src/netbox_initializers/initializers/racks.py index a0cb806..60fbd44 100644 --- a/src/netbox_initializers/initializers/racks.py +++ b/src/netbox_initializers/initializers/racks.py @@ -1,7 +1,7 @@ from dcim.models import Location, Rack, RackRole, RackType, Site from tenancy.models import Tenant -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["name", "site"] REQUIRED_ASSOCS = {"site": (Site, "name")} diff --git a/src/netbox_initializers/initializers/regions.py b/src/netbox_initializers/initializers/regions.py index d6c8e28..a66b1ab 100644 --- a/src/netbox_initializers/initializers/regions.py +++ b/src/netbox_initializers/initializers/regions.py @@ -1,6 +1,6 @@ from dcim.models import Region -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer OPTIONAL_ASSOCS = {"parent": (Region, "name")} diff --git a/src/netbox_initializers/initializers/rirs.py b/src/netbox_initializers/initializers/rirs.py index 69532f3..e0b2248 100644 --- a/src/netbox_initializers/initializers/rirs.py +++ b/src/netbox_initializers/initializers/rirs.py @@ -1,6 +1,6 @@ from ipam.models import RIR -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class RIRInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/route_targets.py b/src/netbox_initializers/initializers/route_targets.py index fdb0caa..955468a 100644 --- a/src/netbox_initializers/initializers/route_targets.py +++ b/src/netbox_initializers/initializers/route_targets.py @@ -1,7 +1,7 @@ from ipam.models import RouteTarget from tenancy.models import Tenant -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer OPTIONAL_ASSOCS = {"tenant": (Tenant, "name")} diff --git a/src/netbox_initializers/initializers/service_templates.py b/src/netbox_initializers/initializers/service_templates.py index beba486..3ca00c3 100644 --- a/src/netbox_initializers/initializers/service_templates.py +++ b/src/netbox_initializers/initializers/service_templates.py @@ -1,6 +1,6 @@ from ipam.models import ServiceTemplate -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["name"] diff --git a/src/netbox_initializers/initializers/services.py b/src/netbox_initializers/initializers/services.py index 38138fb..c4f2e06 100644 --- a/src/netbox_initializers/initializers/services.py +++ b/src/netbox_initializers/initializers/services.py @@ -2,7 +2,7 @@ from ipam.models import Service from virtualization.models import VirtualMachine -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["name", "device", "virtual_machine"] OPTIONAL_ASSOCS = { diff --git a/src/netbox_initializers/initializers/site_groups.py b/src/netbox_initializers/initializers/site_groups.py index 17bc95b..f9a03dc 100644 --- a/src/netbox_initializers/initializers/site_groups.py +++ b/src/netbox_initializers/initializers/site_groups.py @@ -1,6 +1,6 @@ from dcim.models import SiteGroup -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer OPTIONAL_ASSOCS = {"parent": (SiteGroup, "name")} diff --git a/src/netbox_initializers/initializers/sites.py b/src/netbox_initializers/initializers/sites.py index 0aac182..c030343 100644 --- a/src/netbox_initializers/initializers/sites.py +++ b/src/netbox_initializers/initializers/sites.py @@ -2,7 +2,7 @@ from ipam.models import ASN from tenancy.models import Tenant -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer OPTIONAL_ASSOCS = { "region": (Region, "name"), diff --git a/src/netbox_initializers/initializers/tags.py b/src/netbox_initializers/initializers/tags.py index 72e1894..f6564f0 100644 --- a/src/netbox_initializers/initializers/tags.py +++ b/src/netbox_initializers/initializers/tags.py @@ -2,7 +2,7 @@ from extras.models import Tag from netbox.choices import ColorChoices -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class TagInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/tenant_groups.py b/src/netbox_initializers/initializers/tenant_groups.py index 4718542..353b114 100644 --- a/src/netbox_initializers/initializers/tenant_groups.py +++ b/src/netbox_initializers/initializers/tenant_groups.py @@ -1,6 +1,6 @@ from tenancy.models import TenantGroup -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class TenantGroupInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/tenants.py b/src/netbox_initializers/initializers/tenants.py index ec6668b..18ef24a 100644 --- a/src/netbox_initializers/initializers/tenants.py +++ b/src/netbox_initializers/initializers/tenants.py @@ -1,6 +1,6 @@ from tenancy.models import Tenant, TenantGroup -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer OPTIONAL_ASSOCS = {"group": (TenantGroup, "name")} diff --git a/src/netbox_initializers/initializers/users.py b/src/netbox_initializers/initializers/users.py index 895bed3..26aeb95 100644 --- a/src/netbox_initializers/initializers/users.py +++ b/src/netbox_initializers/initializers/users.py @@ -1,6 +1,6 @@ from users.models import Token, User -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer class UserInitializer(BaseInitializer): diff --git a/src/netbox_initializers/initializers/virtual_machines.py b/src/netbox_initializers/initializers/virtual_machines.py index 77191dd..c34b057 100644 --- a/src/netbox_initializers/initializers/virtual_machines.py +++ b/src/netbox_initializers/initializers/virtual_machines.py @@ -2,7 +2,7 @@ from tenancy.models import Tenant from virtualization.models import Cluster, VirtualMachine -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["cluster", "name"] REQUIRED_ASSOCS = {"cluster": (Cluster, "name")} diff --git a/src/netbox_initializers/initializers/virtualization_interfaces.py b/src/netbox_initializers/initializers/virtualization_interfaces.py index 0fe915f..abc5175 100644 --- a/src/netbox_initializers/initializers/virtualization_interfaces.py +++ b/src/netbox_initializers/initializers/virtualization_interfaces.py @@ -1,6 +1,6 @@ from virtualization.models import VirtualMachine, VMInterface -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["name", "virtual_machine"] REQUIRED_ASSOCS = {"virtual_machine": (VirtualMachine, "name")} diff --git a/src/netbox_initializers/initializers/vlan_groups.py b/src/netbox_initializers/initializers/vlan_groups.py index 5997ba3..d9d3389 100644 --- a/src/netbox_initializers/initializers/vlan_groups.py +++ b/src/netbox_initializers/initializers/vlan_groups.py @@ -1,7 +1,7 @@ from django.contrib.contenttypes.models import ContentType from ipam.models import VLANGroup -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer OPTIONAL_ASSOCS = {"scope": (None, "name")} diff --git a/src/netbox_initializers/initializers/vlans.py b/src/netbox_initializers/initializers/vlans.py index 690d44d..17094a6 100644 --- a/src/netbox_initializers/initializers/vlans.py +++ b/src/netbox_initializers/initializers/vlans.py @@ -2,7 +2,7 @@ from ipam.models import VLAN, Role, VLANGroup from tenancy.models import Tenant, TenantGroup -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["name", "vid"] OPTIONAL_ASSOCS = { diff --git a/src/netbox_initializers/initializers/vrfs.py b/src/netbox_initializers/initializers/vrfs.py index 4379e9d..6e44a52 100644 --- a/src/netbox_initializers/initializers/vrfs.py +++ b/src/netbox_initializers/initializers/vrfs.py @@ -1,7 +1,7 @@ from ipam.models import VRF from tenancy.models import Tenant -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["name", "rd"] OPTIONAL_ASSOCS = {"tenant": (Tenant, "name")} diff --git a/src/netbox_initializers/initializers/webhooks.py b/src/netbox_initializers/initializers/webhooks.py index 26625f9..bee2f08 100644 --- a/src/netbox_initializers/initializers/webhooks.py +++ b/src/netbox_initializers/initializers/webhooks.py @@ -1,7 +1,7 @@ from django.contrib.contenttypes.models import ContentType from extras.models import Webhook -from . import BaseInitializer, register_initializer +from netbox_initializers.initializers.base import BaseInitializer, register_initializer def get_content_type_id(hook_name, content_type): diff --git a/src/netbox_initializers/management/commands/load_initializer_data.py b/src/netbox_initializers/management/commands/load_initializer_data.py index 730de02..243484d 100644 --- a/src/netbox_initializers/management/commands/load_initializer_data.py +++ b/src/netbox_initializers/management/commands/load_initializer_data.py @@ -3,7 +3,7 @@ from django.core.management.base import BaseCommand, CommandError -from netbox_initializers.initializers import INITIALIZER_ORDER, INITIALIZER_REGISTRY +from netbox_initializers.initializers.base import INITIALIZER_ORDER, INITIALIZER_REGISTRY class Command(BaseCommand): From 834109bbd613dad512a930716d6d0d5df371b570 Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Sun, 1 Sep 2024 14:21:53 +0200 Subject: [PATCH 09/20] Prepare for Netbox 4.1 --- .github/workflows/linter.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 33533fd..43acc46 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -27,6 +27,7 @@ jobs: VALIDATE_JSCPD: false VALIDATE_PYTHON_MYPY: false VALIDATE_PYTHON_PYINK: false + VALIDATE_PYTHON_PYLINT: false VALIDATE_PYTHON_RUFF: false LINTER_RULES_PATH: / PYTHON_BLACK_CONFIG_FILE: pyproject.toml From d70e794b1248c23a9b46c64aa387c17ae78ccc0a Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Mon, 2 Sep 2024 11:39:17 +0200 Subject: [PATCH 10/20] Use ruff and uv --- docs/dev/Release.md | 8 +- poetry.lock | 239 ------------------ pyproject.toml | 59 +++-- src/netbox_initializers/__init__.py | 4 +- .../initializers/__init__.py | 1 + .../initializers/rack_types.py | 1 - src/netbox_initializers/version.py | 1 + uv.lock | 90 +++++++ 8 files changed, 134 insertions(+), 269 deletions(-) delete mode 100644 poetry.lock create mode 100644 src/netbox_initializers/version.py create mode 100644 uv.lock diff --git a/docs/dev/Release.md b/docs/dev/Release.md index 6851c37..f29db66 100644 --- a/docs/dev/Release.md +++ b/docs/dev/Release.md @@ -12,7 +12,7 @@ Checkout the branch for which the release is to be build. If no branch exists fo ### Set version number -For patch releases the version number in `pyproject.toml` and the `NetBoxInitializersConfig` needs to be updated. If the release is for a new Netbox version additional changes need to be made in `README.md` and `Dockerfile` (for tests). +For patch releases the version number in `src/netbox_initializers/version.py` needs to be updated. If the release is for a new Netbox version additional changes need to be made in `README.md` and `Dockerfile` (for tests). ### Build the release automatically @@ -25,17 +25,17 @@ After changing the version numbers and committing them create a new release with Install the needed Python packages for the build: ```bash -pip install --upgrade poetry +pip install --upgrade uv ``` Then run the build for the wheel and source distributions: ```bash -poetry build +uvx --from build pyproject-build --installer uv ``` #### Upload packages to PyPi ```bash -poetry publish +uvx twine upload dist/* ``` diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index 1aeaf23..0000000 --- a/poetry.lock +++ /dev/null @@ -1,239 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. - -[[package]] -name = "black" -version = "24.8.0" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-24.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09cdeb74d494ec023ded657f7092ba518e8cf78fa8386155e4a03fdcc44679e6"}, - {file = "black-24.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81c6742da39f33b08e791da38410f32e27d632260e599df7245cccee2064afeb"}, - {file = "black-24.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:707a1ca89221bc8a1a64fb5e15ef39cd755633daa672a9db7498d1c19de66a42"}, - {file = "black-24.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d6417535d99c37cee4091a2f24eb2b6d5ec42b144d50f1f2e436d9fe1916fe1a"}, - {file = "black-24.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fb6e2c0b86bbd43dee042e48059c9ad7830abd5c94b0bc518c0eeec57c3eddc1"}, - {file = "black-24.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:837fd281f1908d0076844bc2b801ad2d369c78c45cf800cad7b61686051041af"}, - {file = "black-24.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62e8730977f0b77998029da7971fa896ceefa2c4c4933fcd593fa599ecbf97a4"}, - {file = "black-24.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:72901b4913cbac8972ad911dc4098d5753704d1f3c56e44ae8dce99eecb0e3af"}, - {file = "black-24.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7c046c1d1eeb7aea9335da62472481d3bbf3fd986e093cffd35f4385c94ae368"}, - {file = "black-24.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:649f6d84ccbae73ab767e206772cc2d7a393a001070a4c814a546afd0d423aed"}, - {file = "black-24.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b59b250fdba5f9a9cd9d0ece6e6d993d91ce877d121d161e4698af3eb9c1018"}, - {file = "black-24.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:6e55d30d44bed36593c3163b9bc63bf58b3b30e4611e4d88a0c3c239930ed5b2"}, - {file = "black-24.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:505289f17ceda596658ae81b61ebbe2d9b25aa78067035184ed0a9d855d18afd"}, - {file = "black-24.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b19c9ad992c7883ad84c9b22aaa73562a16b819c1d8db7a1a1a49fb7ec13c7d2"}, - {file = "black-24.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f13f7f386f86f8121d76599114bb8c17b69d962137fc70efe56137727c7047e"}, - {file = "black-24.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:f490dbd59680d809ca31efdae20e634f3fae27fba3ce0ba3208333b713bc3920"}, - {file = "black-24.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eab4dd44ce80dea27dc69db40dab62d4ca96112f87996bca68cd75639aeb2e4c"}, - {file = "black-24.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3c4285573d4897a7610054af5a890bde7c65cb466040c5f0c8b732812d7f0e5e"}, - {file = "black-24.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e84e33b37be070ba135176c123ae52a51f82306def9f7d063ee302ecab2cf47"}, - {file = "black-24.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:73bbf84ed136e45d451a260c6b73ed674652f90a2b3211d6a35e78054563a9bb"}, - {file = "black-24.8.0-py3-none-any.whl", hash = "sha256:972085c618ee94f402da1af548a4f218c754ea7e5dc70acb168bfaca4c2542ed"}, - {file = "black-24.8.0.tar.gz", hash = "sha256:2500945420b6784c38b9ee885af039f5e7471ef284ab03fa35ecdde4688cd83f"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "isort" -version = "5.13.2" -description = "A Python utility / library to sort Python imports." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, - {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, -] - -[package.extras] -colors = ["colorama (>=0.4.6)"] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - -[[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "platformdirs" -version = "4.2.2" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, -] - -[package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] - -[[package]] -name = "ruamel-yaml" -version = "0.18.6" -description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" -optional = false -python-versions = ">=3.7" -files = [ - {file = "ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636"}, - {file = "ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b"}, -] - -[package.dependencies] -"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""} - -[package.extras] -docs = ["mercurial (>5.7)", "ryd"] -jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] - -[[package]] -name = "ruamel-yaml-clib" -version = "0.2.8" -description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" -optional = false -python-versions = ">=3.6" -files = [ - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b"}, - {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"}, - {file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"}, -] - -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.8" -content-hash = "f96359cba6be4885f3531d536e56a3a28684a39f288b2d9a86ba819f3e1161e7" diff --git a/pyproject.toml b/pyproject.toml index 335946d..553f1fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,38 +1,49 @@ -[tool.poetry] -authors = ["Tobias Genannt "] +[project] +name = "netbox-initializers" +authors = [{ name = "Tobias Genannt", email = "tobias.genannt@gmail.com" }] classifiers = [ "Framework :: Django", "Environment :: Plugins", "Topic :: System :: Networking", - "Topic :: System :: Systems Administration" + "Topic :: System :: Systems Administration", ] description = "Load initial data into Netbox" -license = "Apache-2.0" -name = "netbox-initializers" readme = "README.md" repository = "https://github.com/tobiasge/netbox-initializers" -version = "4.1.0" - -[tool.poetry.dependencies] -python = "^3.8" -"ruamel.yaml" = "0.18.6" +license = "Apache-2.0" +dynamic = ["version"] -[tool.poetry.group.dev.dependencies] -black = "^24.8.0" -isort = "^5.13.2" +requires-python = ">=3.10" +dependencies = ["ruamel-yaml>=0.18.6"] [build-system] -build-backend = "poetry.core.masonry.api" -requires = ["poetry-core"] +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.black] -line_length = 100 -target-version = ['py310'] -[tool.isort] -line_length = 100 -multi_line_output = 3 -profile = "black" +[tool.hatch.version] +path = "src/netbox_initializers/version.py" + +[tool.uv] +dev-dependencies = ["ruff==0.6.3"] + +[tool.ruff] +line-length = 100 +target-version = "py311" + +[tool.ruff.lint] +extend-select = ["I", "PL", "W191", "W291", "W292", "W293"] +ignore = ["PLR0912", "PLR0915"] + +[tool.ruff.lint.isort] +section-order = [ + "future", + "standard-library", + "third-party", + "first-party", + "local-folder", +] -[tool.pylint.format] -max-line-length = "100" +[tool.ruff.format] +docstring-code-format = true +docstring-code-line-length = "dynamic" diff --git a/src/netbox_initializers/__init__.py b/src/netbox_initializers/__init__.py index a6e9763..d8f0437 100644 --- a/src/netbox_initializers/__init__.py +++ b/src/netbox_initializers/__init__.py @@ -1,11 +1,13 @@ from netbox.plugins import PluginConfig +from netbox_initializers.version import VERSION + class NetBoxInitializersConfig(PluginConfig): name = "netbox_initializers" verbose_name = "NetBox Initializers" description = "Load initial data into Netbox" - version = "4.1.0" + version = VERSION base_url = "initializers" min_version = "4.1-beta1" max_version = "4.1.99" diff --git a/src/netbox_initializers/initializers/__init__.py b/src/netbox_initializers/initializers/__init__.py index bae56c2..b4e185e 100644 --- a/src/netbox_initializers/initializers/__init__.py +++ b/src/netbox_initializers/initializers/__init__.py @@ -1,3 +1,4 @@ +# ruff: noqa: F401 # All initializers must be imported here, to be registered from .aggregates import AggregateInitializer from .asns import ASNInitializer diff --git a/src/netbox_initializers/initializers/rack_types.py b/src/netbox_initializers/initializers/rack_types.py index 8439474..87c9d11 100644 --- a/src/netbox_initializers/initializers/rack_types.py +++ b/src/netbox_initializers/initializers/rack_types.py @@ -14,7 +14,6 @@ def load_data(self): if rack_types is None: return for params in rack_types: - for assoc, details in REQUIRED_ASSOCS.items(): model, field = details query = {field: params.pop(assoc)} diff --git a/src/netbox_initializers/version.py b/src/netbox_initializers/version.py new file mode 100644 index 0000000..73f980c --- /dev/null +++ b/src/netbox_initializers/version.py @@ -0,0 +1 @@ +VERSION = "4.1.0" diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..e17bbf7 --- /dev/null +++ b/uv.lock @@ -0,0 +1,90 @@ +version = 1 +requires-python = ">=3.10" + +[[package]] +name = "netbox-initializers" +version = "4.1.0" +source = { editable = "." } +dependencies = [ + { name = "ruamel-yaml" }, +] + +[package.dev-dependencies] +dev = [ + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "ruamel-yaml", specifier = ">=0.18.6" }] + +[package.metadata.requires-dev] +dev = [{ name = "ruff", specifier = "==0.6.3" }] + +[[package]] +name = "ruamel-yaml" +version = "0.18.6" +source = { registry = "https://nexus.scanplus.de/repository/pypi-group/simple" } +dependencies = [ + { name = "ruamel-yaml-clib", marker = "python_full_version < '3.13' and platform_python_implementation == 'CPython'" }, +] +sdist = { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml/0.18.6/ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b" } +wheels = [ + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml/0.18.6/ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636" }, +] + +[[package]] +name = "ruamel-yaml-clib" +version = "0.2.8" +source = { registry = "https://nexus.scanplus.de/repository/pypi-group/simple" } +sdist = { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512" } +wheels = [ + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b" }, +] + +[[package]] +name = "ruff" +version = "0.6.3" +source = { registry = "https://nexus.scanplus.de/repository/pypi-group/simple" } +sdist = { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3.tar.gz", hash = "sha256:183b99e9edd1ef63be34a3b51fee0a9f4ab95add123dbf89a71f7b1f0c991983" } +wheels = [ + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-linux_armv6l.whl", hash = "sha256:97f58fda4e309382ad30ede7f30e2791d70dd29ea17f41970119f55bdb7a45c3" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3b061e49b5cf3a297b4d1c27ac5587954ccb4ff601160d3d6b2f70b1622194dc" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:34e2824a13bb8c668c71c1760a6ac7d795ccbd8d38ff4a0d8471fdb15de910b1" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bddfbb8d63c460f4b4128b6a506e7052bad4d6f3ff607ebbb41b0aa19c2770d1" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ced3eeb44df75353e08ab3b6a9e113b5f3f996bea48d4f7c027bc528ba87b672" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47021dff5445d549be954eb275156dfd7c37222acc1e8014311badcb9b4ec8c1" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7d7bd20dc07cebd68cc8bc7b3f5ada6d637f42d947c85264f94b0d1cd9d87384" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:500f166d03fc6d0e61c8e40a3ff853fa8a43d938f5d14c183c612df1b0d6c58a" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:42844ff678f9b976366b262fa2d1d1a3fe76f6e145bd92c84e27d172e3c34500" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70452a10eb2d66549de8e75f89ae82462159855e983ddff91bc0bce6511d0470" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:65a533235ed55f767d1fc62193a21cbf9e3329cf26d427b800fdeacfb77d296f" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2e2c23cef30dc3cbe9cc5d04f2899e7f5e478c40d2e0a633513ad081f7361b5" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d8a136aa7d228975a6aee3dd8bea9b28e2b43e9444aa678fb62aeb1956ff2351" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f92fe93bc72e262b7b3f2bba9879897e2d58a989b4714ba6a5a7273e842ad2f8" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-win32.whl", hash = "sha256:7a62d3b5b0d7f9143d94893f8ba43aa5a5c51a0ffc4a401aa97a81ed76930521" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-win_amd64.whl", hash = "sha256:746af39356fee2b89aada06c7376e1aa274a23493d7016059c3a72e3b296befb" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-win_arm64.whl", hash = "sha256:14a9528a8b70ccc7a847637c29e56fd1f9183a9db743bbc5b8e0c4ad60592a82" }, +] From eb0d85eff13f4712b772c58c0306ec434d725659 Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Mon, 2 Sep 2024 11:54:05 +0200 Subject: [PATCH 11/20] Use ruff and uv --- .github/workflows/linter.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 43acc46..b555138 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -25,10 +25,12 @@ jobs: VALIDATE_ALL_CODEBASE: false VALIDATE_CHECKOV: false VALIDATE_JSCPD: false + VALIDATE_PYTHON_BLACK: false + VALIDATE_PYTHON_ISORT: false VALIDATE_PYTHON_MYPY: false VALIDATE_PYTHON_PYINK: false VALIDATE_PYTHON_PYLINT: false - VALIDATE_PYTHON_RUFF: false + VALIDATE_PYTHON_RUFF: true LINTER_RULES_PATH: / PYTHON_BLACK_CONFIG_FILE: pyproject.toml FILTER_REGEX_EXCLUDE: (.*/)?(LICENSE) From c2296cdd51343a3366e5e1fdd0fc6a18b55a2be8 Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Mon, 2 Sep 2024 12:01:57 +0200 Subject: [PATCH 12/20] Use ruff and uv --- .github/workflows/linter.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index b555138..475cd48 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -32,8 +32,7 @@ jobs: VALIDATE_PYTHON_PYLINT: false VALIDATE_PYTHON_RUFF: true LINTER_RULES_PATH: / - PYTHON_BLACK_CONFIG_FILE: pyproject.toml FILTER_REGEX_EXCLUDE: (.*/)?(LICENSE) YAML_CONFIG_FILE: .yamllint.yaml PYTHON_FLAKE8_CONFIG_FILE: .flake8 - PYTHON_ISORT_CONFIG_FILE: pyproject.toml + From 566ddd6bc92b0382f72c609b4d888a123f1b44fb Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Mon, 2 Sep 2024 12:05:57 +0200 Subject: [PATCH 13/20] Use ruff and uv --- .github/workflows/linter.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 475cd48..f43737e 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -30,7 +30,6 @@ jobs: VALIDATE_PYTHON_MYPY: false VALIDATE_PYTHON_PYINK: false VALIDATE_PYTHON_PYLINT: false - VALIDATE_PYTHON_RUFF: true LINTER_RULES_PATH: / FILTER_REGEX_EXCLUDE: (.*/)?(LICENSE) YAML_CONFIG_FILE: .yamllint.yaml From d77e87ac38ea935f1b607842cfe53fc7cc278d8c Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Mon, 2 Sep 2024 12:08:28 +0200 Subject: [PATCH 14/20] Use ruff and uv --- .github/workflows/codeql-analysis.yml | 28 +++++++++++++-------------- .github/workflows/linter.yml | 1 - 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 9297268..2369637 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,12 +2,12 @@ name: "CodeQL" on: push: - branches: [ "main" ] + branches: ["main"] pull_request: # The branches below must be a subset of the branches above - branches: [ "main" ] + branches: ["main"] schedule: - - cron: '38 4 * * 2' + - cron: "38 4 * * 2" jobs: analyze: @@ -20,15 +20,15 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'python' ] + language: ["python"] steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" + - name: Checkout repository + uses: actions/checkout@v4 + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index f43737e..16efaaf 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -34,4 +34,3 @@ jobs: FILTER_REGEX_EXCLUDE: (.*/)?(LICENSE) YAML_CONFIG_FILE: .yamllint.yaml PYTHON_FLAKE8_CONFIG_FILE: .flake8 - From 501c9ab89082e12f856d62cc916334eeb9666528 Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Mon, 2 Sep 2024 12:40:09 +0200 Subject: [PATCH 15/20] Use ruff and uv --- .github/workflows/release.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a376cf6..b7f68f6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,8 +20,17 @@ jobs: - id: git-checkout name: Checkout uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: "3.12" + - name: Install uv + run: pip install uv - id: build-and-publish name: Build and publish to pypi - uses: JRubics/poetry-publish@v2.0 - with: - pypi_token: ${{ secrets.PYPI_TOKEN }} + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} + TWINE_NON_INTERACTIVE: "true" + run: | + uvx --from build pyproject-build + uvx twine upload dist/* From 3f19d7085caef41f3868ce712af11bd797a144f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 20:31:21 +0000 Subject: [PATCH 16/20] Bump actions/setup-python from 4 to 5 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b7f68f6..1b02349 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: - id: git-checkout name: Checkout uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install uv From 0e29836527dcc433b3b2dab3994fc32c147449af Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Thu, 5 Sep 2024 19:59:30 +0200 Subject: [PATCH 17/20] Fixed uv.lock --- pyproject.toml | 1 - uv.lock | 96 +++++++++++++++++++++++++------------------------- 2 files changed, 48 insertions(+), 49 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 553f1fc..5445898 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,6 @@ dependencies = ["ruamel-yaml>=0.18.6"] requires = ["hatchling"] build-backend = "hatchling.build" - [tool.hatch.version] path = "src/netbox_initializers/version.py" diff --git a/uv.lock b/uv.lock index e17bbf7..be6974e 100644 --- a/uv.lock +++ b/uv.lock @@ -23,68 +23,68 @@ dev = [{ name = "ruff", specifier = "==0.6.3" }] [[package]] name = "ruamel-yaml" version = "0.18.6" -source = { registry = "https://nexus.scanplus.de/repository/pypi-group/simple" } +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ruamel-yaml-clib", marker = "python_full_version < '3.13' and platform_python_implementation == 'CPython'" }, ] -sdist = { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml/0.18.6/ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b" } +sdist = { url = "https://files.pythonhosted.org/packages/29/81/4dfc17eb6ebb1aac314a3eb863c1325b907863a1b8b1382cdffcb6ac0ed9/ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b", size = 143362 } wheels = [ - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml/0.18.6/ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636" }, + { url = "https://files.pythonhosted.org/packages/73/67/8ece580cc363331d9a53055130f86b096bf16e38156e33b1d3014fffda6b/ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636", size = 117761 }, ] [[package]] name = "ruamel-yaml-clib" version = "0.2.8" -source = { registry = "https://nexus.scanplus.de/repository/pypi-group/simple" } -sdist = { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512" } +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/46/ab/bab9eb1566cd16f060b54055dd39cf6a34bfa0240c53a7218c43e974295b/ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512", size = 213824 } wheels = [ - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b" }, + { url = "https://files.pythonhosted.org/packages/ca/01/37ac131614f71b98e9b148b2d7790662dcee92217d2fb4bac1aa377def33/ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d", size = 148236 }, + { url = "https://files.pythonhosted.org/packages/61/ee/4874c9fc96010fce85abefdcbe770650c5324288e988d7a48b527a423815/ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462", size = 133996 }, + { url = "https://files.pythonhosted.org/packages/d3/62/c60b034d9a008bbd566eeecf53a5a4c73d191c8de261290db6761802b72d/ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412", size = 526680 }, + { url = "https://files.pythonhosted.org/packages/90/8c/6cdb44f548b29eb6328b9e7e175696336bc856de2ff82e5776f860f03822/ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f", size = 605853 }, + { url = "https://files.pythonhosted.org/packages/88/30/fc45b45d5eaf2ff36cffd215a2f85e9b90ac04e70b97fd4097017abfb567/ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334", size = 655206 }, + { url = "https://files.pythonhosted.org/packages/af/dc/133547f90f744a0c827bac5411d84d4e81da640deb3af1459e38c5f3b6a0/ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d", size = 689649 }, + { url = "https://files.pythonhosted.org/packages/23/1d/589139191b187a3c750ae8d983c42fd799246d5f0dd84451a0575c9bdbe9/ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d", size = 100044 }, + { url = "https://files.pythonhosted.org/packages/4f/5b/744df20285a75ac4c606452ce9a0fcc42087d122f42294518ded1017697c/ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31", size = 117825 }, + { url = "https://files.pythonhosted.org/packages/b1/15/971b385c098e8d0d170893f5ba558452bb7b776a0c90658b8f4dd0e3382b/ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069", size = 148870 }, + { url = "https://files.pythonhosted.org/packages/01/b0/4ddef56e9f703d7909febc3a421d709a3482cda25826816ec595b73e3847/ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248", size = 134475 }, + { url = "https://files.pythonhosted.org/packages/a4/f7/22d6b620ed895a05d40802d8281eff924dc6190f682d933d4efff60db3b5/ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b", size = 544020 }, + { url = "https://files.pythonhosted.org/packages/7c/e4/0d19d65e340f93df1c47f323d95fa4b256bb28320290f5fddef90837853a/ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe", size = 642643 }, + { url = "https://files.pythonhosted.org/packages/c9/ff/f781eb5e2ae011e586d5426e2086a011cf1e0f59704a6cad1387975c5a62/ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899", size = 695832 }, + { url = "https://files.pythonhosted.org/packages/e3/41/f62e67ac651358b8f0d60cfb12ab2daf99b1b69eeaa188d0cec809d943a6/ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9", size = 730923 }, + { url = "https://files.pythonhosted.org/packages/9f/f0/19ab8acbf983cd1b37f47d27ceb8b10a738d60d36316a54bad57e0d73fbb/ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7", size = 99999 }, + { url = "https://files.pythonhosted.org/packages/ec/54/d8a795997921d87224c65d44499ca595a833093fb215b133f920c1062956/ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb", size = 118008 }, + { url = "https://files.pythonhosted.org/packages/7a/a2/eb5e9d088cb9d15c24d956944c09dca0a89108ad6e2e913c099ef36e3f0d/ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1", size = 144636 }, + { url = "https://files.pythonhosted.org/packages/66/98/8de4f22bbfd9135deb3422e96d450c4bc0a57d38c25976119307d2efe0aa/ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2", size = 135684 }, + { url = "https://files.pythonhosted.org/packages/30/d3/5fe978cd01a61c12efd24d65fa68c6f28f28c8073a06cf11db3a854390ca/ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92", size = 734571 }, + { url = "https://files.pythonhosted.org/packages/55/b3/e2531a050758b717c969cbf76c103b75d8a01e11af931b94ba656117fbe9/ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62", size = 643946 }, + { url = "https://files.pythonhosted.org/packages/0d/aa/06db7ca0995b513538402e11280282c615b5ae5f09eb820460d35fb69715/ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9", size = 692169 }, + { url = "https://files.pythonhosted.org/packages/27/38/4cf4d482b84ecdf51efae6635cc5483a83cf5ca9d9c13e205a750e251696/ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d", size = 740325 }, + { url = "https://files.pythonhosted.org/packages/6f/67/c62c6eea53a4feb042727a3d6c18f50dc99683c2b199c06bd2a9e3db8e22/ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa", size = 98639 }, + { url = "https://files.pythonhosted.org/packages/10/d2/52a3d810d0b5b3720725c0504a27b3fced7b6f310fe928f7019d79387bc1/ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b", size = 115305 }, ] [[package]] name = "ruff" version = "0.6.3" -source = { registry = "https://nexus.scanplus.de/repository/pypi-group/simple" } -sdist = { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3.tar.gz", hash = "sha256:183b99e9edd1ef63be34a3b51fee0a9f4ab95add123dbf89a71f7b1f0c991983" } +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5d/f9/0b32e5d1c6f957df49398cd882a011e9488fcbca0d6acfeeea50ccd37a4d/ruff-0.6.3.tar.gz", hash = "sha256:183b99e9edd1ef63be34a3b51fee0a9f4ab95add123dbf89a71f7b1f0c991983", size = 2463514 } wheels = [ - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-linux_armv6l.whl", hash = "sha256:97f58fda4e309382ad30ede7f30e2791d70dd29ea17f41970119f55bdb7a45c3" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3b061e49b5cf3a297b4d1c27ac5587954ccb4ff601160d3d6b2f70b1622194dc" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:34e2824a13bb8c668c71c1760a6ac7d795ccbd8d38ff4a0d8471fdb15de910b1" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bddfbb8d63c460f4b4128b6a506e7052bad4d6f3ff607ebbb41b0aa19c2770d1" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ced3eeb44df75353e08ab3b6a9e113b5f3f996bea48d4f7c027bc528ba87b672" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47021dff5445d549be954eb275156dfd7c37222acc1e8014311badcb9b4ec8c1" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7d7bd20dc07cebd68cc8bc7b3f5ada6d637f42d947c85264f94b0d1cd9d87384" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:500f166d03fc6d0e61c8e40a3ff853fa8a43d938f5d14c183c612df1b0d6c58a" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:42844ff678f9b976366b262fa2d1d1a3fe76f6e145bd92c84e27d172e3c34500" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70452a10eb2d66549de8e75f89ae82462159855e983ddff91bc0bce6511d0470" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:65a533235ed55f767d1fc62193a21cbf9e3329cf26d427b800fdeacfb77d296f" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2e2c23cef30dc3cbe9cc5d04f2899e7f5e478c40d2e0a633513ad081f7361b5" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d8a136aa7d228975a6aee3dd8bea9b28e2b43e9444aa678fb62aeb1956ff2351" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f92fe93bc72e262b7b3f2bba9879897e2d58a989b4714ba6a5a7273e842ad2f8" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-win32.whl", hash = "sha256:7a62d3b5b0d7f9143d94893f8ba43aa5a5c51a0ffc4a401aa97a81ed76930521" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-win_amd64.whl", hash = "sha256:746af39356fee2b89aada06c7376e1aa274a23493d7016059c3a72e3b296befb" }, - { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.6.3/ruff-0.6.3-py3-none-win_arm64.whl", hash = "sha256:14a9528a8b70ccc7a847637c29e56fd1f9183a9db743bbc5b8e0c4ad60592a82" }, + { url = "https://files.pythonhosted.org/packages/72/68/1da6a1e39a03a229ea57c511691d6225072759cc7764206c3f0989521194/ruff-0.6.3-py3-none-linux_armv6l.whl", hash = "sha256:97f58fda4e309382ad30ede7f30e2791d70dd29ea17f41970119f55bdb7a45c3", size = 9696928 }, + { url = "https://files.pythonhosted.org/packages/6e/59/3b8b1d3a4271c6eb6ceecd3cef19a6d881639a0f18ad651563d6f619aaae/ruff-0.6.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3b061e49b5cf3a297b4d1c27ac5587954ccb4ff601160d3d6b2f70b1622194dc", size = 9448462 }, + { url = "https://files.pythonhosted.org/packages/35/4f/b942ecb8bbebe53aa9b33e9b96df88acd50b70adaaed3070f1d92131a1cb/ruff-0.6.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:34e2824a13bb8c668c71c1760a6ac7d795ccbd8d38ff4a0d8471fdb15de910b1", size = 9176190 }, + { url = "https://files.pythonhosted.org/packages/a0/20/b0bcb29d4ee437f3567b73b6905c034e2e94d29b9b826c66daecc1cf6388/ruff-0.6.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bddfbb8d63c460f4b4128b6a506e7052bad4d6f3ff607ebbb41b0aa19c2770d1", size = 10108892 }, + { url = "https://files.pythonhosted.org/packages/9c/e3/211bc759f424e8823a9937e0f678695ca02113c621dfde1fa756f9f26f6d/ruff-0.6.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ced3eeb44df75353e08ab3b6a9e113b5f3f996bea48d4f7c027bc528ba87b672", size = 9476471 }, + { url = "https://files.pythonhosted.org/packages/b2/a3/2ec35a2d7a554364864206f0e46812b92a074ad8a014b923d821ead532aa/ruff-0.6.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47021dff5445d549be954eb275156dfd7c37222acc1e8014311badcb9b4ec8c1", size = 10294802 }, + { url = "https://files.pythonhosted.org/packages/03/8b/56ef687b3489c88886dea48c78fb4969b6b65f18007d0ac450070edd1f58/ruff-0.6.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7d7bd20dc07cebd68cc8bc7b3f5ada6d637f42d947c85264f94b0d1cd9d87384", size = 11022372 }, + { url = "https://files.pythonhosted.org/packages/a5/21/327d147feb442adb88975e81e2263102789eba9ad2afa102c661912a482f/ruff-0.6.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:500f166d03fc6d0e61c8e40a3ff853fa8a43d938f5d14c183c612df1b0d6c58a", size = 10596596 }, + { url = "https://files.pythonhosted.org/packages/6c/86/ff386de63729da3e08c8099c57f577a00ec9f3eea711b23ac07cf3588dc5/ruff-0.6.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:42844ff678f9b976366b262fa2d1d1a3fe76f6e145bd92c84e27d172e3c34500", size = 11572830 }, + { url = "https://files.pythonhosted.org/packages/38/5d/b33284c108e3f315ddd09b70296fd76bd28ecf8965a520bc93f3bbd8ac40/ruff-0.6.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70452a10eb2d66549de8e75f89ae82462159855e983ddff91bc0bce6511d0470", size = 10262577 }, + { url = "https://files.pythonhosted.org/packages/29/99/9cdfad0d7f460e66567236eddc691473791afd9aff93a0dfcdef0462a6c7/ruff-0.6.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:65a533235ed55f767d1fc62193a21cbf9e3329cf26d427b800fdeacfb77d296f", size = 10098751 }, + { url = "https://files.pythonhosted.org/packages/a8/9f/f801a1619f5549e552f1f722f1db57eb39e7e1d83d482133142781d450de/ruff-0.6.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2e2c23cef30dc3cbe9cc5d04f2899e7f5e478c40d2e0a633513ad081f7361b5", size = 9563859 }, + { url = "https://files.pythonhosted.org/packages/0b/4d/fb2424faf04ffdb960ae2b3a1d991c5183dd981003de727d2d5cc38abc98/ruff-0.6.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d8a136aa7d228975a6aee3dd8bea9b28e2b43e9444aa678fb62aeb1956ff2351", size = 9914291 }, + { url = "https://files.pythonhosted.org/packages/2e/dd/94fddf002a8f6152e8ebfbb51d3f93febc415c1fe694345623c31ce8b33b/ruff-0.6.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f92fe93bc72e262b7b3f2bba9879897e2d58a989b4714ba6a5a7273e842ad2f8", size = 10331549 }, + { url = "https://files.pythonhosted.org/packages/b4/73/ca9c2f9237a430ca423b6dca83b77e9a428afeb7aec80596e86c369123fe/ruff-0.6.3-py3-none-win32.whl", hash = "sha256:7a62d3b5b0d7f9143d94893f8ba43aa5a5c51a0ffc4a401aa97a81ed76930521", size = 7962163 }, + { url = "https://files.pythonhosted.org/packages/55/ce/061c605b1dfb52748d59bc0c7a8507546c178801156415773d18febfd71d/ruff-0.6.3-py3-none-win_amd64.whl", hash = "sha256:746af39356fee2b89aada06c7376e1aa274a23493d7016059c3a72e3b296befb", size = 8800901 }, + { url = "https://files.pythonhosted.org/packages/63/28/ae4ffe7d3b6134ca6d31ebef07447ef70097c4a9e8fbbc519b374c5c1559/ruff-0.6.3-py3-none-win_arm64.whl", hash = "sha256:14a9528a8b70ccc7a847637c29e56fd1f9183a9db743bbc5b8e0c4ad60592a82", size = 8229171 }, ] From 57794486f7ea7f72bede8adbab2fcae382a4322e Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Wed, 15 Jan 2025 07:32:34 +0100 Subject: [PATCH 18/20] Prepare for Netbox 4.2 --- README.md | 6 +- pyproject.toml | 4 +- src/netbox_initializers/__init__.py | 4 +- src/netbox_initializers/initializers/users.py | 3 +- src/netbox_initializers/version.py | 2 +- test/Dockerfile | 2 +- uv.lock | 106 +++++++++--------- 7 files changed, 64 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 8565255..51a9950 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Load data from YAML files into Netbox First activate your virtual environment where Netbox is installed, the install the plugin version correspondig to your Netbox version. ```bash -pip install "netbox-initializers==4.1.*" +pip install "netbox-initializers==4.2.*" ``` Then you need to add the plugin to the `PLUGINS` array in the Netbox configuration. @@ -38,6 +38,6 @@ The initializers where a part of the Docker image and where then extracted into To use the new plugin in a the Netbox Docker image, it musst be installad into the image. To this, the following example can be used as a starting point: ```dockerfile -FROM netboxcommunity/netbox:v4.1 -RUN /opt/netbox/venv/bin/pip install "netbox-initializers==4.1.*" +FROM netboxcommunity/netbox:v4.2 +RUN /opt/netbox/venv/bin/pip install "netbox-initializers==4.2.*" ``` diff --git a/pyproject.toml b/pyproject.toml index 5445898..15e9d54 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ license = "Apache-2.0" dynamic = ["version"] requires-python = ">=3.10" -dependencies = ["ruamel-yaml>=0.18.6"] +dependencies = ["ruamel-yaml>=0.18.10"] [build-system] requires = ["hatchling"] @@ -24,7 +24,7 @@ build-backend = "hatchling.build" path = "src/netbox_initializers/version.py" [tool.uv] -dev-dependencies = ["ruff==0.6.3"] +dev-dependencies = ["ruff==0.9.1"] [tool.ruff] line-length = 100 diff --git a/src/netbox_initializers/__init__.py b/src/netbox_initializers/__init__.py index d8f0437..05f8d7e 100644 --- a/src/netbox_initializers/__init__.py +++ b/src/netbox_initializers/__init__.py @@ -9,8 +9,8 @@ class NetBoxInitializersConfig(PluginConfig): description = "Load initial data into Netbox" version = VERSION base_url = "initializers" - min_version = "4.1-beta1" - max_version = "4.1.99" + min_version = "4.2.0" + max_version = "4.2.99" config = NetBoxInitializersConfig diff --git a/src/netbox_initializers/initializers/users.py b/src/netbox_initializers/initializers/users.py index 26aeb95..4a987b6 100644 --- a/src/netbox_initializers/initializers/users.py +++ b/src/netbox_initializers/initializers/users.py @@ -1,3 +1,4 @@ +from django.utils.crypto import get_random_string from users.models import Token, User from netbox_initializers.initializers.base import BaseInitializer, register_initializer @@ -13,7 +14,7 @@ def load_data(self): for username, user_details in users.items(): api_token = user_details.pop("api_token", Token.generate_key()) - password = user_details.pop("password", User.objects.make_random_password()) + password = user_details.pop("password", get_random_string(length=25)) user, created = User.objects.get_or_create(username=username, defaults=user_details) if created: user.set_password(password) diff --git a/src/netbox_initializers/version.py b/src/netbox_initializers/version.py index 73f980c..773464b 100644 --- a/src/netbox_initializers/version.py +++ b/src/netbox_initializers/version.py @@ -1 +1 @@ -VERSION = "4.1.0" +VERSION = "4.2.0" diff --git a/test/Dockerfile b/test/Dockerfile index ba25a73..73d3211 100644 --- a/test/Dockerfile +++ b/test/Dockerfile @@ -1,4 +1,4 @@ -FROM netboxcommunity/netbox:feature +FROM netboxcommunity/netbox:v4.2 COPY ../ /opt/netbox-initializers/ COPY ./test/config/plugins.py /etc/netbox/config/ diff --git a/uv.lock b/uv.lock index be6974e..7e05d68 100644 --- a/uv.lock +++ b/uv.lock @@ -3,7 +3,7 @@ requires-python = ">=3.10" [[package]] name = "netbox-initializers" -version = "4.1.0" +version = "4.2.0" source = { editable = "." } dependencies = [ { name = "ruamel-yaml" }, @@ -15,76 +15,76 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "ruamel-yaml", specifier = ">=0.18.6" }] +requires-dist = [{ name = "ruamel-yaml", specifier = ">=0.18.10" }] [package.metadata.requires-dev] -dev = [{ name = "ruff", specifier = "==0.6.3" }] +dev = [{ name = "ruff", specifier = "==0.9.1" }] [[package]] name = "ruamel-yaml" -version = "0.18.6" -source = { registry = "https://pypi.org/simple" } +version = "0.18.10" +source = { registry = "https://nexus.scanplus.de/repository/pypi-group/simple" } dependencies = [ { name = "ruamel-yaml-clib", marker = "python_full_version < '3.13' and platform_python_implementation == 'CPython'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/29/81/4dfc17eb6ebb1aac314a3eb863c1325b907863a1b8b1382cdffcb6ac0ed9/ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b", size = 143362 } +sdist = { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml/0.18.10/ruamel.yaml-0.18.10.tar.gz", hash = "sha256:20c86ab29ac2153f80a428e1254a8adf686d3383df04490514ca3b79a362db58" } wheels = [ - { url = "https://files.pythonhosted.org/packages/73/67/8ece580cc363331d9a53055130f86b096bf16e38156e33b1d3014fffda6b/ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636", size = 117761 }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml/0.18.10/ruamel.yaml-0.18.10-py3-none-any.whl", hash = "sha256:30f22513ab2301b3d2b577adc121c6471f28734d3d9728581245f1e76468b4f1" }, ] [[package]] name = "ruamel-yaml-clib" version = "0.2.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/46/ab/bab9eb1566cd16f060b54055dd39cf6a34bfa0240c53a7218c43e974295b/ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512", size = 213824 } +source = { registry = "https://nexus.scanplus.de/repository/pypi-group/simple" } +sdist = { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/01/37ac131614f71b98e9b148b2d7790662dcee92217d2fb4bac1aa377def33/ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d", size = 148236 }, - { url = "https://files.pythonhosted.org/packages/61/ee/4874c9fc96010fce85abefdcbe770650c5324288e988d7a48b527a423815/ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462", size = 133996 }, - { url = "https://files.pythonhosted.org/packages/d3/62/c60b034d9a008bbd566eeecf53a5a4c73d191c8de261290db6761802b72d/ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412", size = 526680 }, - { url = "https://files.pythonhosted.org/packages/90/8c/6cdb44f548b29eb6328b9e7e175696336bc856de2ff82e5776f860f03822/ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f", size = 605853 }, - { url = "https://files.pythonhosted.org/packages/88/30/fc45b45d5eaf2ff36cffd215a2f85e9b90ac04e70b97fd4097017abfb567/ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334", size = 655206 }, - { url = "https://files.pythonhosted.org/packages/af/dc/133547f90f744a0c827bac5411d84d4e81da640deb3af1459e38c5f3b6a0/ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d", size = 689649 }, - { url = "https://files.pythonhosted.org/packages/23/1d/589139191b187a3c750ae8d983c42fd799246d5f0dd84451a0575c9bdbe9/ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d", size = 100044 }, - { url = "https://files.pythonhosted.org/packages/4f/5b/744df20285a75ac4c606452ce9a0fcc42087d122f42294518ded1017697c/ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31", size = 117825 }, - { url = "https://files.pythonhosted.org/packages/b1/15/971b385c098e8d0d170893f5ba558452bb7b776a0c90658b8f4dd0e3382b/ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069", size = 148870 }, - { url = "https://files.pythonhosted.org/packages/01/b0/4ddef56e9f703d7909febc3a421d709a3482cda25826816ec595b73e3847/ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248", size = 134475 }, - { url = "https://files.pythonhosted.org/packages/a4/f7/22d6b620ed895a05d40802d8281eff924dc6190f682d933d4efff60db3b5/ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b", size = 544020 }, - { url = "https://files.pythonhosted.org/packages/7c/e4/0d19d65e340f93df1c47f323d95fa4b256bb28320290f5fddef90837853a/ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe", size = 642643 }, - { url = "https://files.pythonhosted.org/packages/c9/ff/f781eb5e2ae011e586d5426e2086a011cf1e0f59704a6cad1387975c5a62/ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899", size = 695832 }, - { url = "https://files.pythonhosted.org/packages/e3/41/f62e67ac651358b8f0d60cfb12ab2daf99b1b69eeaa188d0cec809d943a6/ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9", size = 730923 }, - { url = "https://files.pythonhosted.org/packages/9f/f0/19ab8acbf983cd1b37f47d27ceb8b10a738d60d36316a54bad57e0d73fbb/ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7", size = 99999 }, - { url = "https://files.pythonhosted.org/packages/ec/54/d8a795997921d87224c65d44499ca595a833093fb215b133f920c1062956/ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb", size = 118008 }, - { url = "https://files.pythonhosted.org/packages/7a/a2/eb5e9d088cb9d15c24d956944c09dca0a89108ad6e2e913c099ef36e3f0d/ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1", size = 144636 }, - { url = "https://files.pythonhosted.org/packages/66/98/8de4f22bbfd9135deb3422e96d450c4bc0a57d38c25976119307d2efe0aa/ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2", size = 135684 }, - { url = "https://files.pythonhosted.org/packages/30/d3/5fe978cd01a61c12efd24d65fa68c6f28f28c8073a06cf11db3a854390ca/ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92", size = 734571 }, - { url = "https://files.pythonhosted.org/packages/55/b3/e2531a050758b717c969cbf76c103b75d8a01e11af931b94ba656117fbe9/ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62", size = 643946 }, - { url = "https://files.pythonhosted.org/packages/0d/aa/06db7ca0995b513538402e11280282c615b5ae5f09eb820460d35fb69715/ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9", size = 692169 }, - { url = "https://files.pythonhosted.org/packages/27/38/4cf4d482b84ecdf51efae6635cc5483a83cf5ca9d9c13e205a750e251696/ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d", size = 740325 }, - { url = "https://files.pythonhosted.org/packages/6f/67/c62c6eea53a4feb042727a3d6c18f50dc99683c2b199c06bd2a9e3db8e22/ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa", size = 98639 }, - { url = "https://files.pythonhosted.org/packages/10/d2/52a3d810d0b5b3720725c0504a27b3fced7b6f310fe928f7019d79387bc1/ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b", size = 115305 }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruamel-yaml-clib/0.2.8/ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b" }, ] [[package]] name = "ruff" -version = "0.6.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5d/f9/0b32e5d1c6f957df49398cd882a011e9488fcbca0d6acfeeea50ccd37a4d/ruff-0.6.3.tar.gz", hash = "sha256:183b99e9edd1ef63be34a3b51fee0a9f4ab95add123dbf89a71f7b1f0c991983", size = 2463514 } +version = "0.9.1" +source = { registry = "https://nexus.scanplus.de/repository/pypi-group/simple" } +sdist = { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1.tar.gz", hash = "sha256:fd2b25ecaf907d6458fa842675382c8597b3c746a2dde6717fe3415425df0c17" } wheels = [ - { url = "https://files.pythonhosted.org/packages/72/68/1da6a1e39a03a229ea57c511691d6225072759cc7764206c3f0989521194/ruff-0.6.3-py3-none-linux_armv6l.whl", hash = "sha256:97f58fda4e309382ad30ede7f30e2791d70dd29ea17f41970119f55bdb7a45c3", size = 9696928 }, - { url = "https://files.pythonhosted.org/packages/6e/59/3b8b1d3a4271c6eb6ceecd3cef19a6d881639a0f18ad651563d6f619aaae/ruff-0.6.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3b061e49b5cf3a297b4d1c27ac5587954ccb4ff601160d3d6b2f70b1622194dc", size = 9448462 }, - { url = "https://files.pythonhosted.org/packages/35/4f/b942ecb8bbebe53aa9b33e9b96df88acd50b70adaaed3070f1d92131a1cb/ruff-0.6.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:34e2824a13bb8c668c71c1760a6ac7d795ccbd8d38ff4a0d8471fdb15de910b1", size = 9176190 }, - { url = "https://files.pythonhosted.org/packages/a0/20/b0bcb29d4ee437f3567b73b6905c034e2e94d29b9b826c66daecc1cf6388/ruff-0.6.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bddfbb8d63c460f4b4128b6a506e7052bad4d6f3ff607ebbb41b0aa19c2770d1", size = 10108892 }, - { url = "https://files.pythonhosted.org/packages/9c/e3/211bc759f424e8823a9937e0f678695ca02113c621dfde1fa756f9f26f6d/ruff-0.6.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ced3eeb44df75353e08ab3b6a9e113b5f3f996bea48d4f7c027bc528ba87b672", size = 9476471 }, - { url = "https://files.pythonhosted.org/packages/b2/a3/2ec35a2d7a554364864206f0e46812b92a074ad8a014b923d821ead532aa/ruff-0.6.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47021dff5445d549be954eb275156dfd7c37222acc1e8014311badcb9b4ec8c1", size = 10294802 }, - { url = "https://files.pythonhosted.org/packages/03/8b/56ef687b3489c88886dea48c78fb4969b6b65f18007d0ac450070edd1f58/ruff-0.6.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7d7bd20dc07cebd68cc8bc7b3f5ada6d637f42d947c85264f94b0d1cd9d87384", size = 11022372 }, - { url = "https://files.pythonhosted.org/packages/a5/21/327d147feb442adb88975e81e2263102789eba9ad2afa102c661912a482f/ruff-0.6.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:500f166d03fc6d0e61c8e40a3ff853fa8a43d938f5d14c183c612df1b0d6c58a", size = 10596596 }, - { url = "https://files.pythonhosted.org/packages/6c/86/ff386de63729da3e08c8099c57f577a00ec9f3eea711b23ac07cf3588dc5/ruff-0.6.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:42844ff678f9b976366b262fa2d1d1a3fe76f6e145bd92c84e27d172e3c34500", size = 11572830 }, - { url = "https://files.pythonhosted.org/packages/38/5d/b33284c108e3f315ddd09b70296fd76bd28ecf8965a520bc93f3bbd8ac40/ruff-0.6.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70452a10eb2d66549de8e75f89ae82462159855e983ddff91bc0bce6511d0470", size = 10262577 }, - { url = "https://files.pythonhosted.org/packages/29/99/9cdfad0d7f460e66567236eddc691473791afd9aff93a0dfcdef0462a6c7/ruff-0.6.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:65a533235ed55f767d1fc62193a21cbf9e3329cf26d427b800fdeacfb77d296f", size = 10098751 }, - { url = "https://files.pythonhosted.org/packages/a8/9f/f801a1619f5549e552f1f722f1db57eb39e7e1d83d482133142781d450de/ruff-0.6.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2e2c23cef30dc3cbe9cc5d04f2899e7f5e478c40d2e0a633513ad081f7361b5", size = 9563859 }, - { url = "https://files.pythonhosted.org/packages/0b/4d/fb2424faf04ffdb960ae2b3a1d991c5183dd981003de727d2d5cc38abc98/ruff-0.6.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d8a136aa7d228975a6aee3dd8bea9b28e2b43e9444aa678fb62aeb1956ff2351", size = 9914291 }, - { url = "https://files.pythonhosted.org/packages/2e/dd/94fddf002a8f6152e8ebfbb51d3f93febc415c1fe694345623c31ce8b33b/ruff-0.6.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f92fe93bc72e262b7b3f2bba9879897e2d58a989b4714ba6a5a7273e842ad2f8", size = 10331549 }, - { url = "https://files.pythonhosted.org/packages/b4/73/ca9c2f9237a430ca423b6dca83b77e9a428afeb7aec80596e86c369123fe/ruff-0.6.3-py3-none-win32.whl", hash = "sha256:7a62d3b5b0d7f9143d94893f8ba43aa5a5c51a0ffc4a401aa97a81ed76930521", size = 7962163 }, - { url = "https://files.pythonhosted.org/packages/55/ce/061c605b1dfb52748d59bc0c7a8507546c178801156415773d18febfd71d/ruff-0.6.3-py3-none-win_amd64.whl", hash = "sha256:746af39356fee2b89aada06c7376e1aa274a23493d7016059c3a72e3b296befb", size = 8800901 }, - { url = "https://files.pythonhosted.org/packages/63/28/ae4ffe7d3b6134ca6d31ebef07447ef70097c4a9e8fbbc519b374c5c1559/ruff-0.6.3-py3-none-win_arm64.whl", hash = "sha256:14a9528a8b70ccc7a847637c29e56fd1f9183a9db743bbc5b8e0c4ad60592a82", size = 8229171 }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-linux_armv6l.whl", hash = "sha256:84330dda7abcc270e6055551aca93fdde1b0685fc4fd358f26410f9349cf1743" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3cae39ba5d137054b0e5b472aee3b78a7c884e61591b100aeb544bcd1fc38d4f" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:50c647ff96f4ba288db0ad87048257753733763b409b2faf2ea78b45c8bb7fcb" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0c8b149e9c7353cace7d698e1656ffcf1e36e50f8ea3b5d5f7f87ff9986a7ca" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:beb3298604540c884d8b282fe7625651378e1986c25df51dec5b2f60cafc31ce" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:39d0174ccc45c439093971cc06ed3ac4dc545f5e8bdacf9f067adf879544d969" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:69572926c0f0c9912288915214ca9b2809525ea263603370b9e00bed2ba56dbd" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:937267afce0c9170d6d29f01fcd1f4378172dec6760a9f4dface48cdabf9610a" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:186c2313de946f2c22bdf5954b8dd083e124bcfb685732cfb0beae0c47233d9b" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f94942a3bb767675d9a051867c036655fe9f6c8a491539156a6f7e6b5f31831" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:728d791b769cc28c05f12c280f99e8896932e9833fef1dd8756a6af2261fd1ab" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2f312c86fb40c5c02b44a29a750ee3b21002bd813b5233facdaf63a51d9a85e1" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ae017c3a29bee341ba584f3823f805abbe5fe9cd97f87ed07ecbf533c4c88366" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5dc40a378a0e21b4cfe2b8a0f1812a6572fc7b230ef12cd9fac9161aa91d807f" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-win32.whl", hash = "sha256:46ebf5cc106cf7e7378ca3c28ce4293b61b449cd121b98699be727d40b79ba72" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-win_amd64.whl", hash = "sha256:342a824b46ddbcdddd3abfbb332fa7fcaac5488bf18073e841236aadf4ad5c19" }, + { url = "https://nexus.scanplus.de/repository/pypi-group/packages/ruff/0.9.1/ruff-0.9.1-py3-none-win_arm64.whl", hash = "sha256:1cd76c7f9c679e6e8f2af8f778367dca82b95009bc7b1a85a47f1521ae524fa7" }, ] From 5815558e8d713b9a5048197dd5aee5887d570a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Pola=C5=84ski?= Date: Mon, 27 Jan 2025 10:57:58 +0100 Subject: [PATCH 19/20] Adding mac initializer. Fixing cables, clusters, prefixes and virtualizzation_interfaces --- .../initializers/__init__.py | 1 + src/netbox_initializers/initializers/base.py | 18 +++++++++++++ .../initializers/cables.py | 17 +++++------- .../initializers/clusters.py | 2 +- src/netbox_initializers/initializers/macs.py | 24 +++++++++++++++++ .../initializers/prefixes.py | 10 ++++--- src/netbox_initializers/initializers/utils.py | 13 ++++++++++ .../initializers/virtualization_interfaces.py | 11 ++++++++ .../initializers/yaml/cables.yml | 8 ++++-- .../initializers/yaml/clusters.yml | 2 +- .../initializers/yaml/macs.yml | 10 +++++++ .../initializers/yaml/prefixes.yml | 26 ++++++++++++++++--- .../yaml/virtualization_interfaces.yml | 20 ++++++++++++-- 13 files changed, 139 insertions(+), 23 deletions(-) create mode 100644 src/netbox_initializers/initializers/macs.py create mode 100644 src/netbox_initializers/initializers/utils.py create mode 100644 src/netbox_initializers/initializers/yaml/macs.yml diff --git a/src/netbox_initializers/initializers/__init__.py b/src/netbox_initializers/initializers/__init__.py index b4e185e..fe5c10b 100644 --- a/src/netbox_initializers/initializers/__init__.py +++ b/src/netbox_initializers/initializers/__init__.py @@ -22,6 +22,7 @@ from .interfaces import InterfaceInitializer from .ip_addresses import IPAddressInitializer from .locations import LocationInitializer +from .macs import MACAddressInitializer from .manufacturers import ManufacturerInitializer from .object_permissions import ObjectPermissionInitializer from .platforms import PlatformInitializer diff --git a/src/netbox_initializers/initializers/base.py b/src/netbox_initializers/initializers/base.py index d7d659c..6423d44 100644 --- a/src/netbox_initializers/initializers/base.py +++ b/src/netbox_initializers/initializers/base.py @@ -2,6 +2,7 @@ from typing import Tuple from core.models import ObjectType +from dcim.models import MACAddress from django.core.exceptions import ObjectDoesNotExist from extras.models import CustomField, Tag from ruamel.yaml import YAML @@ -90,6 +91,22 @@ def set_tags(self, entity, tags): if save: entity.save() + def set_mac_addresses(self, entity, mac_addresses): + if not mac_addresses: + return + + if not hasattr(entity, "mac_addresses"): + raise Exception(f"โš ๏ธ MAC Address cannot be applied to {entity}'s model") + + save = False + for mac_address in MACAddress.objects.filter(mac_address__in=mac_addresses): + + entity.mac_addresses.add(mac_address) + save = True + + if save: + entity.save() + def split_params(self, params: dict, unique_params: list = None) -> Tuple[dict, dict]: """Split params dict into dict with matching params and a dict with default values""" @@ -140,6 +157,7 @@ class InitializationError(Exception): "prefix_vlan_roles", "vlan_groups", "vlans", + "macs", "devices", "interfaces", "route_targets", diff --git a/src/netbox_initializers/initializers/cables.py b/src/netbox_initializers/initializers/cables.py index 5053a69..e18e783 100644 --- a/src/netbox_initializers/initializers/cables.py +++ b/src/netbox_initializers/initializers/cables.py @@ -1,6 +1,6 @@ from typing import Tuple - -from circuits.models import Circuit, CircuitTermination, ProviderNetwork +from circuits.constants import CIRCUIT_TERMINATION_TERMINATION_TYPES +from circuits.models import Circuit, CircuitTermination from dcim.models import ( Cable, CableTermination, @@ -13,12 +13,12 @@ PowerPanel, PowerPort, RearPort, - Site, ) from django.contrib.contenttypes.models import ContentType from django.db.models import Q from netbox_initializers.initializers.base import BaseInitializer, register_initializer +from netbox_initializers.initializers.utils import get_scope_details CONSOLE_PORT_TERMINATION = ContentType.objects.get_for_model(ConsolePort) CONSOLE_SERVER_PORT_TERMINATION = ContentType.objects.get_for_model(ConsoleServerPort) @@ -55,16 +55,11 @@ def get_termination_object(params: dict, side: str): circuit = Circuit.objects.get(cid=circuit_params.pop("cid")) term_side = circuit_params.pop("term_side").upper() - site_name = circuit_params.pop("site", None) - provider_network = circuit_params.pop("provider_network", None) - - if site_name: - circuit_params["site"] = Site.objects.get(name=site_name) - elif provider_network: - circuit_params["provider_network"] = ProviderNetwork.objects.get(name=provider_network) + if scope := circuit_params.pop("scope", None): + circuit_params["termination_type"], circuit_params["termination_id"] = get_scope_details(scope, CIRCUIT_TERMINATION_TERMINATION_TYPES) else: raise ValueError( - f"โš ๏ธ Missing one of required parameters: 'site' or 'provider_network' " + f"โš ๏ธ Missing required parameter: 'scope'" f"for side {term_side} of circuit {circuit}" ) diff --git a/src/netbox_initializers/initializers/clusters.py b/src/netbox_initializers/initializers/clusters.py index 328ffc0..fdecc31 100644 --- a/src/netbox_initializers/initializers/clusters.py +++ b/src/netbox_initializers/initializers/clusters.py @@ -7,7 +7,7 @@ MATCH_PARAMS = ["name", "type"] REQUIRED_ASSOCS = {"type": (ClusterType, "name")} OPTIONAL_ASSOCS = { - "site": (Site, "name"), + "scope": (Site, "name"), "group": (ClusterGroup, "name"), "tenant": (Tenant, "name"), } diff --git a/src/netbox_initializers/initializers/macs.py b/src/netbox_initializers/initializers/macs.py new file mode 100644 index 0000000..f382788 --- /dev/null +++ b/src/netbox_initializers/initializers/macs.py @@ -0,0 +1,24 @@ +from dcim.models import MACAddress + +from netbox_initializers.initializers.base import BaseInitializer, register_initializer + + +class MACAddressInitializer(BaseInitializer): + data_file_name = "macs.yml" + + def load_data(self): + macs = self.load_yaml() + if macs is None: + return + + for mac in macs: + tags = mac.pop("tags", None) + macaddress, created = MACAddress.objects.get_or_create(**mac) + + if created: + print("๐Ÿ—บ๏ธ Created MAC Address", macaddress.mac_address) + + self.set_tags(macaddress, tags) + + +register_initializer("macs", MACAddressInitializer) diff --git a/src/netbox_initializers/initializers/prefixes.py b/src/netbox_initializers/initializers/prefixes.py index cdbada2..a67a076 100644 --- a/src/netbox_initializers/initializers/prefixes.py +++ b/src/netbox_initializers/initializers/prefixes.py @@ -1,13 +1,14 @@ -from dcim.models import Site from ipam.models import VLAN, VRF, Prefix, Role from netaddr import IPNetwork from tenancy.models import Tenant, TenantGroup +from dcim.constants import LOCATION_SCOPE_TYPES +from django.contrib.contenttypes.models import ContentType from netbox_initializers.initializers.base import BaseInitializer, register_initializer +from netbox_initializers.initializers.utils import get_scope_details -MATCH_PARAMS = ["prefix", "site", "vrf", "vlan"] +MATCH_PARAMS = ["prefix", "scope", "vrf", "vlan"] OPTIONAL_ASSOCS = { - "site": (Site, "name"), "tenant": (Tenant, "name"), "tenant_group": (TenantGroup, "name"), "vlan": (VLAN, "name"), @@ -29,6 +30,9 @@ def load_data(self): params["prefix"] = IPNetwork(params["prefix"]) + if scope := params.pop("scope"): + params["scope_type"], params["scope_id"] = get_scope_details(scope, LOCATION_SCOPE_TYPES) + for assoc, details in OPTIONAL_ASSOCS.items(): if assoc in params: model, field = details diff --git a/src/netbox_initializers/initializers/utils.py b/src/netbox_initializers/initializers/utils.py new file mode 100644 index 0000000..26fbc3b --- /dev/null +++ b/src/netbox_initializers/initializers/utils.py @@ -0,0 +1,13 @@ +from django.contrib.contenttypes.models import ContentType + + +def get_scope_details(scope: dict, allowed_termination_types: list): + try: + scope_type = ContentType.objects.get(app_label__in=["dcim", "circuits"], model=scope["type"]) + if scope["type"] not in allowed_termination_types: + raise ValueError(f"{scope['type']} scope type is not permitted on {scope_type.app_label}") + except ContentType.DoesNotExist: + raise ValueError(f"โš ๏ธ Invalid scope type: {scope['type']}") + + scope_id = scope_type.model_class().objects.get(name=scope["name"]).id + return scope_type, scope_id diff --git a/src/netbox_initializers/initializers/virtualization_interfaces.py b/src/netbox_initializers/initializers/virtualization_interfaces.py index abc5175..52ec77a 100644 --- a/src/netbox_initializers/initializers/virtualization_interfaces.py +++ b/src/netbox_initializers/initializers/virtualization_interfaces.py @@ -1,9 +1,11 @@ +from dcim.models import MACAddress from virtualization.models import VirtualMachine, VMInterface from netbox_initializers.initializers.base import BaseInitializer, register_initializer MATCH_PARAMS = ["name", "virtual_machine"] REQUIRED_ASSOCS = {"virtual_machine": (VirtualMachine, "name")} +OPTIONAL_ASSOCS = {"primary_mac_address": (MACAddress, "mac_address")} class VMInterfaceInitializer(BaseInitializer): @@ -16,6 +18,7 @@ def load_data(self): for params in interfaces: custom_field_data = self.pop_custom_fields(params) tags = params.pop("tags", None) + mac_addresses = params.pop("mac_addresses", None) for assoc, details in REQUIRED_ASSOCS.items(): model, field = details @@ -23,6 +26,13 @@ def load_data(self): 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) + matching_params, defaults = self.split_params(params, MATCH_PARAMS) interface, created = VMInterface.objects.get_or_create( **matching_params, defaults=defaults @@ -33,6 +43,7 @@ def load_data(self): self.set_custom_fields_values(interface, custom_field_data) self.set_tags(interface, tags) + self.set_mac_addresses(interface, mac_addresses) register_initializer("virtualization_interfaces", VMInterfaceInitializer) diff --git a/src/netbox_initializers/initializers/yaml/cables.yml b/src/netbox_initializers/initializers/yaml/cables.yml index 3257643..0cab5e9 100644 --- a/src/netbox_initializers/initializers/yaml/cables.yml +++ b/src/netbox_initializers/initializers/yaml/cables.yml @@ -16,7 +16,9 @@ # # termination_x_circuit: # # term_side -> termination side of a circuit. Must be A or B # # cid -> circuit ID value -# # site OR provider_network -> name of Site or ProviderNetwork respectively. If both provided, Site takes precedence +# # scope: +# # type -> select one of the following: region, site, sitegroup, location +# # name -> name of the object in the respective scope type # # ``` # # # # If a termination is a power feed then the required parameter is termination_x_feed. @@ -51,7 +53,9 @@ # termination_b_circuit: # term_side: A # cid: Circuit_ID-1 -# site: AMS 1 +# scope: +# type: site +# name: AMS 1 # type: cat6 # - termination_a_name: psu0 diff --git a/src/netbox_initializers/initializers/yaml/clusters.yml b/src/netbox_initializers/initializers/yaml/clusters.yml index 4e15477..85e1a4a 100644 --- a/src/netbox_initializers/initializers/yaml/clusters.yml +++ b/src/netbox_initializers/initializers/yaml/clusters.yml @@ -4,4 +4,4 @@ # tenant: tenant1 # - name: cluster2 # type: Hyper-V -# site: SING 1 +# scope: SING 1 diff --git a/src/netbox_initializers/initializers/yaml/macs.yml b/src/netbox_initializers/initializers/yaml/macs.yml new file mode 100644 index 0000000..5b293eb --- /dev/null +++ b/src/netbox_initializers/initializers/yaml/macs.yml @@ -0,0 +1,10 @@ +# - mac_address: 00:01:11:11:11:11 +# description: MAC address 1 +# - mac_address: 00:01:22:22:22:22 +# description: Mac address 2 +# - mac_address: 00:01:33:33:33:33 +# description: mac address 3 +# - mac_address: 00:02:44:44:44:44 +# description: mac address 4 +# - mac_address: 00:02:55:55:55:55 +# description: mac address 5 diff --git a/src/netbox_initializers/initializers/yaml/prefixes.yml b/src/netbox_initializers/initializers/yaml/prefixes.yml index fbf3eee..f2e14a2 100644 --- a/src/netbox_initializers/initializers/yaml/prefixes.yml +++ b/src/netbox_initializers/initializers/yaml/prefixes.yml @@ -4,18 +4,28 @@ ## - active ## - reserved ## - deprecated +## scope: +## type: +## - region +## - sitegroup +## - site +## - location ## ## Examples: # - description: prefix1 # prefix: 10.1.1.0/24 -# site: AMS 1 +# scope: +# type: site +# name: AMS 1 # status: active # tenant: tenant1 # vlan: vlan1 # - description: prefix2 # prefix: 10.1.2.0/24 -# site: AMS 2 +# scope: +# type: site +# name: AMS 2 # status: active # tenant: tenant2 # vlan: vlan2 @@ -23,7 +33,17 @@ # vrf: vrf2 # - description: ipv6 prefix1 # prefix: 2001:db8:a000:1::/64 -# site: AMS 2 +# scope: +# type: site +# name: AMS 2 # status: active # tenant: tenant2 # vlan: vlan2 +# - description: ipv6 prefix2 +# prefix: 2001:db8:b000:1::/64 +# scope: +# type: location +# name: cage 101 +# status: active +# tenant: tenant2 +# vlan: vlan1 \ No newline at end of file diff --git a/src/netbox_initializers/initializers/yaml/virtualization_interfaces.yml b/src/netbox_initializers/initializers/yaml/virtualization_interfaces.yml index aeedd58..4af9825 100644 --- a/src/netbox_initializers/initializers/yaml/virtualization_interfaces.yml +++ b/src/netbox_initializers/initializers/yaml/virtualization_interfaces.yml @@ -1,12 +1,28 @@ # - description: Network Interface 1 # enabled: true -# mac_address: 00:77:77:77:77:77 +# primary_mac_address: 00:01:11:11:11:11 # mtu: 1500 # name: Network Interface 1 # virtual_machine: virtual machine 1 # - description: Network Interface 2 # enabled: true -# mac_address: 00:55:55:55:55:55 +# mac_addresses: +# - 00:01:22:22:22:22 +# - 00:01:33:33:33:33 +# primary_mac_address: 00:01:33:33:33:33 # mtu: 1500 # name: Network Interface 2 # virtual_machine: virtual machine 1 +# - description: Network Interface 3 +# enabled: true +# mtu: 1500 +# name: Network Interface 3 +# virtual_machine: virtual machine 2 +# - description: Network Interface 4 +# enabled: true +# mac_addresses: +# - 00:02:44:44:44:44 +# - 00:02:55:55:55:55 +# mtu: 1500 +# name: Network Interface 4 +# virtual_machine: virtual machine 2 \ No newline at end of file From 7e33f53101b9f03f93df49b8403abd09f0f04c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Pola=C5=84ski?= Date: Mon, 27 Jan 2025 12:46:46 +0100 Subject: [PATCH 20/20] Fix linting --- src/netbox_initializers/initializers/cables.py | 4 +++- src/netbox_initializers/initializers/prefixes.py | 3 +-- src/netbox_initializers/initializers/yaml/cables.yml | 2 +- src/netbox_initializers/initializers/yaml/prefixes.yml | 8 ++++---- .../initializers/yaml/virtualization_interfaces.yml | 6 +++--- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/netbox_initializers/initializers/cables.py b/src/netbox_initializers/initializers/cables.py index e18e783..4b39314 100644 --- a/src/netbox_initializers/initializers/cables.py +++ b/src/netbox_initializers/initializers/cables.py @@ -56,7 +56,9 @@ def get_termination_object(params: dict, side: str): term_side = circuit_params.pop("term_side").upper() if scope := circuit_params.pop("scope", None): - circuit_params["termination_type"], circuit_params["termination_id"] = get_scope_details(scope, CIRCUIT_TERMINATION_TERMINATION_TYPES) + scope_type, scope_id = get_scope_details(scope, CIRCUIT_TERMINATION_TERMINATION_TYPES) + circuit_params["termination_type"] = scope_type + circuit_params["termination_id"] = scope_id else: raise ValueError( f"โš ๏ธ Missing required parameter: 'scope'" diff --git a/src/netbox_initializers/initializers/prefixes.py b/src/netbox_initializers/initializers/prefixes.py index a67a076..29d4ed8 100644 --- a/src/netbox_initializers/initializers/prefixes.py +++ b/src/netbox_initializers/initializers/prefixes.py @@ -1,8 +1,7 @@ +from dcim.constants import LOCATION_SCOPE_TYPES from ipam.models import VLAN, VRF, Prefix, Role from netaddr import IPNetwork from tenancy.models import Tenant, TenantGroup -from dcim.constants import LOCATION_SCOPE_TYPES -from django.contrib.contenttypes.models import ContentType from netbox_initializers.initializers.base import BaseInitializer, register_initializer from netbox_initializers.initializers.utils import get_scope_details diff --git a/src/netbox_initializers/initializers/yaml/cables.yml b/src/netbox_initializers/initializers/yaml/cables.yml index 0cab5e9..f84de17 100644 --- a/src/netbox_initializers/initializers/yaml/cables.yml +++ b/src/netbox_initializers/initializers/yaml/cables.yml @@ -53,7 +53,7 @@ # termination_b_circuit: # term_side: A # cid: Circuit_ID-1 -# scope: +# scope: # type: site # name: AMS 1 # type: cat6 diff --git a/src/netbox_initializers/initializers/yaml/prefixes.yml b/src/netbox_initializers/initializers/yaml/prefixes.yml index f2e14a2..1d8c944 100644 --- a/src/netbox_initializers/initializers/yaml/prefixes.yml +++ b/src/netbox_initializers/initializers/yaml/prefixes.yml @@ -15,7 +15,7 @@ # - description: prefix1 # prefix: 10.1.1.0/24 -# scope: +# scope: # type: site # name: AMS 1 # status: active @@ -23,7 +23,7 @@ # vlan: vlan1 # - description: prefix2 # prefix: 10.1.2.0/24 -# scope: +# scope: # type: site # name: AMS 2 # status: active @@ -34,7 +34,7 @@ # - description: ipv6 prefix1 # prefix: 2001:db8:a000:1::/64 # scope: -# type: site +# type: site # name: AMS 2 # status: active # tenant: tenant2 @@ -46,4 +46,4 @@ # name: cage 101 # status: active # tenant: tenant2 -# vlan: vlan1 \ No newline at end of file +# vlan: vlan1 diff --git a/src/netbox_initializers/initializers/yaml/virtualization_interfaces.yml b/src/netbox_initializers/initializers/yaml/virtualization_interfaces.yml index 4af9825..72b198a 100644 --- a/src/netbox_initializers/initializers/yaml/virtualization_interfaces.yml +++ b/src/netbox_initializers/initializers/yaml/virtualization_interfaces.yml @@ -6,7 +6,7 @@ # virtual_machine: virtual machine 1 # - description: Network Interface 2 # enabled: true -# mac_addresses: +# mac_addresses: # - 00:01:22:22:22:22 # - 00:01:33:33:33:33 # primary_mac_address: 00:01:33:33:33:33 @@ -20,9 +20,9 @@ # virtual_machine: virtual machine 2 # - description: Network Interface 4 # enabled: true -# mac_addresses: +# mac_addresses: # - 00:02:44:44:44:44 # - 00:02:55:55:55:55 # mtu: 1500 # name: Network Interface 4 -# virtual_machine: virtual machine 2 \ No newline at end of file +# virtual_machine: virtual machine 2