openstack_cli_block_storage/v3/attachment/create_327.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 Attachment command [microversion = 3.27]
19//!
20//! Wraps invoking of the `v3/attachments` 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::attachment::create_327;
34use openstack_types::block_storage::v3::attachment::response;
35use serde_json::Value;
36
37/// Create an attachment.
38///
39/// This method can be used to create an empty attachment (reserve) or to
40/// create and initialize a volume attachment based on the provided input
41/// parameters.
42///
43/// If the caller does not yet have the connector information but needs to
44/// reserve an attachment for the volume (ie Nova BootFromVolume) the create
45/// can be called with just the volume-uuid and the server identifier. This
46/// will reserve an attachment, mark the volume as reserved and prevent any new
47/// attachment_create calls from being made until the attachment is updated
48/// (completed).
49///
50/// The alternative is that the connection can be reserved and initialized all
51/// at once with a single call if the caller has all of the required
52/// information (connector data) at the time of the call.
53///
54/// NOTE: In Nova terms server == instance, the server_id parameter referenced
55/// below is the UUID of the Instance, for non-nova consumers this can be a
56/// server UUID or some other arbitrary unique identifier.
57///
58/// Starting from microversion 3.54, we can pass the attach mode as argument in
59/// the request body.
60///
61/// Expected format of the input parameter 'body':
62///
63/// ```text
64/// {
65/// "attachment":
66/// {
67/// "volume_uuid": "volume-uuid",
68/// "instance_uuid": "null|nova-server-uuid",
69/// "connector": "null|<connector-object>",
70/// "mode": "null|rw|ro"
71/// }
72/// }
73/// ```
74///
75/// Example connector:
76///
77/// ```text
78/// {
79/// "connector":
80/// {
81/// "initiator": "iqn.1993-08.org.debian:01:cad181614cec",
82/// "ip": "192.168.1.20",
83/// "platform": "x86_64",
84/// "host": "tempest-1",
85/// "os_type": "linux2",
86/// "multipath": false,
87/// "mountpoint": "/dev/vdb",
88/// "mode": "null|rw|ro"
89/// }
90/// }
91/// ```
92///
93/// NOTE all that's required for a reserve is volume_uuid and an instance_uuid.
94///
95/// returns: A summary view of the attachment object
96#[derive(Args)]
97pub struct AttachmentCommand {
98 /// Request Query parameters
99 #[command(flatten)]
100 query: QueryParameters,
101
102 /// Path parameters
103 #[command(flatten)]
104 path: PathParameters,
105
106 /// An attachment object.
107 #[command(flatten)]
108 attachment: Attachment,
109}
110
111/// Query parameters
112#[derive(Args)]
113struct QueryParameters {}
114
115/// Path parameters
116#[derive(Args)]
117struct PathParameters {}
118/// Attachment Body data
119#[derive(Args, Clone)]
120struct Attachment {
121 /// The `connector` object.
122 #[arg(help_heading = "Body parameters", long, value_name="key=value", value_parser=parse_key_val::<String, Value>)]
123 connector: Option<Vec<(String, Value)>>,
124
125 /// The UUID of the volume which the attachment belongs to.
126 #[arg(help_heading = "Body parameters", long)]
127 instance_uuid: Option<String>,
128
129 /// The UUID of the volume which the attachment belongs to.
130 #[arg(help_heading = "Body parameters", long)]
131 volume_uuid: String,
132}
133
134impl AttachmentCommand {
135 /// Perform command action
136 pub async fn take_action<C: CliArgs>(
137 &self,
138 parsed_args: &C,
139 client: &mut AsyncOpenStack,
140 ) -> Result<(), OpenStackCliError> {
141 info!("Create Attachment");
142
143 let op = OutputProcessor::from_args(
144 parsed_args,
145 Some("block-storage.attachment"),
146 Some("create"),
147 );
148 op.validate_args(parsed_args)?;
149
150 let mut ep_builder = create_327::Request::builder();
151 ep_builder.header(
152 http::header::HeaderName::from_static("openstack-api-version"),
153 http::header::HeaderValue::from_static("volume 3.27"),
154 );
155
156 // Set body parameters
157 // Set Request.attachment data
158 let args = &self.attachment;
159 let mut attachment_builder = create_327::AttachmentBuilder::default();
160 if let Some(val) = &args.connector {
161 attachment_builder.connector(val.iter().cloned());
162 }
163
164 if let Some(val) = &args.instance_uuid {
165 attachment_builder.instance_uuid(val);
166 }
167
168 attachment_builder.volume_uuid(&args.volume_uuid);
169
170 ep_builder.attachment(
171 attachment_builder
172 .build()
173 .wrap_err("error preparing the request data")?,
174 );
175
176 let ep = ep_builder
177 .build()
178 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
179
180 let data: serde_json::Value = ep.query_async(client).await?;
181
182 op.output_single::<response::create::AttachmentResponse>(data.clone())?;
183 // Show command specific hints
184 op.show_command_hint()?;
185 Ok(())
186 }
187}