From 20e64870305b60066f1810fa18a9608ac02570d6 Mon Sep 17 00:00:00 2001 From: Louis Date: Fri, 10 Jul 2026 11:20:28 +0200 Subject: [PATCH] Improve Proxmox authentication timeout diagnostics --- COMPATIBILITY.md | 1 + README.md | 4 +++- netbox_vmware_importer/__init__.py | 2 +- netbox_vmware_importer/models.py | 2 ++ netbox_vmware_importer/sync.py | 22 ++++++++++++++++++++-- pyproject.toml | 2 +- 6 files changed, 28 insertions(+), 5 deletions(-) diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index fce14eb..5e3c942 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -13,3 +13,4 @@ | 0.1.8 | 4.4.0 | 4.6.x | | 0.2.0 | 4.4.0 | 4.6.x | | 0.2.1 | 4.4.0 | 4.6.x | +| 0.2.2 | 4.4.0 | 4.6.x | diff --git a/README.md b/README.md index f0160e8..b976806 100644 --- a/README.md +++ b/README.md @@ -47,13 +47,15 @@ sudo systemctl restart netbox netbox-rq 1. In NetBox unter `VM Import > Endpoints` ein Ziel anlegen. 2. Provider auswaehlen. 3. VMware: vCenter Host, Port, Benutzername und Passwort eintragen. -4. Proxmox: Proxmox Host, Port `8006`, Benutzername und Passwort oder API-Token eintragen. +4. Proxmox: Proxmox Host, Port `8006`, Benutzername inklusive Realm und Passwort oder API-Token eintragen, z. B. `root@pam`. 5. Tenant, Site und Cluster fuer den Kunden auswaehlen. 6. Optional Regex-Filter und Sync-Intervall setzen. 7. Auf der Detailseite `Sync jetzt starten` ausfuehren. Bei selbstsignierten Proxmox-Zertifikaten `Validate SSL` deaktiviert lassen. Wenn Proxmox langsam antwortet, kann `API timeout` am Endpoint erhoeht werden. +Wenn Passwort-Login auf `access/ticket` haengt, zuerst den Realm im Benutzernamen pruefen (`root@pam`, `user@pve`, `user@ldaprealm`). Fuer produktive Imports ist ein Proxmox API-Token meistens stabiler als Passwort-Login. + Wenn `Sync interval minutes` gesetzt ist, prueft ein Systemjob alle fuenf Minuten, welche Endpoints faellig sind, und stellt die eigentlichen Sync-Jobs in die Queue. Ab Version `0.1.8` wird beim Speichern eines Endpoints zusaetzlich ein wiederkehrender NetBox-Job fuer genau diesen Endpoint geplant. Nach einem Update vorhandene Endpoints einmal speichern oder `netbox-rq` neu starten und bis zum naechsten Systemjob-Lauf warten. diff --git a/netbox_vmware_importer/__init__.py b/netbox_vmware_importer/__init__.py index d2a7594..fb28686 100644 --- a/netbox_vmware_importer/__init__.py +++ b/netbox_vmware_importer/__init__.py @@ -5,7 +5,7 @@ class VMwareImporterConfig(PluginConfig): name = "netbox_vmware_importer" verbose_name = "Virtualization Importer" description = "Synchronize VMware vSphere and Proxmox VE virtual machines into NetBox." - version = "0.2.1" + version = "0.2.2" author = "Internal NetBox Team" base_url = "vmware-importer" min_version = "4.4.0" diff --git a/netbox_vmware_importer/models.py b/netbox_vmware_importer/models.py index ec964ba..c05e218 100644 --- a/netbox_vmware_importer/models.py +++ b/netbox_vmware_importer/models.py @@ -241,6 +241,8 @@ class VCenterEndpoint(JobsMixin, NetBoxModel): raise ValidationError({"auth_method": _("VMware endpoints currently support username/password authentication only.")}) if self.provider == EndpointProviderChoices.PROVIDER_PROXMOX: + if "@" not in self.username: + raise ValidationError({"username": _("Proxmox usernames must include a realm, e.g. root@pam or user@pve.")}) if self.auth_method == EndpointAuthMethodChoices.METHOD_API_TOKEN and not self.token_name: raise ValidationError({"token_name": _("A token name is required for Proxmox API token authentication.")}) diff --git a/netbox_vmware_importer/sync.py b/netbox_vmware_importer/sync.py index c40e406..2ba3c60 100644 --- a/netbox_vmware_importer/sync.py +++ b/netbox_vmware_importer/sync.py @@ -233,16 +233,21 @@ class ProxmoxClient: self.session = None self.base_url = f"https://{endpoint.host}:{endpoint.port}/api2/json" self.timeout = (10, endpoint.request_timeout_seconds or 120) + self.api_probe_succeeded = False def __enter__(self): if requests is None: raise ProxmoxConnectionError("requests is not installed in the NetBox Python environment.") + if "@" not in self.endpoint.username: + raise ProxmoxConnectionError("Proxmox username must include a realm, e.g. root@pam or user@pve.") self.session = requests.Session() self.session.verify = self.endpoint.validate_ssl if not self.endpoint.validate_ssl and InsecureRequestWarning is not None: requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning) + self._probe_api_availability() + if self.endpoint.auth_method == EndpointAuthMethodChoices.METHOD_API_TOKEN: token_id = self.endpoint.token_name if "!" in self.endpoint.token_name else f"{self.endpoint.username}!{self.endpoint.token_name}" self.session.headers.update({"Authorization": f"PVEAPIToken={token_id}={self.endpoint.password}"}) @@ -255,6 +260,10 @@ class ProxmoxClient: if self.session is not None: self.session.close() + def _probe_api_availability(self): + self._request("GET", "version") + self.api_probe_succeeded = True + def _authenticate_with_password(self): response = self._request( "POST", @@ -284,9 +293,18 @@ class ProxmoxClient: response = self.session.request(method, url, timeout=self.timeout, **kwargs) response.raise_for_status() return response - except requests.Timeout as exc: + except requests.ConnectTimeout as exc: raise ProxmoxConnectionError( - f"Proxmox API {method} {path} timed out after {self.timeout[1]} seconds." + f"Proxmox API {method} {path} connect timed out after {self.timeout[0]} seconds." + ) from exc + except requests.ReadTimeout as exc: + detail = f"Proxmox API {method} {path} read timed out after {self.timeout[1]} seconds." + if path == "access/ticket" and self.api_probe_succeeded: + detail += " API version endpoint responded, so the delay is likely in Proxmox authentication. Check username realm (e.g. root@pam), PAM/LDAP auth, two-factor auth, or use an API token." + raise ProxmoxConnectionError(detail) from exc + except requests.exceptions.SSLError as exc: + raise ProxmoxConnectionError( + f"Proxmox API {method} {path} TLS validation failed. Disable Validate SSL for self-signed certificates or install the CA certificate. Details: {exc}" ) from exc except requests.RequestException as exc: raise ProxmoxConnectionError(f"Proxmox API {method} {path} failed: {exc}") from exc diff --git a/pyproject.toml b/pyproject.toml index 1841262..0d42fb3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "netbox-vmware-importer" -version = "0.2.1" +version = "0.2.2" description = "NetBox plugin to synchronize VMware vSphere and Proxmox VE virtual machines into NetBox." readme = "README.md" requires-python = ">=3.12"