Skip to main content

openstack_cli_placement/v1/usage/
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 Usages command
19//!
20//! Wraps invoking of the `usages` 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::identity::v3::user::find as find_user;
35use openstack_sdk::api::placement::v1::usage::list;
36use openstack_types::placement::v1::usage::response;
37use tracing::warn;
38
39/// Return a report of usage information for resources associated with the
40/// project identified by project_id and user identified by user_id. The value
41/// is a dictionary of resource classes paired with the sum of the allocations
42/// of that resource class for provided parameters.
43///
44/// Normal Response Codes: 200
45///
46/// Error response codes: badRequest(400)
47#[derive(Args)]
48#[command(about = "List usages")]
49pub struct UsagesCommand {
50    /// Request Query parameters
51    #[command(flatten)]
52    query: QueryParameters,
53
54    /// Path parameters
55    #[command(flatten)]
56    path: PathParameters,
57}
58
59/// Query parameters
60#[derive(Args)]
61struct QueryParameters {
62    /// A string that consists of numbers, A-Z, and _ describing the consumer
63    /// type by which to filter usage results. For example, to retrieve only
64    /// usage information for ‘INSTANCE’ type consumers a parameter of
65    /// consumer_type=INSTANCE should be provided. The all query parameter may
66    /// be specified to group all results under one key, all. The unknown query
67    /// parameter may be specified to group all results under one key, unknown.
68    #[arg(help_heading = "Query parameters", long)]
69    consumer_type: Option<String>,
70
71    /// Project resource for which the operation should be performed.
72    #[command(flatten)]
73    project: ProjectInput,
74
75    /// User resource for which the operation should be performed.
76    #[command(flatten)]
77    user: UserInput,
78}
79
80/// Project input select group
81#[derive(Args)]
82#[group(required = true, multiple = false)]
83struct ProjectInput {
84    /// Project Name.
85    #[arg(long, help_heading = "Path parameters", value_name = "PROJECT_NAME")]
86    project_name: Option<String>,
87    /// Project ID.
88    #[arg(long, help_heading = "Path parameters", value_name = "PROJECT_ID")]
89    project_id: Option<String>,
90    /// Current project.
91    #[arg(long, help_heading = "Path parameters", action = clap::ArgAction::SetTrue)]
92    current_project: bool,
93}
94
95/// User input select group
96#[derive(Args)]
97#[group(required = false, multiple = false)]
98struct UserInput {
99    /// User Name.
100    #[arg(long, help_heading = "Path parameters", value_name = "USER_NAME")]
101    user_name: Option<String>,
102    /// User ID.
103    #[arg(long, help_heading = "Path parameters", value_name = "USER_ID")]
104    user_id: Option<String>,
105    /// Current authenticated user.
106    #[arg(long, help_heading = "Path parameters", action = clap::ArgAction::SetTrue)]
107    current_user: bool,
108}
109
110/// Path parameters
111#[derive(Args)]
112struct PathParameters {}
113
114impl UsagesCommand {
115    /// Perform command action
116    pub async fn take_action<C: CliArgs>(
117        &self,
118        parsed_args: &C,
119        client: &mut AsyncOpenStack,
120    ) -> Result<(), OpenStackCliError> {
121        info!("List Usages");
122
123        let op = OutputProcessor::from_args(parsed_args, Some("placement.usage"), Some("list"));
124        op.validate_args(parsed_args)?;
125
126        let mut ep_builder = list::Request::builder();
127
128        // Set query parameters
129        if let Some(val) = &self.query.consumer_type {
130            ep_builder.consumer_type(val);
131        }
132        if let Some(id) = &self.query.project.project_id {
133            // project_id is passed. No need to lookup
134            ep_builder.project_id(id);
135        } else if let Some(name) = &self.query.project.project_name {
136            // project_name is passed. Need to lookup resource
137            let mut sub_find_builder = find_project::Request::builder();
138            warn!(
139                "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."
140            );
141
142            sub_find_builder.id(name);
143            let find_ep = sub_find_builder
144                .build()
145                .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
146            let find_data: serde_json::Value = find_by_name(find_ep).query_async(client).await?;
147            // Try to extract resource id
148            match find_data.get("id") {
149                Some(val) => match val.as_str() {
150                    Some(id_str) => {
151                        ep_builder.project_id(id_str.to_owned());
152                    }
153                    None => {
154                        return Err(OpenStackCliError::ResourceAttributeNotString(
155                            serde_json::to_string(&val)?,
156                        ));
157                    }
158                },
159                None => {
160                    return Err(OpenStackCliError::ResourceAttributeMissing(
161                        "id".to_string(),
162                    ));
163                }
164            };
165        } else if self.query.project.current_project {
166            ep_builder.project_id(
167                client
168                    .get_auth_info()
169                    .ok_or_eyre("Cannot determine current authentication information")?
170                    .token
171                    .user
172                    .id,
173            );
174        }
175        if let Some(id) = &self.query.user.user_id {
176            // user_id is passed. No need to lookup
177            ep_builder.user_id(id);
178        } else if let Some(name) = &self.query.user.user_name {
179            // user_name is passed. Need to lookup resource
180            let mut sub_find_builder = find_user::Request::builder();
181            warn!(
182                "Querying user by name (because of `--user-name` parameter passed) may not be definite. This may fail in which case parameter `--user-id` should be used instead."
183            );
184
185            sub_find_builder.id(name);
186            let find_ep = sub_find_builder
187                .build()
188                .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
189            let find_data: serde_json::Value = find_by_name(find_ep).query_async(client).await?;
190            // Try to extract resource id
191            match find_data.get("id") {
192                Some(val) => match val.as_str() {
193                    Some(id_str) => {
194                        ep_builder.user_id(id_str.to_owned());
195                    }
196                    None => {
197                        return Err(OpenStackCliError::ResourceAttributeNotString(
198                            serde_json::to_string(&val)?,
199                        ));
200                    }
201                },
202                None => {
203                    return Err(OpenStackCliError::ResourceAttributeMissing(
204                        "id".to_string(),
205                    ));
206                }
207            };
208        } else if self.query.user.current_user {
209            ep_builder.user_id(
210                client
211                    .get_auth_info()
212                    .ok_or_eyre("Cannot determine current authentication information")?
213                    .token
214                    .user
215                    .id,
216            );
217        }
218
219        let ep = ep_builder
220            .build()
221            .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
222
223        let data: Vec<serde_json::Value> = ep.query_async(client).await?;
224
225        op.output_list::<response::list::UsageResponse>(data.clone())?;
226        // Show command specific hints
227        op.show_command_hint()?;
228        Ok(())
229    }
230}