use anyhow::{Context, Error, bail};
use crate::common::app_context::AppContext;
use crate::common::clap_ext::ArgMatchesExt;
use crate::http_client::{MantaClient, OpenApiResultExt};
use crate::output::configuration::print_table_struct;
use manta_shared::types::api::configuration::GetConfigurationParams;
use manta_shared::types::dto::CfsConfigurationResponse;
fn parse_configuration_params(
cli_args: &clap::ArgMatches,
settings_hsm_group_name_opt: Option<&str>,
) -> GetConfigurationParams {
let limit = cli_args.limit_or_most_recent();
GetConfigurationParams {
name: cli_args.opt_string("name"),
pattern: cli_args.opt_string("pattern"),
group_name: cli_args.opt_string("group"),
settings_hsm_group_name: settings_hsm_group_name_opt.map(String::from),
since: None,
until: None,
limit,
}
}
pub async fn exec(
ctx: &AppContext<'_>,
token: &str,
cli_args: &clap::ArgMatches,
) -> Result<(), Error> {
let params =
parse_configuration_params(cli_args, ctx.settings_group_name_opt);
let group_name = params.effective_group();
let client = MantaClient::from_app_ctx(ctx, Some(token))?;
let raw = client
.openapi
.get_configurations(
group_name,
params.limit.map(i32::from),
params.name.as_deref(),
params.pattern.as_deref(),
client.site_name(),
)
.await
.into_anyhow()
.await?;
if raw.is_empty() {
bail!("No CFS configuration found!");
}
let only_safe = cli_args.get_flag("only-safe-to-delete");
let only_unsafe = cli_args.get_flag("only-unsafe-to-delete");
let rows: Vec<_> = if only_safe || only_unsafe {
raw
.into_iter()
.filter(|row| {
(!only_safe || row.safe_to_delete)
&& (!only_unsafe || !row.safe_to_delete)
})
.collect()
} else {
raw
};
if cli_args.opt_str("output") == Some("json") {
println!(
"{}",
serde_json::to_string_pretty(&rows)
.context("Failed to serialize CFS configurations to JSON")?
);
} else {
let pairs: Vec<(CfsConfigurationResponse, bool)> = rows
.into_iter()
.map(|row| {
let cfg = serde_json::from_value(row.configuration)?;
Ok::<_, serde_json::Error>((cfg, row.safe_to_delete))
})
.collect::<Result<_, _>>()
.context("Failed to deserialise CFS configurations response")?;
print_table_struct(&pairs);
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
fn config_cmd() -> clap::Command {
crate::build::get::subcommand_get_cfs_configuration()
}
#[test]
fn parse_no_args() {
let matches = config_cmd().get_matches_from(["configurations"]);
let params = parse_configuration_params(&matches, None);
assert!(params.name.is_none());
assert!(params.pattern.is_none());
assert!(params.group_name.is_none());
assert!(params.limit.is_none());
}
#[test]
fn parse_name() {
let matches =
config_cmd().get_matches_from(["configurations", "--name", "my-config"]);
let params = parse_configuration_params(&matches, None);
assert_eq!(params.name.as_deref(), Some("my-config"));
}
#[test]
fn parse_most_recent_sets_limit_to_one() {
let matches =
config_cmd().get_matches_from(["configurations", "--most-recent"]);
let params = parse_configuration_params(&matches, None);
assert_eq!(params.limit, Some(1));
}
#[test]
fn parse_pattern() {
let matches = config_cmd().get_matches_from([
"configurations",
"--pattern",
"compute-*",
]);
let params = parse_configuration_params(&matches, None);
assert_eq!(params.pattern.as_deref(), Some("compute-*"));
}
}