all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Stefan Hanreich <s.hanreich@proxmox.com>
To: pdm-devel@lists.proxmox.com
Subject: [pdm-devel] [PATCH proxmox-datacenter-manager v2 2/5] server: api: add resource-type parameter to list_resources
Date: Tue,  9 Sep 2025 17:54:17 +0200	[thread overview]
Message-ID: <20250909155423.526917-6-s.hanreich@proxmox.com> (raw)
In-Reply-To: <20250909155423.526917-1-s.hanreich@proxmox.com>

Add a new parameter to the list_resources call that filters entities
based on their type. While this should already be possible with the
search function as well, filtering directly by enum is more efficient
than building the search filters and then doing matching based on
strings. The type parameter has precedence, so any search filters will
be applied only on entities that have the type specified in
resource-type.

In pdm-client add a separate method to not pollute existing call sites
with unnecessary parameters. In the future it might make sense to add
another method that takes all possible combinations of parameters.

Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
---
 lib/pdm-api-types/src/resource.rs | 15 ++++++++++++++-
 lib/pdm-client/src/lib.rs         | 15 ++++++++++++++-
 server/src/api/resources.rs       | 18 +++++++++++++++---
 server/src/resource_cache.rs      |  2 +-
 4 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/lib/pdm-api-types/src/resource.rs b/lib/pdm-api-types/src/resource.rs
index f274451..b219250 100644
--- a/lib/pdm-api-types/src/resource.rs
+++ b/lib/pdm-api-types/src/resource.rs
@@ -100,14 +100,27 @@ impl Resource {
     }
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+#[api]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
 /// Type of a PDM resource.
 pub enum ResourceType {
+    /// PVE Storage Resource
+    #[serde(rename = "storage")]
     PveStorage,
+    /// PVE Qemu Resource
+    #[serde(rename = "qemu")]
     PveQemu,
+    /// PVE LXC Resource
+    #[serde(rename = "lxc")]
     PveLxc,
+    /// PVE SDN Resource
+    #[serde(rename = "sdn-zone")]
     PveSdnZone,
+    /// PBS Datastore Resource
+    #[serde(rename = "datastore")]
     PbsDatastore,
+    /// Node resource
+    #[serde(rename = "node")]
     Node,
 }
 
diff --git a/lib/pdm-client/src/lib.rs b/lib/pdm-client/src/lib.rs
index 845738f..f2ff4d4 100644
--- a/lib/pdm-client/src/lib.rs
+++ b/lib/pdm-client/src/lib.rs
@@ -4,7 +4,7 @@ use std::collections::HashMap;
 use std::time::Duration;
 
 use pdm_api_types::remotes::TlsProbeOutcome;
