Skip to main content

openstack_sdk_identity/v3/endpoint/
create.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//! Creates an endpoint.
19//!
20//! Relationship:
21//! `https://docs.openstack.org/api/openstack-identity/3/rel/endpoints`
22//!
23use derive_builder::Builder;
24use http::{HeaderMap, HeaderName, HeaderValue};
25
26use openstack_sdk_core::api::rest_endpoint_prelude::*;
27
28use serde::Deserialize;
29use serde::Serialize;
30use serde_json::Value;
31use std::borrow::Cow;
32use std::collections::BTreeMap;
33
34#[derive(Debug, Deserialize, Clone, Serialize)]
35pub enum Interface {
36    #[serde(rename = "admin")]
37    Admin,
38    #[serde(rename = "internal")]
39    Internal,
40    #[serde(rename = "public")]
41    Public,
42}
43
44/// An `endpoint` object.
45#[derive(Builder, Debug, Deserialize, Clone, Serialize)]
46#[builder(setter(strip_option))]
47pub struct Endpoint<'a> {
48    /// The endpoint description. It is returned only when set on the resource.
49    #[serde(skip_serializing_if = "Option::is_none")]
50    #[builder(default, setter(into))]
51    pub(crate) description: Option<Option<Cow<'a, str>>>,
52
53    /// Defines whether the endpoint appears in the service catalog: - `false`.
54    /// The endpoint does not appear in the service catalog. - `true`. The
55    /// endpoint appears in the service catalog. Default is `true`.
56    #[serde(skip_serializing_if = "Option::is_none")]
57    #[builder(default, setter(into))]
58    pub(crate) enabled: Option<bool>,
59
60    /// The endpoint ID.
61    #[serde(skip_serializing_if = "Option::is_none")]
62    #[builder(default, setter(into))]
63    pub(crate) id: Option<Cow<'a, str>>,
64
65    /// The interface type, which describes the visibility of the endpoint.
66    /// Value is: - `public`. Visible by end users on a publicly available
67    /// network interface. - `internal`. Visible by end users on an unmetered
68    /// internal network interface. - `admin`. Visible by administrative users
69    /// on a secure network interface.
70    #[serde()]
71    #[builder()]
72    pub(crate) interface: Interface,
73
74    /// (Deprecated) The endpoint name. The field will only be returned in
75    /// responses when set on the resource.
76    ///
77    /// This field is deprecated as it provides no value. Endpoints are better
78    /// described by the combination of service, region and interface they
79    /// describe or by their ID.
80    #[serde(skip_serializing_if = "Option::is_none")]
81    #[builder(default, setter(into))]
82    pub(crate) name: Option<Cow<'a, str>>,
83
84    /// (Deprecated in v3.2) The geographic location of the service endpoint.
85    #[serde(skip_serializing_if = "Option::is_none")]
86    #[builder(default, setter(into))]
87    pub(crate) region: Option<Option<Cow<'a, str>>>,
88
89    /// (Since v3.2) The ID of the region that contains the service endpoint.
90    #[serde(skip_serializing_if = "Option::is_none")]
91    #[builder(default, setter(into))]
92    pub(crate) region_id: Option<Option<Cow<'a, str>>>,
93
94    /// The UUID of the service to which the endpoint belongs.
95    #[serde()]
96    #[builder(setter(into))]
97    pub(crate) service_id: Cow<'a, str>,
98
99    /// The endpoint URL.
100    #[serde()]
101    #[builder(setter(into))]
102    pub(crate) url: Cow<'a, str>,
103
104    #[builder(setter(name = "_properties"), default, private)]
105    #[serde(flatten)]
106    _properties: BTreeMap<Cow<'a, str>, Value>,
107}
108
109impl<'a> EndpointBuilder<'a> {
110    pub fn properties<I, K, V>(&mut self, iter: I) -> &mut Self
111    where
112        I: Iterator<Item = (K, V)>,
113        K: Into<Cow<'a, str>>,
114        V: Into<Value>,
115    {
116        self._properties
117            .get_or_insert_with(BTreeMap::new)
118            .extend(iter.map(|(k, v)| (k.into(), v.into())));
119        self
120    }
121}
122
123#[derive(Builder, Debug, Clone)]
124#[builder(setter(strip_option))]
125pub struct Request<'a> {
126    /// An `endpoint` object.
127    #[builder(setter(into))]
128    pub(crate) endpoint: Endpoint<'a>,
129
130    #[builder(setter(name = "_headers"), default, private)]
131    _headers: Option<HeaderMap>,
132}
133impl<'a> Request<'a> {
134    /// Create a builder for the endpoint.
135    pub fn builder() -> RequestBuilder<'a> {
136        RequestBuilder::default()
137    }
138}
139
140impl<'a> RequestBuilder<'a> {
141    /// Add a single header to the Endpoint.
142    pub fn header<K, V>(&mut self, header_name: K, header_value: V) -> &mut Self
143    where
144        K: Into<HeaderName>,
145        V: Into<HeaderValue>,
146    {
147        self._headers
148            .get_or_insert(None)
149            .get_or_insert_with(HeaderMap::new)
150            .insert(header_name.into(), header_value.into());
151        self
152    }
153
154    /// Add multiple headers.
155    pub fn headers<I, T>(&mut self, iter: I) -> &mut Self
156    where
157        I: Iterator<Item = T>,
158        T: Into<(Option<HeaderName>, HeaderValue)>,
159    {
160        self._headers
161            .get_or_insert(None)
162            .get_or_insert_with(HeaderMap::new)
163            .extend(iter.map(Into::into));
164        self
165    }
166}
167
168impl RestEndpoint for Request<'_> {
169    fn method(&self) -> http::Method {
170        http::Method::POST
171    }
172
173    fn endpoint(&self) -> Cow<'static, str> {
174        "endpoints".to_string().into()
175    }
176
177    fn parameters(&self) -> QueryParams<'_> {
178        QueryParams::default()
179    }
180
181    fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
182        let mut params = JsonBodyParams::default();
183
184        params.push("endpoint", serde_json::to_value(&self.endpoint)?);
185
186        params.into_body()
187    }
188
189    fn service_type(&self) -> ServiceType {
190        ServiceType::Identity
191    }
192
193    fn response_key(&self) -> Option<Cow<'static, str>> {
194        Some("endpoint".into())
195    }
196
197    /// Returns headers to be set into the request
198    fn request_headers(&self) -> Option<&HeaderMap> {
199        self._headers.as_ref()
200    }
201
202    /// Returns required API version
203    fn api_version(&self) -> Option<ApiVersion> {
204        Some(ApiVersion::new(3, 0))
205    }
206}
207
208#[cfg(test)]
209mod tests {
210    use super::*;
211    use http::{HeaderName, HeaderValue};
212    use httpmock::MockServer;
213    #[cfg(feature = "sync")]
214    use openstack_sdk_core::api::Query;
215    use openstack_sdk_core::test::client::FakeOpenStackClient;
216    use openstack_sdk_core::types::ServiceType;
217    use serde_json::json;
218
219    #[test]
220    fn test_service_type() {
221        assert_eq!(
222            Request::builder()
223                .endpoint(
224                    EndpointBuilder::default()
225                        .interface(Interface::Admin)
226                        .service_id("foo")
227                        .url("foo")
228                        .build()
229                        .unwrap()
230                )
231                .build()
232                .unwrap()
233                .service_type(),
234            ServiceType::Identity
235        );
236    }
237
238    #[test]
239    fn test_response_key() {
240        assert_eq!(
241            Request::builder()
242                .endpoint(
243                    EndpointBuilder::default()
244                        .interface(Interface::Admin)
245                        .service_id("foo")
246                        .url("foo")
247                        .build()
248                        .unwrap()
249                )
250                .build()
251                .unwrap()
252                .response_key()
253                .unwrap(),
254            "endpoint"
255        );
256    }
257
258    #[cfg(feature = "sync")]
259    #[test]
260    fn endpoint() {
261        let server = MockServer::start();
262        let client = FakeOpenStackClient::new(server.base_url());
263        let mock = server.mock(|when, then| {
264            when.method(httpmock::Method::POST)
265                .path("/endpoints".to_string());
266
267            then.status(200)
268                .header("content-type", "application/json")
269                .json_body(json!({ "endpoint": {} }));
270        });
271
272        let endpoint = Request::builder()
273            .endpoint(
274                EndpointBuilder::default()
275                    .interface(Interface::Admin)
276                    .service_id("foo")
277                    .url("foo")
278                    .build()
279                    .unwrap(),
280            )
281            .build()
282            .unwrap();
283        let _: serde_json::Value = endpoint.query(&client).unwrap();
284        mock.assert();
285    }
286
287    #[cfg(feature = "sync")]
288    #[test]
289    fn endpoint_headers() {
290        let server = MockServer::start();
291        let client = FakeOpenStackClient::new(server.base_url());
292        let mock = server.mock(|when, then| {
293            when.method(httpmock::Method::POST)
294                .path("/endpoints".to_string())
295                .header("foo", "bar")
296                .header("not_foo", "not_bar");
297            then.status(200)
298                .header("content-type", "application/json")
299                .json_body(json!({ "endpoint": {} }));
300        });
301
302        let endpoint = Request::builder()
303            .endpoint(
304                EndpointBuilder::default()
305                    .interface(Interface::Admin)
306                    .service_id("foo")
307                    .url("foo")
308                    .build()
309                    .unwrap(),
310            )
311            .headers(
312                [(
313                    Some(HeaderName::from_static("foo")),
314                    HeaderValue::from_static("bar"),
315                )]
316                .into_iter(),
317            )
318            .header(
319                HeaderName::from_static("not_foo"),
320                HeaderValue::from_static("not_bar"),
321            )
322            .build()
323            .unwrap();
324        let _: serde_json::Value = endpoint.query(&client).unwrap();
325        mock.assert();
326    }
327}