openstack_sdk_load_balancer/v2/pool/
set.rs1use derive_builder::Builder;
29use http::{HeaderMap, HeaderName, HeaderValue};
30
31use openstack_sdk_core::api::rest_endpoint_prelude::*;
32
33use serde::Deserialize;
34use serde::Serialize;
35use std::borrow::Cow;
36
37#[derive(Debug, Deserialize, Clone, Serialize)]
38pub enum LbAlgorithm {
39 #[serde(rename = "LEAST_CONNECTIONS")]
40 LeastConnections,
41 #[serde(rename = "ROUND_ROBIN")]
42 RoundRobin,
43 #[serde(rename = "SOURCE_IP")]
44 SourceIp,
45 #[serde(rename = "SOURCE_IP_PORT")]
46 SourceIpPort,
47}
48
49#[derive(Debug, Deserialize, Clone, Serialize)]
50pub enum Type {
51 #[serde(rename = "APP_COOKIE")]
52 AppCookie,
53 #[serde(rename = "HTTP_COOKIE")]
54 HttpCookie,
55 #[serde(rename = "SOURCE_IP")]
56 SourceIp,
57}
58
59#[derive(Builder, Debug, Deserialize, Clone, Serialize)]
63#[builder(setter(strip_option))]
64pub struct SessionPersistence<'a> {
65 #[serde(skip_serializing_if = "Option::is_none")]
66 #[builder(default, setter(into))]
67 pub(crate) cookie_name: Option<Cow<'a, str>>,
68
69 #[serde(skip_serializing_if = "Option::is_none")]
70 #[builder(default, setter(into))]
71 pub(crate) persistence_granularity: Option<Cow<'a, str>>,
72
73 #[serde(skip_serializing_if = "Option::is_none")]
74 #[builder(default, setter(into))]
75 pub(crate) persistence_timeout: Option<i32>,
76
77 #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
78 #[builder(default)]
79 pub(crate) _type: Option<Type>,
80}
81
82#[derive(Builder, Debug, Deserialize, Clone, Serialize)]
84#[builder(setter(strip_option))]
85pub struct Pool<'a> {
86 #[serde(skip_serializing_if = "Option::is_none")]
89 #[builder(default, setter(into))]
90 pub(crate) admin_state_up: Option<bool>,
91
92 #[serde(skip_serializing_if = "Option::is_none")]
96 #[builder(default, setter(into))]
97 pub(crate) alpn_protocols: Option<Vec<Cow<'a, str>>>,
98
99 #[serde(skip_serializing_if = "Option::is_none")]
106 #[builder(default, setter(into))]
107 pub(crate) ca_tls_container_ref: Option<Cow<'a, str>>,
108
109 #[serde(skip_serializing_if = "Option::is_none")]
114 #[builder(default, setter(into))]
115 pub(crate) crl_container_ref: Option<Cow<'a, str>>,
116
117 #[serde(skip_serializing_if = "Option::is_none")]
119 #[builder(default, setter(into))]
120 pub(crate) description: Option<Cow<'a, str>>,
121
122 #[serde(skip_serializing_if = "Option::is_none")]
125 #[builder(default)]
126 pub(crate) lb_algorithm: Option<LbAlgorithm>,
127
128 #[serde(skip_serializing_if = "Option::is_none")]
130 #[builder(default, setter(into))]
131 pub(crate) name: Option<Cow<'a, str>>,
132
133 #[serde(skip_serializing_if = "Option::is_none")]
137 #[builder(default, setter(into))]
138 pub(crate) session_persistence: Option<SessionPersistence<'a>>,
139
140 #[serde(skip_serializing_if = "Option::is_none")]
144 #[builder(default, setter(into))]
145 pub(crate) tags: Option<Vec<Cow<'a, str>>>,
146
147 #[serde(skip_serializing_if = "Option::is_none")]
152 #[builder(default, setter(into))]
153 pub(crate) tls_ciphers: Option<Cow<'a, str>>,
154
155 #[serde(skip_serializing_if = "Option::is_none")]
163 #[builder(default, setter(into))]
164 pub(crate) tls_container_ref: Option<Cow<'a, str>>,
165
166 #[serde(skip_serializing_if = "Option::is_none")]
171 #[builder(default, setter(into))]
172 pub(crate) tls_enabled: Option<bool>,
173
174 #[serde(skip_serializing_if = "Option::is_none")]
179 #[builder(default, setter(into))]
180 pub(crate) tls_versions: Option<Vec<Cow<'a, str>>>,
181}
182
183#[derive(Builder, Debug, Clone)]
184#[builder(setter(strip_option))]
185pub struct Request<'a> {
186 #[builder(setter(into))]
188 pub(crate) pool: Pool<'a>,
189
190 #[builder(default, setter(into))]
192 id: Cow<'a, str>,
193
194 #[builder(setter(name = "_headers"), default, private)]
195 _headers: Option<HeaderMap>,
196}
197impl<'a> Request<'a> {
198 pub fn builder() -> RequestBuilder<'a> {
200 RequestBuilder::default()
201 }
202}
203
204impl<'a> RequestBuilder<'a> {
205 pub fn header<K, V>(&mut self, header_name: K, header_value: V) -> &mut Self
207 where
208 K: Into<HeaderName>,
209 V: Into<HeaderValue>,
210 {
211 self._headers
212 .get_or_insert(None)
213 .get_or_insert_with(HeaderMap::new)
214 .insert(header_name.into(), header_value.into());
215 self
216 }
217
218 pub fn headers<I, T>(&mut self, iter: I) -> &mut Self
220 where
221 I: Iterator<Item = T>,
222 T: Into<(Option<HeaderName>, HeaderValue)>,
223 {
224 self._headers
225 .get_or_insert(None)
226 .get_or_insert_with(HeaderMap::new)
227 .extend(iter.map(Into::into));
228 self
229 }
230}
231
232impl RestEndpoint for Request<'_> {
233 fn method(&self) -> http::Method {
234 http::Method::PUT
235 }
236
237 fn endpoint(&self) -> Cow<'static, str> {
238 format!("lbaas/pools/{id}", id = self.id.as_ref(),).into()
239 }
240
241 fn parameters(&self) -> QueryParams<'_> {
242 QueryParams::default()
243 }
244
245 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
246 let mut params = JsonBodyParams::default();
247
248 params.push("pool", serde_json::to_value(&self.pool)?);
249
250 params.into_body()
251 }
252
253 fn service_type(&self) -> ServiceType {
254 ServiceType::LoadBalancer
255 }
256
257 fn response_key(&self) -> Option<Cow<'static, str>> {
258 Some("pool".into())
259 }
260
261 fn request_headers(&self) -> Option<&HeaderMap> {
263 self._headers.as_ref()
264 }
265
266 fn api_version(&self) -> Option<ApiVersion> {
268 Some(ApiVersion::new(2, 0))
269 }
270}
271
272#[cfg(test)]
273mod tests {
274 use super::*;
275 use http::{HeaderName, HeaderValue};
276 use httpmock::MockServer;
277 #[cfg(feature = "sync")]
278 use openstack_sdk_core::api::Query;
279 use openstack_sdk_core::test::client::FakeOpenStackClient;
280 use openstack_sdk_core::types::ServiceType;
281 use serde_json::json;
282
283 #[test]
284 fn test_service_type() {
285 assert_eq!(
286 Request::builder()
287 .pool(PoolBuilder::default().build().unwrap())
288 .build()
289 .unwrap()
290 .service_type(),
291 ServiceType::LoadBalancer
292 );
293 }
294
295 #[test]
296 fn test_response_key() {
297 assert_eq!(
298 Request::builder()
299 .pool(PoolBuilder::default().build().unwrap())
300 .build()
301 .unwrap()
302 .response_key()
303 .unwrap(),
304 "pool"
305 );
306 }
307
308 #[cfg(feature = "sync")]
309 #[test]
310 fn endpoint() {
311 let server = MockServer::start();
312 let client = FakeOpenStackClient::new(server.base_url());
313 let mock = server.mock(|when, then| {
314 when.method(httpmock::Method::PUT)
315 .path(format!("/lbaas/pools/{id}", id = "id",));
316
317 then.status(200)
318 .header("content-type", "application/json")
319 .json_body(json!({ "pool": {} }));
320 });
321
322 let endpoint = Request::builder()
323 .id("id")
324 .pool(PoolBuilder::default().build().unwrap())
325 .build()
326 .unwrap();
327 let _: serde_json::Value = endpoint.query(&client).unwrap();
328 mock.assert();
329 }
330
331 #[cfg(feature = "sync")]
332 #[test]
333 fn endpoint_headers() {
334 let server = MockServer::start();
335 let client = FakeOpenStackClient::new(server.base_url());
336 let mock = server.mock(|when, then| {
337 when.method(httpmock::Method::PUT)
338 .path(format!("/lbaas/pools/{id}", id = "id",))
339 .header("foo", "bar")
340 .header("not_foo", "not_bar");
341 then.status(200)
342 .header("content-type", "application/json")
343 .json_body(json!({ "pool": {} }));
344 });
345
346 let endpoint = Request::builder()
347 .id("id")
348 .pool(PoolBuilder::default().build().unwrap())
349 .headers(
350 [(
351 Some(HeaderName::from_static("foo")),
352 HeaderValue::from_static("bar"),
353 )]
354 .into_iter(),
355 )
356 .header(
357 HeaderName::from_static("not_foo"),
358 HeaderValue::from_static("not_bar"),
359 )
360 .build()
361 .unwrap();
362 let _: serde_json::Value = endpoint.query(&client).unwrap();
363 mock.assert();
364 }
365}