icinga2_api/api/action/
process_check_result.rs

1//! API Action process-check-result
2//!
3//! [Official Documentation](https://icinga.com/docs/icinga-2/latest/doc/12-icinga2-api/#process-check-result)
4
5use serde::{Deserialize, Serialize};
6
7use crate::serde::{
8    deserialize_optional_icinga_timestamp, deserialize_optional_seconds_as_duration,
9    serialize_optional_duration_as_seconds, serialize_optional_icinga_timestamp,
10};
11use crate::types::action::StatusResponse;
12use crate::types::common::{command::IcingaCommandLine, performance_data::IcingaPerformanceData};
13use crate::types::enums::object_type::IcingaObjectType;
14use crate::types::filter::IcingaFilter;
15use crate::types::query::ResultsWrapper;
16use crate::types::rest::{RestApiEndpoint, RestApiResponse};
17
18/// REST API Endpoint for the process-check-result call
19#[derive(Debug, Clone, derive_builder::Builder, Serialize, Deserialize)]
20#[builder(
21    build_fn(error = "crate::error::Error", validate = "Self::validate"),
22    derive(Debug)
23)]
24pub struct ProcessCheckResult {
25    ///  For services: 0=OK, 1=WARNING, 2=CRITICAL, 3=UNKNOWN
26    ///  For hosts: 0=UP, 1=DOWN
27    pub exit_status: u64,
28    /// the plugin output without the performance data
29    pub plugin_output: String,
30    /// the performance data
31    #[builder(default)]
32    pub performance_data: Option<Vec<IcingaPerformanceData>>,
33    /// the check command
34    #[builder(default)]
35    pub check_command: Option<IcingaCommandLine>,
36    /// usually the name of the command endpoint
37    #[builder(default)]
38    pub check_source: Option<String>,
39    /// the start time of the check command execution
40    #[serde(
41        serialize_with = "serialize_optional_icinga_timestamp",
42        deserialize_with = "deserialize_optional_icinga_timestamp"
43    )]
44    pub execution_start: Option<time::OffsetDateTime>,
45    /// the end time of the check command execution
46    #[serde(
47        serialize_with = "serialize_optional_icinga_timestamp",
48        deserialize_with = "deserialize_optional_icinga_timestamp"
49    )]
50    pub execution_end: Option<time::OffsetDateTime>,
51    /// Time-to-live duration in seconds for this check result. The next expected check result is now + ttl where freshness checks are executed.
52    #[serde(
53        serialize_with = "serialize_optional_duration_as_seconds",
54        deserialize_with = "deserialize_optional_seconds_as_duration"
55    )]
56    pub ttl: Option<time::Duration>,
57    /// filter to target which host and/or service this check result applies to
58    #[builder(default, setter(strip_option, into))]
59    #[serde(flatten)]
60    filter: Option<IcingaFilter>,
61}
62
63impl ProcessCheckResult {
64    /// create a new builder for this endpoint
65    ///
66    /// this is usually the first step to calling this REST API endpoint
67    #[must_use]
68    pub fn builder() -> ProcessCheckResultBuilder {
69        ProcessCheckResultBuilder::default()
70    }
71}
72
73impl ProcessCheckResultBuilder {
74    /// makes sure the filter object type is valid for this call (either Host or Service)
75    ///
76    /// # Errors
77    ///
78    /// this returns an error if the filter field object type is not Host or Service
79    pub fn validate(&self) -> Result<(), crate::error::Error> {
80        if let Some(Some(filter)) = &self.filter {
81            if filter.object_type != IcingaObjectType::Host
82                && filter.object_type != IcingaObjectType::Service
83            {
84                Err(crate::error::Error::FilterObjectTypeMismatch(
85                    vec![IcingaObjectType::Host, IcingaObjectType::Service],
86                    filter.object_type.to_owned(),
87                ))
88            } else {
89                Ok(())
90            }
91        } else {
92            Ok(())
93        }
94    }
95}
96
97impl RestApiEndpoint for ProcessCheckResult {
98    type RequestBody = ProcessCheckResult;
99
100    fn method(&self) -> Result<reqwest::Method, crate::error::Error> {
101        Ok(reqwest::Method::POST)
102    }
103
104    fn url(&self, base_url: &url::Url) -> Result<url::Url, crate::error::Error> {
105        base_url
106            .join("v1/actions/process-check-result")
107            .map_err(crate::error::Error::CouldNotParseUrlFragment)
108    }
109
110    fn request_body(
111        &self,
112    ) -> Result<Option<std::borrow::Cow<Self::RequestBody>>, crate::error::Error>
113    where
114        Self::RequestBody: Clone + serde::Serialize + std::fmt::Debug,
115    {
116        Ok(Some(std::borrow::Cow::Borrowed(self)))
117    }
118}
119
120impl RestApiResponse<ProcessCheckResult> for ResultsWrapper<StatusResponse> {}