Skip to content

Commit

Permalink
feat(topology): add show labels in pools
Browse files Browse the repository at this point in the history
Signed-off-by: sinhaashish <[email protected]>
  • Loading branch information
sinhaashish committed Sep 3, 2024
1 parent 848bcd5 commit 78669db
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 13 deletions.
4 changes: 3 additions & 1 deletion control-plane/plugin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@ impl ExecuteOperation for GetResources {
volume::Volume::topology(id, &cli_args.output).await
}
GetResources::Pools(args) => pool::Pools::list(args, &cli_args.output).await,
GetResources::Pool { id } => pool::Pool::get(id, &cli_args.output).await,
GetResources::Pool(args) => {
pool::Pool::get(&args.pool_id(), args, &cli_args.output).await
}
GetResources::Nodes(args) => node::Nodes::list(args, &cli_args.output).await,
GetResources::Node(args) => {
node::Node::get(&args.node_id(), args, &cli_args.output).await
Expand Down
4 changes: 2 additions & 2 deletions control-plane/plugin/src/resources/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::resources::{
blockdevice::BlockDeviceArgs,
node::{DrainNodeArgs, GetNodeArgs, GetNodesArgs},
pool::GetPoolsArgs,
pool::{GetPoolArgs, GetPoolsArgs},
snapshot::VolumeSnapshotArgs,
volume::VolumesArgs,
};
Expand Down Expand Up @@ -51,7 +51,7 @@ pub enum GetResources {
/// Get all pools.
Pools(GetPoolsArgs),
/// Get pool with the given ID.
Pool { id: PoolId },
Pool(GetPoolArgs),
/// Get all nodes.
Nodes(GetNodesArgs),
/// Get node with the given ID.
Expand Down
155 changes: 145 additions & 10 deletions control-plane/plugin/src/resources/pool.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
use crate::{
operations::{Get, Label, ListWithArgs, PluginResult},
operations::{Get, GetWithArgs, Label, ListWithArgs, PluginResult},
resources::{
error::{Error, LabelAssignSnafu, OpError, TopologyError},
utils,
utils::{
optional_cell, print_table, validate_topology_key, validate_topology_value, CreateRow,
GetHeaderRow, OutputFormat,
CreateRows, GetHeaderRow, OutputFormat,
},
NodeId, PoolId,
},
rest_wrapper::RestClient,
};
use async_trait::async_trait;
use openapi::apis::StatusCode;
use prettytable::Row;
use prettytable::{Cell, Row};
use serde::Serialize;
use snafu::ResultExt;
use std::collections::HashMap;

Expand Down Expand Up @@ -68,6 +69,27 @@ impl GetHeaderRow for openapi::models::Pool {
}
}

#[derive(Debug, Clone, clap::Args)]
/// Arguments used when getting a pool.
pub struct GetPoolArgs {
/// Id of the pool
pool_id: PoolId,
/// Show the labels of the node
#[clap(long, default_value = "false")]
show_labels: bool,
}

impl GetPoolArgs {
/// Return the pool ID.
pub fn pool_id(&self) -> PoolId {
self.pool_id.clone()
}
/// Return whether to show the labels of the pool.
pub fn show_labels(&self) -> bool {
self.show_labels
}
}

/// Arguments used when getting pools.
#[derive(Debug, Clone, clap::Args)]
pub struct GetPoolsArgs {
Expand All @@ -84,6 +106,10 @@ pub struct GetPoolsArgs {
/// Pools must satisfy all of the specified label constraints.
#[clap(short = 'l', long)]
selector: Option<String>,

/// Show the labels of the node
#[clap(long, default_value = "false")]
show_labels: bool,
}

impl GetPoolsArgs {
Expand All @@ -101,6 +127,11 @@ impl GetPoolsArgs {
pub fn selector(&self) -> &Option<String> {
&self.selector
}

/// Return whether to show the labels of the pool.
pub fn show_labels(&self) -> bool {
self.show_labels
}
}

#[async_trait(?Send)]
Expand Down Expand Up @@ -142,17 +173,45 @@ impl ListWithArgs for Pools {
#[derive(clap::Args, Debug)]
pub struct Pool {}

// #[async_trait(?Send)]
// impl Get for Pool {
// type ID = PoolId;
// async fn get(id: &Self::ID, output: &utils::OutputFormat) -> PluginResult {
// match RestClient::client().pools_api().get_pool(id).await {
// Ok(pool) => {
// // Print table, json or yaml based on output format.
// utils::print_table(output, pool.into_body());
// }
// Err(e) => {
// return Err(Error::GetPoolError {
// id: id.to_string(),
// source: e,
// });
// }
// }
// Ok(())
// }
// }

#[async_trait(?Send)]
impl Get for Pool {
impl GetWithArgs for Pool {
type ID = PoolId;
async fn get(id: &Self::ID, output: &utils::OutputFormat) -> PluginResult {
type Args = GetPoolArgs;
async fn get(id: &Self::ID, args: &Self::Args, output: &utils::OutputFormat) -> PluginResult {
match RestClient::client().pools_api().get_pool(id).await {
Ok(pool) => {
// Print table, json or yaml based on output format.
utils::print_table(output, pool.into_body());
}
Ok(pool) => match output {
OutputFormat::Yaml | OutputFormat::Json => {
print_table(output, pool.clone().into_body());
}
OutputFormat::None => {
print_table(
output,
PoolDisplayLabels::new(pool.into_body(), args.show_labels()),
);
}
},
Err(e) => {
return Err(Error::GetPoolError {
return Err(Error::GetNodeError {
id: id.to_string(),
source: e,
});
Expand Down Expand Up @@ -279,3 +338,79 @@ impl Label for Pool {
Ok(())
}
}

/// The PoolDisplayLabels structure is responsible for controlling the display formatting of Pool
/// objects. `#[serde(flatten)]` and `#[serde(skip)]` attributes are used to ensure that when the
/// object is serialised, only the `inner` object is represented.
#[derive(Serialize, Debug)]
pub struct PoolDisplayLabels {
#[serde(flatten)]
pub inner: Vec<openapi::models::Pool>,
#[serde(skip)]
show_labels: bool,
}

impl PoolDisplayLabels {
/// Create a new `PoolDisplayLabels` instance.
pub(crate) fn new(pool: openapi::models::Pool, show_labels: bool) -> Self {
let vec: Vec<openapi::models::Pool> = vec![pool];
Self {
inner: vec,
show_labels,
}
}
/// Create a new `PoolDisplay` instance from a vector of pools.
pub(crate) fn new_pools(pools: Vec<openapi::models::Pool>, show_labels: bool) -> Self {
Self {
inner: pools,
show_labels,
}
}

/// Get a list of pool labels.
pub(crate) fn get_pool_label_list(pool: &openapi::models::Pool) -> Vec<String> {
let mut pools_labels: Vec<String> = vec![];

match &pool.spec {
Some(spec) => match &spec.labels {
Some(ds) => {
pools_labels = ds
.iter()
.filter(|(key, _)| *key != &"openebs.io/created-by")
.map(|(key, value)| format!("{}={}", key, value))
.collect();
}
None => {}
},
None => {}
}
pools_labels
}
}

// Create the header for a `PoolDisplayLabels` object.
impl GetHeaderRow for PoolDisplayLabels {
fn get_header_row(&self) -> Row {
let mut header = (*utils::POOLS_HEADERS).clone();
if self.show_labels {
header.extend(vec!["LABELS"]);
}
header
}
}

impl CreateRows for PoolDisplayLabels {
fn create_rows(&self) -> Vec<Row> {
let mut rows = vec![];
for node in self.inner.iter() {
let mut row = node.create_rows();
if self.show_labels {
let labelstring = PoolDisplayLabels::get_pool_label_list(node).join(", ");
// Add the node labels to each row.
row[0].add_cell(Cell::new(&labelstring));
}
rows.push(row[0].clone());
}
rows
}
}

0 comments on commit 78669db

Please sign in to comment.