From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 5491A1FF13B for ; Wed, 20 May 2026 15:13:57 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 4BFA77DF1; Wed, 20 May 2026 15:13:55 +0200 (CEST) From: Lukas Wagner To: pdm-devel@lists.proxmox.com Subject: [PATCH datacenter-manager 2/3] clippy: pdm-client: use parameter type for pve_list_storages Date: Wed, 20 May 2026 15:13:46 +0200 Message-ID: <20260520131348.332987-3-l.wagner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260520131348.332987-1-l.wagner@proxmox.com> References: <20260520131348.332987-1-l.wagner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1779282815120 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.053 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: L4NNSXGUPFFUPSKIQL72OCVI5MKGUCGS X-Message-ID-Hash: L4NNSXGUPFFUPSKIQL72OCVI5MKGUCGS X-MailFrom: l.wagner@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Datacenter Manager development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: This API had a quite excessive number of parameters, some of which also had the same type. A parameter type for the filter options reduces the potential for errors. The `formats` parameters was kept as a distinct function parameter and renamed to `include_formats`, to better convey the meaning. Signed-off-by: Lukas Wagner --- lib/pdm-client/src/lib.rs | 43 +++++++++++++++++++-------- ui/src/widget/pve_storage_selector.rs | 19 ++++++++---- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/lib/pdm-client/src/lib.rs b/lib/pdm-client/src/lib.rs index 76b33ef8..c97c9db9 100644 --- a/lib/pdm-client/src/lib.rs +++ b/lib/pdm-client/src/lib.rs @@ -97,6 +97,20 @@ impl std::ops::DerefMut for PdmClient { } } +/// Filter for [`PdmClient::pve_list_storages`]. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct PveListStoragesFilter { + /// Only list stores which support this content type. + pub content: Vec, + /// Only list stores which are enabled (not disabled in config). + pub enabled: Option, + /// Only list status for specified storage + pub storage: Option, + // If target is different to 'node', we only list shared storages which are accessible on + // this 'node' and the specified 'target' node. + pub target: Option, +} + impl PdmClient { pub async fn list_remotes(&self) -> Result, Error> { Ok(self @@ -1103,28 +1117,31 @@ impl PdmClient { Ok(self.0.get(&path).await?.expect_json()?.data) } + /// List storages for a given PVE remote node. + /// + /// The storages can be filtered using the `filter` parameter, for details see + /// [`PveListStoragesFilter`]. If `include_supported_disk_image_formats` is set + /// to true, the result will include information about supported disk image types + /// for each storage. pub async fn pve_list_storages( &self, remote: &str, node: &str, - content: Option>, - enabled: Option, - format: Option, - storage: Option, - target: Option, + filter: PveListStoragesFilter, + include_supported_disk_image_formats: bool, ) -> Result, Error> { let mut builder = ApiPathBuilder::new(format!( "/api2/extjs/pve/remotes/{remote}/nodes/{node}/storage" )) - .maybe_arg("enabled", &enabled) - .maybe_arg("format", &format) - .maybe_arg("storage", &storage) - .maybe_arg("target", &target); - if let Some(content) = content { - for ty in content { - builder = builder.arg("content", ty); - } + .arg("format", include_supported_disk_image_formats) + .maybe_arg("enabled", &filter.enabled) + .maybe_arg("storage", &filter.storage) + .maybe_arg("target", &filter.target); + + for ty in filter.content { + builder = builder.arg("content", ty); } + let path = builder.build(); Ok(self.0.get(&path).await?.expect_json()?.data) diff --git a/ui/src/widget/pve_storage_selector.rs b/ui/src/widget/pve_storage_selector.rs index 488175ab..f43234dc 100644 --- a/ui/src/widget/pve_storage_selector.rs +++ b/ui/src/widget/pve_storage_selector.rs @@ -22,7 +22,10 @@ use pwt::{ }; use pwt_macros::{builder, widget}; -use pdm_client::types::{StorageContent, StorageInfo}; +use pdm_client::{ + types::{StorageContent, StorageInfo}, + PveListStoragesFilter, +}; #[widget(comp=PveStorageSelectorComp, @input)] #[derive(Clone, Properties, PartialEq)] @@ -85,15 +88,19 @@ impl PveStorageSelectorComp { content: Option>, target: Option, ) -> Result, Error> { + let filter = PveListStoragesFilter { + content: content.unwrap_or_default(), + enabled: Some(true), + target: target.as_ref().map(AttrValue::to_string), + ..Default::default() + }; + let mut storages = crate::pdm_client() .pve_list_storages( &remote, &node.unwrap_or(AttrValue::from("localhost")), - content, - Some(true), - Some(true), - None, - target.as_ref().map(AttrValue::to_string), + filter, + true, ) .await?; -- 2.47.3