From c0f3de15124d3779998d83354559354b3625cf04 Mon Sep 17 00:00:00 2001 From: Tobias Genannt Date: Sun, 1 Sep 2024 11:46:30 +0200 Subject: [PATCH 01/11] 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 02/11] 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 03/11] 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 04/11] 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 05/11] 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 06/11] 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 07/11] 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 08/11] 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 09/11] 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 10/11] 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 11/11] 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/*