openstack_cli_load_balancer/v2/pool/member/
list.rs1use 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#[derive(Args)]
51#[command(about = "List Members")]
52pub struct MembersCommand {
53 #[command(flatten)]
55 query: QueryParameters,
56
57 #[command(flatten)]
59 path: PathParameters,
60
61 #[arg(long, default_value_t = 10000)]
63 max_items: usize,
64}
65
66#[derive(Args)]
68struct QueryParameters {
69 #[arg(help_heading = "Query parameters", long)]
71 address: Option<String>,
72
73 #[arg(action=clap::ArgAction::Set, help_heading = "Query parameters", long)]
75 admin_state_up: Option<bool>,
76
77 #[arg(action=clap::ArgAction::Set, help_heading = "Query parameters", long)]
79 backup: Option<bool>,
80
81 #[arg(help_heading = "Query parameters", long)]
83 created_at: Option<String>,
84
85 #[arg(help_heading = "Query parameters", long)]
87 description: Option<String>,
88
89 #[arg(help_heading = "Query parameters", long)]
91 id: Option<String>,
92
93 #[arg(
95 help_heading = "Query parameters",
96 long("page-size"),
97 visible_alias("limit")
98 )]
99 limit: Option<i32>,
100
101 #[arg(help_heading = "Query parameters", long)]
103 marker: Option<String>,
104
105 #[arg(help_heading = "Query parameters", long)]
107 monitor_address: Option<String>,
108
109 #[arg(help_heading = "Query parameters", long)]
111 monitor_port: Option<String>,
112
113 #[arg(help_heading = "Query parameters", long)]
115 name: Option<String>,
116
117 #[arg(help_heading = "Query parameters", long)]
120 not_tags: Option<String>,
121
122 #[arg(help_heading = "Query parameters", long)]
125 not_tags_any: Option<String>,
126
127 #[arg(help_heading = "Query parameters", long, value_parser = ["DEGRADED","DRAINING","ERROR","NO_MONITOR","OFFLINE","ONLINE"])]
129 operating_status: Option<String>,
130
131 #[arg(action=clap::ArgAction::Set, help_heading = "Query parameters", long)]
133 page_reverse: Option<bool>,
134
135 #[command(flatten)]
137 project: ProjectInput,
138
139 #[arg(help_heading = "Query parameters", long)]
141 protocol_port: Option<i32>,
142
143 #[arg(help_heading = "Query parameters", long, value_parser = ["ACTIVE","DELETED","ERROR","PENDING_CREATE","PENDING_DELETE","PENDING_UPDATE"])]
145 provisioning_status: Option<String>,
146
147 #[arg(help_heading = "Query parameters", long)]
149 subnet_id: Option<String>,
150
151 #[arg(help_heading = "Query parameters", long)]
153 tags: Option<String>,
154
155 #[arg(help_heading = "Query parameters", long)]
157 tags_any: Option<String>,
158
159 #[arg(help_heading = "Query parameters", long)]
161 updated_at: Option<String>,
162
163 #[arg(help_heading = "Query parameters", long)]
166 weight: Option<i32>,
167}
168
169#[derive(Args)]
171#[group(required = false, multiple = false)]
172struct ProjectInput {
173 #[arg(long, help_heading = "Path parameters", value_name = "PROJECT_NAME")]
175 project_name: Option<String>,
176 #[arg(long, help_heading = "Path parameters", value_name = "PROJECT_ID")]
178 project_id: Option<String>,
179 #[arg(long, help_heading = "Path parameters", action = clap::ArgAction::SetTrue)]
181 current_project: bool,
182}
183
184#[derive(Args)]
186struct PathParameters {
187 #[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 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 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 ep_builder.project_id(id);
264 } else if let Some(name) = &self.query.project.project_name {
265 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 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 op.show_command_hint()?;
337 Ok(())
338 }
339}