Skip to main content

openstack_keystone_core/resource/
service.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
15use async_trait::async_trait;
16use std::sync::Arc;
17use uuid::Uuid;
18use validator::Validate;
19
20use crate::config::Config;
21use crate::keystone::ServiceState;
22use crate::plugin_manager::PluginManagerApi;
23use crate::resource::{ResourceProviderError, backend::ResourceBackend, types::*};
24
25pub struct ResourceService {
26    backend_driver: Arc<dyn ResourceBackend>,
27}
28
29impl ResourceService {
30    pub fn new<P: PluginManagerApi>(
31        config: &Config,
32        plugin_manager: &P,
33    ) -> Result<Self, ResourceProviderError> {
34        let backend_driver = plugin_manager
35            .get_resource_backend(config.resource.driver.clone())?
36            .clone();
37        Ok(Self { backend_driver })
38    }
39}
40
41#[async_trait]
42impl ResourceApi for ResourceService {
43    /// Check whether the domain is enabled.
44    async fn get_domain_enabled<'a>(
45        &self,
46        state: &ServiceState,
47        domain_id: &'a str,
48    ) -> Result<bool, ResourceProviderError> {
49        self.backend_driver
50            .get_domain_enabled(state, domain_id)
51            .await
52    }
53
54    /// Create new domain.
55    #[tracing::instrument(level = "info", skip(self, state))]
56    async fn create_domain(
57        &self,
58        state: &ServiceState,
59        domain: DomainCreate,
60    ) -> Result<Domain, ResourceProviderError> {
61        let mut new_domain = domain;
62
63        if new_domain.id.is_none() {
64            new_domain.id = Some(Uuid::new_v4().simple().to_string());
65        }
66        new_domain.validate()?;
67        self.backend_driver.create_domain(state, new_domain).await
68    }
69
70    /// Create new project.
71    #[tracing::instrument(level = "info", skip(self, state))]
72    async fn create_project(
73        &self,
74        state: &ServiceState,
75        project: ProjectCreate,
76    ) -> Result<Project, ResourceProviderError> {
77        let mut new_project = project;
78
79        if new_project.id.is_none() {
80            new_project.id = Some(Uuid::new_v4().simple().to_string());
81        }
82        new_project.validate()?;
83        self.backend_driver.create_project(state, new_project).await
84    }
85
86    /// Delete a domain by the ID.
87    #[tracing::instrument(level = "info", skip(self, state))]
88    async fn delete_domain<'a>(
89        &self,
90        state: &ServiceState,
91        id: &'a str,
92    ) -> Result<(), ResourceProviderError> {
93        self.backend_driver.delete_domain(state, id).await
94    }
95
96    /// Delete a project by the ID.
97    #[tracing::instrument(level = "info", skip(self, state))]
98    async fn delete_project<'a>(
99        &self,
100        state: &ServiceState,
101        id: &'a str,
102    ) -> Result<(), ResourceProviderError> {
103        self.backend_driver.delete_project(state, id).await
104    }
105
106    /// Get single domain.
107    #[tracing::instrument(level = "info", skip(self, state))]
108    async fn get_domain<'a>(
109        &self,
110        state: &ServiceState,
111        domain_id: &'a str,
112    ) -> Result<Option<Domain>, ResourceProviderError> {
113        self.backend_driver.get_domain(state, domain_id).await
114    }
115
116    /// Get single project.
117    #[tracing::instrument(level = "info", skip(self, state))]
118    async fn get_project<'a>(
119        &self,
120        state: &ServiceState,
121        project_id: &'a str,
122    ) -> Result<Option<Project>, ResourceProviderError> {
123        self.backend_driver.get_project(state, project_id).await
124    }
125
126    /// Get single project by Name and Domain ID.
127    #[tracing::instrument(level = "info", skip(self, state))]
128    async fn get_project_by_name<'a>(
129        &self,
130        state: &ServiceState,
131        name: &'a str,
132        domain_id: &'a str,
133    ) -> Result<Option<Project>, ResourceProviderError> {
134        self.backend_driver
135            .get_project_by_name(state, name, domain_id)
136            .await
137    }
138
139    /// Get project parents.
140    #[tracing::instrument(level = "info", skip(self, state))]
141    async fn get_project_parents<'a>(
142        &self,
143        state: &ServiceState,
144        project_id: &'a str,
145    ) -> Result<Option<Vec<Project>>, ResourceProviderError> {
146        self.backend_driver
147            .get_project_parents(state, project_id)
148            .await
149    }
150
151    /// Get single domain by its name.
152    #[tracing::instrument(level = "info", skip(self, state))]
153    async fn find_domain_by_name<'a>(
154        &self,
155        state: &ServiceState,
156        domain_name: &'a str,
157    ) -> Result<Option<Domain>, ResourceProviderError> {
158        self.backend_driver
159            .get_domain_by_name(state, domain_name)
160            .await
161    }
162
163    /// List domains.
164    #[tracing::instrument(level = "info", skip(self, state))]
165    async fn list_domains(
166        &self,
167        state: &ServiceState,
168        params: &DomainListParameters,
169    ) -> Result<Vec<Domain>, ResourceProviderError> {
170        self.backend_driver.list_domains(state, params).await
171    }
172
173    /// List projects.
174    #[tracing::instrument(level = "info", skip(self, state))]
175    async fn list_projects(
176        &self,
177        state: &ServiceState,
178        params: &ProjectListParameters,
179    ) -> Result<Vec<Project>, ResourceProviderError> {
180        self.backend_driver.list_projects(state, params).await
181    }
182}