openstack_cli_block_storage/v3/volume/
set_30.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::find;
34use openstack_sdk::api::block_storage::v3::volume::set_30;
35use openstack_sdk::api::find;
36use openstack_types::block_storage::v3::volume::response;
37
38#[derive(Args)]
40pub struct VolumeCommand {
41 #[command(flatten)]
43 query: QueryParameters,
44
45 #[command(flatten)]
47 path: PathParameters,
48
49 #[command(flatten)]
50 volume: Volume,
51}
52
53#[derive(Args)]
55struct QueryParameters {}
56
57#[derive(Args)]
59struct PathParameters {
60 #[arg(
62 help_heading = "Path parameters",
63 id = "path_param_id",
64 value_name = "ID"
65 )]
66 id: String,
67}
68#[derive(Args, Clone)]
70struct Volume {
71 #[arg(help_heading = "Body parameters", long)]
72 description: Option<String>,
73
74 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "description")]
76 no_description: bool,
77
78 #[arg(help_heading = "Body parameters", long)]
79 display_description: Option<String>,
80
81 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "display_description")]
83 no_display_description: bool,
84
85 #[arg(help_heading = "Body parameters", long)]
86 display_name: Option<String>,
87
88 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "display_name")]
90 no_display_name: bool,
91
92 #[arg(help_heading = "Body parameters", long, value_name="key=value", value_parser=parse_key_val::<String, String>)]
93 metadata: Option<Vec<(String, String)>>,
94
95 #[arg(help_heading = "Body parameters", long)]
96 name: Option<String>,
97
98 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "name")]
100 no_name: bool,
101}
102
103impl VolumeCommand {
104 pub async fn take_action<C: CliArgs>(
106 &self,
107 parsed_args: &C,
108 client: &mut AsyncOpenStack,
109 ) -> Result<(), OpenStackCliError> {
110 info!("Set Volume");
111
112 let op = OutputProcessor::from_args(parsed_args, Some("block-storage.volume"), Some("set"));
113 op.validate_args(parsed_args)?;
114
115 let mut find_builder = find::Request::builder();
116
117 find_builder.id(&self.path.id);
118 find_builder.header(
119 http::header::HeaderName::from_static("openstack-api-version"),
120 http::header::HeaderValue::from_static("volume 3.0"),
121 );
122
123 let find_ep = find_builder
124 .build()
125 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
126 let find_data: serde_json::Value = find(find_ep).query_async(client).await?;
127
128 let mut ep_builder = set_30::Request::builder();
129 ep_builder.header(
130 http::header::HeaderName::from_static("openstack-api-version"),
131 http::header::HeaderValue::from_static("volume 3.0"),
132 );
133
134 let resource_id = find_data["id"]
135 .as_str()
136 .ok_or_else(|| eyre::eyre!("resource ID must be a string"))?
137 .to_string();
138 ep_builder.id(resource_id.clone());
139
140 let args = &self.volume;
143 let mut volume_builder = set_30::VolumeBuilder::default();
144 if let Some(val) = &args.description {
145 volume_builder.description(Some(val.into()));
146 } else if args.no_description {
147 volume_builder.description(None);
148 }
149
150 if let Some(val) = &args.display_description {
151 volume_builder.display_description(Some(val.into()));
152 } else if args.no_display_description {
153 volume_builder.display_description(None);
154 }
155
156 if let Some(val) = &args.display_name {
157 volume_builder.display_name(Some(val.into()));
158 } else if args.no_display_name {
159 volume_builder.display_name(None);
160 }
161
162 if let Some(val) = &args.metadata {
163 volume_builder.metadata(val.iter().cloned());
164 }
165
166 if let Some(val) = &args.name {
167 volume_builder.name(Some(val.into()));
168 } else if args.no_name {
169 volume_builder.name(None);
170 }
171
172 ep_builder.volume(
173 volume_builder
174 .build()
175 .wrap_err("error preparing the request data")?,
176 );
177
178 let ep = ep_builder
179 .build()
180 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
181
182 let data: serde_json::Value = ep.query_async(client).await?;
183
184 op.output_single::<response::set::VolumeResponse>(data.clone())?;
185 op.show_command_hint()?;
187 Ok(())
188 }
189}