Skip to main content

openstack_keystone_core/catalog/
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//! # Catalog provider
15//!
16//! Catalog provider takes care of returning the list of the service endpoints
17//! that the API user is able to use according to the valid authentication.
18//!
19//! Following Keystone concepts are covered:
20//!
21//! ## Endpoint
22//!
23//! A network-accessible address, usually a URL, through which you can access a
24//! service. If you are using an extension for templates, you can create an
25//! endpoint template that represents the templates of all consumable services
26//! that are available across the regions.
27//!
28//! ## Service
29//!
30//! An OpenStack service, such as Compute (nova), Object Storage (swift), or
31//! Image service (glance), that provides one or more endpoints through which
32//! users can access resources and perform operations.
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 service::CatalogService;
46
47pub use crate::catalog::error::CatalogProviderError;
48#[cfg(any(test, feature = "mock"))]
49pub use mock::MockCatalogProvider;
50pub use types::CatalogApi;
51
52use types::*;
53
54pub enum CatalogProvider {
55    Service(CatalogService),
56    #[cfg(any(test, feature = "mock"))]
57    Mock(MockCatalogProvider),
58}
59
60impl CatalogProvider {
61    pub fn new<P: PluginManagerApi>(
62        config: &Config,
63        plugin_manager: &P,
64    ) -> Result<Self, CatalogProviderError> {
65        Ok(Self::Service(CatalogService::new(config, plugin_manager)?))
66    }
67}
68
69#[async_trait]
70impl CatalogApi for CatalogProvider {
71    /// List services
72    #[tracing::instrument(level = "info", skip(self, state))]
73    async fn list_services(
74        &self,
75        state: &ServiceState,
76        params: &ServiceListParameters,
77    ) -> Result<Vec<Service>, CatalogProviderError> {
78        match self {
79            Self::Service(provider) => provider.list_services(state, params).await,
80            #[cfg(any(test, feature = "mock"))]
81            Self::Mock(provider) => provider.list_services(state, params).await,
82        }
83    }
84
85    /// Get single service by ID
86    #[tracing::instrument(level = "info", skip(self, state))]
87    async fn get_service<'a>(
88        &self,
89        state: &ServiceState,
90        id: &'a str,
91    ) -> Result<Option<Service>, CatalogProviderError> {
92        match self {
93            Self::Service(provider) => provider.get_service(state, id).await,
94            #[cfg(any(test, feature = "mock"))]
95            Self::Mock(provider) => provider.get_service(state, id).await,
96        }
97    }
98
99    /// List Endpoints
100    #[tracing::instrument(level = "info", skip(self, state))]
101    async fn list_endpoints(
102        &self,
103        state: &ServiceState,
104        params: &EndpointListParameters,
105    ) -> Result<Vec<Endpoint>, CatalogProviderError> {
106        match self {
107            Self::Service(provider) => provider.list_endpoints(state, params).await,
108            #[cfg(any(test, feature = "mock"))]
109            Self::Mock(provider) => provider.list_endpoints(state, params).await,
110        }
111    }
112
113    /// Get single endpoint by ID
114    #[tracing::instrument(level = "info", skip(self, state))]
115    async fn get_endpoint<'a>(
116        &self,
117        state: &ServiceState,
118        id: &'a str,
119    ) -> Result<Option<Endpoint>, CatalogProviderError> {
120        match self {
121            Self::Service(provider) => provider.get_endpoint(state, id).await,
122            #[cfg(any(test, feature = "mock"))]
123            Self::Mock(provider) => provider.get_endpoint(state, id).await,
124        }
125    }
126
127    /// Get catalog
128    #[tracing::instrument(level = "info", skip(self, state))]
129    async fn get_catalog(
130        &self,
131        state: &ServiceState,
132        enabled: bool,
133    ) -> Result<Vec<(Service, Vec<Endpoint>)>, CatalogProviderError> {
134        match self {
135            Self::Service(provider) => provider.get_catalog(state, enabled).await,
136            #[cfg(any(test, feature = "mock"))]
137            Self::Mock(provider) => provider.get_catalog(state, enabled).await,
138        }
139    }
140}