Skip to main content

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::RawQueryAsync;
32use openstack_sdk::api::image::v2::image::file::upload;
33
34/// Uploads binary image data. *(Since Image API v2.0)*
35///
36/// Set the `Content-Type` request header to `application/octet-stream`.
37///
38/// A multiple store backend support is introduced in the Rocky release as a
39/// part of the EXPERIMENTAL Image API v2.8.
40///
41/// Beginning with API version 2.8, an optional `X-Image-Meta-Store` header may
42/// be added to the request. When present, the image data will be placed into
43/// the backing store whose identifier is the value of this header. If the
44/// store identifier specified is not recognized, a 400 (Bad Request) response
45/// is returned. When the header is not present, the image data is placed into
46/// the default backing store.
47///
48/// An optional `x-openstack-image-size` header may be added to the request.
49/// When present, the server will validate that the uploaded data size matches
50/// this value. If the actual size does not match the expected size, a 400 (Bad
51/// Request) response is returned. When not present, the server will calculate
52/// the image size based on the actual request body size.
53///
54/// Example call:
55///
56/// **Preconditions**
57///
58/// Before you can store binary image data, you must meet the following
59/// preconditions:
60///
61/// **Synchronous Postconditions**
62///
63/// **Troubleshooting**
64///
65/// Normal response codes: 204
66///
67/// Error response codes: 400, 401, 403, 404, 409, 410, 413, 415, 503
68#[derive(Args)]
69#[command(about = "Upload binary image data")]
70pub struct FileCommand {
71    /// Request Query parameters
72    #[command(flatten)]
73    query: QueryParameters,
74
75    /// Request Headers parameters
76    #[command(flatten)]
77    headers: HeaderParameters,
78
79    /// Path parameters
80    #[command(flatten)]
81    path: PathParameters,
82
83    /// Source filename (using "-" will read object from stdout)
84    #[arg(long)]
85    file: Option<String>,
86}
87
88/// Query parameters
89#[derive(Args)]
90struct QueryParameters {}
91
92/// Header parameters
93#[derive(Args)]
94struct HeaderParameters {
95    /// The media type descriptor of the body, namely application/octet-stream
96    #[arg(long)]
97    content_type: Option<String>,
98
99    /// A store identifier to upload or import image data. Should only be
100    /// included when making a request to a cloud that supports multiple
101    /// backing stores. Use the Store Discovery call to determine an
102    /// appropriate store identifier. Simply omit this header to use the
103    /// default store.
104    #[arg(long)]
105    x_image_meta_store: Option<String>,
106}
107
108/// Path parameters
109#[derive(Args)]
110struct PathParameters {
111    /// image_id parameter for /v2/images/{image_id}/file API
112    #[arg(
113        help_heading = "Path parameters",
114        id = "path_param_image_id",
115        value_name = "IMAGE_ID"
116    )]
117    image_id: String,
118}
119
120impl FileCommand {
121    /// Perform command action
122    pub async fn take_action<C: CliArgs>(
123        &self,
124        parsed_args: &C,
125        client: &mut AsyncOpenStack,
126    ) -> Result<(), OpenStackCliError> {
127        info!("Upload File");
128
129        let op = OutputProcessor::from_args(parsed_args, Some("image.image/file"), Some("upload"));
130        op.validate_args(parsed_args)?;
131
132        let mut ep_builder = upload::Request::builder();
133        // Set path parameters
134        ep_builder.image_id(&self.path.image_id);
135
136        // Set header parameters
137        if let Some(val) = &self.headers.content_type {
138            ep_builder.header(
139                http::header::HeaderName::from_static("Content-Type"),
140                http::header::HeaderValue::from_str(val)?,
141            );
142        }
143        if let Some(val) = &self.headers.x_image_meta_store {
144            ep_builder.header(
145                http::header::HeaderName::from_static("X-Image-Meta-Store"),
146                http::header::HeaderValue::from_str(val)?,
147            );
148        }
149
150        // The only supported media type
151        ep_builder.header(
152            http::header::CONTENT_TYPE,
153            http::header::HeaderValue::from_static("application/octet-stream"),
154        );
155
156        let ep = ep_builder
157            .build()
158            .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
159        let dst = self.file.clone();
160        let data = build_upload_asyncread(dst).await?;
161
162        let _rsp = ep.raw_query_read_body_async(client, data).await?;
163        // TODO: what if there is an interesting response
164        // Show command specific hints
165        op.show_command_hint()?;
166        Ok(())
167    }
168}