Skip to main content

openstack_keystone_core/resource/
mod.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//! # Resource provider
15//!
16//! Following Keystone concepts are covered by the provider:
17//!
18//! ## Domain
19//!
20//! An Identity service API v3 entity. Domains are a collection of projects and
21//! users that define administrative boundaries for managing Identity entities.
22//! Domains can represent an individual, company, or operator-owned space. They
23//! expose administrative activities directly to system users. Users can be
24//! granted the administrator role for a domain. A domain administrator can
25//! create projects, users, and groups in a domain and assign roles to users and
26//! groups in a domain.
27//!
28//! ## Project
29//!
30//! A container that groups or isolates resources or identity objects. Depending
31//! on the service operator, a project might map to a customer, account,
32//! organization, or tenant.
33use async_trait::async_trait;
34
35pub mod backend;
36pub mod error;
37#[cfg(any(test, feature = "mock"))]
38mod mock;
39pub mod service;
40pub mod types;
41
42use crate::config::Config;
43use crate::keystone::ServiceState;
44use crate::plugin_manager::PluginManagerApi;
45use crate::resource::service::ResourceService;
46use crate::resource::types::*;
47
48pub use crate::resource::error::ResourceProviderError;
49#[cfg(any(test, feature = "mock"))]
50pub use mock::MockResourceProvider;
51pub use types::ResourceApi;
52
53pub enum ResourceProvider {
54    Service(ResourceService),
55    #[cfg(any(test, feature = "mock"))]
56    Mock(MockResourceProvider),
57}
58
59impl ResourceProvider {
60    pub fn new<P: PluginManagerApi>(
61        config: &Config,
62        plugin_manager: &P,
63    ) -> Result<Self, ResourceProviderError> {
64        Ok(Self::Service(ResourceService::new(config, plugin_manager)?))
65    }
66}
67
68#[async_trait]
69impl ResourceApi for ResourceProvider {
70    /// Check whether the domain is enabled.
71    async fn get_domain_enabled<'a>(
72        &self,
73        state: &ServiceState,
74        domain_id: &'a str,
75    ) -> Result<bool, ResourceProviderError> {
76        match self {
77            Self::Service(provider) => provider.get_domain_enabled(state, domain_id).await,
78            #[cfg(any(test, feature = "mock"))]
79            Self::Mock(provider) => provider.get_domain_enabled(state, domain_id).await,
80        }
81    }
82
83    /// Create new domain.
84    async fn create_domain(
85        &self,
86        state: &ServiceState,
87        domain: DomainCreate,
88    ) -> Result<Domain, ResourceProviderError> {
89        match self {
90            Self::Service(provider) => provider.create_domain(state, domain).await,
91            #[cfg(any(test, feature = "mock"))]
92            Self::Mock(provider) => provider.create_domain(state, domain).await,
93        }
94    }
95
96    /// Create new project.
97    async fn create_project(
98        &self,
99        state: &ServiceState,
100        project: ProjectCreate,
101    ) -> Result<Project, ResourceProviderError> {
102        match self {
103            Self::Service(provider) => provider.create_project(state, project).await,
104            #[cfg(any(test, feature = "mock"))]
105            Self::Mock(provider) => provider.create_project(state, project).await,
106        }
107    }
108
109    /// Delete a domain by the ID.
110    async fn delete_domain<'a>(
111        &self,
112        state: &ServiceState,
113        id: &'a str,
114    ) -> Result<(), ResourceProviderError> {
115        match self {
116            Self::Service(provider) => provider.delete_domain(state, id).await,
117            #[cfg(any(test, feature = "mock"))]
118            Self::Mock(provider) => provider.delete_domain(state, id).await,
119        }
120    }
121
122    /// Delete a project by the ID.
123    async fn delete_project<'a>(
124        &self,
125        state: &ServiceState,
126        id: &'a str,
127    ) -> Result<(), ResourceProviderError> {
128        match self {
129            Self::Service(provider) => provider.delete_project(state, id).await,
130            #[cfg(any(test, feature = "mock"))]
131            Self::Mock(provider) => provider.delete_project(state, id).await,
132        }
133    }
134
135    /// Get single domain.
136    async fn get_domain<'a>(
137        &self,
138        state: &ServiceState,
139        domain_id: &'a str,
140    ) -> Result<Option<Domain>, ResourceProviderError> {
141        match self {
142            Self::Service(provider) => provider.get_domain(state, domain_id).await,
143            #[cfg(any(test, feature = "mock"))]
144            Self::Mock(provider) => provider.get_domain(state, domain_id).await,
145        }
146    }
147
148    /// Get single project.
149    async fn get_project<'a>(
150        &self,
151        state: &ServiceState,
152        project_id: &'a str,
153    ) -> Result<Option<Project>, ResourceProviderError> {
154        match self {
155            Self::Service(provider) => provider.get_project(state, project_id).await,
156            #[cfg(any(test, feature = "mock"))]
157            Self::Mock(provider) => provider.get_project(state, project_id).await,
158        }
159    }
160
161    /// Get single project by Name and Domain ID.
162    async fn get_project_by_name<'a>(
163        &self,
164        state: &ServiceState,
165        name: &'a str,
166        domain_id: &'a str,
167    ) -> Result<Option<Project>, ResourceProviderError> {
168        match self {
169            Self::Service(provider) => provider.get_project_by_name(state, name, domain_id).await,
170            #[cfg(any(test, feature = "mock"))]
171            Self::Mock(provider) => provider.get_project_by_name(state, name, domain_id).await,
172        }
173    }
174
175    /// Get project parents.
176    async fn get_project_parents<'a>(
177        &self,
178        state: &ServiceState,
179        project_id: &'a str,
180    ) -> Result<Option<Vec<Project>>, ResourceProviderError> {
181        match self {
182            Self::Service(provider) => provider.get_project_parents(state, project_id).await,
183            #[cfg(any(test, feature = "mock"))]
184            Self::Mock(provider) => provider.get_project_parents(state, project_id).await,
185        }
186    }
187
188    /// Get single domain by its name.
189    async fn find_domain_by_name<'a>(
190        &self,
191        state: &ServiceState,
192        domain_name: &'a str,
193    ) -> Result<Option<Domain>, ResourceProviderError> {
194        match self {
195            Self::Service(provider) => provider.find_domain_by_name(state, domain_name).await,
196            #[cfg(any(test, feature = "mock"))]
197            Self::Mock(provider) => provider.find_domain_by_name(state, domain_name).await,
198        }
199    }
200
201    /// List domains.
202    async fn list_domains(
203        &self,
204        state: &ServiceState,
205        params: &DomainListParameters,
206    ) -> Result<Vec<Domain>, ResourceProviderError> {
207        match self {
208            Self::Service(provider) => provider.list_domains(state, params).await,
209            #[cfg(any(test, feature = "mock"))]
210            Self::Mock(provider) => provider.list_domains(state, params).await,
211        }
212    }
213
214    /// List projects.
215    async fn list_projects(
216        &self,
217        state: &ServiceState,
218        params: &ProjectListParameters,
219    ) -> Result<Vec<Project>, ResourceProviderError> {
220        match self {
221            Self::Service(provider) => provider.list_projects(state, params).await,
222            #[cfg(any(test, feature = "mock"))]
223            Self::Mock(provider) => provider.list_projects(state, params).await,
224        }
225    }
226}