Skip to main content

openstack_cli_load_balancer/v2/loadbalancer/
list.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//! List Loadbalancers command
19//!
20//! Wraps invoking of the `v2/lbaas/loadbalancers` with `GET` method
21
22use clap::Args;
23use eyre::OptionExt;
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_by_name;
33use openstack_sdk::api::identity::v3::project::find as find_project;
34use openstack_sdk::api::load_balancer::v2::loadbalancer::list;
35use openstack_sdk::api::{Pagination, paged};
36use openstack_types::load_balancer::v2::loadbalancer::response;
37use tracing::warn;
38
39/// Lists all load balancers for the project.
40///
41/// Use the `fields` query parameter to control which fields are returned in
42/// the response body. Additionally, you can filter results by using query
43/// string parameters. For information, see
44/// [Filtering and column selection](#filtering).
45///
46/// Administrative users can specify a project ID that is different than their
47/// own to list load balancers for other projects.
48///
49/// The list might be empty.
50#[derive(Args)]
51#[command(about = "List Load Balancers")]
52pub struct LoadbalancersCommand {
53    /// Request Query parameters
54    #[command(flatten)]
55    query: QueryParameters,
56
57    /// Path parameters
58    #[command(flatten)]
59    path: PathParameters,
60
61    /// Total limit of entities count to return. Use this when there are too many entries.
62    #[arg(long, default_value_t = 10000)]
63    max_items: usize,
64}
65
66/// Query parameters
67#[derive(Args)]
68struct QueryParameters {
69    /// An availability zone name.
70    #[arg(help_heading = "Query parameters", long)]
71    availability_zone: Option<String>,
72
73    /// The UTC date and timestamp when the resource was created.
74    #[arg(help_heading = "Query parameters", long)]
75    created_at: Option<String>,
76
77    /// A human-readable description for the resource.
78    #[arg(help_heading = "Query parameters", long)]
79    description: Option<String>,
80
81    /// The ID of the flavor.
82    #[arg(help_heading = "Query parameters", long)]
83    flavor_id: Option<String>,
84
85    /// The ID of the resource
86    #[arg(help_heading = "Query parameters", long)]
87    id: Option<String>,
88
89    /// Page size
90    #[arg(
91        help_heading = "Query parameters",
92        long("page-size"),
93        visible_alias("limit")
94    )]
95    limit: Option<i32>,
96
97    /// ID of the last item in the previous list
98    #[arg(help_heading = "Query parameters", long)]
99    marker: Option<String>,
100
101    /// Human-readable name of the resource.
102    #[arg(help_heading = "Query parameters", long)]
103    name: Option<String>,
104
105    /// Return the list of entities that do not have one or more of the given
106    /// tags.
107    #[arg(help_heading = "Query parameters", long)]
108    not_tags: Option<String>,
109
110    /// Return the list of entities that do not have at least one of the given
111    /// tags.
112    #[arg(help_heading = "Query parameters", long)]
113    not_tags_any: Option<String>,
114
115    /// The operating status of the resource.
116    #[arg(help_heading = "Query parameters", long, value_parser = ["DEGRADED","DRAINING","ERROR","NO_MONITOR","OFFLINE","ONLINE"])]
117    operating_status: Option<String>,
118
119    /// The page direction.
120    #[arg(action=clap::ArgAction::Set, help_heading = "Query parameters", long)]
121    page_reverse: Option<bool>,
122
123    /// Project resource for which the operation should be performed.
124    #[command(flatten)]
125    project: ProjectInput,
126
127    /// Provider name for the load balancer.
128    #[arg(help_heading = "Query parameters", long)]
129    provider: Option<String>,
130
131    /// The provisioning status of the resource.
132    #[arg(help_heading = "Query parameters", long, value_parser = ["ACTIVE","DELETED","ERROR","PENDING_CREATE","PENDING_DELETE","PENDING_UPDATE"])]
133    provisioning_status: Option<String>,
134
135    /// Return the list of entities that have this tag or tags.
136    #[arg(help_heading = "Query parameters", long)]
137    tags: Option<String>,
138
139    /// Return the list of entities that have one or more of the given tags.
140    #[arg(help_heading = "Query parameters", long)]
141    tags_any: Option<String>,
142
143    /// The UTC date and timestamp when the resource was last updated.
144    #[arg(help_heading = "Query parameters", long)]
145    updated_at: Option<String>,
146
147    /// The IP address of the Virtual IP (VIP).
148    #[arg(help_heading = "Query parameters", long)]
149    vip_address: Option<String>,
150
151    /// The ID of the network for the Virtual IP (VIP).
152    #[arg(help_heading = "Query parameters", long)]
153    vip_network_id: Option<String>,
154
155    /// The ID of the Virtual IP (VIP) port.
156    #[arg(help_heading = "Query parameters", long)]
157    vip_port_id: Option<String>,
158
159    /// The ID of the QoS Policy which will apply to the Virtual IP (VIP).
160    #[arg(help_heading = "Query parameters", long)]
161    vip_qos_policy_id: Option<String>,
162
163    /// The ID of the subnet for the Virtual IP (VIP).
164    #[arg(help_heading = "Query parameters", long)]
165    vip_subnet_id: Option<String>,
166}
167
168/// Project input select group
169#[derive(Args)]
170#[group(required = false, multiple = false)]
171struct ProjectInput {
172    /// Project Name.
173    #[arg(long, help_heading = "Path parameters", value_name = "PROJECT_NAME")]
174    project_name: Option<String>,
175    /// Project ID.
176    #[arg(long, help_heading = "Path parameters", value_name = "PROJECT_ID")]
177    project_id: Option<String>,
178    /// Current project.
179    #[arg(long, help_heading = "Path parameters", action = clap::ArgAction::SetTrue)]
180    current_project: bool,
181}
182
183/// Path parameters
184#[derive(Args)]
185struct PathParameters {}
186
187impl LoadbalancersCommand {
188    /// Perform command action
189    pub async fn take_action<C: CliArgs>(
190        &self,
191        parsed_args: &C,
192        client: &mut AsyncOpenStack,
193    ) -> Result<(), OpenStackCliError> {
194        info!("List Loadbalancers");
195
196        let op = OutputProcessor::from_args(
197            parsed_args,
198            Some("load-balancer.loadbalancer"),
199            Some("list"),
200        );
201        op.validate_args(parsed_args)?;
202
203        let mut ep_builder = list::Request::builder();
204
205        // Set query parameters
206        if let Some(val) = &self.query.availability_zone {
207            ep_builder.availability_zone(val);
208        }
209        if let Some(val) = &self.query.created_at {
210            ep_builder.created_at(val);
211        }
212        if let Some(val) = &self.query.description {
213            ep_builder.description(val);
214        }
215        if let Some(val) = &self.query.flavor_id {
216            ep_builder.flavor_id(val);
217        }
218        if let Some(val) = &self.query.id {
219            ep_builder.id(val);
220        }
221        if let Some(val) = &self.query.limit {
222            ep_builder.limit(*val);
223        }
224        if let Some(val) = &self.query.marker {
225            ep_builder.marker(val);
226        }
227        if let Some(val) = &self.query.name {
228            ep_builder.name(val);
229        }
230        if let Some(val) = &self.query.not_tags {
231            ep_builder.not_tags(val);
232        }
233        if let Some(val) = &self.query.not_tags_any {
234            ep_builder.not_tags_any(val);
235        }
236        if let Some(val) = &self.query.operating_status {
237            ep_builder.operating_status(val);
238        }
239        if let Some(val) = &self.query.page_reverse {
240            ep_builder.page_reverse(*val);
241        }
242        if let Some(id) = &self.query.project.project_id {
243            // project_id is passed. No need to lookup
244            ep_builder.project_id(id);
245        } else if let Some(name) = &self.query.project.project_name {
246            // project_name is passed. Need to lookup resource
247            let mut sub_find_builder = find_project::Request::builder();
248            warn!(
249                "Querying project by name (because of `--project-name` parameter passed) may not be definite. This may fail in which case parameter `--project-id` should be used instead."
250            );
251
252            sub_find_builder.id(name);
253            let find_ep = sub_find_builder
254                .build()
255                .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
256            let find_data: serde_json::Value = find_by_name(find_ep).query_async(client).await?;
257            // Try to extract resource id
258            match find_data.get("id") {
259                Some(val) => match val.as_str() {
260                    Some(id_str) => {
261                        ep_builder.project_id(id_str.to_owned());
262                    }
263                    None => {
264                        return Err(OpenStackCliError::ResourceAttributeNotString(
265                            serde_json::to_string(&val)?,
266                        ));
267                    }
268                },
269                None => {
270                    return Err(OpenStackCliError::ResourceAttributeMissing(
271                        "id".to_string(),
272                    ));
273                }
274            };
275        } else if self.query.project.current_project {
276            ep_builder.project_id(
277                client
278                    .get_auth_info()
279                    .ok_or_eyre("Cannot determine current authentication information")?
280                    .token
281                    .user
282                    .id,
283            );
284        }
285        if let Some(val) = &self.query.provider {
286            ep_builder.provider(val);
287        }
288        if let Some(val) = &self.query.provisioning_status {
289            ep_builder.provisioning_status(val);
290        }
291        if let Some(val) = &self.query.tags {
292            ep_builder.tags(val);
293        }
294        if let Some(val) = &self.query.tags_any {
295            ep_builder.tags_any(val);
296        }
297        if let Some(val) = &self.query.updated_at {
298            ep_builder.updated_at(val);
299        }
300        if let Some(val) = &self.query.vip_address {
301            ep_builder.vip_address(val);
302        }
303        if let Some(val) = &self.query.vip_network_id {
304            ep_builder.vip_network_id(val);
305        }
306        if let Some(val) = &self.query.vip_port_id {
307            ep_builder.vip_port_id(val);
308        }
309        if let Some(val) = &self.query.vip_qos_policy_id {
310            ep_builder.vip_qos_policy_id(val);
311        }
312        if let Some(val) = &self.query.vip_subnet_id {
313            ep_builder.vip_subnet_id(val);
314        }
315
316        let ep = ep_builder
317            .build()
318            .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
319
320        let data: Vec<serde_json::Value> = paged(ep, Pagination::Limit(self.max_items))
321            .query_async(client)
322            .await?;
323
324        op.output_list::<response::list::LoadbalancerResponse>(data.clone())?;
325        // Show command specific hints
326        op.show_command_hint()?;
327        Ok(())
328    }
329}