openstack_cli_block_storage/v3/volume/
create_313.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_313;
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)]
81 consistencygroup_id: Option<String>,
82
83 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "consistencygroup_id")]
85 no_consistencygroup_id: bool,
86
87 #[arg(help_heading = "Body parameters", long)]
89 description: Option<String>,
90
91 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "description")]
93 no_description: bool,
94
95 #[arg(help_heading = "Body parameters", long)]
96 display_description: Option<String>,
97
98 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "display_description")]
100 no_display_description: bool,
101
102 #[arg(help_heading = "Body parameters", long)]
103 display_name: Option<String>,
104
105 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "display_name")]
107 no_display_name: bool,
108
109 #[arg(help_heading = "Body parameters", long)]
110 group_id: Option<String>,
111
112 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "group_id")]
114 no_group_id: bool,
115
116 #[arg(help_heading = "Body parameters", long)]
117 image_id: Option<String>,
118
119 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "image_id")]
121 no_image_id: bool,
122
123 #[arg(help_heading = "Body parameters", long)]
133 image_ref: Option<String>,
134
135 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "image_ref")]
137 no_image_ref: bool,
138
139 #[arg(help_heading = "Body parameters", long, value_name="key=value", value_parser=parse_key_val::<String, String>)]
142 metadata: Option<Vec<(String, String)>>,
143
144 #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
145 multiattach: Option<Option<bool>>,
146
147 #[arg(help_heading = "Body parameters", long)]
149 name: Option<String>,
150
151 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "name")]
153 no_name: bool,
154
155 #[arg(help_heading = "Body parameters", long)]
157 size: Option<Option<i32>>,
158
159 #[arg(help_heading = "Body parameters", long)]
161 snapshot_id: Option<String>,
162
163 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "snapshot_id")]
165 no_snapshot_id: bool,
166
167 #[arg(help_heading = "Body parameters", long)]
169 source_volid: Option<String>,
170
171 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "source_volid")]
173 no_source_volid: bool,
174
175 #[arg(help_heading = "Body parameters", long)]
186 volume_type: Option<String>,
187
188 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "volume_type")]
190 no_volume_type: bool,
191}
192
193impl VolumeCommand {
194 pub async fn take_action<C: CliArgs>(
196 &self,
197 parsed_args: &C,
198 client: &mut AsyncOpenStack,
199 ) -> Result<(), OpenStackCliError> {
200 info!("Create Volume");
201
202 let op =
203 OutputProcessor::from_args(parsed_args, Some("block-storage.volume"), Some("create"));
204 op.validate_args(parsed_args)?;
205
206 let mut ep_builder = create_313::Request::builder();
207 ep_builder.header(
208 http::header::HeaderName::from_static("openstack-api-version"),
209 http::header::HeaderValue::from_static("volume 3.13"),
210 );
211
212 if let Some(arg) = &self.os_sch_hnt_scheduler_hints {
215 ep_builder.os_sch_hnt_scheduler_hints(arg.iter().cloned());
216 }
217
218 let args = &self.volume;
220 let mut volume_builder = create_313::VolumeBuilder::default();
221 if let Some(val) = &args.availability_zone {
222 volume_builder.availability_zone(Some(val.into()));
223 } else if args.no_availability_zone {
224 volume_builder.availability_zone(None);
225 }
226
227 if let Some(val) = &args.consistencygroup_id {
228 volume_builder.consistencygroup_id(Some(val.into()));
229 } else if args.no_consistencygroup_id {
230 volume_builder.consistencygroup_id(None);
231 }
232
233 if let Some(val) = &args.description {
234 volume_builder.description(Some(val.into()));
235 } else if args.no_description {
236 volume_builder.description(None);
237 }
238
239 if let Some(val) = &args.display_description {
240 volume_builder.display_description(Some(val.into()));
241 } else if args.no_display_description {
242 volume_builder.display_description(None);
243 }
244
245 if let Some(val) = &args.display_name {
246 volume_builder.display_name(Some(val.into()));
247 } else if args.no_display_name {
248 volume_builder.display_name(None);
249 }
250
251 if let Some(val) = &args.group_id {
252 volume_builder.group_id(Some(val.into()));
253 } else if args.no_group_id {
254 volume_builder.group_id(None);
255 }
256
257 if let Some(val) = &args.image_ref {
258 volume_builder.image_ref(Some(val.into()));
259 } else if args.no_image_ref {
260 volume_builder.image_ref(None);
261 }
262
263 if let Some(val) = &args.image_id {
264 volume_builder.image_id(Some(val.into()));
265 } else if args.no_image_id {
266 volume_builder.image_id(None);
267 }
268
269 if let Some(val) = &args.metadata {
270 volume_builder.metadata(val.iter().cloned());
271 }
272
273 if let Some(val) = &args.multiattach {
274 volume_builder.multiattach(*val);
275 }
276
277 if let Some(val) = &args.name {
278 volume_builder.name(Some(val.into()));
279 } else if args.no_name {
280 volume_builder.name(None);
281 }
282
283 if let Some(val) = &args.size {
284 volume_builder.size(*val);
285 }
286
287 if let Some(val) = &args.snapshot_id {
288 volume_builder.snapshot_id(Some(val.into()));
289 } else if args.no_snapshot_id {
290 volume_builder.snapshot_id(None);
291 }
292
293 if let Some(val) = &args.source_volid {
294 volume_builder.source_volid(Some(val.into()));
295 } else if args.no_source_volid {
296 volume_builder.source_volid(None);
297 }
298
299 if let Some(val) = &args.volume_type {
300 volume_builder.volume_type(Some(val.into()));
301 } else if args.no_volume_type {
302 volume_builder.volume_type(None);
303 }
304
305 ep_builder.volume(
306 volume_builder
307 .build()
308 .wrap_err("error preparing the request data")?,
309 );
310
311 let ep = ep_builder
312 .build()
313 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
314
315 let data: serde_json::Value = ep.query_async(client).await?;
316
317 op.output_single::<response::create::VolumeResponse>(data.clone())?;
318 op.show_command_hint()?;
320 Ok(())
321 }
322}