openstack_sdk/api/compute/v2/server/volume_attachment/
create_20.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)]
37#[builder(setter(strip_option))]
38pub struct VolumeAttachment<'a> {
39 #[serde(skip_serializing_if = "Option::is_none")]
46 #[builder(default, setter(into))]
47 pub(crate) device: Option<Option<Cow<'a, str>>>,
48
49 #[serde(rename = "volumeId")]
51 #[builder(setter(into))]
52 pub(crate) volume_id: Cow<'a, str>,
53}
54
55#[derive(Builder, Debug, Clone)]
56#[builder(setter(strip_option))]
57pub struct Request<'a> {
58 #[builder(setter(into))]
61 pub(crate) volume_attachment: VolumeAttachment<'a>,
62
63 #[builder(default, setter(into))]
66 server_id: Cow<'a, str>,
67
68 #[builder(setter(name = "_headers"), default, private)]
69 _headers: Option<HeaderMap>,
70}
71impl<'a> Request<'a> {
72 pub fn builder() -> RequestBuilder<'a> {
74 RequestBuilder::default()
75 }
76}
77
78impl RequestBuilder<'_> {
79 pub fn header(&mut self, header_name: &'static str, header_value: &'static str) -> &mut Self
81where {
82 self._headers
83 .get_or_insert(None)
84 .get_or_insert_with(HeaderMap::new)
85 .insert(header_name, HeaderValue::from_static(header_value));
86 self
87 }
88
89 pub fn headers<I, T>(&mut self, iter: I) -> &mut Self
91 where
92 I: Iterator<Item = T>,
93 T: Into<(Option<HeaderName>, HeaderValue)>,
94 {
95 self._headers
96 .get_or_insert(None)
97 .get_or_insert_with(HeaderMap::new)
98 .extend(iter.map(Into::into));
99 self
100 }
101}
102
103impl RestEndpoint for Request<'_> {
104 fn method(&self) -> http::Method {
105 http::Method::POST
106 }
107
108 fn endpoint(&self) -> Cow<'static, str> {
109 format!(
110 "servers/{server_id}/os-volume_attachments",
111 server_id = self.server_id.as_ref(),
112 )
113 .into()
114 }
115
116 fn parameters(&self) -> QueryParams {
117 QueryParams::default()
118 }
119
120 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
121 let mut params = JsonBodyParams::default();
122
123 params.push(
124 "volumeAttachment",
125 serde_json::to_value(&self.volume_attachment)?,
126 );
127
128 params.into_body()
129 }
130
131 fn service_type(&self) -> ServiceType {
132 ServiceType::Compute
133 }
134
135 fn response_key(&self) -> Option<Cow<'static, str>> {
136 Some("volumeAttachment".into())
137 }
138
139 fn request_headers(&self) -> Option<&HeaderMap> {
141 self._headers.as_ref()
142 }
143
144 fn api_version(&self) -> Option<ApiVersion> {
146 Some(ApiVersion::new(2, 0))
147 }
148}
149
150#[cfg(test)]
151mod tests {
152 use super::*;
153 #[cfg(feature = "sync")]
154 use crate::api::Query;
155 use crate::test::client::FakeOpenStackClient;
156 use crate::types::ServiceType;
157 use http::{HeaderName, HeaderValue};
158 use httpmock::MockServer;
159 use serde_json::json;
160
161 #[test]
162 fn test_service_type() {
163 assert_eq!(
164 Request::builder()
165 .volume_attachment(
166 VolumeAttachmentBuilder::default()
167 .volume_id("foo")
168 .build()
169 .unwrap()
170 )
171 .build()
172 .unwrap()
173 .service_type(),
174 ServiceType::Compute
175 );
176 }
177
178 #[test]
179 fn test_response_key() {
180 assert_eq!(
181 Request::builder()
182 .volume_attachment(
183 VolumeAttachmentBuilder::default()
184 .volume_id("foo")
185 .build()
186 .unwrap()
187 )
188 .build()
189 .unwrap()
190 .response_key()
191 .unwrap(),
192 "volumeAttachment"
193 );
194 }
195
196 #[cfg(feature = "sync")]
197 #[test]
198 fn endpoint() {
199 let server = MockServer::start();
200 let client = FakeOpenStackClient::new(server.base_url());
201 let mock = server.mock(|when, then| {
202 when.method(httpmock::Method::POST).path(format!(
203 "/servers/{server_id}/os-volume_attachments",
204 server_id = "server_id",
205 ));
206
207 then.status(200)
208 .header("content-type", "application/json")
209 .json_body(json!({ "volumeAttachment": {} }));
210 });
211
212 let endpoint = Request::builder()
213 .server_id("server_id")
214 .volume_attachment(
215 VolumeAttachmentBuilder::default()
216 .volume_id("foo")
217 .build()
218 .unwrap(),
219 )
220 .build()
221 .unwrap();
222 let _: serde_json::Value = endpoint.query(&client).unwrap();
223 mock.assert();
224 }
225
226 #[cfg(feature = "sync")]
227 #[test]
228 fn endpoint_headers() {
229 let server = MockServer::start();
230 let client = FakeOpenStackClient::new(server.base_url());
231 let mock = server.mock(|when, then| {
232 when.method(httpmock::Method::POST)
233 .path(format!(
234 "/servers/{server_id}/os-volume_attachments",
235 server_id = "server_id",
236 ))
237 .header("foo", "bar")
238 .header("not_foo", "not_bar");
239 then.status(200)
240 .header("content-type", "application/json")
241 .json_body(json!({ "volumeAttachment": {} }));
242 });
243
244 let endpoint = Request::builder()
245 .server_id("server_id")
246 .volume_attachment(
247 VolumeAttachmentBuilder::default()
248 .volume_id("foo")
249 .build()
250 .unwrap(),
251 )
252 .headers(
253 [(
254 Some(HeaderName::from_static("foo")),
255 HeaderValue::from_static("bar"),
256 )]
257 .into_iter(),
258 )
259 .header("not_foo", "not_bar")
260 .build()
261 .unwrap();
262 let _: serde_json::Value = endpoint.query(&client).unwrap();
263 mock.assert();
264 }
265}