openstack_sdk_load_balancer/v2/pool/member/
create.rs1use derive_builder::Builder;
59use http::{HeaderMap, HeaderName, HeaderValue};
60
61use openstack_sdk_core::api::rest_endpoint_prelude::*;
62
63use serde::Deserialize;
64use serde::Serialize;
65use std::borrow::Cow;
66
67#[derive(Builder, Debug, Deserialize, Clone, Serialize)]
69#[builder(setter(strip_option))]
70pub struct Member<'a> {
71 #[serde()]
73 #[builder(setter(into))]
74 pub(crate) address: Cow<'a, str>,
75
76 #[serde(skip_serializing_if = "Option::is_none")]
79 #[builder(default, setter(into))]
80 pub(crate) admin_state_up: Option<bool>,
81
82 #[serde(skip_serializing_if = "Option::is_none")]
87 #[builder(default, setter(into))]
88 pub(crate) backup: Option<bool>,
89
90 #[serde(skip_serializing_if = "Option::is_none")]
93 #[builder(default, setter(into))]
94 pub(crate) monitor_address: Option<Cow<'a, str>>,
95
96 #[serde(skip_serializing_if = "Option::is_none")]
99 #[builder(default, setter(into))]
100 pub(crate) monitor_port: Option<i32>,
101
102 #[serde(skip_serializing_if = "Option::is_none")]
104 #[builder(default, setter(into))]
105 pub(crate) name: Option<Cow<'a, str>>,
106
107 #[serde(skip_serializing_if = "Option::is_none")]
109 #[builder(default, setter(into))]
110 pub(crate) project_id: Option<Cow<'a, str>>,
111
112 #[serde()]
114 #[builder(setter(into))]
115 pub(crate) protocol_port: i32,
116
117 #[serde(skip_serializing_if = "Option::is_none")]
122 #[builder(default, setter(into))]
123 pub(crate) request_sriov: Option<bool>,
124
125 #[serde(skip_serializing_if = "Option::is_none")]
127 #[builder(default, setter(into))]
128 pub(crate) subnet_id: Option<Cow<'a, str>>,
129
130 #[serde(skip_serializing_if = "Option::is_none")]
134 #[builder(default, setter(into))]
135 pub(crate) tags: Option<Vec<Cow<'a, str>>>,
136
137 #[serde(skip_serializing_if = "Option::is_none")]
138 #[builder(default, setter(into))]
139 pub(crate) tenant_id: Option<Cow<'a, str>>,
140
141 #[serde(skip_serializing_if = "Option::is_none")]
148 #[builder(default, setter(into))]
149 pub(crate) weight: Option<i32>,
150}
151
152#[derive(Builder, Debug, Clone)]
153#[builder(setter(strip_option))]
154pub struct Request<'a> {
155 #[builder(setter(into))]
157 pub(crate) member: Member<'a>,
158
159 #[builder(default, setter(into))]
161 pool_id: Cow<'a, str>,
162
163 #[builder(setter(name = "_headers"), default, private)]
164 _headers: Option<HeaderMap>,
165}
166impl<'a> Request<'a> {
167 pub fn builder() -> RequestBuilder<'a> {
169 RequestBuilder::default()
170 }
171}
172
173impl<'a> RequestBuilder<'a> {
174 pub fn header<K, V>(&mut self, header_name: K, header_value: V) -> &mut Self
176 where
177 K: Into<HeaderName>,
178 V: Into<HeaderValue>,
179 {
180 self._headers
181 .get_or_insert(None)
182 .get_or_insert_with(HeaderMap::new)
183 .insert(header_name.into(), header_value.into());
184 self
185 }
186
187 pub fn headers<I, T>(&mut self, iter: I) -> &mut Self
189 where
190 I: Iterator<Item = T>,
191 T: Into<(Option<HeaderName>, HeaderValue)>,
192 {
193 self._headers
194 .get_or_insert(None)
195 .get_or_insert_with(HeaderMap::new)
196 .extend(iter.map(Into::into));
197 self
198 }
199}
200
201impl RestEndpoint for Request<'_> {
202 fn method(&self) -> http::Method {
203 http::Method::POST
204 }
205
206 fn endpoint(&self) -> Cow<'static, str> {
207 format!(
208 "lbaas/pools/{pool_id}/members",
209 pool_id = self.pool_id.as_ref(),
210 )
211 .into()
212 }
213
214 fn parameters(&self) -> QueryParams<'_> {
215 QueryParams::default()
216 }
217
218 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
219 let mut params = JsonBodyParams::default();
220
221 params.push("member", serde_json::to_value(&self.member)?);
222
223 params.into_body()
224 }
225
226 fn service_type(&self) -> ServiceType {
227 ServiceType::LoadBalancer
228 }
229
230 fn response_key(&self) -> Option<Cow<'static, str>> {
231 Some("member".into())
232 }
233
234 fn request_headers(&self) -> Option<&HeaderMap> {
236 self._headers.as_ref()
237 }
238
239 fn api_version(&self) -> Option<ApiVersion> {
241 Some(ApiVersion::new(2, 0))
242 }
243}
244
245#[cfg(test)]
246mod tests {
247 use super::*;
248 use http::{HeaderName, HeaderValue};
249 use httpmock::MockServer;
250 #[cfg(feature = "sync")]
251 use openstack_sdk_core::api::Query;
252 use openstack_sdk_core::test::client::FakeOpenStackClient;
253 use openstack_sdk_core::types::ServiceType;
254 use serde_json::json;
255
256 #[test]
257 fn test_service_type() {
258 assert_eq!(
259 Request::builder()
260 .member(
261 MemberBuilder::default()
262 .address("foo")
263 .protocol_port(123)
264 .build()
265 .unwrap()
266 )
267 .build()
268 .unwrap()
269 .service_type(),
270 ServiceType::LoadBalancer
271 );
272 }
273
274 #[test]
275 fn test_response_key() {
276 assert_eq!(
277 Request::builder()
278 .member(
279 MemberBuilder::default()
280 .address("foo")
281 .protocol_port(123)
282 .build()
283 .unwrap()
284 )
285 .build()
286 .unwrap()
287 .response_key()
288 .unwrap(),
289 "member"
290 );
291 }
292
293 #[cfg(feature = "sync")]
294 #[test]
295 fn endpoint() {
296 let server = MockServer::start();
297 let client = FakeOpenStackClient::new(server.base_url());
298 let mock = server.mock(|when, then| {
299 when.method(httpmock::Method::POST).path(format!(
300 "/lbaas/pools/{pool_id}/members",
301 pool_id = "pool_id",
302 ));
303
304 then.status(200)
305 .header("content-type", "application/json")
306 .json_body(json!({ "member": {} }));
307 });
308
309 let endpoint = Request::builder()
310 .pool_id("pool_id")
311 .member(
312 MemberBuilder::default()
313 .address("foo")
314 .protocol_port(123)
315 .build()
316 .unwrap(),
317 )
318 .build()
319 .unwrap();
320 let _: serde_json::Value = endpoint.query(&client).unwrap();
321 mock.assert();
322 }
323
324 #[cfg(feature = "sync")]
325 #[test]
326 fn endpoint_headers() {
327 let server = MockServer::start();
328 let client = FakeOpenStackClient::new(server.base_url());
329 let mock = server.mock(|when, then| {
330 when.method(httpmock::Method::POST)
331 .path(format!(
332 "/lbaas/pools/{pool_id}/members",
333 pool_id = "pool_id",
334 ))
335 .header("foo", "bar")
336 .header("not_foo", "not_bar");
337 then.status(200)
338 .header("content-type", "application/json")
339 .json_body(json!({ "member": {} }));
340 });
341
342 let endpoint = Request::builder()
343 .pool_id("pool_id")
344 .member(
345 MemberBuilder::default()
346 .address("foo")
347 .protocol_port(123)
348 .build()
349 .unwrap(),
350 )
351 .headers(
352 [(
353 Some(HeaderName::from_static("foo")),
354 HeaderValue::from_static("bar"),
355 )]
356 .into_iter(),
357 )
358 .header(
359 HeaderName::from_static("not_foo"),
360 HeaderValue::from_static("not_bar"),
361 )
362 .build()
363 .unwrap();
364 let _: serde_json::Value = endpoint.query(&client).unwrap();
365 mock.assert();
366 }
367}