openstack_cli_network/v2/subnet/
set.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_sdk::api::QueryAsync;
32use openstack_sdk::api::find;
33use openstack_sdk::api::network::v2::subnet::find;
34use openstack_sdk::api::network::v2::subnet::set;
35use openstack_types::network::v2::subnet::response;
36use serde_json::Value;
37
38#[derive(Args)]
48#[command(about = "Update subnet")]
49pub struct SubnetCommand {
50 #[command(flatten)]
52 query: QueryParameters,
53
54 #[command(flatten)]
56 path: PathParameters,
57
58 #[command(flatten)]
59 subnet: Subnet,
60}
61
62#[derive(Args)]
64struct QueryParameters {}
65
66#[derive(Args)]
68struct PathParameters {
69 #[arg(
71 help_heading = "Path parameters",
72 id = "path_param_id",
73 value_name = "ID"
74 )]
75 id: String,
76}
77#[derive(Args, Clone)]
79struct Subnet {
80 #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long, value_name="JSON", value_parser=openstack_cli_core::common::parse_json)]
87 allocation_pools: Option<Vec<Value>>,
88
89 #[arg(help_heading = "Body parameters", long)]
92 description: Option<String>,
93
94 #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long)]
99 dns_nameservers: Option<Vec<String>>,
100
101 #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
104 dns_publish_fixed_ip: Option<bool>,
105
106 #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
109 enable_dhcp: Option<bool>,
110
111 #[arg(help_heading = "Body parameters", long)]
114 gateway_ip: Option<String>,
115
116 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "gateway_ip")]
118 no_gateway_ip: bool,
119
120 #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long, value_name="JSON", value_parser=openstack_cli_core::common::parse_json)]
125 host_routes: Option<Vec<Value>>,
126
127 #[arg(help_heading = "Body parameters", long)]
129 name: Option<String>,
130
131 #[arg(help_heading = "Body parameters", long)]
134 segment_id: Option<String>,
135
136 #[arg(help_heading = "Body parameters", long, action = clap::ArgAction::SetTrue, conflicts_with = "segment_id")]
138 no_segment_id: bool,
139
140 #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long)]
144 service_types: Option<Vec<String>>,
145}
146
147impl SubnetCommand {
148 pub async fn take_action<C: CliArgs>(
150 &self,
151 parsed_args: &C,
152 client: &mut AsyncOpenStack,
153 ) -> Result<(), OpenStackCliError> {
154 info!("Set Subnet");
155
156 let op = OutputProcessor::from_args(parsed_args, Some("network.subnet"), Some("set"));
157 op.validate_args(parsed_args)?;
158
159 let mut find_builder = find::Request::builder();
160
161 find_builder.id(&self.path.id);
162
163 let find_ep = find_builder
164 .build()
165 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
166 let find_data: serde_json::Value = find(find_ep).query_async(client).await?;
167
168 let mut ep_builder = set::Request::builder();
169
170 let resource_id = find_data["id"]
171 .as_str()
172 .ok_or_else(|| eyre::eyre!("resource ID must be a string"))?
173 .to_string();
174 ep_builder.id(resource_id.clone());
175
176 let args = &self.subnet;
179 let mut subnet_builder = set::SubnetBuilder::default();
180 if let Some(val) = &args.allocation_pools {
181 let allocation_pools_builder: Vec<set::AllocationPools> = val
182 .iter()
183 .flat_map(|v| serde_json::from_value::<set::AllocationPools>(v.to_owned()))
184 .collect::<Vec<set::AllocationPools>>();
185 subnet_builder.allocation_pools(allocation_pools_builder);
186 }
187
188 if let Some(val) = &args.description {
189 subnet_builder.description(val);
190 }
191
192 if let Some(val) = &args.dns_nameservers {
193 subnet_builder.dns_nameservers(val.iter().map(Into::into).collect::<Vec<_>>());
194 }
195
196 if let Some(val) = &args.dns_publish_fixed_ip {
197 subnet_builder.dns_publish_fixed_ip(*val);
198 }
199
200 if let Some(val) = &args.enable_dhcp {
201 subnet_builder.enable_dhcp(*val);
202 }
203
204 if let Some(val) = &args.gateway_ip {
205 subnet_builder.gateway_ip(Some(val.into()));
206 } else if args.no_gateway_ip {
207 subnet_builder.gateway_ip(None);
208 }
209
210 if let Some(val) = &args.host_routes {
211 let host_routes_builder: Vec<set::HostRoutes> = val
212 .iter()
213 .flat_map(|v| serde_json::from_value::<set::HostRoutes>(v.to_owned()))
214 .collect::<Vec<set::HostRoutes>>();
215 subnet_builder.host_routes(host_routes_builder);
216 }
217
218 if let Some(val) = &args.name {
219 subnet_builder.name(val);
220 }
221
222 if let Some(val) = &args.segment_id {
223 subnet_builder.segment_id(Some(val.into()));
224 } else if args.no_segment_id {
225 subnet_builder.segment_id(None);
226 }
227
228 if let Some(val) = &args.service_types {
229 subnet_builder.service_types(val.iter().map(Into::into).collect::<Vec<_>>());
230 }
231
232 ep_builder.subnet(
233 subnet_builder
234 .build()
235 .wrap_err("error preparing the request data")?,
236 );
237
238 let ep = ep_builder
239 .build()
240 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
241
242 let data: serde_json::Value = ep.query_async(client).await?;
243
244 op.output_single::<response::set::SubnetResponse>(data.clone())?;
245 op.show_command_hint()?;
247 Ok(())
248 }
249}