Skip to main content

regent_sdk/state/attribute/utilities/
debug.rs

1//! Debug message attribute
2//!
3//! This module provides the `DebugBlockExpectedState` type for outputting debug messages
4//! during compliance assessment. Useful for troubleshooting and logging.
5//!
6//! **Compatible OS:** All (cross-platform)
7//!
8//! # Examples
9//!
10//! ## Rust API
11//!
12//! ```no_run
13//! use regent_sdk::state::attribute::utilities::debug::DebugBlockExpectedState;
14//! use regent_sdk::{Attribute, ExpectedState, Privilege};
15//!
16//! // Output a debug message
17//! let debug_msg = DebugBlockExpectedState::builder("Checking system configuration")
18//!     .build()
19//!     .unwrap();
20//!
21//! let expected_state = ExpectedState::new()
22//!     .with_attribute(Attribute::debug(debug_msg, Privilege::None, None))
23//!     .build();
24//! ```
25//!
26//! ## YAML API
27//!
28//! ```yaml
29//! Attributes:
30//!   - Name: Debug message to print
31//!     Privilege: !None
32//!     Detail: !Debug
33//!       Msg: "Checking system configuration"
34//! ```
35
36use crate::error::RegentError;
37use crate::hosts::managed_host::InternalApiCallOutcome;
38use crate::hosts::managed_host::{AssessCompliance, ReachCompliance, Timeout};
39use crate::hosts::properties::HostProperties;
40use crate::secrets::SecretProvidersPool;
41use crate::state::Check;
42use crate::state::attribute::HostHandler;
43use crate::state::attribute::Privilege;
44
45use crate::state::compliance::AttributeComplianceAssessment;
46use serde::{Deserialize, Serialize};
47use std::time::Duration;
48
49/// Configuration for a debug message
50#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
51#[serde(deny_unknown_fields)]
52#[serde(rename_all = "PascalCase")]
53pub struct DebugBlockExpectedState {
54    /// Debug message to output during compliance assessment
55    msg: String,
56    // var: Option<String>, // TODO
57}
58
59impl Timeout for DebugBlockExpectedState {
60    fn default_timeout(&self) -> Duration {
61        Duration::from_secs(1)
62    }
63}
64
65impl Check for DebugBlockExpectedState {
66    fn check(&self) -> Result<(), RegentError> {
67        Ok(())
68    }
69
70    fn check_host_compatibility(
71        &self,
72        _host_properties: &HostProperties,
73    ) -> Result<(), RegentError> {
74        // Debug messages are cross-platform compatible
75        Ok(())
76    }
77}
78
79impl<Handler: HostHandler> AssessCompliance<Handler> for DebugBlockExpectedState {
80    async fn assess_compliance(
81        &self,
82        _host_handler: &mut Handler,
83        host_properties: &Option<HostProperties>,
84        _privilege: &Privilege,
85        _optional_secret_provider: &Option<SecretProvidersPool>,
86    ) -> Result<AttributeComplianceAssessment, RegentError> {
87        // Early check: verify host compatibility (always passes for debug)
88        if let Some(props) = host_properties {
89            self.check_host_compatibility(props)?;
90        }
91        // Debug is a no-op that doesn't affect compliance state
92        return Ok(AttributeComplianceAssessment::Compliant);
93    }
94}
95
96#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
97pub struct DebugApiCall {}
98
99impl DebugApiCall {
100    pub fn display(&self) -> String {
101        "Debug module".into()
102    }
103}
104
105impl Timeout for DebugApiCall {
106    fn default_timeout(&self) -> Duration {
107        Duration::from_secs(1)
108    }
109}
110
111impl Check for DebugApiCall {
112    fn check(&self) -> Result<(), RegentError> {
113        Ok(())
114    }
115
116    fn check_host_compatibility(
117        &self,
118        _host_properties: &HostProperties,
119    ) -> Result<(), RegentError> {
120        // Debug messages are cross-platform compatible
121        Ok(())
122    }
123}
124
125impl<Handler: HostHandler> ReachCompliance<Handler> for DebugApiCall {
126    async fn call(
127        &self,
128        _host_handler: &mut Handler,
129        host_properties: &Option<HostProperties>,
130        _optional_secret_provider: &Option<SecretProvidersPool>,
131    ) -> Result<InternalApiCallOutcome, RegentError> {
132        // Early check: verify host compatibility (always passes for debug)
133        if let Some(props) = host_properties {
134            self.check_host_compatibility(props)?;
135        }
136
137        Ok(InternalApiCallOutcome::Success(None))
138    }
139}
140
141#[cfg(test)]
142mod tests {
143
144    use super::*;
145
146    #[test]
147    fn parsing_debug_module_block_from_yaml_str() {
148        let attribute = "---
149Msg: some content
150    ";
151
152        let attribute: DebugBlockExpectedState = yaml_serde::from_str(attribute).unwrap();
153
154        assert_eq!(attribute.msg, "some content".to_string());
155    }
156}