-use pdm_api_types::resource::{PveResource, RemoteResources, TopEntities};
+use pdm_api_types::resource::{PveResource, RemoteResources, ResourceType, TopEntities};
 use pdm_api_types::rrddata::{
     LxcDataPoint, NodeDataPoint, PbsDatastoreDataPoint, PbsNodeDataPoint, PveStorageDataPoint,
     QemuDataPoint,
@@ -865,6 +865,19 @@ impl<T: HttpApiClient> PdmClient<T> {
         Ok(self.0.get(&path).await?.expect_json()?.data)
     }
 
+    pub async fn resources_by_type(
+        &self,
+        max_age: Option<u64>,
+        resource_type: ResourceType,
+    ) -> Result<Vec<RemoteResources>, Error> {
+        let path = ApiPathBuilder::new("/api2/extjs/resources/list")
+            .maybe_arg("max-age", &max_age)
+            .arg("resource-type", resource_type)
+            .build();
+
+        Ok(self.0.get(&path).await?.expect_json()?.data)
+    }
+
     pub async fn pve_list_networks(
         &self,
         remote: &str,
diff --git a/server/src/api/resources.rs b/server/src/api/resources.rs
index 736bfb9..dcdf0ea 100644
--- a/server/src/api/resources.rs
+++ b/server/src/api/resources.rs
@@ -150,6 +150,10 @@ fn remote_matches_search_term(remote_name: &str, online: Option<bool>, term: &Se
                 description: "Search term to filter for, uses special syntax e.g. <TODO>",
                 optional: true,
             },
+            "resource-type": {
+                type: ResourceType,
+                optional: true,
+            },
         }
     },
     returns: {
@@ -163,10 +167,11 @@ fn remote_matches_search_term(remote_name: &str, online: Option<bool>, term: &Se
 /// List all resources from remote nodes.
 pub async fn get_resources(
     max_age: u64,
+    resource_type: Option<ResourceType>,
     search: Option<String>,
     rpcenv: &mut dyn RpcEnvironment,
 ) -> Result<Vec<RemoteResources>, Error> {
-    get_resources_impl(max_age, search, Some(rpcenv)).await
+    get_resources_impl(max_age, search, resource_type, Some(rpcenv)).await
 }
 
 // helper to determine if the combination of search terms requires the results
@@ -208,6 +213,7 @@ fn is_remotes_only(filters: &Search) -> bool {
 pub(crate) async fn get_resources_impl(
     max_age: u64,
     search: Option<String>,
+    resource_type: Option<ResourceType>,
     rpcenv: Option<&mut dyn RpcEnvironment>,
 ) -> Result<Vec<RemoteResources>, Error> {
     let user_info = CachedUserInfo::new()?;
@@ -252,8 +258,14 @@ pub(crate) async fn get_resources_impl(
 
             if remotes_only {
                 resources.clear();
-            } else if !filter.is_empty() {
+            } else if resource_type.is_some() || !filter.is_empty() {
                 resources.retain(|resource| {
+                    if let Some(resource_type) = resource_type {
+                        if resource.resource_type() != resource_type {
+                            return false;
+                        }
+                    }
+
                     filter.matches(|filter| {
                         // if we get can't decide if it matches, don't filter it out
                         resource_matches_search_term(resource, filter).unwrap_or(true)
@@ -318,7 +330,7 @@ pub async fn get_status(
     max_age: u64,
     rpcenv: &mut dyn RpcEnvironment,
 ) -> Result<ResourcesStatus, Error> {
-    let remotes = get_resources(max_age, None, rpcenv).await?;
+    let remotes = get_resources(max_age, None, None, rpcenv).await?;
     let mut counts = ResourcesStatus::default();
     for remote in remotes {
         if remote.error.is_some() {
diff --git a/server/src/resource_cache.rs b/server/src/resource_cache.rs
index 0ae86ee..aa20c54 100644
--- a/server/src/resource_cache.rs
+++ b/server/src/resource_cache.rs
@@ -21,7 +21,7 @@ pub fn start_task() {
 async fn resource_caching_task() -> Result<(), Error> {
     loop {
         if let Err(err) =
-            crate::api::resources::get_resources_impl(METRIC_POLL_INTERVALL, None, None).await
+            crate::api::resources::get_resources_impl(METRIC_POLL_INTERVALL, None, None, None).await
         {
             log::error!("could not update resource cache: {err}");
         }
-- 
2.47.3


_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel


  parent reply	other threads:[~2025-09-09 15:54 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-09 15:54 [pdm-devel] [PATCH manager/proxmox{-api-types, -datacenter-manager} v2 0/8] Add SDN resources to dashboard + SDN zone overview tree Stefan Hanreich
2025-09-09 15:54 ` [pdm-devel] [PATCH pve-manager v2 1/1] cluster: resources: add sdn property to cluster resources schema Stefan Hanreich
2025-09-09 15:54 ` [pdm-devel] [PATCH proxmox-api-types v2 1/2] cluster: resource: add sdn property Stefan Hanreich
2025-09-09 15:54 ` [pdm-devel] [PATCH proxmox-api-types v2 2/2] regenerate Stefan Hanreich
2025-09-09 15:54 ` [pdm-devel] [PATCH proxmox-datacenter-manager v2 1/5] pdm-api-types: add sdn cluster resource Stefan Hanreich
2025-09-09 15:54 ` Stefan Hanreich [this message]
2025-09-09 15:54 ` [pdm-devel] [PATCH proxmox-datacenter-manager v2 3/5] ui: add sdn status report to dashboard Stefan Hanreich
2025-09-09 15:54 ` [pdm-devel] [PATCH proxmox-datacenter-manager v2 4/5] ui: images: add sdn icon Stefan Hanreich
2025-09-09 15:54 ` [pdm-devel] [PATCH proxmox-datacenter-manager v2 5/5] ui: sdn: add zone tree Stefan Hanreich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250909155423.526917-6-s.hanreich@proxmox.com \
    --to=s.hanreich@proxmox.com \
    --cc=pdm-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal