manta_server/service/
cluster.rs

1//! Cluster-scoped node detail queries using HSM group membership.
2
3use manta_backend_dispatcher::error::Error;
4use manta_backend_dispatcher::interfaces::hsm::group::GroupTrait;
5use manta_shared::types::dto::NodeDetails;
6
7use crate::server::common::app_context::InfraContext;
8use crate::service::authorization::validate_user_group_vec_access;
9use crate::service::node_details;
10pub use manta_shared::types::api::cluster::GetClusterParams;
11
12/// Fetch full node details for every member of the requested HSM
13/// groups.
14///
15/// When `params.group_name` is unset the scope expands to every
16/// group the token can access. The optional `status_filter` matches
17/// case-insensitively against either the power or configuration
18/// status. Results are sorted by xname for stable rendering.
19pub async fn get_cluster_nodes(
20  infra: &InfraContext<'_>,
21  token: &str,
22  params: &GetClusterParams,
23) -> Result<Vec<NodeDetails>, Error> {
24  // Get list of target groups the user is asking for
25  let target_group_vec: Vec<String> = if let Some(group) = &params.group_name {
26    vec![group.clone()]
27  } else {
28    infra
29      .backend
30      .get_group_available(token)
31      .await?
32      .iter()
33      .map(|group| group.label.clone())
34      .collect()
35  };
36
37  // Validate groups and get list of groups available
38  validate_user_group_vec_access(infra, token, &target_group_vec).await?;
39
40  let mut group_vec_node_list = infra
41    .backend
42    .get_member_vec_from_group_name_vec(token, &target_group_vec)
43    .await?;
44
45  group_vec_node_list.sort();
46
47  let mut node_details_list =
48    node_details::get_node_details(infra, token, &group_vec_node_list).await?;
49
50  // Apply status filter
51  if let Some(ref status) = params.status_filter {
52    node_details_list.retain(|nd| {
53      nd.power_status.eq_ignore_ascii_case(status)
54        || nd.configuration_status.eq_ignore_ascii_case(status)
55    });
56  }
57
58  node_details_list.sort_by(|a, b| a.xname.cmp(&b.xname));
59
60  Ok(node_details_list)
61}