use clap::Args;
use tracing::info;
use openstack_cli_core::cli::CliArgs;
use openstack_cli_core::error::OpenStackCliError;
use openstack_cli_core::output::OutputProcessor;
use openstack_sdk::AsyncOpenStack;
use openstack_cli_core::common::build_upload_asyncread;
use openstack_sdk::api::QueryAsync;
use openstack_sdk::api::image::v2::image::file::upload;
use openstack_sdk::api::raw_with_body;
#[derive(Args)]
#[command(about = "Upload binary image data")]
pub struct FileCommand {
#[command(flatten)]
query: QueryParameters,
#[command(flatten)]
headers: HeaderParameters,
#[command(flatten)]
path: PathParameters,
#[arg(long)]
file: Option<String>,
}
#[derive(Args)]
struct QueryParameters {}
#[derive(Args)]
struct HeaderParameters {
#[arg(long)]
content_type: Option<String>,
#[arg(long)]
x_image_meta_store: Option<String>,
}
#[derive(Args)]
struct PathParameters {
#[arg(
help_heading = "Path parameters",
id = "path_param_image_id",
value_name = "IMAGE_ID"
)]
image_id: String,
}
impl FileCommand {
pub async fn take_action<C: CliArgs>(
&self,
parsed_args: &C,
client: &mut AsyncOpenStack,
) -> Result<(), OpenStackCliError> {
info!("Upload File");
let op = OutputProcessor::from_args(parsed_args, Some("image.image/file"), Some("upload"));
op.validate_args(parsed_args)?;
let mut ep_builder = upload::Request::builder();
ep_builder.image_id(&self.path.image_id);
if let Some(val) = &self.headers.content_type {
ep_builder.header(
http::header::HeaderName::from_static("Content-Type"),
http::header::HeaderValue::from_str(val)?,
);
}
if let Some(val) = &self.headers.x_image_meta_store {
ep_builder.header(
http::header::HeaderName::from_static("X-Image-Meta-Store"),
http::header::HeaderValue::from_str(val)?,
);
}
ep_builder.header(
http::header::CONTENT_TYPE,
http::header::HeaderValue::from_static("application/octet-stream"),
);
let ep = ep_builder
.build()
.map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
let dst = self.file.clone();
let data = build_upload_asyncread(dst).await?;
let _rsp = raw_with_body(ep, data).query_async(client).await?;
op.show_command_hint()?;
Ok(())
}
}