use std::path::PathBuf;
use clap::Parser;
use cosmian_kms_client::{
KmsClient,
cosmian_kmip::kmip_2_1::kmip_objects::ObjectType,
kmip_2_1::{kmip_types::UniqueIdentifier, requests::import_object_request},
read_bytes_from_file,
reexport::cosmian_kms_client_utils::import_utils::{
ImportKeyFormat, KeyUsage, prepare_key_import_elements,
},
};
use crate::{actions::kms::console, error::result::KmsCliResult};
#[derive(Parser, Default, Debug)]
#[clap(verbatim_doc_comment)]
pub struct ImportSecretDataOrKeyAction {
#[clap(required = true)]
pub(crate) key_file: PathBuf,
#[clap(required = false)]
pub(crate) key_id: Option<String>,
#[clap(long, short = 'f', default_value = "json-ttlv")]
pub(crate) key_format: ImportKeyFormat,
#[clap(long, short = 'p')]
pub(crate) public_key_id: Option<String>,
#[clap(long, short = 'k')]
pub(crate) private_key_id: Option<String>,
#[clap(long, short = 'c')]
pub(crate) certificate_id: Option<String>,
#[clap(long, short = 'u', required = false, default_value = "false")]
pub(crate) unwrap: bool,
#[clap(
required = false,
long = "replace",
short = 'r',
default_value = "false"
)]
pub(crate) replace_existing: bool,
#[clap(long = "tag", short = 't', value_name = "TAG")]
pub(crate) tags: Vec<String>,
#[clap(long)]
pub(crate) key_usage: Option<Vec<KeyUsage>>,
#[clap(
long = "wrapping-key-id",
short = 'w',
required = false,
verbatim_doc_comment
)]
pub(crate) wrapping_key_id: Option<String>,
}
impl ImportSecretDataOrKeyAction {
pub async fn run(&self, kms_rest_client: KmsClient) -> KmsCliResult<UniqueIdentifier> {
let key_bytes = read_bytes_from_file(&self.key_file)?;
let vendor_id = kms_rest_client.config.vendor_id.as_str();
let (object, import_attributes) = prepare_key_import_elements(
vendor_id,
&self.key_usage,
&self.key_format,
key_bytes,
&self.certificate_id,
&self.private_key_id,
&self.public_key_id,
self.wrapping_key_id.as_ref(),
)?;
let object_type: ObjectType = object.object_type();
let import_object_request = import_object_request(
vendor_id,
self.key_id.clone(),
object,
Some(import_attributes),
self.unwrap,
self.replace_existing,
&self.tags,
)?;
let unique_identifier = kms_rest_client
.import(import_object_request)
.await?
.unique_identifier;
let stdout = format!(
"The {:?} in file {} was successfully imported with id: {}.",
object_type,
self.key_file.display(),
unique_identifier,
);
let mut stdout = console::Stdout::new(&stdout);
stdout.set_tags(Some(&self.tags));
stdout.set_unique_identifier(&unique_identifier);
stdout.write()?;
Ok(unique_identifier)
}
}