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::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}