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