openstack_sdk/api/compute/v2/server_external_event/
create_282.rs1use derive_builder::Builder;
34use http::{HeaderMap, HeaderName, HeaderValue};
35
36use crate::api::rest_endpoint_prelude::*;
37
38use serde::Deserialize;
39use serde::Serialize;
40use std::borrow::Cow;
41
42#[derive(Debug, Deserialize, Clone, Serialize)]
43pub enum Name {
44 #[serde(rename = "accelerator-request-bound")]
45 AcceleratorRequestBound,
46 #[serde(rename = "network-changed")]
47 NetworkChanged,
48 #[serde(rename = "network-vif-deleted")]
49 NetworkVifDeleted,
50 #[serde(rename = "network-vif-plugged")]
51 NetworkVifPlugged,
52 #[serde(rename = "network-vif-unplugged")]
53 NetworkVifUnplugged,
54 #[serde(rename = "power-update")]
55 PowerUpdate,
56 #[serde(rename = "volume-extended")]
57 VolumeExtended,
58}
59
60#[derive(Debug, Deserialize, Clone, Serialize)]
61pub enum Status {
62 #[serde(rename = "completed")]
63 Completed,
64 #[serde(rename = "failed")]
65 Failed,
66 #[serde(rename = "in-progress")]
67 InProgress,
68}
69
70#[derive(Builder, Debug, Deserialize, Clone, Serialize)]
71#[builder(setter(strip_option))]
72pub struct Events<'a> {
73 #[serde()]
84 #[builder()]
85 pub(crate) name: Name,
86
87 #[serde()]
91 #[builder(setter(into))]
92 pub(crate) server_uuid: Cow<'a, str>,
93
94 #[serde(skip_serializing_if = "Option::is_none")]
97 #[builder(default)]
98 pub(crate) status: Option<Status>,
99
100 #[serde(skip_serializing_if = "Option::is_none")]
109 #[builder(default, setter(into))]
110 pub(crate) tag: Option<Cow<'a, str>>,
111}
112
113#[derive(Builder, Debug, Clone)]
114#[builder(setter(strip_option))]
115pub struct Request<'a> {
116 #[builder(setter(into))]
118 pub(crate) events: Vec<Events<'a>>,
119
120 #[builder(setter(name = "_headers"), default, private)]
121 _headers: Option<HeaderMap>,
122}
123impl<'a> Request<'a> {
124 pub fn builder() -> RequestBuilder<'a> {
126 RequestBuilder::default()
127 }
128}
129
130impl<'a> RequestBuilder<'a> {
131 pub fn header<K, V>(&mut self, header_name: K, header_value: V) -> &mut Self
133 where
134 K: Into<HeaderName>,
135 V: Into<HeaderValue>,
136 {
137 self._headers
138 .get_or_insert(None)
139 .get_or_insert_with(HeaderMap::new)
140 .insert(header_name.into(), header_value.into());
141 self
142 }
143
144 pub fn headers<I, T>(&mut self, iter: I) -> &mut Self
146 where
147 I: Iterator<Item = T>,
148 T: Into<(Option<HeaderName>, HeaderValue)>,
149 {
150 self._headers
151 .get_or_insert(None)
152 .get_or_insert_with(HeaderMap::new)
153 .extend(iter.map(Into::into));
154 self
155 }
156}
157
158impl RestEndpoint for Request<'_> {
159 fn method(&self) -> http::Method {
160 http::Method::POST
161 }
162
163 fn endpoint(&self) -> Cow<'static, str> {
164 "os-server-external-events".to_string().into()
165 }
166
167 fn parameters(&self) -> QueryParams<'_> {
168 QueryParams::default()
169 }
170
171 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
172 let mut params = JsonBodyParams::default();
173
174 params.push("events", serde_json::to_value(&self.events)?);
175
176 params.into_body()
177 }
178
179 fn service_type(&self) -> ServiceType {
180 ServiceType::Compute
181 }
182
183 fn response_key(&self) -> Option<Cow<'static, str>> {
184 None
185 }
186
187 fn request_headers(&self) -> Option<&HeaderMap> {
189 self._headers.as_ref()
190 }
191
192 fn api_version(&self) -> Option<ApiVersion> {
194 Some(ApiVersion::new(2, 82))
195 }
196}
197
198#[cfg(test)]
199mod tests {
200 use super::*;
201 #[cfg(feature = "sync")]
202 use crate::api::Query;
203 use crate::test::client::FakeOpenStackClient;
204 use crate::types::ServiceType;
205 use http::{HeaderName, HeaderValue};
206 use httpmock::MockServer;
207 use serde_json::json;
208
209 #[test]
210 fn test_service_type() {
211 assert_eq!(
212 Request::builder()
213 .events(Vec::from([EventsBuilder::default()
214 .name(Name::AcceleratorRequestBound)
215 .server_uuid("foo")
216 .build()
217 .unwrap()]))
218 .build()
219 .unwrap()
220 .service_type(),
221 ServiceType::Compute
222 );
223 }
224
225 #[test]
226 fn test_response_key() {
227 assert!(Request::builder()
228 .events(Vec::from([EventsBuilder::default()
229 .name(Name::AcceleratorRequestBound)
230 .server_uuid("foo")
231 .build()
232 .unwrap()]))
233 .build()
234 .unwrap()
235 .response_key()
236 .is_none())
237 }
238
239 #[cfg(feature = "sync")]
240 #[test]
241 fn endpoint() {
242 let server = MockServer::start();
243 let client = FakeOpenStackClient::new(server.base_url());
244 let mock = server.mock(|when, then| {
245 when.method(httpmock::Method::POST)
246 .path("/os-server-external-events".to_string());
247
248 then.status(200)
249 .header("content-type", "application/json")
250 .json_body(json!({ "dummy": {} }));
251 });
252
253 let endpoint = Request::builder()
254 .events(Vec::from([EventsBuilder::default()
255 .name(Name::AcceleratorRequestBound)
256 .server_uuid("foo")
257 .build()
258 .unwrap()]))
259 .build()
260 .unwrap();
261 let _: serde_json::Value = endpoint.query(&client).unwrap();
262 mock.assert();
263 }
264
265 #[cfg(feature = "sync")]
266 #[test]
267 fn endpoint_headers() {
268 let server = MockServer::start();
269 let client = FakeOpenStackClient::new(server.base_url());
270 let mock = server.mock(|when, then| {
271 when.method(httpmock::Method::POST)
272 .path("/os-server-external-events".to_string())
273 .header("foo", "bar")
274 .header("not_foo", "not_bar");
275 then.status(200)
276 .header("content-type", "application/json")
277 .json_body(json!({ "dummy": {} }));
278 });
279
280 let endpoint = Request::builder()
281 .events(Vec::from([EventsBuilder::default()
282 .name(Name::AcceleratorRequestBound)
283 .server_uuid("foo")
284 .build()
285 .unwrap()]))
286 .headers(
287 [(
288 Some(HeaderName::from_static("foo")),
289 HeaderValue::from_static("bar"),
290 )]
291 .into_iter(),
292 )
293 .header(
294 HeaderName::from_static("not_foo"),
295 HeaderValue::from_static("not_bar"),
296 )
297 .build()
298 .unwrap();
299 let _: serde_json::Value = endpoint.query(&client).unwrap();
300 mock.assert();
301 }
302}