Skip to main content

openstack_cli_load_balancer/v2/pool/member/
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 Members command
19//!
20//! Wraps invoking of the `v2/lbaas/pools/{pool_id}/members` 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::pool::member::list;
35use openstack_sdk::api::{Pagination, paged};
36use openstack_types::load_balancer::v2::pool::member::response;
37use tracing::warn;
38
39/// Lists all members 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 members for other projects.
48///
49/// The list might be empty.
50#[derive(Args)]
51#[command(about = "List Members")]
52pub struct MembersCommand {
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    /// The IP address of the backend member server.
70    #[arg(help_heading = "Query parameters", long)]
71    address: Option<String>,
72
73    /// The administrative state of the resource
74    #[arg(action=clap::ArgAction::Set, help_heading = "Query parameters", long)]
75    admin_state_up: Option<bool>,
76
77    /// Is the member a backup?
78    #[arg(action=clap::ArgAction::Set, help_heading = "Query parameters", long)]
79    backup: Option<bool>,
80
81    /// The UTC date and timestamp when the resource was created.
82    #[arg(help_heading = "Query parameters", long)]
83    created_at: Option<String>,
84
85    /// A human-readable description for the resource.
86    #[arg(help_heading = "Query parameters", long)]
87    description: Option<String>,
88
89    /// The ID of the resource
90    #[arg(help_heading = "Query parameters", long)]
91    id: Option<String>,
92
93    /// Page size
94    #[arg(
95        help_heading = "Query parameters",
96        long("page-size"),
97        visible_alias("limit")
98    )]
99    limit: Option<i32>,
100
101    /// ID of the last item in the previous list
102    #[arg(help_heading = "Query parameters", long)]
103    marker: Option<String>,
104
105    /// An alternate IP address used for health monitoring a backend member.
106    #[arg(help_heading = "Query parameters", long)]
107    monitor_address: Option<String>,
108
109    /// An alternate protocol port used for health monitoring a backend member.
110    #[arg(help_heading = "Query parameters", long)]
111    monitor_port: Option<String>,
112
113    /// Human-readable name of the resource.
114    #[arg(help_heading = "Query parameters", long)]
115    name: Option<String>,
116
117    /// Return the list of entities that do not have one or more of the given
118    /// tags.
119    #[arg(help_heading = "Query parameters", long)]
120    not_tags: Option<String>,
121
122    /// Return the list of entities that do not have at least one of the given
123    /// tags.
124    #[arg(help_heading = "Query parameters", long)]
125    not_tags_any: Option<String>,
126
127    /// The operating status of the resource.
128    #[arg(help_heading = "Query parameters", long, value_parser = ["DEGRADED","DRAINING","ERROR","NO_MONITOR","OFFLINE","ONLINE"])]
129    operating_status: Option<String>,
130
131    /// The page direction.
132    #[arg(action=clap::ArgAction::Set, help_heading = "Query parameters", long)]
133    page_reverse: Option<bool>,
134
135    /// Project resource for which the operation should be performed.
136    #[command(flatten)]
137    project: ProjectInput,
138
139    /// The protocol port number the backend member server is listening on.
140    #[arg(help_heading = "Query parameters", long)]
141    protocol_port: Option<i32>,
142
143    /// The provisioning status of the resource.
144    #[arg(help_heading = "Query parameters", long, value_parser = ["ACTIVE","DELETED","ERROR","PENDING_CREATE","PENDING_DELETE","PENDING_UPDATE"])]
145    provisioning_status: Option<String>,
146
147    /// The subnet ID the member service is accessible from.
148    #[arg(help_heading = "Query parameters", long)]
149    subnet_id: Option<String>,
150
151    /// Return the list of entities that have this tag or tags.
152    #[arg(help_heading = "Query parameters", long)]
153    tags: Option<String>,
154
155    /// Return the list of entities that have one or more of the given tags.
156    #[arg(help_heading = "Query parameters", long)]
157    tags_any: Option<String>,
158
159    /// The UTC date and timestamp when the resource was last updated.
160    #[arg(help_heading = "Query parameters", long)]
161    updated_at: Option<String>,
162
163    /// The weight of a member determines the portion of requests or
164    /// connections it services compared to the other members of the pool.
165    #[arg(help_heading = "Query parameters", long)]
166    weight: Option<i32>,
167}
168
169/// Project input select group
170#[derive(Args)]
171#[group(required = false, multiple = false)]
172struct ProjectInput {
173    /// Project Name.
174    #[arg(long, help_heading = "Path parameters", value_name = "PROJECT_NAME")]
175    project_name: Option<String>,
176    /// Project ID.
177    #[arg(long, help_heading = "Path parameters", value_name = "PROJECT_ID")]
178    project_id: Option<String>,
179    /// Current project.
180    #[arg(long, help_heading = "Path parameters", action = clap::ArgAction::SetTrue)]
181    current_project: bool,
182}
183
184/// Path parameters
185#[derive(Args)]
186struct PathParameters {
187    /// pool_id parameter for /v2/lbaas/pools/{pool_id}/members/{member_id} API
188    #[arg(
189        help_heading = "Path parameters",
190        id = "path_param_pool_id",
191        value_name = "POOL_ID"
192    )]
193    pool_id: String,
194}
195
196impl MembersCommand {
197    /// Perform command action
198    pub async fn take_action<C: CliArgs>(
199        &self,
200        parsed_args: &C,
201        client: &mut AsyncOpenStack,
202    ) -> Result<(), OpenStackCliError> {
203        info!("List Members");
204
205        let op = OutputProcessor::from_args(
206            parsed_args,
207            Some("load-balancer.pool/member"),
208            Some("list"),
209        );
210        op.validate_args(parsed_args)?;
211
212        let mut ep_builder = list::Request::builder();
213
214        ep_builder.pool_id(&self.path.pool_id);
215        // Set query parameters
216        if let Some(val) = &self.query.address {
217            ep_builder.address(val);
218        }
219        if let Some(val) = &self.query.admin_state_up {
220            ep_builder.admin_state_up(*val);
221        }
222        if let Some(val) = &self.query.backup {
223            ep_builder.backup(*val);
224        }
225        if let Some(val) = &self.query.created_at {
226            ep_builder.created_at(val);
227        }
228        if let Some(val) = &self.query.description {
229            ep_builder.description(val);
230        }
231        if let Some(val) = &self.query.id {
232            ep_builder.id(val);
233        }
234        if let Some(val) = &self.query.limit {
235            ep_builder.limit(*val);
236        }
237        if let Some(val) = &self.query.marker {
238            ep_builder.marker(val);
239        }
240        if let Some(val) = &self.query.monitor_address {
241            ep_builder.monitor_address(val);
242        }
243        if let Some(val) = &self.query.monitor_port {
244            ep_builder.monitor_port(val);
245        }
246        if let Some(val) = &self.query.name {
247            ep_builder.name(val);
248        }
249        if let Some(val) = &self.query.not_tags {
250            ep_builder.not_tags(val);
251        }
252        if let Some(val) = &self.query.not_tags_any {
253            ep_builder.not_tags_any(val);
254        }
255        if let Some(val) = &self.query.operating_status {
256            ep_builder.operating_status(val);
257        }
258        if let Some(val) = &self.query.page_reverse {
259            ep_builder.page_reverse(*val);
260        }
261        if let Some(id) = &self.query.project.project_id {
262            // project_id is passed. No need to lookup
263            ep_builder.project_id(id);
264        } else if let Some(name) = &self.query.project.project_name {
265            // project_name is passed. Need to lookup resource
266            let mut sub_find_builder = find_project::Request::builder();
267            warn!(
268                "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."
269            );
270
271            sub_find_builder.id(name);
272            let find_ep = sub_find_builder
273                .build()
274                .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
275            let find_data: serde_json::Value = find_by_name(find_ep).query_async(client).await?;
276            // Try to extract resource id
277            match find_data.get("id") {
278                Some(val) => match val.as_str() {
279                    Some(id_str) => {
280                        ep_builder.project_id(id_str.to_owned());
281                    }
282                    None => {
283                        return Err(OpenStackCliError::ResourceAttributeNotString(
284                            serde_json::to_string(&val)?,
285                        ));
286                    }
287                },
288                None => {
289                    return Err(OpenStackCliError::ResourceAttributeMissing(
290                        "id".to_string(),
291                    ));
292                }
293            };
294        } else if self.query.project.current_project {
295            ep_builder.project_id(
296                client
297                    .get_auth_info()
298                    .ok_or_eyre("Cannot determine current authentication information")?
299                    .token
300                    .user
301                    .id,
302            );
303        }
304        if let Some(val) = &self.query.protocol_port {
305            ep_builder.protocol_port(*val);
306        }
307        if let Some(val) = &self.query.provisioning_status {
308            ep_builder.provisioning_status(val);
309        }
310        if let Some(val) = &self.query.subnet_id {
311            ep_builder.subnet_id(val);
312        }
313        if let Some(val) = &self.query.tags {
314            ep_builder.tags(val);
315        }
316        if let Some(val) = &self.query.tags_any {
317            ep_builder.tags_any(val);
318        }
319        if let Some(val) = &self.query.updated_at {
320            ep_builder.updated_at(val);
321        }
322        if let Some(val) = &self.query.weight {
323            ep_builder.weight(*val);
324        }
325
326        let ep = ep_builder
327            .build()
328            .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
329
330        let data: Vec<serde_json::Value> = paged(ep, Pagination::Limit(self.max_items))
331            .query_async(client)
332            .await?;
333
334        op.output_list::<response::list::MemberResponse>(data.clone())?;
335        // Show command specific hints
336        op.show_command_hint()?;
337        Ok(())
338    }
339}