openstack_cli_image/v2/image/file/upload.rs
1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5// http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12//
13// SPDX-License-Identifier: Apache-2.0
14//
15// WARNING: This file is automatically generated from OpenAPI schema using
16// `openstack-codegenerator`.
17
18//! Upload File command
19//!
20//! Wraps invoking of the `v2/images/{image_id}/file` with `PUT` method
21
22use clap::Args;
23use tracing::info;
24
25use openstack_cli_core::cli::CliArgs;
26use openstack_cli_core::error::OpenStackCliError;
27use openstack_cli_core::output::OutputProcessor;
28use openstack_sdk::AsyncOpenStack;
29
30use openstack_cli_core::common::build_upload_asyncread;
31use openstack_sdk::api::QueryAsync;
32use openstack_sdk::api::image::v2::image::file::upload;
33use openstack_sdk::api::raw_with_body;
34
35/// Uploads binary image data. *(Since Image API v2.0)*
36///
37/// Set the `Content-Type` request header to `application/octet-stream`.
38///
39/// A multiple store backend support is introduced in the Rocky release as a
40/// part of the EXPERIMENTAL Image API v2.8.
41///
42/// Beginning with API version 2.8, an optional `X-Image-Meta-Store` header may
43/// be added to the request. When present, the image data will be placed into
44/// the backing store whose identifier is the value of this header. If the
45/// store identifier specified is not recognized, a 400 (Bad Request) response
46/// is returned. When the header is not present, the image data is placed into
47/// the default backing store.
48///
49/// An optional `x-openstack-image-size` header may be added to the request.
50/// When present, the server will validate that the uploaded data size matches
51/// this value. If the actual size does not match the expected size, a 400 (Bad
52/// Request) response is returned. When not present, the server will calculate
53/// the image size based on the actual request body size.
54///
55/// Example call:
56///
57/// **Preconditions**
58///
59/// Before you can store binary image data, you must meet the following
60/// preconditions:
61///
62/// **Synchronous Postconditions**
63///
64/// **Troubleshooting**
65///
66/// Normal response codes: 204
67///
68/// Error response codes: 400, 401, 403, 404, 409, 410, 413, 415, 503
69#[derive(Args)]
70#[command(about = "Upload binary image data")]
71pub struct FileCommand {
72 /// Request Query parameters
73 #[command(flatten)]
74 query: QueryParameters,
75
76 /// Request Headers parameters
77 #[command(flatten)]
78 headers: HeaderParameters,
79
80 /// Path parameters
81 #[command(flatten)]
82 path: PathParameters,
83
84 /// Source filename (using "-" will read object from stdout)
85 #[arg(long)]
86 file: Option<String>,
87}
88
89/// Query parameters
90#[derive(Args)]
91struct QueryParameters {}
92
93/// Header parameters
94#[derive(Args)]
95struct HeaderParameters {
96 /// The media type descriptor of the body, namely application/octet-stream
97 #[arg(long)]
98 content_type: Option<String>,
99
100 /// A store identifier to upload or import image data. Should only be
101 /// included when making a request to a cloud that supports multiple
102 /// backing stores. Use the Store Discovery call to determine an
103 /// appropriate store identifier. Simply omit this header to use the
104 /// default store.
105 #[arg(long)]
106 x_image_meta_store: Option<String>,
107}
108
109/// Path parameters
110#[derive(Args)]
111struct PathParameters {
112 /// image_id parameter for /v2/images/{image_id}/file API
113 #[arg(
114 help_heading = "Path parameters",
115 id = "path_param_image_id",
116 value_name = "IMAGE_ID"
117 )]
118 image_id: String,
119}
120
121impl FileCommand {
122 /// Perform command action
123 pub async fn take_action<C: CliArgs>(
124 &self,
125 parsed_args: &C,
126 client: &mut AsyncOpenStack,
127 ) -> Result<(), OpenStackCliError> {
128 info!("Upload File");
129
130 let op = OutputProcessor::from_args(parsed_args, Some("image.image/file"), Some("upload"));
131 op.validate_args(parsed_args)?;
132
133 let mut ep_builder = upload::Request::builder();
134 // Set path parameters
135 ep_builder.image_id(&self.path.image_id);
136
137 // Set header parameters
138 if let Some(val) = &self.headers.content_type {
139 ep_builder.header(
140 http::header::HeaderName::from_static("Content-Type"),
141 http::header::HeaderValue::from_str(val)?,
142 );
143 }
144 if let Some(val) = &self.headers.x_image_meta_store {
145 ep_builder.header(
146 http::header::HeaderName::from_static("X-Image-Meta-Store"),
147 http::header::HeaderValue::from_str(val)?,
148 );
149 }
150
151 // The only supported media type
152 ep_builder.header(
153 http::header::CONTENT_TYPE,
154 http::header::HeaderValue::from_static("application/octet-stream"),
155 );
156
157 let ep = ep_builder
158 .build()
159 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
160 let dst = self.file.clone();
161 let data = build_upload_asyncread(dst).await?;
162
163 let _rsp = raw_with_body(ep, data).query_async(client).await?;
164 // TODO: what if there is an interesting response
165 // Show command specific hints
166 op.show_command_hint()?;
167 Ok(())
168 }
169}