From 93e005f1a57561203c8a5f69795f3ea4a2bc35dd Mon Sep 17 00:00:00 2001 From: Clint Branham Date: Sat, 21 Mar 2026 10:15:25 -0500 Subject: [PATCH] feat: add version gating from PVE API history, document version policy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add RequireVersion calls based on pve_api endpoint-history.json data: - Cloud-Init management: introduced PVE 7.2 - Storage URL download: introduced PVE 7.0 - Backup compliance info: introduced PVE 7.0 - Container interfaces: introduced PVE 8.1 - Pool update/delete: introduced PVE 8.1 Update README with version policy: - PVE 9.x: primary target - PVE 8.x: supported - PVE 7.x (7.0+): best-effort with clear version errors - PVE 6.x and older: hard blocked - Document two-tier gating (introduced vs default) behavior Parameter-level version changes are not gated — the API returns clear errors for unknown parameters, which is acceptable. Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 12 +++++++++++- .../Cmdlets/Backup/GetPveBackupInfoCmdlet.cs | 1 + .../Cmdlets/CloudInit/GetPveCloudInitConfigCmdlet.cs | 1 + .../CloudInit/InvokePveCloudInitRegenerateCmdlet.cs | 1 + .../Cmdlets/CloudInit/SetPveCloudInitConfigCmdlet.cs | 1 + .../Containers/GetPveContainerInterfaceCmdlet.cs | 1 + src/PSProxmoxVE/Cmdlets/Pools/RemovePvePoolCmdlet.cs | 1 + src/PSProxmoxVE/Cmdlets/Pools/SetPvePoolCmdlet.cs | 1 + .../Storage/InvokePveStorageDownloadCmdlet.cs | 1 + 9 files changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 738c5ac..dde808e 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,17 @@ A production-grade C# binary PowerShell module for managing Proxmox VE environme |---|---| | 9.x (current, 9.1.6+) | **Primary target — fully supported** | | 8.x | Supported | -| 7.x | EOL 2024 — **not supported** | +| 7.x (7.0+) | **Best-effort** — core cmdlets work, newer features emit clear version errors | +| 6.x and older | **Not supported** — hard blocked by version checks | + +### Version Gating Policy + +The module uses a two-tier version check for cmdlets that require newer PVE APIs: + +- **Hard block** (introduced version): The API endpoint doesn't exist — the cmdlet emits a terminating error with a clear message like *"This operation requires Proxmox VE 8.1 or later."* +- **Warning** (default version): The feature exists but may not be enabled by default — a warning is emitted but the command proceeds, allowing users who manually enabled the feature to succeed. + +Most cmdlets target endpoints available since PVE 4.2 and require no version check. Cmdlets that need newer APIs include SDN (introduced 6.2, default 8.0+), cloud-init management (7.2+), container interfaces (8.1+), VM disk import (8.1+), and pool management (8.1+ for update/delete). ## Prerequisites diff --git a/src/PSProxmoxVE/Cmdlets/Backup/GetPveBackupInfoCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Backup/GetPveBackupInfoCmdlet.cs index 0ea3a9e..2cc33b3 100644 --- a/src/PSProxmoxVE/Cmdlets/Backup/GetPveBackupInfoCmdlet.cs +++ b/src/PSProxmoxVE/Cmdlets/Backup/GetPveBackupInfoCmdlet.cs @@ -17,6 +17,7 @@ namespace PSProxmoxVE.Cmdlets.Backup protected override void ProcessRecord() { var session = GetSession(); + RequireVersion(session, "Backup compliance info", 7, 0); var service = new BackupService(); WriteVerbose("Getting guests not covered by backup jobs..."); diff --git a/src/PSProxmoxVE/Cmdlets/CloudInit/GetPveCloudInitConfigCmdlet.cs b/src/PSProxmoxVE/Cmdlets/CloudInit/GetPveCloudInitConfigCmdlet.cs index 8022413..fb3f16f 100644 --- a/src/PSProxmoxVE/Cmdlets/CloudInit/GetPveCloudInitConfigCmdlet.cs +++ b/src/PSProxmoxVE/Cmdlets/CloudInit/GetPveCloudInitConfigCmdlet.cs @@ -29,6 +29,7 @@ namespace PSProxmoxVE.Cmdlets.CloudInit protected override void ProcessRecord() { var session = GetSession(); + RequireVersion(session, "Cloud-Init management", 7, 2); using var client = new PveHttpClient(session); WriteVerbose($"Getting cloud-init config for VM {VmId}..."); diff --git a/src/PSProxmoxVE/Cmdlets/CloudInit/InvokePveCloudInitRegenerateCmdlet.cs b/src/PSProxmoxVE/Cmdlets/CloudInit/InvokePveCloudInitRegenerateCmdlet.cs index c56146f..873472a 100644 --- a/src/PSProxmoxVE/Cmdlets/CloudInit/InvokePveCloudInitRegenerateCmdlet.cs +++ b/src/PSProxmoxVE/Cmdlets/CloudInit/InvokePveCloudInitRegenerateCmdlet.cs @@ -36,6 +36,7 @@ namespace PSProxmoxVE.Cmdlets.CloudInit return; var session = GetSession(); + RequireVersion(session, "Cloud-Init management", 7, 2); WriteVerbose($"Regenerating cloud-init drive for VM {VmId}..."); var service = new CloudInitService(); diff --git a/src/PSProxmoxVE/Cmdlets/CloudInit/SetPveCloudInitConfigCmdlet.cs b/src/PSProxmoxVE/Cmdlets/CloudInit/SetPveCloudInitConfigCmdlet.cs index b7df92a..fe8c452 100644 --- a/src/PSProxmoxVE/Cmdlets/CloudInit/SetPveCloudInitConfigCmdlet.cs +++ b/src/PSProxmoxVE/Cmdlets/CloudInit/SetPveCloudInitConfigCmdlet.cs @@ -68,6 +68,7 @@ namespace PSProxmoxVE.Cmdlets.CloudInit protected override void ProcessRecord() { var session = GetSession(); + RequireVersion(session, "Cloud-Init management", 7, 2); if (!ShouldProcess($"VM {VmId} on {Node}", "Set PVE Cloud-Init Config")) return; diff --git a/src/PSProxmoxVE/Cmdlets/Containers/GetPveContainerInterfaceCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Containers/GetPveContainerInterfaceCmdlet.cs index 1bec648..965f4b0 100644 --- a/src/PSProxmoxVE/Cmdlets/Containers/GetPveContainerInterfaceCmdlet.cs +++ b/src/PSProxmoxVE/Cmdlets/Containers/GetPveContainerInterfaceCmdlet.cs @@ -27,6 +27,7 @@ namespace PSProxmoxVE.Cmdlets.Containers protected override void ProcessRecord() { var session = GetSession(); + RequireVersion(session, "Container interface listing", 8, 1); WriteVerbose($"Getting network interfaces for container {VmId}..."); var service = new ContainerService(); diff --git a/src/PSProxmoxVE/Cmdlets/Pools/RemovePvePoolCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Pools/RemovePvePoolCmdlet.cs index 40cff8b..6959469 100644 --- a/src/PSProxmoxVE/Cmdlets/Pools/RemovePvePoolCmdlet.cs +++ b/src/PSProxmoxVE/Cmdlets/Pools/RemovePvePoolCmdlet.cs @@ -27,6 +27,7 @@ namespace PSProxmoxVE.Cmdlets.Pools return; var session = GetSession(); + RequireVersion(session, "Pool deletion", 8, 1); var service = new PoolService(); WriteVerbose($"Removing pool '{PoolId}'..."); diff --git a/src/PSProxmoxVE/Cmdlets/Pools/SetPvePoolCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Pools/SetPvePoolCmdlet.cs index 1872b72..ae71b9d 100644 --- a/src/PSProxmoxVE/Cmdlets/Pools/SetPvePoolCmdlet.cs +++ b/src/PSProxmoxVE/Cmdlets/Pools/SetPvePoolCmdlet.cs @@ -44,6 +44,7 @@ namespace PSProxmoxVE.Cmdlets.Pools return; var session = GetSession(); + RequireVersion(session, "Pool update", 8, 1); var service = new PoolService(); var config = new Dictionary(); diff --git a/src/PSProxmoxVE/Cmdlets/Storage/InvokePveStorageDownloadCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Storage/InvokePveStorageDownloadCmdlet.cs index c04a5d6..ca2b5cb 100644 --- a/src/PSProxmoxVE/Cmdlets/Storage/InvokePveStorageDownloadCmdlet.cs +++ b/src/PSProxmoxVE/Cmdlets/Storage/InvokePveStorageDownloadCmdlet.cs @@ -49,6 +49,7 @@ namespace PSProxmoxVE.Cmdlets.Storage return; var session = GetSession(); + RequireVersion(session, "Storage URL download", 7, 0); using var client = new PveHttpClient(session); WriteVerbose($"Downloading '{Url}' to {Node}/{Storage}...");