icinga2_api/api/action/
send_custom_notification.rs

1//! API Action send-custom-notification
2//!
3//! [Official Documentation](https://icinga.com/docs/icinga-2/latest/doc/12-icinga2-api/#send-custom-notification)
4
5use serde::{Deserialize, Serialize};
6
7use crate::types::action::StatusResponse;
8use crate::types::enums::object_type::IcingaObjectType;
9use crate::types::filter::IcingaFilter;
10use crate::types::query::ResultsWrapper;
11use crate::types::rest::{RestApiEndpoint, RestApiResponse};
12
13/// REST API Endpoint for the reschedule-check call
14#[derive(Debug, Clone, derive_builder::Builder, Serialize, Deserialize)]
15#[builder(
16    build_fn(error = "crate::error::Error", validate = "Self::validate"),
17    derive(Debug)
18)]
19pub struct SendCustomNotification {
20    /// the author of the custom notification
21    author: String,
22    /// the body of the custom notification
23    comment: String,
24    /// Default: false. If true, the notification is sent regardless of downtimes or whether notifications are enabled or not.
25    force: Option<bool>,
26    /// filter to target which host and/or service for which to send the custom notification
27    #[builder(default, setter(strip_option, into))]
28    #[serde(flatten)]
29    filter: Option<IcingaFilter>,
30}
31
32impl SendCustomNotification {
33    /// create a new builder for this endpoint
34    ///
35    /// this is usually the first step to calling this REST API endpoint
36    #[must_use]
37    pub fn builder() -> SendCustomNotificationBuilder {
38        SendCustomNotificationBuilder::default()
39    }
40}
41
42impl SendCustomNotificationBuilder {
43    /// makes sure the filter object type is valid for this call (either Host or Service)
44    ///
45    /// # Errors
46    ///
47    /// this returns an error if the filter field object type is not Host or Service
48    pub fn validate(&self) -> Result<(), crate::error::Error> {
49        if let Some(Some(filter)) = &self.filter {
50            if filter.object_type != IcingaObjectType::Host
51                && filter.object_type != IcingaObjectType::Service
52            {
53                Err(crate::error::Error::FilterObjectTypeMismatch(
54                    vec![IcingaObjectType::Host, IcingaObjectType::Service],
55                    filter.object_type.to_owned(),
56                ))
57            } else {
58                Ok(())
59            }
60        } else {
61            Ok(())
62        }
63    }
64}
65
66impl RestApiEndpoint for SendCustomNotification {
67    type RequestBody = SendCustomNotification;
68
69    fn method(&self) -> Result<reqwest::Method, crate::error::Error> {
70        Ok(reqwest::Method::POST)
71    }
72
73    fn url(&self, base_url: &url::Url) -> Result<url::Url, crate::error::Error> {
74        base_url
75            .join("v1/actions/send-custom-notification")
76            .map_err(crate::error::Error::CouldNotParseUrlFragment)
77    }
78
79    fn request_body(
80        &self,
81    ) -> Result<Option<std::borrow::Cow<Self::RequestBody>>, crate::error::Error>
82    where
83        Self::RequestBody: Clone + serde::Serialize + std::fmt::Debug,
84    {
85        Ok(Some(std::borrow::Cow::Borrowed(self)))
86    }
87}
88
89impl RestApiResponse<SendCustomNotification> for ResultsWrapper<StatusResponse> {}