openstack_cli_image/v2/image/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 Images command
19//!
20//! Wraps invoking of the `v2/images` with `GET` method
21
22use clap::Args;
23use tracing::info;
24
25use openstack_cli_core::cli::CliArgs;
26use openstack_cli_core::error::OpenStackCliError;
27use openstack_cli_core::output::OutputProcessor;
28use openstack_sdk::AsyncOpenStack;
29
30use openstack_sdk::api::QueryAsync;
31use openstack_sdk::api::image::v2::image::list;
32use openstack_sdk::api::{Pagination, paged};
33use openstack_types::image::v2::image::response;
34
35/// Lists public virtual machine (VM) images. *(Since Image API v2.0)*
36///
37/// **Pagination**
38///
39/// Returns a subset of the larger collection of images and a link that you can
40/// use to get the next set of images. You should always check for the presence
41/// of a `next` link and use it as the URI in a subsequent HTTP GET request.
42/// You should follow this pattern until a `next` link is no longer provided.
43///
44/// The `next` link preserves any query parameters that you send in your
45/// initial request. You can use the `first` link to jump back to the first
46/// page of the collection. If you prefer to paginate through images manually,
47/// use the `limit` and `marker` parameters.
48///
49/// **Query Filters**
50///
51/// The list operation accepts query parameters to filter the response.
52///
53/// A client can provide direct comparison filters by using most image
54/// attributes, such as `name=Ubuntu`, `visibility=public`, and so on.
55///
56/// To filter using image tags, use the filter `tag` (note the singular). To
57/// filter on multiple tags, include each tag separately in the query. For
58/// example, to find images with the tag **ready**, include `tag=ready` in your
59/// query string. To find images tagged with **ready** and **approved**,
60/// include `tag=ready&tag=approved` in your query string. (Note that only
61/// images containing *both* tags will be included in the response.)
62///
63/// A client cannot use any `link` in the json-schema, such as self, file, or
64/// schema, to filter the response.
65///
66/// You can list VM images that have a status of `active`, `queued`, or
67/// `saving`.
68///
69/// **The** `in` **Operator**
70///
71/// As a convenience, you may specify several values for any of the following
72/// fields by using the `in` operator:
73///
74/// For most of these, usage is straight forward. For example, to list images
75/// in queued or saving status, use:
76///
77/// `GET /v2/images?status=in:saving,queued`
78///
79/// To find images in a particular list of image IDs, use:
80///
81/// `GET /v2/images?id=in:3afb79c1-131a-4c38-a87c-bc4b801d14e6,2e011209-660f-44b5-baf2-2eb4babae53d`
82///
83/// Using the `in` operator with the `name` property of images can be a bit
84/// trickier, depending upon how creatively you have named your images. The
85/// general rule is that if an image name contains a comma (`,`), you must
86/// enclose the entire name in quotation marks (`"`). As usual, you must URL
87/// encode any characters that require it.
88///
89/// For example, to find images named `glass, darkly` or `share me`, you would
90/// use the following filter specification:
91///
92/// `GET v2/images?name=in:"glass,%20darkly",share%20me`
93///
94/// As with regular filtering by name, you must specify the complete name you
95/// are looking for. Thus, for example, the query string `name=in:glass,share`
96/// will only match images with the exact name `glass` or the exact name
97/// `share`. It will not find an image named `glass, darkly` or an image named
98/// `share me`.
99///
100/// **Size Comparison Filters**
101///
102/// You can use the `size_min` and `size_max` query parameters to filter images
103/// that are greater than or less than the image size. The size, in bytes, is
104/// the size of an image on disk.
105///
106/// For example, to filter the container to include only images that are from 1
107/// to 4 MB, set the `size_min` query parameter to `1048576` and the `size_max`
108/// query parameter to `4194304`.
109///
110/// **Time Comparison Filters**
111///
112/// You can use a *comparison operator* along with the `created_at` or
113/// `updated_at` fields to filter your results. Specify the operator first, a
114/// colon (`:`) as a separator, and then the time in
115/// [ISO 8601 Format](https://en.wikipedia.org/wiki/ISO_8601). Available
116/// comparison operators are:
117///
118/// For example:
119///
120/// **Sorting**
121///
122/// You can use query parameters to sort the results of this operation.
123///
124/// To sort the response, use the `sort_key` and `sort_dir` query parameters:
125///
126/// Alternatively, specify the `sort` query parameter:
127///
128/// Normal response codes: 200
129///
130/// Error response codes: 400, 401, 403
131#[derive(Args)]
132#[command(about = "List images")]
133pub struct ImagesCommand {
134 /// Request Query parameters
135 #[command(flatten)]
136 query: QueryParameters,
137
138 /// Path parameters
139 #[command(flatten)]
140 path: PathParameters,
141
142 /// Total limit of entities count to return. Use this when there are too many entries.
143 #[arg(long, default_value_t = 10000)]
144 max_items: usize,
145}
146
147/// Query parameters
148#[derive(Args)]
149struct QueryParameters {
150 /// Specify a comparison filter based on the date and time when the
151 /// resource was created.
152 #[arg(help_heading = "Query parameters", long)]
153 created_at: Option<String>,
154
155 /// id filter parameter
156 #[arg(help_heading = "Query parameters", long)]
157 id: Option<String>,
158
159 /// Requests a page size of items. Returns a number of items up to a limit
160 /// value. Use the limit parameter to make an initial limited request and
161 /// use the ID of the last-seen item from the response as the marker
162 /// parameter value in a subsequent limited request.
163 #[arg(
164 help_heading = "Query parameters",
165 long("page-size"),
166 visible_alias("limit")
167 )]
168 limit: Option<i32>,
169
170 /// The ID of the last-seen item. Use the limit parameter to make an
171 /// initial limited request and use the ID of the last-seen item from the
172 /// response as the marker parameter value in a subsequent limited request.
173 #[arg(help_heading = "Query parameters", long)]
174 marker: Option<String>,
175
176 /// Filters the response by a member status. A valid value is accepted,
177 /// pending, rejected, or all. Default is accepted.
178 #[arg(help_heading = "Query parameters", long, value_parser = ["accepted","all","pending","rejected"])]
179 member_status: Option<String>,
180
181 /// Filters the response by a name, as a string. A valid value is the name
182 /// of an image.
183 #[arg(help_heading = "Query parameters", long)]
184 name: Option<String>,
185
186 /// When true, filters the response to display only "hidden" images. By
187 /// default, "hidden" images are not included in the image-list response.
188 /// (Since Image API v2.7)
189 #[arg(action=clap::ArgAction::Set, help_heading = "Query parameters", long)]
190 os_hidden: Option<bool>,
191
192 /// Filters the response by a project (also called a “tenant”) ID. Shows
193 /// only images that are shared with you by the specified owner.
194 #[arg(help_heading = "Query parameters", long)]
195 owner: Option<String>,
196
197 /// Filters the response by the ‘protected’ image property. A valid value
198 /// is one of ‘true’, ‘false’ (must be all lowercase). Any other value will
199 /// result in a 400 response.
200 #[arg(action=clap::ArgAction::Set, help_heading = "Query parameters", long)]
201 protected: Option<bool>,
202
203 /// Filters the response by a maximum image size, in bytes.
204 #[arg(help_heading = "Query parameters", long)]
205 size_max: Option<String>,
206
207 /// Filters the response by a minimum image size, in bytes.
208 #[arg(help_heading = "Query parameters", long)]
209 size_min: Option<String>,
210
211 /// Sorts the response by one or more attribute and sort direction
212 /// combinations. You can also set multiple sort keys and directions.
213 /// Default direction is desc. Use the comma (,) character to separate
214 /// multiple values. For example: `sort=name:asc,status:desc`
215 #[arg(help_heading = "Query parameters", long)]
216 sort: Option<String>,
217
218 /// Sorts the response by a set of one or more sort direction and attribute
219 /// (sort_key) combinations. A valid value for the sort direction is asc
220 /// (ascending) or desc (descending). If you omit the sort direction in a
221 /// set, the default is desc.
222 #[arg(help_heading = "Query parameters", long, value_parser = ["asc","desc"])]
223 sort_dir: Option<String>,
224
225 /// Sorts the response by an attribute, such as name, id, or updated_at.
226 /// Default is created_at. The API uses the natural sorting direction of
227 /// the sort_key image attribute.
228 #[arg(help_heading = "Query parameters", long)]
229 sort_key: Option<String>,
230
231 /// Filters the response by an image status.
232 #[arg(help_heading = "Query parameters", long)]
233 status: Option<String>,
234
235 /// Filters the response by the specified tag value. May be repeated, but
236 /// keep in mind that you're making a conjunctive query, so only images
237 /// containing all the tags specified will appear in the response.
238 #[arg(action=clap::ArgAction::Append, help_heading = "Query parameters", long)]
239 tag: Option<Vec<String>>,
240
241 /// Specify a comparison filter based on the date and time when the
242 /// resource was most recently modified.
243 #[arg(help_heading = "Query parameters", long)]
244 updated_at: Option<String>,
245
246 /// Filters the response by an image visibility value. A valid value is
247 /// public, private, community, shared, or all. (Note that if you filter on
248 /// shared, the images included in the response will only be those where
249 /// your member status is accepted unless you explicitly include a
250 /// member_status filter in the request.) If you omit this parameter, the
251 /// response shows public, private, and those shared images with a member
252 /// status of accepted.
253 #[arg(help_heading = "Query parameters", long, value_parser = ["all","community","private","public","shared"])]
254 visibility: Option<String>,
255}
256
257/// Path parameters
258#[derive(Args)]
259struct PathParameters {}
260
261impl ImagesCommand {
262 /// Perform command action
263 pub async fn take_action<C: CliArgs>(
264 &self,
265 parsed_args: &C,
266 client: &mut AsyncOpenStack,
267 ) -> Result<(), OpenStackCliError> {
268 info!("List Images");
269
270 let op = OutputProcessor::from_args(parsed_args, Some("image.image"), Some("list"));
271 op.validate_args(parsed_args)?;
272
273 let mut ep_builder = list::Request::builder();
274
275 // Set query parameters
276 if let Some(val) = &self.query.created_at {
277 ep_builder.created_at(val);
278 }
279 if let Some(val) = &self.query.id {
280 ep_builder.id(val);
281 }
282 if let Some(val) = &self.query.limit {
283 ep_builder.limit(*val);
284 }
285 if let Some(val) = &self.query.marker {
286 ep_builder.marker(val);
287 }
288 if let Some(val) = &self.query.member_status {
289 ep_builder.member_status(val);
290 }
291 if let Some(val) = &self.query.name {
292 ep_builder.name(val);
293 }
294 if let Some(val) = &self.query.os_hidden {
295 ep_builder.os_hidden(*val);
296 }
297 if let Some(val) = &self.query.owner {
298 ep_builder.owner(val);
299 }
300 if let Some(val) = &self.query.protected {
301 ep_builder.protected(*val);
302 }
303 if let Some(val) = &self.query.size_max {
304 ep_builder.size_max(val);
305 }
306 if let Some(val) = &self.query.size_min {
307 ep_builder.size_min(val);
308 }
309 if let Some(val) = &self.query.sort {
310 ep_builder.sort(val);
311 }
312 if let Some(val) = &self.query.sort_dir {
313 ep_builder.sort_dir(val);
314 }
315 if let Some(val) = &self.query.sort_key {
316 ep_builder.sort_key(val);
317 }
318 if let Some(val) = &self.query.status {
319 ep_builder.status(val);
320 }
321 if let Some(val) = &self.query.tag {
322 ep_builder.tag(val.iter());
323 }
324 if let Some(val) = &self.query.updated_at {
325 ep_builder.updated_at(val);
326 }
327 if let Some(val) = &self.query.visibility {
328 ep_builder.visibility(val);
329 }
330
331 let ep = ep_builder
332 .build()
333 .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?;
334
335 let data: Vec<serde_json::Value> = paged(ep, Pagination::Limit(self.max_items))
336 .query_async(client)
337 .await?;
338
339 op.output_list::<response::list::ImageResponse>(data.clone())?;
340 // Show command specific hints
341 op.show_command_hint()?;
342 Ok(())
343 }
344}