Skip to main content

openstack_cli_load_balancer/v2/pool/
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 Pool command
19//!
20//! Wraps invoking of the `v2/lbaas/pools` 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 clap::ValueEnum;
32use openstack_sdk::api::QueryAsync;
33use openstack_sdk::api::load_balancer::v2::pool::create;
34use openstack_types::load_balancer::v2::pool::response;
35use serde_json::Value;
36
37/// Creates a pool for a load balancer.
38///
39/// The pool defines how requests should be balanced across the backend member
40/// servers.
41///
42/// This operation provisions a pool by using the configuration that you define
43/// in the request object. After the API validates the request and starts the
44/// provisioning process, the API returns a response object, which contains a
45/// unique ID.
46///
47/// In the response, the pool [provisioning status](#prov-status) is `ACTIVE`,
48/// `PENDING_CREATE`, or `ERROR`.
49///
50/// If the status is `PENDING_CREATE`, issue GET `/v2/lbaas/pools/{pool_id}` to
51/// view the progress of the provisioning operation. When the pool status
52/// changes to `ACTIVE`, the pool is successfully provisioned and is ready for
53/// further configuration.
54///
55/// At a minimum, you must specify these pool attributes:
56///
57/// Some attributes receive default values if you omit them from the request:
58///
59/// If the API cannot fulfill the request due to insufficient data or data that
60/// is not valid, the service returns the HTTP `Bad Request (400)` response
61/// code with information about the failure in the response body. Validation
62/// errors require that you correct the error and submit the request again.
63///
64/// Specifying a project_id is deprecated. The pool will inherit the project_id
65/// of the parent load balancer.
66///
67/// You can configure all documented features of the pool at creation time by
68/// specifying the additional elements or attributes in the request.
69///
70/// To create a pool, the parent load balancer must have an `ACTIVE`
71/// provisioning status.
72///
73/// `SOURCE_IP_PORT` algorithm is available from version 2.13.
74#[derive(Args)]
75#[command(about = "Create Pool")]
76pub struct PoolCommand {
77    /// Request Query parameters
78    #[command(flatten)]
79    query: QueryParameters,
80
81    /// Path parameters
82    #[command(flatten)]
83    path: PathParameters,
84
85    /// Defines mandatory and optional attributes of a POST request.
86    #[command(flatten)]
87    pool: Pool,
88}
89
90/// Query parameters
91#[derive(Args)]
92struct QueryParameters {}
93
94/// Path parameters
95#[derive(Args)]
96struct PathParameters {}
97
98#[derive(Clone, Eq, Ord, PartialEq, PartialOrd, ValueEnum)]
99enum LbAlgorithm {
100    LeastConnections,
101    RoundRobin,
102    SourceIp,
103    SourceIpPort,
104}
105
106#[derive(Clone, Eq, Ord, PartialEq, PartialOrd, ValueEnum)]
107enum Protocol {
108    Http,
109    Https,
110    Proxy,
111    Proxyv2,
112    Sctp,
113    Tcp,
114    Udp,
115}
116
117#[derive(Clone, Eq, Ord, PartialEq, PartialOrd, ValueEnum)]
118enum SessionPersistenceType {
119    AppCookie,
120    HttpCookie,
121    SourceIp,
122}
123
124/// SessionPersistence Body data
125#[derive(Args, Clone)]
126#[group(required = false, multiple = true)]
127struct SessionPersistence {
128    #[arg(help_heading = "Body parameters", long)]
129    cookie_name: Option<String>,
130
131    #[arg(help_heading = "Body parameters", long)]
132    persistence_granularity: Option<String>,
133
134    #[arg(help_heading = "Body parameters", long)]
135    persistence_timeout: Option<i32>,
136
137    #[arg(help_heading = "Body parameters", long, required = false)]
138    _type: SessionPersistenceType,
139}
140
141/// Pool Body data
142#[derive(Args, Clone)]
143struct Pool {
144    /// The administrative state of the resource, which is up (`true`) or down
145    /// (`false`). Default is `true`.
146    #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
147    admin_state_up: Option<bool>,
148
149    /// A list of ALPN protocols. Available protocols: http/1.0, http/1.1, h2
150    ///
151    /// **New in version 2.24**
152    ///
153    /// Parameter is an array, may be provided multiple times.
154    #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long)]
155    alpn_protocols: Option<Vec<String>>,
156
157    /// The reference of the
158    /// [key manager service](https://docs.openstack.org/castellan/latest/)
159    /// secret containing a PEM format CA certificate bundle for `tls_enabled`
160    /// pools.
161    ///
162    /// **New in version 2.8**
163    #[arg(help_heading = "Body parameters", long)]
164    ca_tls_container_ref: Option<String>,
165
166    /// The reference of the
167    /// [key manager service](https://docs.openstack.org/castellan/latest/)
168    /// secret containing a PEM format CA revocation list file for
169    /// `tls_enabled` pools.
170    #[arg(help_heading = "Body parameters", long)]
171    crl_container_ref: Option<String>,
172
173    /// A human-readable description for the resource.
174    #[arg(help_heading = "Body parameters", long)]
175    description: Option<String>,
176
177    /// Defines mandatory and optional attributes of a POST request.
178    #[arg(help_heading = "Body parameters", long, value_name="JSON", value_parser=openstack_cli_core::common::parse_json)]
179    healthmonitor: Option<Value>,
180
181    /// The load balancing algorithm for the pool. One of `LEAST_CONNECTIONS`,
182    /// `ROUND_ROBIN`, `SOURCE_IP`, or `SOURCE_IP_PORT`.
183    #[arg(help_heading = "Body parameters", long)]
184    lb_algorithm: LbAlgorithm,
185
186    /// The ID of the listener for the pool. Either `listener_id` or
187    /// `loadbalancer_id` must be specified. The listener has some
188    /// restrictions, See
189    /// [Protocol Combinations (Listener/Pool)](#valid-protocol).
190    #[arg(help_heading = "Body parameters", long)]
191    listener_id: Option<String>,
192
193    /// The ID of the load balancer for the pool. Either `listener_id` or
194    /// `loadbalancer_id` must be specified.
195    #[arg(help_heading = "Body parameters", long)]
196    loadbalancer_id: Option<String>,
197
198    /// Parameter is an array, may be provided multiple times.
199    #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long, value_name="JSON", value_parser=openstack_cli_core::common::parse_json)]
200    members: Option<Vec<Value>>,
201
202    /// Human-readable name of the resource.
203    #[arg(help_heading = "Body parameters", long)]
204    name: Option<String>,
205
206    /// The ID of the project owning this resource. (deprecated)
207    #[arg(help_heading = "Body parameters", long)]
208    project_id: Option<String>,
209
210    /// The protocol for the resource. One of `HTTP`, `HTTPS`, `PROXY`,
211    /// `PROXYV2`, `SCTP`, `TCP`, or `UDP`.
212    #[arg(help_heading = "Body parameters", long)]
213    protocol: Protocol,
214
215    /// A JSON object specifying the session persistence for the pool or `null`
216    /// for no session persistence. See
217    /// [Pool Session Persistence](#session-persistence). Default is `null`.
218    #[command(flatten)]
219    session_persistence: Option<SessionPersistence>,
220
221    /// Parameter is an array, may be provided multiple times.
222    #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long)]
223    tags: Option<Vec<String>>,
224
225    #[arg(help_heading = "Body parameters", long)]
226    tenant_id: Option<String>,
227
228    /// List of ciphers in OpenSSL format (colon-separated). See
229    /// <https://www.openssl.org/docs/man1.1.1/man1/ciphers.html>
230    ///
231    /// **New in version 2.15**
232    #[arg(help_heading = "Body parameters", long)]
233    tls_ciphers: Option<String>,
234
235    /// The reference to the
236    /// [key manager service](https://docs.openstack.org/castellan/latest/)
237    /// secret containing a PKCS12 format certificate/key bundle for
238    /// `tls_enabled` pools for TLS client authentication to the member
239    /// servers.
240    ///
241    /// **New in version 2.8**
242    #[arg(help_heading = "Body parameters", long)]
243    tls_container_ref: Option<String>,
244
245    /// When `true` connections to backend member servers will use TLS
246    /// encryption. Default is `false`.
247    ///
248    /// **New in version 2.8**
249    #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)]
250    tls_enabled: Option<bool>,
251
252    /// A list of TLS protocol versions. Available versions: SSLv3, TLSv1,
253    /// TLSv1.1, TLSv1.2, TLSv1.3
254    ///
255    /// **New in version 2.17**
256    ///
257    /// Parameter is an array, may be provided multiple times.
258    #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long)]
259    tls_versions: Option<Vec<String>>,
260}
261
262impl PoolCommand {
263    /// Perform command action
264    pub async fn take_action<C: CliArgs>(
265        &self,
266        parsed_args: &C,
267        client: &mut AsyncOpenStack,
268    ) -> Result<(), OpenStackCliError> {
269        info!("Create Pool");
270
271        let op =
272            OutputProcessor::from_args(parsed_args, Some("load-balancer.pool"), Some("create"));
273        op.validate_args(parsed_args)?;
274
275        let mut ep_builder = create::Request::builder();
276
277        // Set body parameters
278        // Set Request.pool data
279        let args = &self.pool;
280        let mut pool_builder = create::PoolBuilder::default();
281        if let Some(val) = &args.admin_state_up {
282            pool_builder.admin_state_up(*val);
283        }
284
285        if let Some(val) = &args.alpn_protocols {
286            pool_builder.alpn_protocols(val.iter().map(Into::into).collect::<Vec<_>>());
287        }
288
289        if let Some(val) = &args.ca_tls_container_ref {
290            pool_builder.ca_tls_container_ref(val);
291        }
292
293        if let Some(val) = &args.crl_container_ref {
294            pool_builder.crl_container_ref(val);
295        }
296
297        if let Some(val) = &args.description {
298            pool_builder.description(val);
299        }
300
301        if let Some(val) = &args.healthmonitor {
302            pool_builder.healthmonitor(serde_json::from_value::<create::Healthmonitor>(
303                val.to_owned(),
304            )?);
305        }
306
307        let tmp = match &args.lb_algorithm {
308            LbAlgorithm::LeastConnections => create::LbAlgorithm::LeastConnections,
309            LbAlgorithm::RoundRobin => create::LbAlgorithm::RoundRobin,
310            LbAlgorithm::SourceIp => create::LbAlgorithm::SourceIp,
311            LbAlgorithm::SourceIpPort => create::LbAlgorithm::SourceIpPort,
312        };
313        pool_builder.lb_algorithm(tmp);
314
315        if let Some(val) = &args.listener_id {
316            pool_builder.listener_id(val);
317        }
318
319        if let Some(val) = &args.loadbalancer_id {
320            pool_builder.loadbalancer_id(val);
321        }
322
323        if let Some(val) = &args.members {
324            let members_builder: Vec<create::Members> = val
325                .iter()
326                .flat_map(|v| serde_json::from_value::<create::Members>(v.to_owned()))
327                .collect::<Vec<create::Members>>();
328            pool_builder.members(members_builder);
329        }
330
331        if let Some(val) = &args.name {
332            pool_builder.name(val);
333        }
334
335        if let Some(val) = &args.project_id {
336            pool_builder.project_id(val);
337        }
338
339        let tmp = match &args.protocol {
340            Protocol::Http => create::Protocol::Http,
341            Protocol::Https => create::Protocol::Https,
342            Protocol::Proxy => create::Protocol::Proxy,
343            Protocol::Proxyv2 => create::Protocol::Proxyv2,
344            Protocol::Sctp => create::Protocol::Sctp,
345            Protocol::Tcp => create::Protocol::Tcp,
346            Protocol::Udp => create::Protocol::Udp,
347        };
348        pool_builder.protocol(tmp);
349
350        if let Some(val) = &args.session_persistence {
351            let mut session_persistence_builder = create::SessionPersistenceBuilder::default();
352            if let Some(val) = &val.cookie_name {
353                session_persistence_builder.cookie_name(val);
354            }
355            if let Some(val) = &val.persistence_granularity {
356                session_persistence_builder.persistence_granularity(val);
357            }
358            if let Some(val) = &val.persistence_timeout {
359                session_persistence_builder.persistence_timeout(*val);
360            }
361
362            let tmp = match &val._type {
363                SessionPersistenceType::AppCookie => create::SessionPersistenceType::AppCookie,
364                SessionPersistenceType::HttpCookie => create::SessionPersistenceType::HttpCookie,
365                SessionPersistenceType::SourceIp => create::SessionPersistenceType::SourceIp,
366            };
367            session_persistence_builder._type(tmp);
368            pool_builder.session_persistence(
369                session_persistence_builder
370                    .build()
371                    .wrap_err("error preparing the request data")?,
372            );
373        }
374
375        if let Some(val) = &args.tags {
376            pool_builder.tags(val.iter().map(Into::into).collect::<Vec<_>>());
377        }
378
379        if let Some(val) = &args.tenant_id {
380            pool_builder.tenant_id(val);
381        }
382
383        if let Some(val) = &args.tls_ciphers {
384            pool_builder.tls_ciphers(val);
385        }
386
387        if let Some(val) = &args.tls_container_ref {
388            pool_builder.tls_container_ref(val);
389        }
390
391        if let Some(val) = &args.tls_enabled {
392            pool_builder.tls_enabled(*val);
393        }
394
395        if let Some(val) = &args.tls_versions {
396            pool_builder.tls_versions(val.iter().map(Into::into).collect::<Vec<_>>());
397        }
398
399        ep_builder.pool(
400            pool_builder
401                .build()
402                .wrap_err("error preparing the request data")?,
403        );
404
405        let ep = ep_builder
406            .build()
407            .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
408
409        let data: serde_json::Value = ep.query_async(client).await?;
410
411        op.output_single::<response::create::PoolResponse>(data.clone())?;
412        // Show command specific hints
413        op.show_command_hint()?;
414        Ok(())
415    }
416}