From 95baf2940a2521b68d40d55b062cd7d1a05b26e1 Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Thu, 20 Mar 2025 22:41:53 +0100 Subject: [PATCH 01/21] enhances NetBox version detection #446 --- module/netbox/connection.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/module/netbox/connection.py b/module/netbox/connection.py index 5c86d26..d3a0dd5 100644 --- a/module/netbox/connection.py +++ b/module/netbox/connection.py @@ -196,15 +196,29 @@ class NetBoxHandler: str: NetBox API version """ response = None + result = None + try: response = self.session.get( - self.url, + f"{self.url}/status", timeout=self.settings.timeout, verify=self.settings.validate_tls_certs) except Exception as e: do_error_exit(f"NetBox connection: {e}") - result = str(response.headers.get("API-Version")) + # noinspection PyBroadException + try: + result = grab(response.json(), "netbox-version").split("-")[0] + except Exception: + pass + + if not isinstance(result, str): + result = str(response.headers.get("API-Version")) + + try: + version.parse(result) + except Exception as e: + do_error_exit(f"Unable to parse NetBox version '{result}': {e}") log.info(f"Successfully connected to NetBox '{self.settings.host_fqdn}'") log.debug(f"Detected NetBox API version: {result}") From deafd5b629fcd346eb13a6253d601cfcaa0da146 Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Fri, 21 Mar 2025 07:39:55 +0100 Subject: [PATCH 02/21] fixes issue with retrieving platform name for newer guest tools #448 --- module/sources/vmware/connection.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/module/sources/vmware/connection.py b/module/sources/vmware/connection.py index 9ab8974..1b3be80 100644 --- a/module/sources/vmware/connection.py +++ b/module/sources/vmware/connection.py @@ -2180,10 +2180,13 @@ class VMWareHandler(SourceBase): platform = get_string_or_none(grab(obj, "guest.guestFullName", fallback=platform)) # extract prettyName from extraConfig exposed by guest tools - extra_config = [x.value for x in grab(obj, "config.extraConfig", fallback=[]) - if x.key == "guestOS.detailed.data"] - if len(extra_config) > 0: - pretty_name = [x for x in quoted_split(extra_config[0].replace("' ", "', ")) if x.startswith("prettyName")] + extra_config = {x.key: x.value for x in grab(obj, "config.extraConfig", fallback=[]) + if x.key in ["guestOS.detailed.data", "guestInfo.detailed.data"]} + + # first try 'guestInfo.detailed.data' and then 'guestOS.detailed.data' + detailed_data = extra_config.get("guestInfo.detailed.data") or extra_config.get("guestOS.detailed.data") + if isinstance(detailed_data, str): + pretty_name = [x for x in quoted_split(detailed_data.replace("' ", "', ")) if x.startswith("prettyName")] if len(pretty_name) > 0: platform = pretty_name[0].replace("prettyName='","") From f201402115f5a3b0764253da1289711cf7ef86f0 Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Fri, 9 May 2025 13:05:06 +0200 Subject: [PATCH 03/21] fixes issue with type hints for python <3.10.0 setups #456 --- module/sources/common/source_base.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/module/sources/common/source_base.py b/module/sources/common/source_base.py index fc81a16..0e95e5c 100644 --- a/module/sources/common/source_base.py +++ b/module/sources/common/source_base.py @@ -8,6 +8,7 @@ # repository or visit: . import re +from typing import Union,Optional from ipaddress import ip_interface, ip_address, IPv6Address, IPv4Address, IPv6Network, IPv4Network from packaging import version @@ -179,7 +180,7 @@ class SourceBase: return return_data - def return_longest_matching_prefix_for_ip(self, ip_to_match=None, site_name=None) -> NBPrefix|None: + def return_longest_matching_prefix_for_ip(self, ip_to_match=None, site_name=None) -> Optional[NBPrefix]: """ This is a lazy approach to find the longest matching prefix to an IP address. If site_name is set only IP prefixes from that site are matched. @@ -716,7 +717,7 @@ class SourceBase: return data_to_update - def add_vlan_group(self, vlan_data, vlan_site, vlan_cluster) -> NBVLAN | dict: + def add_vlan_group(self, vlan_data, vlan_site, vlan_cluster) -> Union[NBVLAN ,dict]: """ This function will try to find a matching VLAN group according to the settings. Name matching will take precedence over ID matching. First match wins. From 51d95defadb295f89d29798456cf4c3a0d1dfe52 Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Tue, 17 Jun 2025 15:06:26 +0200 Subject: [PATCH 04/21] adds distroVersion to VM linux platform #448 --- module/sources/vmware/connection.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/module/sources/vmware/connection.py b/module/sources/vmware/connection.py index 1b3be80..497f04f 100644 --- a/module/sources/vmware/connection.py +++ b/module/sources/vmware/connection.py @@ -2186,9 +2186,15 @@ class VMWareHandler(SourceBase): # first try 'guestInfo.detailed.data' and then 'guestOS.detailed.data' detailed_data = extra_config.get("guestInfo.detailed.data") or extra_config.get("guestOS.detailed.data") if isinstance(detailed_data, str): - pretty_name = [x for x in quoted_split(detailed_data.replace("' ", "', ")) if x.startswith("prettyName")] - if len(pretty_name) > 0: - platform = pretty_name[0].replace("prettyName='","") + detailed_data_dict = dict() + for detailed_data_item in quoted_split(detailed_data.replace("' ", "', ")): + detailed_data_key, detailed_data_value = detailed_data_item.split("=") + detailed_data_dict[detailed_data_key] = detailed_data_value.strip("'") + if len(detailed_data_dict.get("prettyName","")) > 0: + platform = detailed_data_dict.get("prettyName") + if detailed_data_dict.get("prettyName").lower() == "linux" and \ + detailed_data_dict.get("distroVersion") not in platform: + platform = f'{platform} {detailed_data_dict.get("distroVersion")}' if platform is not None: platform = self.get_object_relation(platform, "vm_platform_relation", fallback=platform) From 53e5b07d2a3834f990998dbf6d15bed6e5e3f86f Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Wed, 18 Jun 2025 12:06:17 +0200 Subject: [PATCH 05/21] fixes issue with parsing of vm guest data #448 --- module/sources/vmware/connection.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/module/sources/vmware/connection.py b/module/sources/vmware/connection.py index 497f04f..02a1765 100644 --- a/module/sources/vmware/connection.py +++ b/module/sources/vmware/connection.py @@ -2188,11 +2188,14 @@ class VMWareHandler(SourceBase): if isinstance(detailed_data, str): detailed_data_dict = dict() for detailed_data_item in quoted_split(detailed_data.replace("' ", "', ")): + if "=" not in detailed_data_item: + continue + detailed_data_key, detailed_data_value = detailed_data_item.split("=") detailed_data_dict[detailed_data_key] = detailed_data_value.strip("'") if len(detailed_data_dict.get("prettyName","")) > 0: platform = detailed_data_dict.get("prettyName") - if detailed_data_dict.get("prettyName").lower() == "linux" and \ + if detailed_data_dict.get("familyName", "").lower() == "linux" and \ detailed_data_dict.get("distroVersion") not in platform: platform = f'{platform} {detailed_data_dict.get("distroVersion")}' From f496c95bee410428a278fea7dfb85545ba5b9189 Mon Sep 17 00:00:00 2001 From: joachimBurket Date: Thu, 3 Jul 2025 17:41:43 +0200 Subject: [PATCH 06/21] only set the Cluster scope_type if the site_name is not None --- module/sources/vmware/connection.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/module/sources/vmware/connection.py b/module/sources/vmware/connection.py index 02a1765..742f54c 100644 --- a/module/sources/vmware/connection.py +++ b/module/sources/vmware/connection.py @@ -1388,8 +1388,9 @@ class VMWareHandler(SourceBase): } if version.parse(self.inventory.netbox_api_version) >= version.parse("4.2.0"): - data["scope_id"] = {"name": site_name} - data["scope_type"] = "dcim.site" + if site_name is not None: + data["scope_id"] = {"name": site_name} + data["scope_type"] = "dcim.site" else: data["site"] = {"name": site_name} From 5c8e54cdbb8617690d2b14dd86407b6c36dda950 Mon Sep 17 00:00:00 2001 From: Littlericket <1573629+Littlericket@users.noreply.github.com> Date: Fri, 21 Mar 2025 15:33:51 +0100 Subject: [PATCH 07/21] fix: handle object and multi-object custom fields correctly --- module/netbox/object_classes.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/module/netbox/object_classes.py b/module/netbox/object_classes.py index 96df5fd..9d25093 100644 --- a/module/netbox/object_classes.py +++ b/module/netbox/object_classes.py @@ -683,6 +683,29 @@ class NetBoxObject: if self.data_model.get(key) == NBCustomField: if current_value is None: current_value = dict() + + # Fix for object/multi-object custom fields + # When patching, we only need the IDs, not the full object representation + new_value_copy = new_value.copy() + for field_name, field_value in new_value_copy.items(): + # Check for custom field type + custom_field = self.inventory.get_by_data(NBCustomField, data={"name": field_name}) + if custom_field is not None: + field_type = grab(custom_field, "data.type") + + # Handle object type custom fields - need only ID + if field_type == "object" and isinstance(field_value, dict) and field_value.get('id') is not None: + new_value[field_name] = field_value.get('id') + + # Handle multi-object type custom fields - need list of IDs + elif field_type == "multi-object" and isinstance(field_value, list): + ids = [] + for item in field_value: + if isinstance(item, dict) and item.get('id') is not None: + ids.append(item.get('id')) + if ids: + new_value[field_name] = ids + new_value = {**current_value, **new_value} new_value_str = str(new_value) elif isinstance(new_value, (NetBoxObject, NBObjectList)): @@ -1288,7 +1311,7 @@ class NBCustomField(NetBoxObject): "object_types": list, # field name (object_types) for NetBox < 4.0.0 "content_types": list, - "type": ["text", "longtext", "integer", "boolean", "date", "url", "json", "select", "multiselect"], + "type": ["text", "longtext", "integer", "boolean", "date", "url", "json", "select", "multiselect", "object", "multi-object"], "name": 50, "label": 50, "description": 200, From 499862a3324599f7a31d05361596a4d854047464 Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Fri, 24 Oct 2025 22:39:51 +0200 Subject: [PATCH 08/21] adds support for check-refish source 2.0.0 #478 --- module/sources/check_redfish/import_inventory.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/module/sources/check_redfish/import_inventory.py b/module/sources/check_redfish/import_inventory.py index 7a893ba..95fbe1f 100644 --- a/module/sources/check_redfish/import_inventory.py +++ b/module/sources/check_redfish/import_inventory.py @@ -30,7 +30,7 @@ class CheckRedfish(SourceBase): """ # minimum check_redfish inventory version - minimum_check_redfish_version = "1.2.0" + minimum_check_redfish_version = "2.0.0" dependent_netbox_objects = [ NBTag, @@ -239,8 +239,8 @@ class CheckRedfish(SourceBase): if name is not None and self.settings.overwrite_host_name is True: device_data["name"] = name if "dell" in str(manufacturer).lower(): - chassi = grab(self.inventory_file_content, "inventory.chassi.0") - if chassi and "sku" in chassi: + chassis = grab(self.inventory_file_content, "inventory.chassis.0") + if chassis and "sku" in chassis: # add ServiceTag self.add_update_custom_field({ @@ -253,9 +253,9 @@ class CheckRedfish(SourceBase): "description": "Dell Service Tag" }) - device_data["custom_fields"]["service_tag"] = chassi.get("sku") + device_data["custom_fields"]["service_tag"] = chassis.get("sku") else: - log.warning(f"No chassi or sku data found for " + log.warning(f"No chassis or sku data found for " f"'{self.device_object.get_display_name()}' in inventory file.") self.device_object.update(data=device_data, source=self) From 714e57eb54b3de8d948b588403388a4833fd961e Mon Sep 17 00:00:00 2001 From: rizlas Date: Sat, 3 Jan 2026 16:29:30 +0100 Subject: [PATCH 09/21] feat: GA build and push docker image --- .github/workflows/docker-image.yml | 86 ++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 .github/workflows/docker-image.yml diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 0000000..8931bfb --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,86 @@ +name: Build netbox-sync docker image + +on: + push: + tags: + - v[0-9]+.[0-9]+.[0-9]+ + branches: + - development + paths: + - module/** + - netbox-sync.py + - requirements.txt + workflow_dispatch: + +jobs: + build-and-push: + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Lower case docker image name + id: docker_image + uses: ASzc/change-string-case-action@v6 + with: + string: ${{ github.repository }} + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Docker meta GitHub Container Registry + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ steps.docker_image.outputs.lowercase }} + tags: | + type=semver,pattern={{version}} + type=ref,event=branch + + - name: Build and push with tags - ${{ steps.meta.outputs.tags }} + uses: docker/build-push-action@v6 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_PASSWORD }} + + - name: Docker hub meta + id: meta_dhub + uses: docker/metadata-action@v5 + with: + images: docker.io/bbricardo/${{ steps.docker_image.outputs.lowercase }} + tags: | + type=semver,pattern={{version}} + type=ref,event=branch + + - name: Build and push with tags - ${{ steps.meta_dhub.outputs.tags }} + uses: docker/build-push-action@v6 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.meta_dhub.outputs.tags }} + labels: ${{ steps.meta_dhub.outputs.labels }} From 577caebf5c519a830930781e82800665718c0a75 Mon Sep 17 00:00:00 2001 From: rizlas Date: Sat, 3 Jan 2026 16:42:00 +0100 Subject: [PATCH 10/21] fix: docker image removed specific os version --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index f048b55..2263c0c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.11-slim-bookworm AS builder +FROM python:3.11-slim AS builder COPY requirements.txt . @@ -13,7 +13,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends git && \ $VENV/bin/pip install --upgrade git+https://github.com/vmware/vsphere-automation-sdk-python.git && \ find $VENV -type d -name "__pycache__" -print0 | xargs -0 -n1 rm -rf -FROM python:3.11-slim-bookworm AS netbox-sync +FROM python:3.11-slim AS netbox-sync ARG VENV=/opt/netbox-sync/venv From 2154f50741534a5e53c466cebd8af475257af472 Mon Sep 17 00:00:00 2001 From: Jeroendev <45510403+jeroendev-one@users.noreply.github.com> Date: Fri, 16 Jan 2026 14:48:18 +0100 Subject: [PATCH 11/21] Fix distroVersion if unknown version in VMWARE File "/opt/netbox-sync/module/sources/vmware/connection.py", line 2200, in add_virtual_machine detailed_data_dict.get("distroVersion") not in platform: TypeError: 'in ' requires string as left operand, not NoneType Fixes this error, this seemed to be when a OS version is not known in VMWare. --- module/sources/vmware/connection.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/module/sources/vmware/connection.py b/module/sources/vmware/connection.py index 742f54c..5b09bde 100644 --- a/module/sources/vmware/connection.py +++ b/module/sources/vmware/connection.py @@ -2196,9 +2196,14 @@ class VMWareHandler(SourceBase): detailed_data_dict[detailed_data_key] = detailed_data_value.strip("'") if len(detailed_data_dict.get("prettyName","")) > 0: platform = detailed_data_dict.get("prettyName") - if detailed_data_dict.get("familyName", "").lower() == "linux" and \ - detailed_data_dict.get("distroVersion") not in platform: - platform = f'{platform} {detailed_data_dict.get("distroVersion")}' + + distro_version = detailed_data_dict.get("distroVersion") + if detailed_data_dict.get("familyName", "").lower() == "linux" and distro_version: + if distro_version not in platform: + platform = f'{platform} {distro_version}' + if platform is not None: + platform = self.get_object_relation(platform, "vm_platform_relation", fallback=platform) + if platform is not None: platform = self.get_object_relation(platform, "vm_platform_relation", fallback=platform) From 92ae8ce5f0804f5043ac4c49638a2ba3f1382797 Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Thu, 29 Jan 2026 07:58:14 +0100 Subject: [PATCH 12/21] updates and pins dependencies #488 #481 --- Dockerfile | 6 +- pyproject.toml | 24 ++++ requirements.txt | 22 ++-- uv.lock | 303 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 344 insertions(+), 11 deletions(-) create mode 100644 pyproject.toml create mode 100644 uv.lock diff --git a/Dockerfile b/Dockerfile index 2263c0c..b32d833 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ -FROM python:3.11-slim AS builder +FROM python:3.13-slim AS builder COPY requirements.txt . ARG VENV=/opt/netbox-sync/venv # Install dependencies -RUN apt-get update && apt-get install -y --no-install-recommends git && \ +RUN apt-get update && apt-get install -y --no-install-recommends git gcc libc-dev && \ rm -rf /var/lib/apt/lists/* && \ python3 -m venv $VENV && \ $VENV/bin/python3 -m pip install --upgrade pip && \ @@ -13,7 +13,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends git && \ $VENV/bin/pip install --upgrade git+https://github.com/vmware/vsphere-automation-sdk-python.git && \ find $VENV -type d -name "__pycache__" -print0 | xargs -0 -n1 rm -rf -FROM python:3.11-slim AS netbox-sync +FROM python:3.13-slim AS netbox-sync ARG VENV=/opt/netbox-sync/venv diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..7da0418 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,24 @@ +[project] +name = "netbox-sync" +version = "1.8.0" +description = "Sync objects from various sources to NetBox" +authors = [ + { name = "Ricardo Bartels", email = "ricardo.bartels@telekom.de" } +] +readme = "README.md" +license = "MIT" +license-files = ["LICENSE.txt"] +requires-python = ">=3.13" +dependencies = [ + "aiodns>=4.0.0", + "packaging>=26.0", + "pyvmomi==8.0.3.0.1", + "pyyaml>=6.0.3", + "requests>=2.32.5", + "urllib3>=2.6.3", + "wheel>=0.46.3", +] + +[project.urls] +Repository = "https://github.com/bb-ricardo/netbox-sync.git" +Issues = "https://github.com/bb-ricardo/netbox-sync/issues" diff --git a/requirements.txt b/requirements.txt index 71a0030..eb25441 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,14 @@ -packaging -urllib3==2.2.2 -wheel -requests==2.32.3 -pyvmomi==8.0.2.0.1 -aiodns==3.0.0 -pycares==4.0.0 -pyyaml==6.0.1 +aiodns==4.0.0 +certifi==2026.1.4 +cffi==2.0.0 +charset-normalizer==3.4.4 +idna==3.11 +packaging==26.0 +pycares==5.0.1 +pycparser==3.0 +pyvmomi==8.0.3.0.1 +pyyaml==6.0.3 +requests==2.32.5 +six==1.17.0 +urllib3==2.6.3 +wheel==0.46.3 diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..8708596 --- /dev/null +++ b/uv.lock @@ -0,0 +1,303 @@ +version = 1 +revision = 3 +requires-python = ">=3.13" +resolution-markers = [ + "python_full_version >= '3.14'", + "python_full_version < '3.14'", +] + +[[package]] +name = "aiodns" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycares" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/10/da/97235e953109936bfeda62c1f9f1a7c5652d4dc49f2b5911f9ae1043afa9/aiodns-4.0.0.tar.gz", hash = "sha256:17be26a936ba788c849ba5fd20e0ba69d8c46e6273e846eb5430eae2630ce5b1", size = 26204, upload-time = "2026-01-10T22:33:27.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/60/14ac40c03e8a26216e4f2642497b776e52f9e3214e4fd537628829bbb082/aiodns-4.0.0-py3-none-any.whl", hash = "sha256:a188a75fb8b2b7862ac8f84811a231402fb74f5b4e6f10766dc8a4544b0cf989", size = 11334, upload-time = "2026-01-10T22:33:25.65Z" }, +] + +[[package]] +name = "certifi" +version = "2026.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120", size = 154268, upload-time = "2026-01-04T02:42:41.825Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c", size = 152900, upload-time = "2026-01-04T02:42:40.15Z" }, +] + +[[package]] +name = "cffi" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" }, + { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" }, + { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" }, + { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" }, + { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" }, + { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" }, + { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" }, + { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" }, + { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" }, + { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" }, + { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" }, + { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" }, + { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" }, + { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" }, + { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" }, + { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" }, + { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" }, + { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" }, + { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" }, + { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" }, + { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" }, + { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" }, + { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "netbox-sync" +version = "1.8.0" +source = { virtual = "." } +dependencies = [ + { name = "aiodns" }, + { name = "packaging" }, + { name = "pyvmomi" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "urllib3" }, + { name = "wheel" }, +] + +[package.metadata] +requires-dist = [ + { name = "aiodns", specifier = ">=4.0.0" }, + { name = "packaging", specifier = ">=26.0" }, + { name = "pyvmomi", specifier = "==8.0.3.0.1" }, + { name = "pyyaml", specifier = ">=6.0.3" }, + { name = "requests", specifier = ">=2.32.5" }, + { name = "urllib3", specifier = ">=2.6.3" }, + { name = "wheel", specifier = ">=0.46.3" }, +] + +[[package]] +name = "packaging" +version = "26.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, +] + +[[package]] +name = "pycares" +version = "5.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/a0/9c823651872e6a0face3f0311de2a40c8bbcb9c8dcb15680bd019ac56ac7/pycares-5.0.1.tar.gz", hash = "sha256:5a3c249c830432631439815f9a818463416f2a8cbdb1e988e78757de9ae75081", size = 652222, upload-time = "2026-01-01T12:37:00.604Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/0a/6bd9bdc2d0ee23ff3aabab7747212e2c5323a081b9b745624d62df88f7e9/pycares-5.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7d1b2c6b152c65f14d0e12d741fabb78a487f0f0d22773eede8d8cfc97af612b", size = 136242, upload-time = "2026-01-01T12:35:38.372Z" }, + { url = "https://files.pythonhosted.org/packages/18/2a/2e9f888fc076cfe7a3493a3c4113e787cc4b4533f531dfb562ac9b04898f/pycares-5.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8c8ffcc9a48cfc296fe1aefc07d2c8e29a7f97e4bb366ce17effea6a38825f70", size = 131070, upload-time = "2026-01-01T12:35:39.262Z" }, + { url = "https://files.pythonhosted.org/packages/ec/5b/83b5aaf7b6ed102f63cd768a747b6cb5d4624f2eaecd84868d103b9dbf39/pycares-5.0.1-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8efc38c2703e3530b823a4165a7b28d7ce0fdcf41960fb7a4ca834a0f8cfe79", size = 221137, upload-time = "2026-01-01T12:35:40.155Z" }, + { url = "https://files.pythonhosted.org/packages/33/d3/d77ab0b33fb805d02896c385176c462e3386d94457a5e508245c39f41829/pycares-5.0.1-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e380bf6eff42c260f829a0a14547e13375e949053a966c23ca204a13647ef265", size = 252252, upload-time = "2026-01-01T12:35:41.287Z" }, + { url = "https://files.pythonhosted.org/packages/14/32/8afbc798bce26dfcc5bc1f6bf1560d31cdd0af837ff52cbede657bf9262e/pycares-5.0.1-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:35dd5858ee1246bd092a212b5e85a8ef70853f7cfaf16b99569bf4af3ae4695d", size = 239447, upload-time = "2026-01-01T12:35:42.614Z" }, + { url = "https://files.pythonhosted.org/packages/61/1b/a056393fda383b2eda5dab20bd0dd034fd631bf5ae754aabb20da815bdfe/pycares-5.0.1-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c257c6e7bf310cdb5823aa9d9a28f1e370fed8c653a968d38a954a8f8e0375ce", size = 223822, upload-time = "2026-01-01T12:35:43.594Z" }, + { url = "https://files.pythonhosted.org/packages/ca/c7/9817f0fb954ab9926f88403f2b91a3e4984a277e2b7a4563e0118e4e1ffa/pycares-5.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:07711acb0ef75758f081fb7436acaccc91e8afd5ae34fd35d4edc44297e81f27", size = 223986, upload-time = "2026-01-01T12:35:44.893Z" }, + { url = "https://files.pythonhosted.org/packages/e1/a9/c0ea15c871c77e8c20bcaab18f56ae83988ea4c302155d106cc6a1bd83a9/pycares-5.0.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:30e5db1ae85cffb031dd8bc1b37903cd74c6d37eb737643bbca3ff2cd4bc6ae2", size = 251838, upload-time = "2026-01-01T12:35:46.271Z" }, + { url = "https://files.pythonhosted.org/packages/be/a4/fe4068abfadf3e06cc22333e87e4730de3c170075572041d5545926062a3/pycares-5.0.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:efbe7f89425a14edbc94787042309be77cb3674415eb6079b356e1f9552ba747", size = 238238, upload-time = "2026-01-01T12:35:47.196Z" }, + { url = "https://files.pythonhosted.org/packages/a7/25/4f140518768d974af4221cfd574a30d99d40b3d5c54c479da2c1553be59e/pycares-5.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5de9e7ce52d638d78723c24704eb032e60b96fbb6fe90c6b3110882987251377", size = 223574, upload-time = "2026-01-01T12:35:48.191Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0a/6e4afa4a2baffd1eba6c18a90cda17681d4838d3cab5a485e471386e04dc/pycares-5.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:0e99af0a1ce015ab6cc6bd85ce158d95ed89fb3b654515f1d0989d1afcf11026", size = 117472, upload-time = "2026-01-01T12:35:50.674Z" }, + { url = "https://files.pythonhosted.org/packages/57/d0/a99f97e9aa8c8404fc899540cf30be63cda0df5150e3c0837423917c7e4c/pycares-5.0.1-cp313-cp313-win_arm64.whl", hash = "sha256:2a511c9f3b11b7ce9f159c956ea1b8f2de7f419d7ca9fa24528d582cb015dbf9", size = 108889, upload-time = "2026-01-01T12:35:51.902Z" }, + { url = "https://files.pythonhosted.org/packages/38/b2/4af99ff17acb81377c971831520540d1859bf401dc85712eb4abc2e6751f/pycares-5.0.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e330e3561be259ad7a1b7b0ce282c872938625f76587fae7ac8d6bc5af1d0c3d", size = 136635, upload-time = "2026-01-01T12:35:53.365Z" }, + { url = "https://files.pythonhosted.org/packages/42/da/e2e1683811c427492ee0e86e8fae8d55eb5cca032220438599991fdad866/pycares-5.0.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:82bd37fec2a3fa62add30d4a3854720f7b051386e2f18e6e8f4ee94b89b5a7b0", size = 131093, upload-time = "2026-01-01T12:35:54.28Z" }, + { url = "https://files.pythonhosted.org/packages/cd/2a/9cf2120cafc19e5c589d5252a9ddd3108cc87e9db09938d16317807de03b/pycares-5.0.1-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:258c38aaa82ad1d565b4591cdb93d2c191be8e0a2c70926999c8e0b717a01f2a", size = 221096, upload-time = "2026-01-01T12:35:57.096Z" }, + { url = "https://files.pythonhosted.org/packages/2c/cc/c5fbf6377e2d6b1f1618f147ad898e5d8ae1585fc726d6301f07aeda6cac/pycares-5.0.1-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ccc1b2df8a09ca20eefbe20b9f7a484d376525c0fb173cfadd692320013c6bc5", size = 252330, upload-time = "2026-01-01T12:35:58.182Z" }, + { url = "https://files.pythonhosted.org/packages/3b/df/17a7c518c45bb994f76d9064d2519674e2a3950f895abbe6af123ead04ac/pycares-5.0.1-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3c4dfc80cc8b43dc79e02a15486c58eead5cae0a40906d6be64e2522285b5b39", size = 239799, upload-time = "2026-01-01T12:36:00.378Z" }, + { url = "https://files.pythonhosted.org/packages/3f/6c/d79c94809742b56b9180a9a9ec2937607db0b8eb34b8ca75d86d3114d6dd/pycares-5.0.1-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f498a6606247bfe896c2a4d837db711eb7b0ba23e409e16e4b23def4bada4b9d", size = 223501, upload-time = "2026-01-01T12:36:02.695Z" }, + { url = "https://files.pythonhosted.org/packages/69/08/83084b67cbce08f44fd803b88816fc80d2fe2fb3d483d5432925df44371b/pycares-5.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a7d197835cdb4b202a3b12562b32799e27bb132262d4aa1ac3ee9d440e8ec22c", size = 223708, upload-time = "2026-01-01T12:36:04.357Z" }, + { url = "https://files.pythonhosted.org/packages/15/57/63a6e9ef356c5149b8ec72a694e02207fd8ae643895aeb78a9f0c07f1502/pycares-5.0.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f78ab823732b050d658eb735d553726663c9bccdeeee0653247533a23eb2e255", size = 251816, upload-time = "2026-01-01T12:36:05.618Z" }, + { url = "https://files.pythonhosted.org/packages/43/1c/1c85c6355cf7bc3ae86a1024d60f9cabdc12af63306a5f59370ac8718a41/pycares-5.0.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f444ab7f318e9b2c209b45496fb07bff5e7ada606e15d5253a162964aa078527", size = 238259, upload-time = "2026-01-01T12:36:07.609Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7f/bd5ff5a460e50433f993560e4e5d229559a8bf271dbdf6be832faf1973b5/pycares-5.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9de80997de7538619b7dd28ec4371e5172e3f9480e4fc648726d3d5ba661ca05", size = 223732, upload-time = "2026-01-01T12:36:09.893Z" }, + { url = "https://files.pythonhosted.org/packages/b5/fe/e77738366e00dc0918bbeb0c8fc63579e5d9cec748a2b838e207e548b5d9/pycares-5.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:206ce9f3cb9d51f5065c81b23c22996230fbc2cf58ae22834c623631b2b473aa", size = 120847, upload-time = "2026-01-01T12:36:11.494Z" }, + { url = "https://files.pythonhosted.org/packages/81/17/758e9af7ee8589ac6deddf7ea56d75b982f155bc2052ef61c45d5f371389/pycares-5.0.1-cp314-cp314-win_arm64.whl", hash = "sha256:45fb3b07231120e8cb5b75be7f15f16115003e9251991dc37a3e5c63733d63b5", size = 112595, upload-time = "2026-01-01T12:36:12.973Z" }, + { url = "https://files.pythonhosted.org/packages/56/12/4f1d418fed957fc96089c69d9ec82314b3b91c48c7f9463385842acad9c4/pycares-5.0.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:602f3eac4b880a2527d21f52b2319cb10fde9225d103d338c4d0b2b07f136849", size = 137061, upload-time = "2026-01-01T12:36:15.027Z" }, + { url = "https://files.pythonhosted.org/packages/29/8c/559cea98a8a5d0f38b50b4b812a07fdbcdb1a961bed9e2e9d5d343e53c6f/pycares-5.0.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1c3736deef003f0c57bc4e7f94d54270d0824350a8f5ceaba3a20b2ce8fb427", size = 131551, upload-time = "2026-01-01T12:36:16.74Z" }, + { url = "https://files.pythonhosted.org/packages/34/cd/aee5d8070888d7be509d4f32a348e2821309ec67980498e5a974cd9e4990/pycares-5.0.1-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e63328df86d37150ce697fb5d9313d1d468dd4dddee1d09342cb2ed241ce6ad9", size = 230409, upload-time = "2026-01-01T12:36:18.909Z" }, + { url = "https://files.pythonhosted.org/packages/5e/94/15d5cf7d8e7af4b4ce3e19ea117dfe565c08d60d82f043ad23843703a135/pycares-5.0.1-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:57f6fd696213329d9a69b9664a68b1ff2a71ccbdc1fc928a42c9a92858c1ec5d", size = 261297, upload-time = "2026-01-01T12:36:20.771Z" }, + { url = "https://files.pythonhosted.org/packages/af/46/24f6ddc7a37ec6eaa1c38f617f39624211d8e7cdca49b644bfc5f467f275/pycares-5.0.1-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9d0878edabfbecb48a29e8769284003d8dbc05936122fe361849cd5fa52722e0", size = 248071, upload-time = "2026-01-01T12:36:22.925Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f0/7eb7fe44f0db55b9083725ab7a084874c2dc02806d9613e07e719838c2ab/pycares-5.0.1-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50e21f27a91be122e066ddd78c2d0d2769e547561481d8342a9d652a345b89f7", size = 232073, upload-time = "2026-01-01T12:36:25.773Z" }, + { url = "https://files.pythonhosted.org/packages/1d/cd/993b17e0c049a56b5af4df3fd053acc57b37e17e0dcd709b2d337c22d57d/pycares-5.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:97ceda969f5a5d5c6b15558b658c29e4301b3a2c4615523797b5f9d4ac74772e", size = 232815, upload-time = "2026-01-01T12:36:27.798Z" }, + { url = "https://files.pythonhosted.org/packages/7a/ff/170177bcc5dff31e735f209f5de63362f513ac18846c83d50e4e68f57866/pycares-5.0.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:4d1713e602ab09882c3e65499b2cc763bff0371117327cad704cf524268c2604", size = 261111, upload-time = "2026-01-01T12:36:29.94Z" }, + { url = "https://files.pythonhosted.org/packages/4d/4a/4c6497b8ca9279b4038ee8c7e2c49504008d594d06a044e00678b30c10fe/pycares-5.0.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:954a379055d6c66b2e878b52235b382168d1a3230793ff44454019394aecac5e", size = 246311, upload-time = "2026-01-01T12:36:31.352Z" }, + { url = "https://files.pythonhosted.org/packages/06/19/1603f51f0d73bf34017a9e6967540c2bc138f9541aa7cc1ef38990b3ce9d/pycares-5.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:145d8a20f7fd1d58a2e49b7ef4309ec9bdcab479ac65c2e49480e20d3f890c23", size = 232027, upload-time = "2026-01-01T12:36:34.374Z" }, + { url = "https://files.pythonhosted.org/packages/7a/de/c000a682757b84688722ac232a24a86b6f195f1f4732432ecf35d0a768a5/pycares-5.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:ebc9daba03c7ff3f62616c84c6cb37517445d15df00e1754852d6006039eb4a4", size = 121267, upload-time = "2026-01-01T12:36:35.741Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c4/8bfffecd08b9b198113fcff5f0ab84bbe696f07dec46dd1ccae0e7b28c23/pycares-5.0.1-cp314-cp314t-win_arm64.whl", hash = "sha256:e0a86eff6bf9e91d5dd8876b1b82ee45704f46b1104c24291d3dea2c1fc8ebcb", size = 113043, upload-time = "2026-01-01T12:36:37.895Z" }, +] + +[[package]] +name = "pycparser" +version = "3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, +] + +[[package]] +name = "pyvmomi" +version = "8.0.3.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/78/4a3847c0487283e57679364b5797ee8f7a2c40a13bccdb430864e9190782/pyvmomi-8.0.3.0.1.tar.gz", hash = "sha256:db795c960159cfa3c81e6af4cf1f46618e61cf0349db1666de75df98a4f29c69", size = 1191984, upload-time = "2024-06-26T19:29:36.985Z" } + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "requests" +version = "2.32.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, +] + +[[package]] +name = "wheel" +version = "0.46.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/89/24/a2eb353a6edac9a0303977c4cb048134959dd2a51b48a269dfc9dde00c8a/wheel-0.46.3.tar.gz", hash = "sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803", size = 60605, upload-time = "2026-01-22T12:39:49.136Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/22/b76d483683216dde3d67cba61fb2444be8d5be289bf628c13fc0fd90e5f9/wheel-0.46.3-py3-none-any.whl", hash = "sha256:4b399d56c9d9338230118d705d9737a2a468ccca63d5e813e2a4fc7815d8bc4d", size = 30557, upload-time = "2026-01-22T12:39:48.099Z" }, +] From 05badcece7b49eed89235e2418f0ab0b7c9179fe Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Thu, 29 Jan 2026 08:16:12 +0100 Subject: [PATCH 13/21] reworks and fixes again detecting of distro version #492 --- module/sources/vmware/connection.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/module/sources/vmware/connection.py b/module/sources/vmware/connection.py index 5b09bde..fe416a7 100644 --- a/module/sources/vmware/connection.py +++ b/module/sources/vmware/connection.py @@ -2194,16 +2194,14 @@ class VMWareHandler(SourceBase): detailed_data_key, detailed_data_value = detailed_data_item.split("=") detailed_data_dict[detailed_data_key] = detailed_data_value.strip("'") - if len(detailed_data_dict.get("prettyName","")) > 0: + if len(detailed_data_dict.get("prettyName", "")) > 0: platform = detailed_data_dict.get("prettyName") distro_version = detailed_data_dict.get("distroVersion") - if detailed_data_dict.get("familyName", "").lower() == "linux" and distro_version: - if distro_version not in platform: - platform = f'{platform} {distro_version}' - if platform is not None: - platform = self.get_object_relation(platform, "vm_platform_relation", fallback=platform) - + if detailed_data_dict.get("familyName", "").lower() == "linux" and \ + distro_version is not None and \ + distro_version not in platform: + platform = f'{platform} {distro_version}' if platform is not None: platform = self.get_object_relation(platform, "vm_platform_relation", fallback=platform) From 7c9c69aaaed0ba7939204b02f18db2242c68af51 Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Thu, 29 Jan 2026 09:05:02 +0100 Subject: [PATCH 14/21] Skip prune on source failure #490 --- netbox-sync.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/netbox-sync.py b/netbox-sync.py index e499838..42c0ef2 100755 --- a/netbox-sync.py +++ b/netbox-sync.py @@ -87,6 +87,13 @@ def main(): log.info("Initializing sources") sources = instantiate_sources() + # disable pruning if an enabled source is unavailable + if nb_handler.settings.prune_enabled is True: + for source in inventory.source_list: + if getattr(source.settings, "enabled", False) is True and source.init_successful is False: + nb_handler.settings.prune_enabled = False + log.warning(f"disabling pruning as source '{source.name}' is unavailable") + # all sources are unavailable if len(sources) == 0: log.error("No working sources found. Exit.") From bb61e3243dbf8e1cfbc9e7cd521a466df55737c6 Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Wed, 4 Feb 2026 10:30:48 +0100 Subject: [PATCH 15/21] fixes issue with correct path of netbox status API call #446 --- module/netbox/connection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/netbox/connection.py b/module/netbox/connection.py index d3a0dd5..b132001 100644 --- a/module/netbox/connection.py +++ b/module/netbox/connection.py @@ -200,7 +200,7 @@ class NetBoxHandler: try: response = self.session.get( - f"{self.url}/status", + f"{self.url}status", timeout=self.settings.timeout, verify=self.settings.validate_tls_certs) except Exception as e: From 7c1fa010cb2325fb95456bb110a2e41860a95209 Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Mon, 9 Mar 2026 08:27:37 +0100 Subject: [PATCH 16/21] adds detecction of missing os tools to report os-release #495 --- .github/workflows/docker-image.yml | 2 +- module/sources/vmware/connection.py | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 8931bfb..5f25ff6 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -71,7 +71,7 @@ jobs: id: meta_dhub uses: docker/metadata-action@v5 with: - images: docker.io/bbricardo/${{ steps.docker_image.outputs.lowercase }} + images: docker.io/bbricardo/netbox-sync:${{ github.ref.name }} tags: | type=semver,pattern={{version}} type=ref,event=branch diff --git a/module/sources/vmware/connection.py b/module/sources/vmware/connection.py index fe416a7..0d5c945 100644 --- a/module/sources/vmware/connection.py +++ b/module/sources/vmware/connection.py @@ -2186,8 +2186,14 @@ class VMWareHandler(SourceBase): # first try 'guestInfo.detailed.data' and then 'guestOS.detailed.data' detailed_data = extra_config.get("guestInfo.detailed.data") or extra_config.get("guestOS.detailed.data") + + # if guestOS tools ar installed but are not able to determine the os-release + # then check against this pattern to guess if a correct os string has been returned + invalid_patterns = ["Usage:", "Error:", "command not found", "No such file"] + if isinstance(detailed_data, str): detailed_data_dict = dict() + pretty_name = None for detailed_data_item in quoted_split(detailed_data.replace("' ", "', ")): if "=" not in detailed_data_item: continue @@ -2195,13 +2201,15 @@ class VMWareHandler(SourceBase): detailed_data_key, detailed_data_value = detailed_data_item.split("=") detailed_data_dict[detailed_data_key] = detailed_data_value.strip("'") if len(detailed_data_dict.get("prettyName", "")) > 0: - platform = detailed_data_dict.get("prettyName") - - distro_version = detailed_data_dict.get("distroVersion") - if detailed_data_dict.get("familyName", "").lower() == "linux" and \ - distro_version is not None and \ - distro_version not in platform: - platform = f'{platform} {distro_version}' + pretty_name = detailed_data_dict.get("prettyName") + + if pretty_name and not any(pretty_name.startswith(p) for p in invalid_patterns): + platform = pretty_name + distro_version = detailed_data_dict.get("distroVersion") + if detailed_data_dict.get("familyName", "").lower() == "linux" and \ + distro_version is not None and \ + distro_version not in platform: + platform = f'{platform} {distro_version}' if platform is not None: platform = self.get_object_relation(platform, "vm_platform_relation", fallback=platform) From 31a0481bee37c35e3466643cab44ffa22c69c991 Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Mon, 9 Mar 2026 08:51:50 +0100 Subject: [PATCH 17/21] fixes dockerhub action --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 5f25ff6..eeecb17 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -71,7 +71,7 @@ jobs: id: meta_dhub uses: docker/metadata-action@v5 with: - images: docker.io/bbricardo/netbox-sync:${{ github.ref.name }} + images: docker.io/${{ secrets.DOCKER_HUB_USERNAME }}/${{ steps.docker_image.outputs.lowercase }} tags: | type=semver,pattern={{version}} type=ref,event=branch From 527c16ce30c3114e1d1c27b28020cbdae3bcca81 Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Mon, 9 Mar 2026 09:15:14 +0100 Subject: [PATCH 18/21] adds setuptools pinning for version 81.0.0 #497 --- pyproject.toml | 1 + requirements.txt | 1 + uv.lock | 11 +++++++++++ 3 files changed, 13 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 7da0418..caddd46 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ dependencies = [ "pyvmomi==8.0.3.0.1", "pyyaml>=6.0.3", "requests>=2.32.5", + "setuptools==81.0.0", "urllib3>=2.6.3", "wheel>=0.46.3", ] diff --git a/requirements.txt b/requirements.txt index eb25441..42a9d7d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,6 +9,7 @@ pycparser==3.0 pyvmomi==8.0.3.0.1 pyyaml==6.0.3 requests==2.32.5 +setuptools==81.0.0 six==1.17.0 urllib3==2.6.3 wheel==0.46.3 diff --git a/uv.lock b/uv.lock index 8708596..123a41d 100644 --- a/uv.lock +++ b/uv.lock @@ -132,6 +132,7 @@ dependencies = [ { name = "pyvmomi" }, { name = "pyyaml" }, { name = "requests" }, + { name = "setuptools" }, { name = "urllib3" }, { name = "wheel" }, ] @@ -143,6 +144,7 @@ requires-dist = [ { name = "pyvmomi", specifier = "==8.0.3.0.1" }, { name = "pyyaml", specifier = ">=6.0.3" }, { name = "requests", specifier = ">=2.32.5" }, + { name = "setuptools", specifier = "==81.0.0" }, { name = "urllib3", specifier = ">=2.6.3" }, { name = "wheel", specifier = ">=0.46.3" }, ] @@ -272,6 +274,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] +[[package]] +name = "setuptools" +version = "81.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0d/1c/73e719955c59b8e424d015ab450f51c0af856ae46ea2da83eba51cc88de1/setuptools-81.0.0.tar.gz", hash = "sha256:487b53915f52501f0a79ccfd0c02c165ffe06631443a886740b91af4b7a5845a", size = 1198299, upload-time = "2026-02-06T21:10:39.601Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/e3/c164c88b2e5ce7b24d667b9bd83589cf4f3520d97cad01534cd3c4f55fdb/setuptools-81.0.0-py3-none-any.whl", hash = "sha256:fdd925d5c5d9f62e4b74b30d6dd7828ce236fd6ed998a08d81de62ce5a6310d6", size = 1062021, upload-time = "2026-02-06T21:10:37.175Z" }, +] + [[package]] name = "six" version = "1.17.0" From 4c5fbc8d31c462f7c7997a29c597277d02a0eca0 Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Mon, 9 Mar 2026 09:41:18 +0100 Subject: [PATCH 19/21] adds pushrm to gitbub steps --- .github/workflows/docker-image.yml | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index eeecb17..adc3aca 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -7,6 +7,7 @@ on: branches: - development paths: + - .github/** - module/** - netbox-sync.py - requirements.txt @@ -36,6 +37,14 @@ jobs: with: string: ${{ github.repository }} + - name: set dockerhub repo name + uses: mad9000/actions-find-and-replace-string@5 + id: dockerhub_image + with: + source: ${{ steps.docker_image.outputs.lowercase }} + find: 'bb-ricardo' + replace: ${{ vars.DOCKER_HUB_USERNAME }} + - name: Log in to GitHub Container Registry uses: docker/login-action@v3 with: @@ -64,19 +73,19 @@ jobs: - name: Log in to Docker Hub uses: docker/login-action@v3 with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} + username: ${{ vars.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_PASSWORD }} - name: Docker hub meta id: meta_dhub uses: docker/metadata-action@v5 with: - images: docker.io/${{ secrets.DOCKER_HUB_USERNAME }}/${{ steps.docker_image.outputs.lowercase }} + images: docker.io/${{ steps.dockerhub_image.outputs.value }} tags: | type=semver,pattern={{version}} type=ref,event=branch - - name: Build and push with tags - ${{ steps.meta_dhub.outputs.tags }} + - name: Build and push with tags - ${{ steps.dockerhub_image.outputs.value }} uses: docker/build-push-action@v6 with: context: . @@ -84,3 +93,12 @@ jobs: platforms: linux/amd64,linux/arm64 tags: ${{ steps.meta_dhub.outputs.tags }} labels: ${{ steps.meta_dhub.outputs.labels }} + + - name: push README to Dockerhub + uses: christian-korneck/update-container-description-action@v1 + env: + DOCKER_USER: ${{ vars.DOCKER_HUB_USERNAME }} + DOCKER_PASS: ${{ secrets.DOCKER_HUB_PASSWORD }} + with: + destination_container_repo: ${{ steps.dockerhub_image.outputs.value }} + provider: dockerhub From 49e0688efaa6a0ee2a3cee2ff62bb964c7ffe0c4 Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Wed, 18 Mar 2026 20:50:22 +0100 Subject: [PATCH 20/21] disables docker pushrm for github actions --- .github/workflows/docker-image.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index adc3aca..6b68930 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -94,11 +94,11 @@ jobs: tags: ${{ steps.meta_dhub.outputs.tags }} labels: ${{ steps.meta_dhub.outputs.labels }} - - name: push README to Dockerhub - uses: christian-korneck/update-container-description-action@v1 - env: - DOCKER_USER: ${{ vars.DOCKER_HUB_USERNAME }} - DOCKER_PASS: ${{ secrets.DOCKER_HUB_PASSWORD }} - with: - destination_container_repo: ${{ steps.dockerhub_image.outputs.value }} - provider: dockerhub +# - name: push README to Dockerhub +# uses: christian-korneck/update-container-description-action@v1 +# env: +# DOCKER_USER: ${{ vars.DOCKER_HUB_USERNAME }} +# DOCKER_PASS: ${{ secrets.DOCKER_HUB_PASSWORD }} +# with: +# destination_container_repo: ${{ steps.dockerhub_image.outputs.value }} +# provider: dockerhub From e972c94eac7437a9a7c0ed2adcf2e5db8fbcd3e9 Mon Sep 17 00:00:00 2001 From: Ricardo Bartels Date: Wed, 18 Mar 2026 21:17:34 +0100 Subject: [PATCH 21/21] bumps version to 1.8.1 --- README.md | 6 +++--- module/__init__.py | 6 +++--- module/common/__init__.py | 2 +- module/common/cli_parser.py | 2 +- module/common/config.py | 2 +- module/common/logging.py | 2 +- module/common/misc.py | 2 +- module/common/support.py | 2 +- module/config/__init__.py | 2 +- module/config/base.py | 2 +- module/config/file_output.py | 2 +- module/config/files.py | 2 +- module/config/formatter.py | 2 +- module/config/group.py | 2 +- module/config/option.py | 2 +- module/config/parser.py | 2 +- module/netbox/__init__.py | 2 +- module/netbox/config.py | 2 +- module/netbox/connection.py | 2 +- module/netbox/inventory.py | 2 +- module/netbox/manufacturer_mapping.py | 2 +- module/netbox/object_classes.py | 10 +++++----- module/sources/__init__.py | 2 +- module/sources/check_redfish/config.py | 2 +- module/sources/check_redfish/import_inventory.py | 2 +- module/sources/common/config.py | 2 +- module/sources/common/handle_vlan.py | 2 +- module/sources/common/permitted_subnets.py | 2 +- module/sources/common/source_base.py | 2 +- module/sources/vmware/config.py | 2 +- module/sources/vmware/connection.py | 2 +- netbox-sync.py | 2 +- pyproject.toml | 2 +- scripts/publi.sh | 2 +- scripts/set_version.sh | 8 +++++--- settings-example.ini | 2 +- 36 files changed, 48 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 0430a67..ce8c6be 100644 --- a/README.md +++ b/README.md @@ -99,18 +99,18 @@ usage: netbox-sync.py [-h] [-c settings.ini [settings.ini ...]] [-g] Sync objects from various sources to NetBox -Version: 1.8.0 (2025-03-07) +Version: 1.8.1 (2026-03-18) Project URL: https://github.com/bb-ricardo/netbox-sync options: -h, --help show this help message and exit - -c settings.ini [settings.ini ...], --config settings.ini [settings.ini ...] + -c, --config settings.ini [settings.ini ...] points to the config file to read config data from which is not installed under the default path './settings.ini' -g, --generate_config generates default config file. - -l {DEBUG3,DEBUG2,DEBUG,INFO,WARNING,ERROR}, --log_level {DEBUG3,DEBUG2,DEBUG,INFO,WARNING,ERROR} + -l, --log_level {DEBUG3,DEBUG2,DEBUG,INFO,WARNING,ERROR} set log level (overrides config) -n, --dry_run Operate as usual but don't change anything in NetBox. Great if you want to test and see what would be diff --git a/module/__init__.py b/module/__init__.py index 32323f9..a099794 100644 --- a/module/__init__.py +++ b/module/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # @@ -7,8 +7,8 @@ # For a copy, see file LICENSE.txt included in this # repository or visit: . -__version__ = "1.8.0" -__version_date__ = "2025-03-07" +__version__ = "1.8.1" +__version_date__ = "2026-03-18" __author__ = "Ricardo Bartels " __description__ = "NetBox Sync" __license__ = "MIT" diff --git a/module/common/__init__.py b/module/common/__init__.py index 4b85b91..88ba5d3 100644 --- a/module/common/__init__.py +++ b/module/common/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/common/cli_parser.py b/module/common/cli_parser.py index 3d890cf..b26e159 100644 --- a/module/common/cli_parser.py +++ b/module/common/cli_parser.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/common/config.py b/module/common/config.py index bb8dd06..21522ad 100644 --- a/module/common/config.py +++ b/module/common/config.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/common/logging.py b/module/common/logging.py index 6bc7650..b6764fd 100644 --- a/module/common/logging.py +++ b/module/common/logging.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/common/misc.py b/module/common/misc.py index 77038dc..50526ef 100644 --- a/module/common/misc.py +++ b/module/common/misc.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/common/support.py b/module/common/support.py index e800da1..6fea646 100644 --- a/module/common/support.py +++ b/module/common/support.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/config/__init__.py b/module/config/__init__.py index 02d7fef..b657b98 100644 --- a/module/config/__init__.py +++ b/module/config/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/config/base.py b/module/config/base.py index d9876c8..7d71b1f 100644 --- a/module/config/base.py +++ b/module/config/base.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/config/file_output.py b/module/config/file_output.py index 3b2f6e5..5adfd49 100644 --- a/module/config/file_output.py +++ b/module/config/file_output.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/config/files.py b/module/config/files.py index 2b734cc..6bed2d4 100644 --- a/module/config/files.py +++ b/module/config/files.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/config/formatter.py b/module/config/formatter.py index 1fef402..533c9be 100644 --- a/module/config/formatter.py +++ b/module/config/formatter.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/config/group.py b/module/config/group.py index 8880147..14e50b8 100644 --- a/module/config/group.py +++ b/module/config/group.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/config/option.py b/module/config/option.py index e792269..b458abd 100644 --- a/module/config/option.py +++ b/module/config/option.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/config/parser.py b/module/config/parser.py index d46256d..ddfeaae 100644 --- a/module/config/parser.py +++ b/module/config/parser.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/netbox/__init__.py b/module/netbox/__init__.py index 6891c37..b2cbb2b 100644 --- a/module/netbox/__init__.py +++ b/module/netbox/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/netbox/config.py b/module/netbox/config.py index 8f943c0..7bf00f1 100644 --- a/module/netbox/config.py +++ b/module/netbox/config.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/netbox/connection.py b/module/netbox/connection.py index b132001..02ba53b 100644 --- a/module/netbox/connection.py +++ b/module/netbox/connection.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/netbox/inventory.py b/module/netbox/inventory.py index 2daa39b..3674c87 100644 --- a/module/netbox/inventory.py +++ b/module/netbox/inventory.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/netbox/manufacturer_mapping.py b/module/netbox/manufacturer_mapping.py index d3aa2f7..cecb163 100644 --- a/module/netbox/manufacturer_mapping.py +++ b/module/netbox/manufacturer_mapping.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/netbox/object_classes.py b/module/netbox/object_classes.py index 9d25093..dae2113 100644 --- a/module/netbox/object_classes.py +++ b/module/netbox/object_classes.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # @@ -683,7 +683,7 @@ class NetBoxObject: if self.data_model.get(key) == NBCustomField: if current_value is None: current_value = dict() - + # Fix for object/multi-object custom fields # When patching, we only need the IDs, not the full object representation new_value_copy = new_value.copy() @@ -692,11 +692,11 @@ class NetBoxObject: custom_field = self.inventory.get_by_data(NBCustomField, data={"name": field_name}) if custom_field is not None: field_type = grab(custom_field, "data.type") - + # Handle object type custom fields - need only ID if field_type == "object" and isinstance(field_value, dict) and field_value.get('id') is not None: new_value[field_name] = field_value.get('id') - + # Handle multi-object type custom fields - need list of IDs elif field_type == "multi-object" and isinstance(field_value, list): ids = [] @@ -705,7 +705,7 @@ class NetBoxObject: ids.append(item.get('id')) if ids: new_value[field_name] = ids - + new_value = {**current_value, **new_value} new_value_str = str(new_value) elif isinstance(new_value, (NetBoxObject, NBObjectList)): diff --git a/module/sources/__init__.py b/module/sources/__init__.py index 4be4120..e1bf82c 100644 --- a/module/sources/__init__.py +++ b/module/sources/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/sources/check_redfish/config.py b/module/sources/check_redfish/config.py index 2c21fff..38d6e8e 100644 --- a/module/sources/check_redfish/config.py +++ b/module/sources/check_redfish/config.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/sources/check_redfish/import_inventory.py b/module/sources/check_redfish/import_inventory.py index 95fbe1f..ee14673 100644 --- a/module/sources/check_redfish/import_inventory.py +++ b/module/sources/check_redfish/import_inventory.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/sources/common/config.py b/module/sources/common/config.py index 5fa7b3f..115bc70 100644 --- a/module/sources/common/config.py +++ b/module/sources/common/config.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/sources/common/handle_vlan.py b/module/sources/common/handle_vlan.py index 18bf986..b93253c 100644 --- a/module/sources/common/handle_vlan.py +++ b/module/sources/common/handle_vlan.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/sources/common/permitted_subnets.py b/module/sources/common/permitted_subnets.py index a4c88e8..82cf30d 100644 --- a/module/sources/common/permitted_subnets.py +++ b/module/sources/common/permitted_subnets.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/sources/common/source_base.py b/module/sources/common/source_base.py index 0e95e5c..4d20e9d 100644 --- a/module/sources/common/source_base.py +++ b/module/sources/common/source_base.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/sources/vmware/config.py b/module/sources/vmware/config.py index 7e448a2..e4d8e2b 100644 --- a/module/sources/vmware/config.py +++ b/module/sources/vmware/config.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/module/sources/vmware/connection.py b/module/sources/vmware/connection.py index 0d5c945..e63763c 100644 --- a/module/sources/vmware/connection.py +++ b/module/sources/vmware/connection.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/netbox-sync.py b/netbox-sync.py index 42c0ef2..c85de91 100755 --- a/netbox-sync.py +++ b/netbox-sync.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/pyproject.toml b/pyproject.toml index caddd46..1617676 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "netbox-sync" -version = "1.8.0" +version = "1.8.1" description = "Sync objects from various sources to NetBox" authors = [ { name = "Ricardo Bartels", email = "ricardo.bartels@telekom.de" } diff --git a/scripts/publi.sh b/scripts/publi.sh index 2a585ac..928b6c9 100755 --- a/scripts/publi.sh +++ b/scripts/publi.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # diff --git a/scripts/set_version.sh b/scripts/set_version.sh index f947e0e..ae7cc9a 100755 --- a/scripts/set_version.sh +++ b/scripts/set_version.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved. +# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved. # # netbox-sync.py # @@ -11,8 +11,9 @@ EXAMPLE_CONFIG_FILE="settings-example.ini" VERSION_DATA_FILE="module/__init__.py" README_FILE="README.md" +PYPROJECT_TOML="pyproject.toml" VERSION_TO_SET="$1" -COPYRIGHT_PATTERN="# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved." +COPYRIGHT_PATTERN="# Copyright (c) 2020 - 2026 Ricardo Bartels. All rights reserved." BASE_PATH="$(realpath "$(dirname "${0}")/..")" # shellcheck disable=SC2181 @@ -28,6 +29,7 @@ read -rp "Should '$VERSION_TO_SET' be set as the new version [yN]: " -n1 ANSWER # setting new version and date sed -i "" -e 's/^__version__.*/__version__ = "'"${VERSION_TO_SET}"'"/g' "${VERSION_DATA_FILE}" sed -i "" -e 's/^__version_date__.*/__version_date__ = "'"$(date +%F)"'"/g' "${VERSION_DATA_FILE}" +sed -i "" -e 's/^version = .*/version = "'"${VERSION_TO_SET}"'"/g' ${PYPROJECT_TOML} # update config [[ -e "${EXAMPLE_CONFIG_FILE}" ]] && rm "$EXAMPLE_CONFIG_FILE" @@ -46,7 +48,7 @@ README_BOTTOM=$(sed -n '/## TESTING/,$ p' "${README_FILE}") } > "${README_FILE}" # update COPYRIGHT notice date -NEW_COPYRIGHT_NOTICE="${COPYRIGHT_PATTERN//..../$(date +%Y)}" +NEW_COPYRIGHT_NOTICE="${COPYRIGHT_PATTERN//2020 - $(($(date +%Y)-1))/2020 - $(date +%Y)}" grep -lR "$COPYRIGHT_PATTERN" "${BASE_PATH}" | while read -r FILE; do sed -i "" -e 's/'"${COPYRIGHT_PATTERN}"'/'"${NEW_COPYRIGHT_NOTICE}"'/g' "${FILE}" done diff --git a/settings-example.ini b/settings-example.ini index 432d4c2..ec2d5f1 100644 --- a/settings-example.ini +++ b/settings-example.ini @@ -1,5 +1,5 @@ ;;; Welcome to the NetBox Sync configuration file. -;;; Version: 1.8.0 (2025-03-07) +;;; Version: 1.8.1 (2026-03-18) ;;; Project URL: https://github.com/bb-ricardo/netbox-sync ; The values in this file override the default values used by the system if a config