openstack_sdk/api/compute/v2/server/interface/
create_249.rs1use derive_builder::Builder;
26use http::{HeaderMap, HeaderName, HeaderValue};
27
28use crate::api::rest_endpoint_prelude::*;
29
30use serde::Deserialize;
31use serde::Serialize;
32use std::borrow::Cow;
33
34#[derive(Builder, Debug, Deserialize, Clone, Serialize)]
35#[builder(setter(strip_option))]
36pub struct FixedIps<'a> {
37 #[serde()]
39 #[builder(setter(into))]
40 pub(crate) ip_address: Cow<'a, str>,
41}
42
43#[derive(Builder, Debug, Deserialize, Clone, Serialize)]
45#[builder(setter(strip_option))]
46pub struct InterfaceAttachment<'a> {
47 #[serde(skip_serializing_if = "Option::is_none")]
50 #[builder(default, setter(into))]
51 pub(crate) fixed_ips: Option<Vec<FixedIps<'a>>>,
52
53 #[serde(skip_serializing_if = "Option::is_none")]
59 #[builder(default, setter(into))]
60 pub(crate) net_id: Option<Cow<'a, str>>,
61
62 #[serde(skip_serializing_if = "Option::is_none")]
67 #[builder(default, setter(into))]
68 pub(crate) port_id: Option<Cow<'a, str>>,
69
70 #[serde(skip_serializing_if = "Option::is_none")]
77 #[builder(default, setter(into))]
78 pub(crate) tag: Option<Cow<'a, str>>,
79}
80
81#[derive(Builder, Debug, Clone)]
82#[builder(setter(strip_option))]
83pub struct Request<'a> {
84 #[builder(setter(into))]
86 pub(crate) interface_attachment: InterfaceAttachment<'a>,
87
88 #[builder(default, setter(into))]
90 server_id: Cow<'a, str>,
91
92 #[builder(setter(name = "_headers"), default, private)]
93 _headers: Option<HeaderMap>,
94}
95impl<'a> Request<'a> {
96 pub fn builder() -> RequestBuilder<'a> {
98 RequestBuilder::default()
99 }
100}
101
102impl<'a> RequestBuilder<'a> {
103 pub fn header<K, V>(&mut self, header_name: K, header_value: V) -> &mut Self
105 where
106 K: Into<HeaderName>,
107 V: Into<HeaderValue>,
108 {
109 self._headers
110 .get_or_insert(None)
111 .get_or_insert_with(HeaderMap::new)
112 .insert(header_name.into(), header_value.into());
113 self
114 }
115
116 pub fn headers<I, T>(&mut self, iter: I) -> &mut Self
118 where
119 I: Iterator<Item = T>,
120 T: Into<(Option<HeaderName>, HeaderValue)>,
121 {
122 self._headers
123 .get_or_insert(None)
124 .get_or_insert_with(HeaderMap::new)
125 .extend(iter.map(Into::into));
126 self
127 }
128}
129
130impl RestEndpoint for Request<'_> {
131 fn method(&self) -> http::Method {
132 http::Method::POST
133 }
134
135 fn endpoint(&self) -> Cow<'static, str> {
136 format!(
137 "servers/{server_id}/os-interface",
138 server_id = self.server_id.as_ref(),
139 )
140 .into()
141 }
142
143 fn parameters(&self) -> QueryParams<'_> {
144 QueryParams::default()
145 }
146
147 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
148 let mut params = JsonBodyParams::default();
149
150 params.push(
151 "interfaceAttachment",
152 serde_json::to_value(&self.interface_attachment)?,
153 );
154
155 params.into_body()
156 }
157
158 fn service_type(&self) -> ServiceType {
159 ServiceType::Compute
160 }
161
162 fn response_key(&self) -> Option<Cow<'static, str>> {
163 Some("interfaceAttachment".into())
164 }
165
166 fn request_headers(&self) -> Option<&HeaderMap> {
168 self._headers.as_ref()
169 }
170
171 fn api_version(&self) -> Option<ApiVersion> {
173 Some(ApiVersion::new(2, 49))
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use super::*;
180 #[cfg(feature = "sync")]
181 use crate::api::Query;
182 use crate::test::client::FakeOpenStackClient;
183 use crate::types::ServiceType;
184 use http::{HeaderName, HeaderValue};
185 use httpmock::MockServer;
186 use serde_json::json;
187
188 #[test]
189 fn test_service_type() {
190 assert_eq!(
191 Request::builder()
192 .interface_attachment(InterfaceAttachmentBuilder::default().build().unwrap())
193 .build()
194 .unwrap()
195 .service_type(),
196 ServiceType::Compute
197 );
198 }
199
200 #[test]
201 fn test_response_key() {
202 assert_eq!(
203 Request::builder()
204 .interface_attachment(InterfaceAttachmentBuilder::default().build().unwrap())
205 .build()
206 .unwrap()
207 .response_key()
208 .unwrap(),
209 "interfaceAttachment"
210 );
211 }
212
213 #[cfg(feature = "sync")]
214 #[test]
215 fn endpoint() {
216 let server = MockServer::start();
217 let client = FakeOpenStackClient::new(server.base_url());
218 let mock = server.mock(|when, then| {
219 when.method(httpmock::Method::POST).path(format!(
220 "/servers/{server_id}/os-interface",
221 server_id = "server_id",
222 ));
223
224 then.status(200)
225 .header("content-type", "application/json")
226 .json_body(json!({ "interfaceAttachment": {} }));
227 });
228
229 let endpoint = Request::builder()
230 .server_id("server_id")
231 .interface_attachment(InterfaceAttachmentBuilder::default().build().unwrap())
232 .build()
233 .unwrap();
234 let _: serde_json::Value = endpoint.query(&client).unwrap();
235 mock.assert();
236 }
237
238 #[cfg(feature = "sync")]
239 #[test]
240 fn endpoint_headers() {
241 let server = MockServer::start();
242 let client = FakeOpenStackClient::new(server.base_url());
243 let mock = server.mock(|when, then| {
244 when.method(httpmock::Method::POST)
245 .path(format!(
246 "/servers/{server_id}/os-interface",
247 server_id = "server_id",
248 ))
249 .header("foo", "bar")
250 .header("not_foo", "not_bar");
251 then.status(200)
252 .header("content-type", "application/json")
253 .json_body(json!({ "interfaceAttachment": {} }));
254 });
255
256 let endpoint = Request::builder()
257 .server_id("server_id")
258 .interface_attachment(InterfaceAttachmentBuilder::default().build().unwrap())
259 .headers(
260 [(
261 Some(HeaderName::from_static("foo")),
262 HeaderValue::from_static("bar"),
263 )]
264 .into_iter(),
265 )
266 .header(
267 HeaderName::from_static("not_foo"),
268 HeaderValue::from_static("not_bar"),
269 )
270 .build()
271 .unwrap();
272 let _: serde_json::Value = endpoint.query(&client).unwrap();
273 mock.assert();
274 }
275}