From f8b5e51e393a1569d52d2ceb2d6e52a140be34e5 Mon Sep 17 00:00:00 2001 From: OpenStack codegenerator <16461884+gtema@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:58:40 +0000 Subject: [PATCH] feat: Regenerate identity.project identity.project schema is now coming directly from Keystone code. Change-Id: Ice429170933c762568cb494fb7871f28cd78662d Changes are triggered by https://review.opendev.org/931671 --- .../src/identity/v3/credential/create.rs | 2 +- .../src/identity/v3/credential/set.rs | 2 +- .../src/identity/v3/credential/show.rs | 2 +- .../src/identity/v3/project/create.rs | 58 ++++++--- openstack_cli/src/identity/v3/project/list.rs | 117 ++++++++++++++---- openstack_cli/src/identity/v3/project/set.rs | 76 +++--------- openstack_cli/src/identity/v3/project/show.rs | 14 ++- .../src/identity/v3/project/tag/replace.rs | 8 ++ .../src/identity/v3/project/tag/set.rs | 33 ++--- .../src/identity/v3/user/access_rule/list.rs | 42 +++---- .../src/identity/v3/user/access_rule/show.rs | 37 +++--- .../src/api/identity/v3/project/create.rs | 72 ++++++----- .../src/api/identity/v3/project/head.rs | 56 +++++++-- .../src/api/identity/v3/project/list.rs | 31 ++--- .../src/api/identity/v3/project/set.rs | 69 +---------- .../api/identity/v3/project/tag/replace.rs | 33 ++++- .../api/identity/v3/user/access_rule/get.rs | 11 +- .../api/identity/v3/user/access_rule/list.rs | 11 +- 18 files changed, 369 insertions(+), 305 deletions(-) diff --git a/openstack_cli/src/identity/v3/credential/create.rs b/openstack_cli/src/identity/v3/credential/create.rs index d7b2831ee..609e6313a 100644 --- a/openstack_cli/src/identity/v3/credential/create.rs +++ b/openstack_cli/src/identity/v3/credential/create.rs @@ -116,7 +116,7 @@ struct ResponseData { #[structable(optional)] id: Option, - /// The links for the `credential` resource. + /// The link to the resources in question. /// #[serde()] #[structable(optional, pretty)] diff --git a/openstack_cli/src/identity/v3/credential/set.rs b/openstack_cli/src/identity/v3/credential/set.rs index 455581f6c..8457b86bd 100644 --- a/openstack_cli/src/identity/v3/credential/set.rs +++ b/openstack_cli/src/identity/v3/credential/set.rs @@ -114,7 +114,7 @@ struct ResponseData { #[structable(optional)] id: Option, - /// The links for the `credential` resource. + /// The link to the resources in question. /// #[serde()] #[structable(optional, pretty)] diff --git a/openstack_cli/src/identity/v3/credential/show.rs b/openstack_cli/src/identity/v3/credential/show.rs index 7557e7d81..7827d1755 100644 --- a/openstack_cli/src/identity/v3/credential/show.rs +++ b/openstack_cli/src/identity/v3/credential/show.rs @@ -84,7 +84,7 @@ struct ResponseData { #[structable(optional)] id: Option, - /// The links for the `credential` resource. + /// The link to the resources in question. /// #[serde()] #[structable(optional, pretty)] diff --git a/openstack_cli/src/identity/v3/project/create.rs b/openstack_cli/src/identity/v3/project/create.rs index f44a352fa..42b796979 100644 --- a/openstack_cli/src/identity/v3/project/create.rs +++ b/openstack_cli/src/identity/v3/project/create.rs @@ -83,25 +83,37 @@ struct Project { /// The ID of the domain for the project. /// + /// For projects acting as a domain, the `domain_id` must not be specified, + /// it will be generated by the Identity service implementation. + /// + /// For regular projects (i.e. those not acing as a domain), if `domain_id` + /// is not specified, but `parent_id` is specified, then the domain ID of + /// the parent will be used. If neither `domain_id` or `parent_id` is + /// specified, the Identity service implementation will default to the + /// domain to which the client’s token is scoped. If both `domain_id` and + /// `parent_id` are specified, and they do not indicate the same domain, an + /// `Bad Request (400)` will be returned. + /// #[arg(help_heading = "Body parameters", long)] domain_id: Option, - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. + /// If set to `true`, project is enabled. If set to `false`, project is + /// disabled. The default is `true`. /// #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)] enabled: Option, - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. + /// If set to `true`, project is enabled. If set to `false`, project is + /// disabled. The default is `true`. /// #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)] is_domain: Option, - /// The name of the project. + /// The name of the project, which must be unique within the owning domain. + /// A project can have the same name as its domain. /// #[arg(help_heading = "Body parameters", long)] - name: Option, + name: String, /// The resource options for the project. Available resource options are /// `immutable`. @@ -109,14 +121,26 @@ struct Project { #[command(flatten)] options: Option, - /// The ID of the parent for the project. + /// The ID of the parent of the project. + /// + /// If specified on project creation, this places the project within a + /// hierarchy and implicitly defines the owning domain, which will be the + /// same domain as the parent specified. If `parent_id` is not specified + /// and `is_domain` is `false`, then the project will use its owning domain + /// as its parent. If `is_domain` is `true` (i.e. the project is acting as + /// a domain), then `parent_id` must not specified (or if it is, it must be + /// `null`) since domains have no parents. + /// + /// `parent_id` is immutable, and can’t be updated after the project is + /// created - hence a project cannot be moved within the hierarchy. /// /// **New in version 3.4** /// #[arg(help_heading = "Body parameters", long)] parent_id: Option, - /// A list of simple strings assigned to a project. + /// A list of simple strings assigned to a project. Tags can be used to + /// classify projects into groups. /// #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long)] tags: Option>, @@ -137,8 +161,8 @@ struct ResponseData { #[structable(optional)] domain_id: Option, - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. + /// If set to `true`, project is enabled. If set to `false`, project is + /// disabled. /// #[serde()] #[structable(optional)] @@ -150,13 +174,19 @@ struct ResponseData { #[structable(optional)] id: Option, - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. + /// If set to `true`, project is enabled. If set to `false`, project is + /// disabled. /// #[serde()] #[structable(optional)] is_domain: Option, + /// The link to the resources in question. + /// + #[serde()] + #[structable(optional, pretty)] + links: Option, + /// The name of the project. /// #[serde()] @@ -225,9 +255,7 @@ impl ProjectCommand { project_builder.parent_id(Some(val.into())); } - if let Some(val) = &args.name { - project_builder.name(val); - } + project_builder.name(&args.name); if let Some(val) = &args.tags { project_builder.tags(val.iter().map(Into::into).collect::>()); diff --git a/openstack_cli/src/identity/v3/project/list.rs b/openstack_cli/src/identity/v3/project/list.rs index b8bfd69bc..f74b56c92 100644 --- a/openstack_cli/src/identity/v3/project/list.rs +++ b/openstack_cli/src/identity/v3/project/list.rs @@ -31,10 +31,14 @@ use crate::OpenStackCliError; use crate::OutputConfig; use crate::StructTable; +use eyre::OptionExt; +use openstack_sdk::api::find_by_name; +use openstack_sdk::api::identity::v3::domain::find as find_domain; use openstack_sdk::api::identity::v3::project::list; use openstack_sdk::api::QueryAsync; use serde_json::Value; use structable_derive::StructTable; +use tracing::warn; /// Lists projects. /// @@ -56,33 +60,48 @@ pub struct ProjectsCommand { /// Query parameters #[derive(Args)] struct QueryParameters { - /// Filters the response by a domain ID. - /// - #[arg(help_heading = "Query parameters", long)] - domain_id: Option, + /// Domain resource for which the operation should be performed. + #[command(flatten)] + domain: DomainInput, - /// If set to true, then only enabled projects will be returned. Any value - /// other than 0 (including no value) will be interpreted as true. - /// #[arg(action=clap::ArgAction::Set, help_heading = "Query parameters", long)] enabled: Option, - /// If this is specified as true, then only projects acting as a domain are - /// included. Otherwise, only projects that are not acting as a domain are - /// included. - /// #[arg(action=clap::ArgAction::Set, help_heading = "Query parameters", long)] is_domain: Option, - /// Filters the response by a resource name. - /// #[arg(help_heading = "Query parameters", long)] name: Option, - /// Filters the response by a parent ID. - /// + #[arg(help_heading = "Query parameters", long)] + not_tags: Option, + + #[arg(help_heading = "Query parameters", long)] + not_tags_any: Option, + #[arg(help_heading = "Query parameters", long)] parent_id: Option, + + #[arg(help_heading = "Query parameters", long)] + tags: Option, + + #[arg(help_heading = "Query parameters", long)] + tags_any: Option, +} + +/// Domain input select group +#[derive(Args)] +#[group(required = false, multiple = false)] +struct DomainInput { + /// Domain Name. + #[arg(long, help_heading = "Path parameters", value_name = "DOMAIN_NAME")] + domain_name: Option, + /// Domain ID. + #[arg(long, help_heading = "Path parameters", value_name = "DOMAIN_ID")] + domain_id: Option, + /// Current domain. + #[arg(long, help_heading = "Path parameters", action = clap::ArgAction::SetTrue)] + current_domain: bool, } /// Path parameters @@ -103,8 +122,8 @@ struct ResponseData { #[structable(optional, wide)] domain_id: Option, - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. + /// If set to `true`, project is enabled. If set to `false`, project is + /// disabled. /// #[serde()] #[structable(optional, wide)] @@ -116,8 +135,8 @@ struct ResponseData { #[structable(optional)] id: Option, - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. + /// If set to `true`, project is enabled. If set to `false`, project is + /// disabled. /// #[serde()] #[structable(optional, wide)] @@ -167,21 +186,71 @@ impl ProjectsCommand { // Set path parameters // Set query parameters - if let Some(val) = &self.query.domain_id { - ep_builder.domain_id(val); + if let Some(id) = &self.query.domain.domain_id { + // domain_id is passed. No need to lookup + ep_builder.domain_id(id); + } else if let Some(name) = &self.query.domain.domain_name { + // domain_name is passed. Need to lookup resource + let mut sub_find_builder = find_domain::Request::builder(); + warn!("Querying domain by name (because of `--domain-name` parameter passed) may not be definite. This may fail in which case parameter `--domain-id` should be used instead."); + + sub_find_builder.id(name); + let find_ep = sub_find_builder + .build() + .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?; + let find_data: serde_json::Value = find_by_name(find_ep).query_async(client).await?; + // Try to extract resource id + match find_data.get("id") { + Some(val) => match val.as_str() { + Some(id_str) => { + ep_builder.domain_id(id_str.to_owned()); + } + None => { + return Err(OpenStackCliError::ResourceAttributeNotString( + serde_json::to_string(&val)?, + )) + } + }, + None => { + return Err(OpenStackCliError::ResourceAttributeMissing( + "id".to_string(), + )) + } + }; + } else if self.query.domain.current_domain { + ep_builder.domain_id( + client + .get_auth_info() + .ok_or_eyre("Cannot determine current authentication information")? + .token + .user + .id, + ); } if let Some(val) = &self.query.enabled { ep_builder.enabled(*val); } - if let Some(val) = &self.query.is_domain { - ep_builder.is_domain(*val); - } if let Some(val) = &self.query.name { ep_builder.name(val); } if let Some(val) = &self.query.parent_id { ep_builder.parent_id(val); } + if let Some(val) = &self.query.is_domain { + ep_builder.is_domain(*val); + } + if let Some(val) = &self.query.tags { + ep_builder.tags(val); + } + if let Some(val) = &self.query.tags_any { + ep_builder.tags_any(val); + } + if let Some(val) = &self.query.not_tags { + ep_builder.not_tags(val); + } + if let Some(val) = &self.query.not_tags_any { + ep_builder.not_tags_any(val); + } // Set body parameters let ep = ep_builder diff --git a/openstack_cli/src/identity/v3/project/set.rs b/openstack_cli/src/identity/v3/project/set.rs index 33dfac51c..64a364bc4 100644 --- a/openstack_cli/src/identity/v3/project/set.rs +++ b/openstack_cli/src/identity/v3/project/set.rs @@ -76,14 +76,6 @@ struct PathParameters { )] id: String, } -/// Options Body data -#[derive(Args, Clone)] -#[group(required = false, multiple = true)] -struct Options { - #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)] - immutable: Option, -} - /// Project Body data #[derive(Args, Clone)] struct Project { @@ -92,42 +84,20 @@ struct Project { #[arg(help_heading = "Body parameters", long)] description: Option, - /// The ID of the domain for the project. - /// - #[arg(help_heading = "Body parameters", long)] - domain_id: Option, - - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. + /// If set to `true`, project is enabled. If set to `false`, project is + /// disabled. /// #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)] enabled: Option, - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. - /// - #[arg(action=clap::ArgAction::Set, help_heading = "Body parameters", long)] - is_domain: Option, - - /// The name of the project. + /// The name of the project, which must be unique within the owning domain. + /// A project can have the same name as its domain. /// #[arg(help_heading = "Body parameters", long)] name: Option, - /// The resource options for the project. Available resource options are - /// `immutable`. - /// - #[command(flatten)] - options: Option, - - /// The ID of the parent for the project. - /// - /// **New in version 3.4** - /// - #[arg(help_heading = "Body parameters", long)] - parent_id: Option, - - /// A list of simple strings assigned to a project. + /// A list of simple strings assigned to a project. Tags can be used to + /// classify projects into groups. /// #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long)] tags: Option>, @@ -148,8 +118,8 @@ struct ResponseData { #[structable(optional)] domain_id: Option, - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. + /// If set to `true`, project is enabled. If set to `false`, project is + /// disabled. /// #[serde()] #[structable(optional)] @@ -161,13 +131,19 @@ struct ResponseData { #[structable(optional)] id: Option, - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. + /// If set to `true`, project is enabled. If set to `false`, project is + /// disabled. /// #[serde()] #[structable(optional)] is_domain: Option, + /// The link to the resources in question. + /// + #[serde()] + #[structable(optional, pretty)] + links: Option, + /// The name of the project. /// #[serde()] @@ -233,22 +209,10 @@ impl ProjectCommand { project_builder.description(Some(val.into())); } - if let Some(val) = &args.domain_id { - project_builder.domain_id(Some(val.into())); - } - if let Some(val) = &args.enabled { project_builder.enabled(*val); } - if let Some(val) = &args.is_domain { - project_builder.is_domain(*val); - } - - if let Some(val) = &args.parent_id { - project_builder.parent_id(Some(val.into())); - } - if let Some(val) = &args.name { project_builder.name(val); } @@ -257,14 +221,6 @@ impl ProjectCommand { project_builder.tags(val.iter().map(Into::into).collect::>()); } - if let Some(val) = &args.options { - let mut options_builder = set::OptionsBuilder::default(); - if let Some(val) = &val.immutable { - options_builder.immutable(*val); - } - project_builder.options(options_builder.build().expect("A valid object")); - } - ep_builder.project(project_builder.build().unwrap()); let ep = ep_builder diff --git a/openstack_cli/src/identity/v3/project/show.rs b/openstack_cli/src/identity/v3/project/show.rs index e7303d3a9..d0b724a1b 100644 --- a/openstack_cli/src/identity/v3/project/show.rs +++ b/openstack_cli/src/identity/v3/project/show.rs @@ -85,8 +85,8 @@ struct ResponseData { #[structable(optional)] domain_id: Option, - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. + /// If set to `true`, project is enabled. If set to `false`, project is + /// disabled. /// #[serde()] #[structable(optional)] @@ -98,13 +98,19 @@ struct ResponseData { #[structable(optional)] id: Option, - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. + /// If set to `true`, project is enabled. If set to `false`, project is + /// disabled. /// #[serde()] #[structable(optional)] is_domain: Option, + /// The link to the resources in question. + /// + #[serde()] + #[structable(optional, pretty)] + links: Option, + /// The name of the project. /// #[serde()] diff --git a/openstack_cli/src/identity/v3/project/tag/replace.rs b/openstack_cli/src/identity/v3/project/tag/replace.rs index 60500ef2e..19682fbda 100644 --- a/openstack_cli/src/identity/v3/project/tag/replace.rs +++ b/openstack_cli/src/identity/v3/project/tag/replace.rs @@ -50,6 +50,11 @@ pub struct TagCommand { /// Path parameters #[command(flatten)] path: PathParameters, + + /// A list of simple strings assigned to a project. + /// + #[arg(action=clap::ArgAction::Append, help_heading = "Body parameters", long)] + tags: Vec, } /// Query parameters @@ -110,6 +115,9 @@ impl TagCommand { ep_builder.project_id(&self.path.project_id); // Set query parameters // Set body parameters + // Set Request.tags data + + ep_builder.tags(self.tags.iter().map(Into::into).collect::>()); let ep = ep_builder .build() diff --git a/openstack_cli/src/identity/v3/project/tag/set.rs b/openstack_cli/src/identity/v3/project/tag/set.rs index ee283e037..479cb9188 100644 --- a/openstack_cli/src/identity/v3/project/tag/set.rs +++ b/openstack_cli/src/identity/v3/project/tag/set.rs @@ -31,10 +31,11 @@ use crate::OpenStackCliError; use crate::OutputConfig; use crate::StructTable; +use bytes::Bytes; +use http::Response; use openstack_sdk::api::identity::v3::project::tag::set; -use openstack_sdk::api::QueryAsync; -use serde_json::Value; -use std::collections::HashMap; +use openstack_sdk::api::RawQueryAsync; +use structable_derive::StructTable; /// Creates the specified tag and adds it to the list of tags in the project. /// @@ -78,23 +79,9 @@ struct PathParameters { )] value: String, } -/// Response data as HashMap type -#[derive(Deserialize, Serialize)] -struct ResponseData(HashMap); - -impl StructTable for ResponseData { - fn build(&self, _options: &OutputConfig) -> (Vec, Vec>) { - let headers: Vec = Vec::from(["Name".to_string(), "Value".to_string()]); - let mut rows: Vec> = Vec::new(); - rows.extend(self.0.iter().map(|(k, v)| { - Vec::from([ - k.clone(), - serde_json::to_string(&v).expect("Is a valid data"), - ]) - })); - (headers, rows) - } -} +/// Tag response representation +#[derive(Deserialize, Serialize, Clone, StructTable)] +struct ResponseData {} impl TagCommand { /// Perform command action @@ -120,8 +107,10 @@ impl TagCommand { .build() .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?; - let data = ep.query_async(client).await?; - op.output_single::(data)?; + let _rsp: Response = ep.raw_query_async(client).await?; + let data = ResponseData {}; + // Maybe output some headers metadata + op.output_human::(&data)?; Ok(()) } } diff --git a/openstack_cli/src/identity/v3/user/access_rule/list.rs b/openstack_cli/src/identity/v3/user/access_rule/list.rs index 334bae360..d0a6b0d51 100644 --- a/openstack_cli/src/identity/v3/user/access_rule/list.rs +++ b/openstack_cli/src/identity/v3/user/access_rule/list.rs @@ -36,7 +36,8 @@ use openstack_sdk::api::find_by_name; use openstack_sdk::api::identity::v3::user::access_rule::list; use openstack_sdk::api::identity::v3::user::find as find_user; use openstack_sdk::api::QueryAsync; -use structable_derive::StructTable; +use serde_json::Value; +use std::collections::HashMap; use tracing::warn; /// List all access rules for a user. @@ -82,24 +83,22 @@ struct UserInput { #[arg(long, help_heading = "Path parameters", action = clap::ArgAction::SetTrue)] current_user: bool, } -/// AccessRules response representation -#[derive(Deserialize, Serialize, Clone, StructTable)] -struct ResponseData { - #[serde()] - #[structable(optional)] - id: Option, - - #[serde()] - #[structable(optional, wide)] - method: Option, - - #[serde()] - #[structable(optional, wide)] - path: Option, - - #[serde()] - #[structable(optional, wide)] - service: Option, +/// Response data as HashMap type +#[derive(Deserialize, Serialize)] +struct ResponseData(HashMap); + +impl StructTable for ResponseData { + fn build(&self, _options: &OutputConfig) -> (Vec, Vec>) { + let headers: Vec = Vec::from(["Name".to_string(), "Value".to_string()]); + let mut rows: Vec> = Vec::new(); + rows.extend(self.0.iter().map(|(k, v)| { + Vec::from([ + k.clone(), + serde_json::to_string(&v).expect("Is a valid data"), + ]) + })); + (headers, rows) + } } impl AccessRulesCommand { @@ -167,9 +166,8 @@ impl AccessRulesCommand { .build() .map_err(|x| OpenStackCliError::EndpointBuild(x.to_string()))?; - let data: Vec = ep.query_async(client).await?; - - op.output_list::(data)?; + let data = ep.query_async(client).await?; + op.output_single::(data)?; Ok(()) } } diff --git a/openstack_cli/src/identity/v3/user/access_rule/show.rs b/openstack_cli/src/identity/v3/user/access_rule/show.rs index 2008474b1..93e239120 100644 --- a/openstack_cli/src/identity/v3/user/access_rule/show.rs +++ b/openstack_cli/src/identity/v3/user/access_rule/show.rs @@ -36,7 +36,8 @@ use openstack_sdk::api::find_by_name; use openstack_sdk::api::identity::v3::user::access_rule::get; use openstack_sdk::api::identity::v3::user::find as find_user; use openstack_sdk::api::QueryAsync; -use structable_derive::StructTable; +use serde_json::Value; +use std::collections::HashMap; use tracing::warn; /// Show details of an access rule. @@ -92,24 +93,22 @@ struct UserInput { #[arg(long, help_heading = "Path parameters", action = clap::ArgAction::SetTrue)] current_user: bool, } -/// AccessRule response representation -#[derive(Deserialize, Serialize, Clone, StructTable)] -struct ResponseData { - #[serde()] - #[structable(optional)] - id: Option, - - #[serde()] - #[structable(optional)] - method: Option, - - #[serde()] - #[structable(optional)] - path: Option, - - #[serde()] - #[structable(optional)] - service: Option, +/// Response data as HashMap type +#[derive(Deserialize, Serialize)] +struct ResponseData(HashMap); + +impl StructTable for ResponseData { + fn build(&self, _options: &OutputConfig) -> (Vec, Vec>) { + let headers: Vec = Vec::from(["Name".to_string(), "Value".to_string()]); + let mut rows: Vec> = Vec::new(); + rows.extend(self.0.iter().map(|(k, v)| { + Vec::from([ + k.clone(), + serde_json::to_string(&v).expect("Is a valid data"), + ]) + })); + (headers, rows) + } } impl AccessRuleCommand { diff --git a/openstack_sdk/src/api/identity/v3/project/create.rs b/openstack_sdk/src/api/identity/v3/project/create.rs index c90efbed8..2d3b948be 100644 --- a/openstack_sdk/src/api/identity/v3/project/create.rs +++ b/openstack_sdk/src/api/identity/v3/project/create.rs @@ -27,9 +27,7 @@ use crate::api::rest_endpoint_prelude::*; use serde::Deserialize; use serde::Serialize; -use serde_json::Value; use std::borrow::Cow; -use std::collections::BTreeMap; /// The resource options for the project. Available resource options are /// `immutable`. @@ -55,29 +53,41 @@ pub struct Project<'a> { /// The ID of the domain for the project. /// + /// For projects acting as a domain, the `domain_id` must not be specified, + /// it will be generated by the Identity service implementation. + /// + /// For regular projects (i.e. those not acing as a domain), if `domain_id` + /// is not specified, but `parent_id` is specified, then the domain ID of + /// the parent will be used. If neither `domain_id` or `parent_id` is + /// specified, the Identity service implementation will default to the + /// domain to which the client’s token is scoped. If both `domain_id` and + /// `parent_id` are specified, and they do not indicate the same domain, an + /// `Bad Request (400)` will be returned. + /// #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(into))] pub(crate) domain_id: Option>>, - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. + /// If set to `true`, project is enabled. If set to `false`, project is + /// disabled. The default is `true`. /// #[serde(skip_serializing_if = "Option::is_none")] #[builder(default)] pub(crate) enabled: Option, - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. + /// If set to `true`, project is enabled. If set to `false`, project is + /// disabled. The default is `true`. /// #[serde(skip_serializing_if = "Option::is_none")] #[builder(default)] pub(crate) is_domain: Option, - /// The name of the project. + /// The name of the project, which must be unique within the owning domain. + /// A project can have the same name as its domain. /// - #[serde(skip_serializing_if = "Option::is_none")] - #[builder(default, setter(into))] - pub(crate) name: Option>, + #[serde()] + #[builder(setter(into))] + pub(crate) name: Cow<'a, str>, /// The resource options for the project. Available resource options are /// `immutable`. @@ -86,7 +96,18 @@ pub struct Project<'a> { #[builder(default, setter(into))] pub(crate) options: Option, - /// The ID of the parent for the project. + /// The ID of the parent of the project. + /// + /// If specified on project creation, this places the project within a + /// hierarchy and implicitly defines the owning domain, which will be the + /// same domain as the parent specified. If `parent_id` is not specified + /// and `is_domain` is `false`, then the project will use its owning domain + /// as its parent. If `is_domain` is `true` (i.e. the project is acting as + /// a domain), then `parent_id` must not specified (or if it is, it must be + /// `null`) since domains have no parents. + /// + /// `parent_id` is immutable, and can’t be updated after the project is + /// created - hence a project cannot be moved within the hierarchy. /// /// **New in version 3.4** /// @@ -94,29 +115,12 @@ pub struct Project<'a> { #[builder(default, setter(into))] pub(crate) parent_id: Option>>, - /// A list of simple strings assigned to a project. + /// A list of simple strings assigned to a project. Tags can be used to + /// classify projects into groups. /// #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(into))] pub(crate) tags: Option>>, - - #[builder(setter(name = "_properties"), default, private)] - #[serde(flatten)] - _properties: BTreeMap, Value>, -} - -impl<'a> ProjectBuilder<'a> { - pub fn properties(&mut self, iter: I) -> &mut Self - where - I: Iterator, - K: Into>, - V: Into, - { - self._properties - .get_or_insert_with(BTreeMap::new) - .extend(iter.map(|(k, v)| (k.into(), v.into()))); - self - } } #[derive(Builder, Debug, Clone)] @@ -218,7 +222,7 @@ mod tests { fn test_service_type() { assert_eq!( Request::builder() - .project(ProjectBuilder::default().build().unwrap()) + .project(ProjectBuilder::default().name("foo").build().unwrap()) .build() .unwrap() .service_type(), @@ -230,7 +234,7 @@ mod tests { fn test_response_key() { assert_eq!( Request::builder() - .project(ProjectBuilder::default().build().unwrap()) + .project(ProjectBuilder::default().name("foo").build().unwrap()) .build() .unwrap() .response_key() @@ -253,7 +257,7 @@ mod tests { }); let endpoint = Request::builder() - .project(ProjectBuilder::default().build().unwrap()) + .project(ProjectBuilder::default().name("foo").build().unwrap()) .build() .unwrap(); let _: serde_json::Value = endpoint.query(&client).unwrap(); @@ -275,7 +279,7 @@ mod tests { }); let endpoint = Request::builder() - .project(ProjectBuilder::default().build().unwrap()) + .project(ProjectBuilder::default().name("foo").build().unwrap()) .headers( [( Some(HeaderName::from_static("foo")), diff --git a/openstack_sdk/src/api/identity/v3/project/head.rs b/openstack_sdk/src/api/identity/v3/project/head.rs index 2bef53870..e8baf5f07 100644 --- a/openstack_sdk/src/api/identity/v3/project/head.rs +++ b/openstack_sdk/src/api/identity/v3/project/head.rs @@ -15,29 +15,58 @@ // WARNING: This file is automatically generated from OpenAPI schema using // `openstack-codegenerator`. -//! Get project or list projects. +//! List projects. //! -//! GET/HEAD /v3/projects GET/HEAD /v3/projects/{project_id} +//! GET/HEAD /v3/projects //! use derive_builder::Builder; use http::{HeaderMap, HeaderName, HeaderValue}; use crate::api::rest_endpoint_prelude::*; +use std::borrow::Cow; + #[derive(Builder, Debug, Clone)] #[builder(setter(strip_option))] -pub struct Request { +pub struct Request<'a> { + #[builder(default, setter(into))] + domain_id: Option>, + + #[builder(default)] + enabled: Option, + + #[builder(default)] + is_domain: Option, + + #[builder(default, setter(into))] + name: Option>, + + #[builder(default, setter(into))] + not_tags: Option>, + + #[builder(default, setter(into))] + not_tags_any: Option>, + + #[builder(default, setter(into))] + parent_id: Option>, + + #[builder(default, setter(into))] + tags: Option>, + + #[builder(default, setter(into))] + tags_any: Option>, + #[builder(setter(name = "_headers"), default, private)] _headers: Option, } -impl Request { +impl<'a> Request<'a> { /// Create a builder for the endpoint. - pub fn builder() -> RequestBuilder { + pub fn builder() -> RequestBuilder<'a> { RequestBuilder::default() } } -impl RequestBuilder { +impl<'a> RequestBuilder<'a> { /// Add a single header to the Project. pub fn header(&mut self, header_name: &'static str, header_value: &'static str) -> &mut Self where { @@ -62,7 +91,7 @@ where { } } -impl RestEndpoint for Request { +impl<'a> RestEndpoint for Request<'a> { fn method(&self) -> http::Method { http::Method::HEAD } @@ -72,7 +101,18 @@ impl RestEndpoint for Request { } fn parameters(&self) -> QueryParams { - QueryParams::default() + let mut params = QueryParams::default(); + params.push_opt("domain_id", self.domain_id.as_ref()); + params.push_opt("enabled", self.enabled); + params.push_opt("name", self.name.as_ref()); + params.push_opt("parent_id", self.parent_id.as_ref()); + params.push_opt("is_domain", self.is_domain); + params.push_opt("tags", self.tags.as_ref()); + params.push_opt("tags-any", self.tags_any.as_ref()); + params.push_opt("not-tags", self.not_tags.as_ref()); + params.push_opt("not-tags-any", self.not_tags_any.as_ref()); + + params } fn service_type(&self) -> ServiceType { diff --git a/openstack_sdk/src/api/identity/v3/project/list.rs b/openstack_sdk/src/api/identity/v3/project/list.rs index 0c819bb26..c7d305780 100644 --- a/openstack_sdk/src/api/identity/v3/project/list.rs +++ b/openstack_sdk/src/api/identity/v3/project/list.rs @@ -30,34 +30,33 @@ use std::borrow::Cow; #[derive(Builder, Debug, Clone)] #[builder(setter(strip_option))] pub struct Request<'a> { - /// Filters the response by a domain ID. - /// #[builder(default, setter(into))] domain_id: Option>, - /// If set to true, then only enabled projects will be returned. Any value - /// other than 0 (including no value) will be interpreted as true. - /// #[builder(default)] enabled: Option, - /// If this is specified as true, then only projects acting as a domain are - /// included. Otherwise, only projects that are not acting as a domain are - /// included. - /// #[builder(default)] is_domain: Option, - /// Filters the response by a resource name. - /// #[builder(default, setter(into))] name: Option>, - /// Filters the response by a parent ID. - /// + #[builder(default, setter(into))] + not_tags: Option>, + + #[builder(default, setter(into))] + not_tags_any: Option>, + #[builder(default, setter(into))] parent_id: Option>, + #[builder(default, setter(into))] + tags: Option>, + + #[builder(default, setter(into))] + tags_any: Option>, + #[builder(setter(name = "_headers"), default, private)] _headers: Option, } @@ -106,9 +105,13 @@ impl<'a> RestEndpoint for Request<'a> { let mut params = QueryParams::default(); params.push_opt("domain_id", self.domain_id.as_ref()); params.push_opt("enabled", self.enabled); - params.push_opt("is_domain", self.is_domain); params.push_opt("name", self.name.as_ref()); params.push_opt("parent_id", self.parent_id.as_ref()); + params.push_opt("is_domain", self.is_domain); + params.push_opt("tags", self.tags.as_ref()); + params.push_opt("tags-any", self.tags_any.as_ref()); + params.push_opt("not-tags", self.not_tags.as_ref()); + params.push_opt("not-tags-any", self.not_tags_any.as_ref()); params } diff --git a/openstack_sdk/src/api/identity/v3/project/set.rs b/openstack_sdk/src/api/identity/v3/project/set.rs index 6cca7f78f..4e7b78fd1 100644 --- a/openstack_sdk/src/api/identity/v3/project/set.rs +++ b/openstack_sdk/src/api/identity/v3/project/set.rs @@ -27,20 +27,7 @@ use crate::api::rest_endpoint_prelude::*; use serde::Deserialize; use serde::Serialize; -use serde_json::Value; use std::borrow::Cow; -use std::collections::BTreeMap; - -/// The resource options for the project. Available resource options are -/// `immutable`. -/// -#[derive(Builder, Debug, Deserialize, Clone, Serialize)] -#[builder(setter(strip_option))] -pub struct Options { - #[serde(skip_serializing_if = "Option::is_none")] - #[builder(default)] - pub(crate) immutable: Option, -} /// A `project` object /// @@ -53,70 +40,26 @@ pub struct Project<'a> { #[builder(default, setter(into))] pub(crate) description: Option>>, - /// The ID of the domain for the project. - /// - #[serde(skip_serializing_if = "Option::is_none")] - #[builder(default, setter(into))] - pub(crate) domain_id: Option>>, - - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. + /// If set to `true`, project is enabled. If set to `false`, project is + /// disabled. /// #[serde(skip_serializing_if = "Option::is_none")] #[builder(default)] pub(crate) enabled: Option, - /// If the user is enabled, this value is `true`. If the user is disabled, - /// this value is `false`. - /// - #[serde(skip_serializing_if = "Option::is_none")] - #[builder(default)] - pub(crate) is_domain: Option, - - /// The name of the project. + /// The name of the project, which must be unique within the owning domain. + /// A project can have the same name as its domain. /// #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(into))] pub(crate) name: Option>, - /// The resource options for the project. Available resource options are - /// `immutable`. - /// - #[serde(skip_serializing_if = "Option::is_none")] - #[builder(default, setter(into))] - pub(crate) options: Option, - - /// The ID of the parent for the project. - /// - /// **New in version 3.4** - /// - #[serde(skip_serializing_if = "Option::is_none")] - #[builder(default, setter(into))] - pub(crate) parent_id: Option>>, - - /// A list of simple strings assigned to a project. + /// A list of simple strings assigned to a project. Tags can be used to + /// classify projects into groups. /// #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(into))] pub(crate) tags: Option>>, - - #[builder(setter(name = "_properties"), default, private)] - #[serde(flatten)] - _properties: BTreeMap, Value>, -} - -impl<'a> ProjectBuilder<'a> { - pub fn properties(&mut self, iter: I) -> &mut Self - where - I: Iterator, - K: Into>, - V: Into, - { - self._properties - .get_or_insert_with(BTreeMap::new) - .extend(iter.map(|(k, v)| (k.into(), v.into()))); - self - } } #[derive(Builder, Debug, Clone)] diff --git a/openstack_sdk/src/api/identity/v3/project/tag/replace.rs b/openstack_sdk/src/api/identity/v3/project/tag/replace.rs index 69aac0119..55675df13 100644 --- a/openstack_sdk/src/api/identity/v3/project/tag/replace.rs +++ b/openstack_sdk/src/api/identity/v3/project/tag/replace.rs @@ -31,6 +31,11 @@ use std::borrow::Cow; #[derive(Builder, Debug, Clone)] #[builder(setter(strip_option))] pub struct Request<'a> { + /// A list of simple strings assigned to a project. + /// + #[builder(setter(into))] + pub(crate) tags: Vec>, + /// project_id parameter for /v3/projects/{project_id}/tags/{value} API /// #[builder(default, setter(into))] @@ -88,6 +93,14 @@ impl<'a> RestEndpoint for Request<'a> { QueryParams::default() } + fn body(&self) -> Result)>, BodyError> { + let mut params = JsonBodyParams::default(); + + params.push("tags", serde_json::to_value(&self.tags)?); + + params.into_body() + } + fn service_type(&self) -> ServiceType { ServiceType::Identity } @@ -122,7 +135,11 @@ mod tests { #[test] fn test_service_type() { assert_eq!( - Request::builder().build().unwrap().service_type(), + Request::builder() + .tags(Vec::from(["foo".into()])) + .build() + .unwrap() + .service_type(), ServiceType::Identity ); } @@ -130,7 +147,12 @@ mod tests { #[test] fn test_response_key() { assert_eq!( - Request::builder().build().unwrap().response_key().unwrap(), + Request::builder() + .tags(Vec::from(["foo".into()])) + .build() + .unwrap() + .response_key() + .unwrap(), "tags" ); } @@ -150,7 +172,11 @@ mod tests { .json_body(json!({ "tags": {} })); }); - let endpoint = Request::builder().project_id("project_id").build().unwrap(); + let endpoint = Request::builder() + .project_id("project_id") + .tags(Vec::from(["foo".into()])) + .build() + .unwrap(); let _: serde_json::Value = endpoint.query(&client).unwrap(); mock.assert(); } @@ -174,6 +200,7 @@ mod tests { let endpoint = Request::builder() .project_id("project_id") + .tags(Vec::from(["foo".into()])) .headers( [( Some(HeaderName::from_static("foo")), diff --git a/openstack_sdk/src/api/identity/v3/user/access_rule/get.rs b/openstack_sdk/src/api/identity/v3/user/access_rule/get.rs index 9fc04446b..a0ba21981 100644 --- a/openstack_sdk/src/api/identity/v3/user/access_rule/get.rs +++ b/openstack_sdk/src/api/identity/v3/user/access_rule/get.rs @@ -100,7 +100,7 @@ impl<'a> RestEndpoint for Request<'a> { } fn response_key(&self) -> Option> { - Some("access_rule".into()) + None } /// Returns headers to be set into the request @@ -136,10 +136,7 @@ mod tests { #[test] fn test_response_key() { - assert_eq!( - Request::builder().build().unwrap().response_key().unwrap(), - "access_rule" - ); + assert!(Request::builder().build().unwrap().response_key().is_none()) } #[cfg(feature = "sync")] @@ -155,7 +152,7 @@ mod tests { then.status(200) .header("content-type", "application/json") - .json_body(json!({ "access_rule": {} })); + .json_body(json!({ "dummy": {} })); }); let endpoint = Request::builder() @@ -182,7 +179,7 @@ mod tests { .header("not_foo", "not_bar"); then.status(200) .header("content-type", "application/json") - .json_body(json!({ "access_rule": {} })); + .json_body(json!({ "dummy": {} })); }); let endpoint = Request::builder() diff --git a/openstack_sdk/src/api/identity/v3/user/access_rule/list.rs b/openstack_sdk/src/api/identity/v3/user/access_rule/list.rs index 22a841426..2d53e7db7 100644 --- a/openstack_sdk/src/api/identity/v3/user/access_rule/list.rs +++ b/openstack_sdk/src/api/identity/v3/user/access_rule/list.rs @@ -93,7 +93,7 @@ impl<'a> RestEndpoint for Request<'a> { } fn response_key(&self) -> Option> { - Some("access_rules".into()) + None } /// Returns headers to be set into the request @@ -129,10 +129,7 @@ mod tests { #[test] fn test_response_key() { - assert_eq!( - Request::builder().build().unwrap().response_key().unwrap(), - "access_rules" - ); + assert!(Request::builder().build().unwrap().response_key().is_none()) } #[cfg(feature = "sync")] @@ -147,7 +144,7 @@ mod tests { then.status(200) .header("content-type", "application/json") - .json_body(json!({ "access_rules": {} })); + .json_body(json!({ "dummy": {} })); }); let endpoint = Request::builder().user_id("user_id").build().unwrap(); @@ -169,7 +166,7 @@ mod tests { .header("not_foo", "not_bar"); then.status(200) .header("content-type", "application/json") - .json_body(json!({ "access_rules": {} })); + .json_body(json!({ "dummy": {} })); }); let endpoint = Request::builder()