Skip to main content

openstack_cli_network/v2/router/
create.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5//     http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12//
13// SPDX-License-Identifier: Apache-2.0
14//
15// WARNING: This file is automatically generated from OpenAPI schema using
16// `openstack-codegenerator`.
17
18//! Create Router command
19//!
20//! Wraps invoking of the `v2.0/routers` with `POST` method
21
22use 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::network::v2::router::create;
33use openstack_types::network::v2::router::response;
34use serde_json::Value;
35
36/// Creates a logical router.
37///
38/// This operation creates a logical router. The logical router does not have
39/// any internal interface and it is not associated with any subnet. You can
40/// optionally specify an external gateway for a router at create time. The
41/// external gateway for the router must be plugged into an external network.
42/// An external network has its `router:external` extended field set to `true`.
43/// To specify an external gateway, the ID of the external network must be
44/// passed in the `network_id` parameter of the `external_gateway_info`
45/// attribute in the request body.
46///
47/// Normal response codes: 201
48///
49/// Error response codes: 400, 401
50#[derive(Args)]
51#[command(about = "Create router")]
52pub struct RouterCommand {
53    /// Request Query parameters
54    #[command(flatten)]
55    query: QueryParameters,
56
57    /// Path parameters
58    #[command(flatten)]
59    path: PathParameters,
60
61    /// A `router` object.
62    #[command(flatten)]
63    router: Router,
64}
65
66/// Query parameters
67#[derive(Args)]
68struct QueryParameters {}
69
70/// Path parameters
71#[derive(Args)]
72struct PathParameters {}
73/// ExternalGatewayInfo Body data
74#[derive(Args, Clone)]
75#[group(required = false, multiple = true)]
76struct ExternalGatewayInfo {
77    #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
78    enable_snat: Option<bool>,
79
80    /// Parameter is an array, may be provided multiple times.
81    #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long, value_name="JSON", value_parser=openstack_cli_core::common::parse_json)]
82    external_fixed_ips: Option<Vec<Value>>,
83
84    #[arg(help_heading = "Body parameters", long, required = false)]
85    network_id: String,
86
87    #[arg(help_heading = "Body parameters", long)]
88    qos_policy_id: Option<String>,
89}
90
91/// Router Body data
92#[derive(Args, Clone)]
93struct Router {
94    /// The administrative state of the resource, which is up (`true`) or down
95    /// (`false`). Default is `true`.
96    #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
97    admin_state_up: Option<bool>,
98
99    /// The availability zone candidates for the router. It is available when
100    /// `router_availability_zone` extension is enabled.
101    ///
102    /// Parameter is an array, may be provided multiple times.
103    #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long)]
104    availability_zone_hints: Option<Vec<String>>,
105
106    /// A human-readable description for the resource. Default is an empty
107    /// string.
108    #[arg(help_heading = "Body parameters", long)]
109    description: Option<String>,
110
111    /// `true` indicates a distributed router. It is available when `dvr`
112    /// extension is enabled.
113    #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
114    distributed: Option<Option<bool>>,
115
116    /// Enable NDP proxy attribute. Default is `false`, To persist this
117    /// attribute value, set the `enable_ndp_proxy_by_default` option in the
118    /// `neutron.conf` file. It is available when `router-extend-ndp-proxy`
119    /// extension is enabled.
120    #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
121    enable_ndp_proxy: Option<Option<bool>>,
122
123    /// The external gateway information of the router. If the router has an
124    /// external gateway, this would be a dict with `network_id`,
125    /// `enable_snat`, `external_fixed_ips` and `qos_policy_id`. Otherwise,
126    /// this would be `null`.
127    #[command(flatten)]
128    external_gateway_info: Option<ExternalGatewayInfo>,
129
130    /// The ID of the flavor associated with the router.
131    #[arg(help_heading = "Body parameters", long)]
132    flavor_id: Option<String>,
133
134    /// `true` indicates a highly-available router. It is available when
135    /// `l3-ha` extension is enabled.
136    #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
137    ha: Option<Option<bool>>,
138
139    /// Human-readable name of the resource. Default is an empty string.
140    #[arg(help_heading = "Body parameters", long)]
141    name: Option<String>,
142
143    /// The ID of the project that owns the resource. Only administrative and
144    /// users with advsvc role can specify a project ID other than their own.
145    /// You cannot change this value through authorization policies.
146    #[arg(help_heading = "Body parameters", long)]
147    tenant_id: Option<String>,
148}
149
150impl RouterCommand {
151    /// Perform command action
152    pub async fn take_action<C: CliArgs>(
153        &self,
154        parsed_args: &C,
155        client: &mut AsyncOpenStack,
156    ) -> Result<(), OpenStackCliError> {
157        info!("Create Router");
158
159        let op = OutputProcessor::from_args(parsed_args, Some("network.router"), Some("create"));
160        op.validate_args(parsed_args)?;
161
162        let mut ep_builder = create::Request::builder();
163
164        // Set body parameters
165        // Set Request.router data
166        let args = &self.router;
167        let mut router_builder = create::RouterBuilder::default();
168        if let Some(val) = &args.admin_state_up {
169            router_builder.admin_state_up(*val);
170        }
171
172        if let Some(val) = &args.availability_zone_hints {
173            router_builder.availability_zone_hints(val.iter().map(Into::into).collect::<Vec<_>>());
174        }
175
176        if let Some(val) = &args.description {
177            router_builder.description(val);
178        }
179
180        if let Some(val) = &args.distributed {
181            router_builder.distributed(*val);
182        }
183
184        if let Some(val) = &args.enable_ndp_proxy {
185            router_builder.enable_ndp_proxy(*val);
186        }
187
188        if let Some(val) = &args.external_gateway_info {
189            let mut external_gateway_info_builder = create::ExternalGatewayInfoBuilder::default();
190            if let Some(val) = &val.enable_snat {
191                external_gateway_info_builder.enable_snat(*val);
192            }
193            if let Some(val) = &val.external_fixed_ips {
194                let external_fixed_ips_builder: Vec<create::ExternalFixedIps> = val
195                    .iter()
196                    .flat_map(|v| serde_json::from_value::<create::ExternalFixedIps>(v.to_owned()))
197                    .collect::<Vec<create::ExternalFixedIps>>();
198                external_gateway_info_builder.external_fixed_ips(external_fixed_ips_builder);
199            }
200
201            external_gateway_info_builder.network_id(&val.network_id);
202            if let Some(val) = &val.qos_policy_id {
203                external_gateway_info_builder.qos_policy_id(Some(val.into()));
204            }
205            router_builder.external_gateway_info(
206                external_gateway_info_builder
207                    .build()
208                    .wrap_err("error preparing the request data")?,
209            );
210        }
211
212        if let Some(val) = &args.flavor_id {
213            router_builder.flavor_id(val);
214        }
215
216        if let Some(val) = &args.ha {
217            router_builder.ha(*val);
218        }
219
220        if let Some(val) = &args.name {
221            router_builder.name(val);
222        }
223
224        if let Some(val) = &args.tenant_id {
225            router_builder.tenant_id(val);
226        }
227
228        ep_builder.router(
229            router_builder
230                .build()
231                .wrap_err("error preparing the request data")?,
232        );
233
234        let ep = ep_builder
235            .build()
236            .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
237
238        let data: serde_json::Value = ep.query_async(client).await?;
239
240        op.output_single::<response::create::RouterResponse>(data.clone())?;
241        // Show command specific hints
242        op.show_command_hint()?;
243        Ok(())
244    }
245}