use clap::Parser;
use cosmian_kms_client::{
KmsClient,
cosmian_kmip::kmip_2_1::kmip_types::UniqueIdentifier,
kmip_2_1::{
kmip_attributes::Attribute,
kmip_operations::{DeleteAttribute, DeleteAttributeResponse},
kmip_types::{AttributeReference, Tag},
},
};
use cosmian_logger::trace;
use super::set::SetOrDeleteAttributes;
use crate::{
actions::kms::{console, labels::ATTRIBUTE_ID, shared::get_key_uid},
error::result::KmsCliResult,
};
#[derive(Parser, Debug)]
#[clap(verbatim_doc_comment)]
pub struct DeleteAttributesAction {
#[clap(flatten)]
pub(crate) requested_attributes: SetOrDeleteAttributes,
#[clap(long = "attribute", value_name = "ATTRIBUTE", verbatim_doc_comment)]
pub(crate) attribute_tags: Option<Vec<Tag>>,
}
impl DeleteAttributesAction {
async fn delete_attribute(
&self,
kms_rest_client: &KmsClient,
id: &str,
current_attribute: Option<Attribute>,
attribute_references: Option<Vec<AttributeReference>>,
) -> KmsCliResult<UniqueIdentifier> {
let id = UniqueIdentifier::TextString(id.to_owned());
let DeleteAttributeResponse { unique_identifier } = kms_rest_client
.delete_attribute(DeleteAttribute {
unique_identifier: Some(id.clone()),
current_attribute: current_attribute.clone(),
attribute_references,
})
.await?;
if let Some(attr) = ¤t_attribute {
trace!("response for {unique_identifier}: {}", attr);
} else {
trace!("response for {unique_identifier}: <none>");
}
let mut stdout = console::Stdout::new("Attribute deleted successfully");
stdout.set_tags(self.requested_attributes.tags.as_ref());
stdout.set_unique_identifier(&id);
if let Some(current_attribute) = current_attribute {
stdout.set_attribute(current_attribute);
}
stdout.write()?;
Ok(id)
}
pub async fn process(&self, kms_rest_client: KmsClient) -> KmsCliResult<()> {
trace!("{self:?}");
let id = get_key_uid(
self.requested_attributes.id.as_ref(),
self.requested_attributes.tags.as_ref(),
ATTRIBUTE_ID,
)?;
for attribute in self.requested_attributes.get_attributes_from_args()? {
self.delete_attribute(&kms_rest_client, &id, Some(attribute), None)
.await?;
}
if let Some(tags) = &self.attribute_tags {
let mut references: Vec<AttributeReference> = Vec::with_capacity(tags.len());
for tag in tags {
references.push(AttributeReference::Standard(tag.to_owned()));
}
self.delete_attribute(&kms_rest_client, &id, None, Some(references))
.await?;
}
Ok(())
}
}