use clap::Args;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use tracing::info;
use openstack_sdk::AsyncOpenStack;
use crate::Cli;
use crate::OpenStackCliError;
use crate::output::OutputProcessor;
use structable::StructTable;
use structable::StructTableOptions;
#[derive(Args)]
pub struct ShowCommand {
#[arg(long, alias = "type")]
service_type: String,
}
#[derive(Deserialize, Serialize, StructTable)]
pub struct CatalogEndpoint {
id: String,
interface: String,
region: String,
url: String,
}
impl ShowCommand {
pub async fn take_action(
&self,
parsed_args: &Cli,
client: &mut AsyncOpenStack,
) -> Result<(), OpenStackCliError> {
info!("Show service endpoint catalog configuration");
let op = OutputProcessor::from_args(parsed_args, Some("catalog"), Some("show"));
op.validate_args(parsed_args)?;
let data: Vec<Value> = client
.get_token_catalog()
.unwrap_or_default()
.into_iter()
.filter(|x| x.service_type == self.service_type)
.flat_map(|x| {
let mut eps = x.endpoints;
eps.sort_by_key(|x| {
format!("{}{}", x.region.as_deref().unwrap_or_default(), x.interface)
});
eps
})
.map(serde_json::to_value)
.collect::<Result<Vec<_>, _>>()?;
if data.is_empty() {
return Err(openstack_sdk::catalog::CatalogError::ServiceNotConfigured(
self.service_type.clone(),
)
.into());
}
op.output_list::<CatalogEndpoint>(data)?;
op.show_command_hint()?;
Ok(())
}
}