openstack_cli_load_balancer/v2/pool/
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::list;
35use openstack_sdk::api::{Pagination, paged};
36use openstack_types::load_balancer::v2::pool::response;
37use tracing::warn;
38
39#[derive(Args)]
51#[command(about = "List Pools")]
52pub struct PoolsCommand {
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(action=clap::ArgAction::Set, help_heading = "Query parameters", long)]
71 admin_state_up: Option<bool>,
72
73 #[arg(help_heading = "Query parameters", long)]
75 alpn_protocols: Option<String>,
76
77 #[arg(help_heading = "Query parameters", long)]
79 created_at: Option<String>,
80
81 #[arg(help_heading = "Query parameters", long)]
83 description: Option<String>,
84
85 #[arg(help_heading = "Query parameters", long)]
87 id: Option<String>,
88
89 #[arg(
91 help_heading = "Query parameters",
92 long("page-size"),
93 visible_alias("limit")
94 )]
95 limit: Option<i32>,
96
97 #[arg(help_heading = "Query parameters", long)]
99 loadbalancer_id: Option<String>,
100
101 #[arg(help_heading = "Query parameters", long)]
103 marker: Option<String>,
104
105 #[arg(help_heading = "Query parameters", long)]
107 name: Option<String>,
108
109 #[arg(help_heading = "Query parameters", long)]
112 not_tags: Option<String>,
113
114 #[arg(help_heading = "Query parameters", long)]
117 not_tags_any: Option<String>,
118
119 #[arg(help_heading = "Query parameters", long, value_parser = ["DEGRADED","DRAINING","ERROR","NO_MONITOR","OFFLINE","ONLINE"])]
121 operating_status: Option<String>,
122
123 #[arg(action=clap::ArgAction::Set, help_heading = "Query parameters", long)]
125 page_reverse: Option<bool>,
126
127 #[command(flatten)]
129 project: ProjectInput,
130
131 #[arg(help_heading = "Query parameters", long, value_parser = ["ACTIVE","DELETED","ERROR","PENDING_CREATE","PENDING_DELETE","PENDING_UPDATE"])]
133 provisioning_status: Option<String>,
134
135 #[arg(help_heading = "Query parameters", long)]
137 tags: Option<String>,
138
139 #[arg(help_heading = "Query parameters", long)]
141 tags_any: Option<String>,
142
143 #[arg(help_heading = "Query parameters", long)]
145 tls_ciphers: Option<String>,
146
147 #[arg(action=clap::ArgAction::Set, help_heading = "Query parameters", long)]
148 tls_enabled: Option<bool>,
149
150 #[arg(help_heading = "Query parameters", long)]
152 tls_versions: Option<String>,
153
154 #[arg(help_heading = "Query parameters", long)]
156 updated_at: Option<String>,
157}
158
159#[derive(Args)]
161#[group(required = false, multiple = false)]
162struct ProjectInput {
163 #[arg(long, help_heading = "Path parameters", value_name = "PROJECT_NAME")]
165 project_name: Option<String>,
166 #[arg(long, help_heading = "Path parameters", value_name = "PROJECT_ID")]
168 project_id: Option<String>,
169 #[arg(long, help_heading = "Path parameters", action = clap::ArgAction::SetTrue)]
171 current_project: bool,
172}
173
174#[derive(Args)]
176struct PathParameters {}
177
178impl PoolsCommand {
179 pub async fn take_action<C: CliArgs>(
181 &self,
182 parsed_args: &C,
183 client: &mut AsyncOpenStack,
184 ) -> Result<(), OpenStackCliError> {
185 info!("List Pools");
186
187 let op = OutputProcessor::from_args(parsed_args, Some("load-balancer.pool"), Some("list"));
188 op.validate_args(parsed_args)?;
189
190 let mut ep_builder = list::Request::builder();
191
192 if let Some(val) = &self.query.admin_state_up {
194 ep_builder.admin_state_up(*val);
195 }
196 if let Some(val) = &self.query.alpn_protocols {
197 ep_builder.alpn_protocols(val);
198 }
199 if let Some(val) = &self.query.created_at {
200 ep_builder.created_at(val);
201 }
202 if let Some(val) = &self.query.description {
203 ep_builder.description(val);
204 }
205 if let Some(val) = &self.query.id {
206 ep_builder.id(val);
207 }
208 if let Some(val) = &self.query.limit {
209 ep_builder.limit(*val);
210 }
211 if let Some(val) = &self.query.loadbalancer_id {
212 ep_builder.loadbalancer_id(val);
213 }
214 if let Some(val) = &self.query.marker {
215 ep_builder.marker(val);
216 }
217 if let Some(val) = &self.query.name {
218 ep_builder.name(val);
219 }
220 if let Some(val) = &self.query.not_tags {
221 ep_builder.not_tags(val);
222 }
223 if let Some(val) = &self.query.not_tags_any {
224 ep_builder.not_tags_any(val);
225 }
226 if let Some(val) = &self.query.operating_status {
227 ep_builder.operating_status(val);
228 }
229 if let Some(val) = &self.query.page_reverse {
230 ep_builder.page_reverse(*val);
231 }
232 if let Some(id) = &self.query.project.project_id {
233 ep_builder.project_id(id);
235 } else if let Some(name) = &self.query.project.project_name {
236 let mut sub_find_builder = find_project::Request::builder();
238 warn!(
239 "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."
240 );
241
242 sub_find_builder.id(name);
243 let find_ep = sub_find_builder
244 .build()
245 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
246 let find_data: serde_json::Value = find_by_name(find_ep).query_async(client).await?;
247 match find_data.get("id") {
249 Some(val) => match val.as_str() {
250 Some(id_str) => {
251 ep_builder.project_id(id_str.to_owned());
252 }
253 None => {
254 return Err(OpenStackCliError::ResourceAttributeNotString(
255 serde_json::to_string(&val)?,
256 ));
257 }
258 },
259 None => {
260 return Err(OpenStackCliError::ResourceAttributeMissing(
261 "id".to_string(),
262 ));
263 }
264 };
265 } else if self.query.project.current_project {
266 ep_builder.project_id(
267 client
268 .get_auth_info()
269 .ok_or_eyre("Cannot determine current authentication information")?
270 .token
271 .user
272 .id,
273 );
274 }
275 if let Some(val) = &self.query.provisioning_status {
276 ep_builder.provisioning_status(val);
277 }
278 if let Some(val) = &self.query.tags {
279 ep_builder.tags(val);
280 }
281 if let Some(val) = &self.query.tags_any {
282 ep_builder.tags_any(val);
283 }
284 if let Some(val) = &self.query.tls_ciphers {
285 ep_builder.tls_ciphers(val);
286 }
287 if let Some(val) = &self.query.tls_enabled {
288 ep_builder.tls_enabled(*val);
289 }
290 if let Some(val) = &self.query.tls_versions {
291 ep_builder.tls_versions(val);
292 }
293 if let Some(val) = &self.query.updated_at {
294 ep_builder.updated_at(val);
295 }
296
297 let ep = ep_builder
298 .build()
299 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
300
301 let data: Vec<serde_json::Value> = paged(ep, Pagination::Limit(self.max_items))
302 .query_async(client)
303 .await?;
304
305 op.output_list::<response::list::PoolResponse>(data.clone())?;
306 op.show_command_hint()?;
308 Ok(())
309 }
310}