openstack_cli_network/v2/router/
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::router::find;
34use openstack_sdk::api::network::v2::router::set;
35use openstack_types::network::v2::router::response;
36use serde_json::Value;
37
38#[derive(Args)]
48#[command(about = "Update router")]
49pub struct RouterCommand {
50 #[command(flatten)]
52 query: QueryParameters,
53
54 #[command(flatten)]
56 path: PathParameters,
57
58 #[command(flatten)]
60 router: Router,
61}
62
63#[derive(Args)]
65struct QueryParameters {}
66
67#[derive(Args)]
69struct PathParameters {
70 #[arg(
72 help_heading = "Path parameters",
73 id = "path_param_id",
74 value_name = "ID"
75 )]
76 id: String,
77}
78#[derive(Args, Clone)]
80#[group(required = false, multiple = true)]
81struct ExternalGatewayInfo {
82 #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
83 enable_snat: Option<bool>,
84
85 #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long, value_name="JSON", value_parser=openstack_cli_core::common::parse_json)]
87 external_fixed_ips: Option<Vec<Value>>,
88
89 #[arg(help_heading = "Body parameters", long, required = false)]
90 network_id: String,
91
92 #[arg(help_heading = "Body parameters", long)]
93 qos_policy_id: Option<String>,
94}
95
96#[derive(Args, Clone)]
98struct Router {
99 #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
102 admin_state_up: Option<bool>,
103
104 #[arg(help_heading = "Body parameters", long)]
107 description: Option<String>,
108
109 #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
112 distributed: Option<Option<bool>>,
113
114 #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
119 enable_ndp_proxy: Option<Option<bool>>,
120
121 #[command(flatten)]
126 external_gateway_info: Option<ExternalGatewayInfo>,
127
128 #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
131 ha: Option<Option<bool>>,
132
133 #[arg(help_heading = "Body parameters", long)]
135 name: Option<String>,
136
137 #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long, value_name="JSON", value_parser=openstack_cli_core::common::parse_json)]
143 routes: Option<Vec<Value>>,
144}
145
146impl RouterCommand {
147 pub async fn take_action<C: CliArgs>(
149 &self,
150 parsed_args: &C,
151 client: &mut AsyncOpenStack,
152 ) -> Result<(), OpenStackCliError> {
153 info!("Set Router");
154
155 let op = OutputProcessor::from_args(parsed_args, Some("network.router"), Some("set"));
156 op.validate_args(parsed_args)?;
157
158 let mut find_builder = find::Request::builder();
159
160 find_builder.id(&self.path.id);
161
162 let find_ep = find_builder
163 .build()
164 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
165 let find_data: serde_json::Value = find(find_ep).query_async(client).await?;
166
167 let mut ep_builder = set::Request::builder();
168
169 let resource_id = find_data["id"]
170 .as_str()
171 .ok_or_else(|| eyre::eyre!("resource ID must be a string"))?
172 .to_string();
173 ep_builder.id(resource_id.clone());
174
175 let args = &self.router;
178 let mut router_builder = set::RouterBuilder::default();
179 if let Some(val) = &args.admin_state_up {
180 router_builder.admin_state_up(*val);
181 }
182
183 if let Some(val) = &args.description {
184 router_builder.description(val);
185 }
186
187 if let Some(val) = &args.distributed {
188 router_builder.distributed(*val);
189 }
190
191 if let Some(val) = &args.enable_ndp_proxy {
192 router_builder.enable_ndp_proxy(*val);
193 }
194
195 if let Some(val) = &args.external_gateway_info {
196 let mut external_gateway_info_builder = set::ExternalGatewayInfoBuilder::default();
197 if let Some(val) = &val.enable_snat {
198 external_gateway_info_builder.enable_snat(*val);
199 }
200 if let Some(val) = &val.external_fixed_ips {
201 let external_fixed_ips_builder: Vec<set::ExternalFixedIps> = val
202 .iter()
203 .flat_map(|v| serde_json::from_value::<set::ExternalFixedIps>(v.to_owned()))
204 .collect::<Vec<set::ExternalFixedIps>>();
205 external_gateway_info_builder.external_fixed_ips(external_fixed_ips_builder);
206 }
207
208 external_gateway_info_builder.network_id(&val.network_id);
209 if let Some(val) = &val.qos_policy_id {
210 external_gateway_info_builder.qos_policy_id(Some(val.into()));
211 }
212 router_builder.external_gateway_info(
213 external_gateway_info_builder
214 .build()
215 .wrap_err("error preparing the request data")?,
216 );
217 }
218
219 if let Some(val) = &args.ha {
220 router_builder.ha(*val);
221 }
222
223 if let Some(val) = &args.name {
224 router_builder.name(val);
225 }
226
227 if let Some(val) = &args.routes {
228 let routes_builder: Vec<set::Routes> = val
229 .iter()
230 .flat_map(|v| serde_json::from_value::<set::Routes>(v.to_owned()))
231 .collect::<Vec<set::Routes>>();
232 router_builder.routes(routes_builder);
233 }
234
235 ep_builder.router(
236 router_builder
237 .build()
238 .wrap_err("error preparing the request data")?,
239 );
240
241 let ep = ep_builder
242 .build()
243 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
244
245 let data: serde_json::Value = ep.query_async(client).await?;
246
247 op.output_single::<response::set::RouterResponse>(data.clone())?;
248 op.show_command_hint()?;
250 Ok(())
251 }
252}