openstack_cli_block_storage/v3/volume/
create_353.rs1use 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::create_353;
34use openstack_types::block_storage::v3::volume::response;
35use serde_json::Value;
36
37#[derive(Args)]
43pub struct VolumeCommand {
44 #[command(flatten)]
46 query: QueryParameters,
47
48 #[command(flatten)]
50 path: PathParameters,
51
52 #[arg(help_heading = "Body parameters", long, value_name="key=value", value_parser=parse_key_val::<String, Value>)]
54 os_sch_hnt_scheduler_hints: Option<Vec<(String, Value)>>,
55
56 #[command(flatten)]
58 volume: Volume,
59}
60
61#[derive(Args)]
63struct QueryParameters {}
64
65#[derive(Args)]
67struct PathParameters {}
68#[derive(Args, Clone)]
70struct Volume {
71 #[arg(help_heading = "Body parameters", long)]
73 availability_zone: Option<String>,
74
75 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "availability_zone")]
77 no_availability_zone: bool,
78
79 #[arg(help_heading = "Body parameters", long)]
83 backup_id: Option<String>,
84
85 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "backup_id")]
87 no_backup_id: bool,
88
89 #[arg(help_heading = "Body parameters", long)]
91 consistencygroup_id: Option<String>,
92
93 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "consistencygroup_id")]
95 no_consistencygroup_id: bool,
96
97 #[arg(help_heading = "Body parameters", long)]
99 description: Option<String>,
100
101 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "description")]
103 no_description: bool,
104
105 #[arg(help_heading = "Body parameters", long)]
106 display_description: Option<String>,
107
108 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "display_description")]
110 no_display_description: bool,
111
112 #[arg(help_heading = "Body parameters", long)]
113 display_name: Option<String>,
114
115 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "display_name")]
117 no_display_name: bool,
118
119 #[arg(help_heading = "Body parameters", long)]
120 group_id: Option<String>,
121
122 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "group_id")]
124 no_group_id: bool,
125
126 #[arg(help_heading = "Body parameters", long)]
127 image_id: Option<String>,
128
129 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "image_id")]
131 no_image_id: bool,
132
133 #[arg(help_heading = "Body parameters", long)]
143 image_ref: Option<String>,
144
145 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "image_ref")]
147 no_image_ref: bool,
148
149 #[arg(help_heading = "Body parameters", long, value_name="key=value", value_parser=parse_key_val::<String, String>)]
152 metadata: Option<Vec<(String, String)>>,
153
154 #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
155 multiattach: Option<Option<bool>>,
156
157 #[arg(help_heading = "Body parameters", long)]
159 name: Option<String>,
160
161 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "name")]
163 no_name: bool,
164
165 #[arg(help_heading = "Body parameters", long)]
167 size: Option<Option<i32>>,
168
169 #[arg(help_heading = "Body parameters", long)]
171 snapshot_id: Option<String>,
172
173 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "snapshot_id")]
175 no_snapshot_id: bool,
176
177 #[arg(help_heading = "Body parameters", long)]
179 source_volid: Option<String>,
180
181 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "source_volid")]
183 no_source_volid: bool,
184
185 #[arg(help_heading = "Body parameters", long)]
196 volume_type: Option<String>,
197
198 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "volume_type")]
200 no_volume_type: bool,
201}
202
203impl VolumeCommand {
204 pub async fn take_action<C: CliArgs>(
206 &self,
207 parsed_args: &C,
208 client: &mut AsyncOpenStack,
209 ) -> Result<(), OpenStackCliError> {
210 info!("Create Volume");
211
212 let op =
213 OutputProcessor::from_args(parsed_args, Some("block-storage.volume"), Some("create"));
214 op.validate_args(parsed_args)?;
215
216 let mut ep_builder = create_353::Request::builder();
217 ep_builder.header(
218 http::header::HeaderName::from_static("openstack-api-version"),
219 http::header::HeaderValue::from_static("volume 3.53"),
220 );
221
222 if let Some(arg) = &self.os_sch_hnt_scheduler_hints {
225 ep_builder.os_sch_hnt_scheduler_hints(arg.iter().cloned());
226 }
227
228 let args = &self.volume;
230 let mut volume_builder = create_353::VolumeBuilder::default();
231 if let Some(val) = &args.availability_zone {
232 volume_builder.availability_zone(Some(val.into()));
233 } else if args.no_availability_zone {
234 volume_builder.availability_zone(None);
235 }
236
237 if let Some(val) = &args.backup_id {
238 volume_builder.backup_id(Some(val.into()));
239 } else if args.no_backup_id {
240 volume_builder.backup_id(None);
241 }
242
243 if let Some(val) = &args.consistencygroup_id {
244 volume_builder.consistencygroup_id(Some(val.into()));
245 } else if args.no_consistencygroup_id {
246 volume_builder.consistencygroup_id(None);
247 }
248
249 if let Some(val) = &args.description {
250 volume_builder.description(Some(val.into()));
251 } else if args.no_description {
252 volume_builder.description(None);
253 }
254
255 if let Some(val) = &args.display_description {
256 volume_builder.display_description(Some(val.into()));
257 } else if args.no_display_description {
258 volume_builder.display_description(None);
259 }
260
261 if let Some(val) = &args.display_name {
262 volume_builder.display_name(Some(val.into()));
263 } else if args.no_display_name {
264 volume_builder.display_name(None);
265 }
266
267 if let Some(val) = &args.group_id {
268 volume_builder.group_id(Some(val.into()));
269 } else if args.no_group_id {
270 volume_builder.group_id(None);
271 }
272
273 if let Some(val) = &args.image_ref {
274 volume_builder.image_ref(Some(val.into()));
275 } else if args.no_image_ref {
276 volume_builder.image_ref(None);
277 }
278
279 if let Some(val) = &args.image_id {
280 volume_builder.image_id(Some(val.into()));
281 } else if args.no_image_id {
282 volume_builder.image_id(None);
283 }
284
285 if let Some(val) = &args.metadata {
286 volume_builder.metadata(val.iter().cloned());
287 }
288
289 if let Some(val) = &args.multiattach {
290 volume_builder.multiattach(*val);
291 }
292
293 if let Some(val) = &args.name {
294 volume_builder.name(Some(val.into()));
295 } else if args.no_name {
296 volume_builder.name(None);
297 }
298
299 if let Some(val) = &args.size {
300 volume_builder.size(*val);
301 }
302
303 if let Some(val) = &args.snapshot_id {
304 volume_builder.snapshot_id(Some(val.into()));
305 } else if args.no_snapshot_id {
306 volume_builder.snapshot_id(None);
307 }
308
309 if let Some(val) = &args.source_volid {
310 volume_builder.source_volid(Some(val.into()));
311 } else if args.no_source_volid {
312 volume_builder.source_volid(None);
313 }
314
315 if let Some(val) = &args.volume_type {
316 volume_builder.volume_type(Some(val.into()));
317 } else if args.no_volume_type {
318 volume_builder.volume_type(None);
319 }
320
321 ep_builder.volume(
322 volume_builder
323 .build()
324 .wrap_err("error preparing the request data")?,
325 );
326
327 let ep = ep_builder
328 .build()
329 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
330
331 let data: serde_json::Value = ep.query_async(client).await?;
332
333 op.output_single::<response::create::VolumeResponse>(data.clone())?;
334 op.show_command_hint()?;
336 Ok(())
337 }
338}