Skip to main content

openstack_cli_block_storage/v3/volume_manage/
create_30.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//! Create VolumeManage command [microversion = 3.0]
19//!
20//! Wraps invoking of the `v3/os-volume-manage` with `POST` method
21
22use clap::Args;
23use eyre::WrapErr;
24use tracing::info;
25
26use openstack_cli_core::cli::CliArgs;
27use openstack_cli_core::error::OpenStackCliError;
28use openstack_cli_core::output::OutputProcessor;
29use openstack_sdk::AsyncOpenStack;
30
31use openstack_cli_core::common::parse_key_val;
32use openstack_sdk::api::QueryAsync;
33use openstack_sdk::api::block_storage::v3::volume_manage::create_30;
34use serde_json::Value;
35
36/// Instruct Cinder to manage a storage object.
37///
38/// Manages an existing backend storage object (e.g. a Linux logical volume or
39/// a SAN disk) by creating the Cinder objects required to manage it, and
40/// possibly renaming the backend storage object (driver dependent)
41///
42/// From an API perspective, this operation behaves very much like a volume
43/// creation operation, except that properties such as image, snapshot and
44/// volume references don't make sense, because we are taking an existing
45/// storage object into Cinder management.
46///
47/// Required HTTP Body:
48///
49/// ```text
50/// {
51///   "volume": {
52///     "host": "<Cinder host on which the existing storage resides>",
53///     "cluster": "<Cinder cluster on which the storage resides>",
54///     "ref": "<Driver-specific reference to existing storage object>"
55///   }
56/// }
57/// ```
58///
59/// See the appropriate Cinder drivers' implementations of the manage_volume
60/// method to find out the accepted format of 'ref'.
61///
62/// This API call will return with an error if any of the above elements are
63/// missing from the request, or if the 'host' element refers to a cinder host
64/// that is not registered.
65///
66/// The volume will later enter the error state if it is discovered that 'ref'
67/// is bad.
68///
69/// Optional elements to 'volume' are:
70///
71/// ```text
72/// name               A name for the new volume.
73/// description        A description for the new volume.
74/// volume_type        ID or name of a volume type to associate with
75///                    the new Cinder volume. Does not necessarily
76///                    guarantee that the managed volume will have the
77///                    properties described in the volume_type. The
78///                    driver may choose to fail if it identifies that
79///                    the specified volume_type is not compatible with
80///                    the backend storage object.
81/// metadata           Key/value pairs to be associated with the new
82///                    volume.
83/// availability_zone  The availability zone to associate with the new
84///                    volume.
85/// bootable           If set to True, marks the volume as bootable.
86/// ```
87#[derive(Args)]
88pub struct VolumeManageCommand {
89    /// Request Query parameters
90    #[command(flatten)]
91    query: QueryParameters,
92
93    /// Path parameters
94    #[command(flatten)]
95    path: PathParameters,
96
97    #[command(flatten)]
98    volume: Volume,
99}
100
101/// Query parameters
102#[derive(Args)]
103struct QueryParameters {}
104
105/// Path parameters
106#[derive(Args)]
107struct PathParameters {}
108/// Volume Body data
109#[derive(Args, Clone)]
110struct Volume {
111    #[arg(help_heading = "Body parameters", long)]
112    availability_zone: Option<String>,
113
114    /// Set explicit NULL for the availability_zone
115    #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "availability_zone")]
116    no_availability_zone: bool,
117
118    #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
119    bootable: Option<bool>,
120
121    #[arg(help_heading = "Body parameters", long)]
122    description: Option<String>,
123
124    /// Set explicit NULL for the description
125    #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "description")]
126    no_description: bool,
127
128    #[arg(help_heading = "Body parameters", long)]
129    host: Option<String>,
130
131    /// Set explicit NULL for the host
132    #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "host")]
133    no_host: bool,
134
135    #[arg(help_heading = "Body parameters", long, value_name="key=value", value_parser=parse_key_val::<String, String>)]
136    metadata: Option<Vec<(String, String)>>,
137
138    #[arg(help_heading = "Body parameters", long)]
139    name: Option<String>,
140
141    /// Set explicit NULL for the name
142    #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "name")]
143    no_name: bool,
144
145    #[arg(help_heading = "Body parameters", long, value_name="JSON", value_parser=openstack_cli_core::common::parse_json)]
146    _ref: Value,
147
148    #[arg(help_heading = "Body parameters", long)]
149    volume_type: Option<String>,
150
151    /// Set explicit NULL for the volume_type
152    #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "volume_type")]
153    no_volume_type: bool,
154}
155
156impl VolumeManageCommand {
157    /// Perform command action
158    pub async fn take_action<C: CliArgs>(
159        &self,
160        parsed_args: &C,
161        client: &mut AsyncOpenStack,
162    ) -> Result<(), OpenStackCliError> {
163        info!("Create VolumeManage");
164
165        let op = OutputProcessor::from_args(
166            parsed_args,
167            Some("block-storage.volume_manage"),
168            Some("create"),
169        );
170        op.validate_args(parsed_args)?;
171
172        let mut ep_builder = create_30::Request::builder();
173        ep_builder.header(
174            http::header::HeaderName::from_static("openstack-api-version"),
175            http::header::HeaderValue::from_static("volume 3.0"),
176        );
177
178        // Set body parameters
179        // Set Request.volume data
180        let args = &self.volume;
181        let mut volume_builder = create_30::VolumeBuilder::default();
182        if let Some(val) = &args.availability_zone {
183            volume_builder.availability_zone(Some(val.into()));
184        } else if args.no_availability_zone {
185            volume_builder.availability_zone(None);
186        }
187
188        if let Some(val) = &args.bootable {
189            volume_builder.bootable(*val);
190        }
191
192        if let Some(val) = &args.description {
193            volume_builder.description(Some(val.into()));
194        } else if args.no_description {
195            volume_builder.description(None);
196        }
197
198        if let Some(val) = &args.host {
199            volume_builder.host(Some(val.into()));
200        } else if args.no_host {
201            volume_builder.host(None);
202        }
203
204        if let Some(val) = &args.metadata {
205            volume_builder.metadata(val.iter().cloned());
206        }
207
208        if let Some(val) = &args.name {
209            volume_builder.name(Some(val.into()));
210        } else if args.no_name {
211            volume_builder.name(None);
212        }
213
214        volume_builder._ref(args._ref.clone());
215
216        if let Some(val) = &args.volume_type {
217            volume_builder.volume_type(Some(val.into()));
218        } else if args.no_volume_type {
219            volume_builder.volume_type(None);
220        }
221
222        ep_builder.volume(
223            volume_builder
224                .build()
225                .wrap_err("error preparing the request data")?,
226        );
227
228        let ep = ep_builder
229            .build()
230            .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
231        openstack_sdk::api::ignore(ep).query_async(client).await?;
232        // Show command specific hints
233        op.show_command_hint()?;
234        Ok(())
235    }
236}