datadog_agent_config_testing/config_registry/
mod.rs

1/// Datadog Agent configuration annotations, generated from `schema_overlay.yaml`.
2///
3/// Type definitions live here (hand-written); the annotation constants and statics live in the
4/// `generated` module, which `build.rs` writes and `.gitignore` excludes.
5pub use datadog_agent_config::classifier::{structs, Pipeline, PipelineAffinity, Severity};
6
7/// Support level for a configuration key, as recorded in the testing annotation layer.
8///
9/// Unlike the prod [`datadog_agent_config::classifier::SupportLevel`], this enum includes
10/// [`Full`][SupportLevel::Full] so that generated annotation constants can express keys that work
11/// identically to the core agent. The prod classifier omits `Full` because fully supported keys
12/// require no diagnostic action.
13#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14pub enum SupportLevel {
15    /// Fully supported with identical behavior to the core agent.
16    Full,
17    /// Supported but with behavioral or default-value differences.
18    Partial,
19    /// Explicitly incompatible; ADP does not support this key.
20    Incompatible(Severity),
21    /// Intentionally ignored.
22    #[allow(unused)]
23    Ignored,
24    /// Unrecognized by ADP.
25    #[allow(unused)]
26    Unrecognized,
27}
28
29/// Declares a set of [`SalukiAnnotation`] constants and generates a companion `ALL` slice.
30///
31/// Each entry declares one named `pub const` annotation. The macro also emits:
32///
33/// ```ignore
34/// pub const ALL: &[&SalukiAnnotation] = &[&NAME1, &NAME2, ...];
35/// ```
36///
37/// so that `annotations_index.rs` can aggregate submodules with a single
38/// `v.extend_from_slice(my_module::ALL)` line rather than listing every constant by name.
39#[macro_export]
40macro_rules! declare_annotations {
41    ( $( $(#[$attr:meta])* $name:ident = $val:expr ;)+ ) => {
42        $(
43            $(#[$attr])*
44            pub const $name: $crate::config_registry::SalukiAnnotation = $val;
45        )+
46
47        /// All annotations declared in this module, in declaration order.
48        pub const ALL: &[$crate::config_registry::SalukiAnnotationRef] = &[
49            $( &$name, )+
50        ];
51    };
52}
53
54/// The shape of a configuration value.
55#[derive(Clone, Copy, Debug, PartialEq, Eq)]
56pub enum ValueType {
57    /// A boolean (`true` / `false`).
58    Bool,
59    /// A UTF-8 string.
60    String,
61    /// An unsigned integer.
62    Integer,
63    /// A floating-point number.
64    Float,
65    /// A list of strings (YAML sequence or space-separated env var string).
66    StringList,
67    /// A map from strings to lists of strings.
68    StringMapList,
69    /// A duration, expressed as a Go duration string (for example, `10s`) or integer nanoseconds.
70    Duration,
71}
72
73/// Which schema source of truth defined the `SchemaEntry`
74#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
75#[repr(u8)]
76pub(crate) enum Schema {
77    /// Saluki defined the `SchemaEntry`.
78    Saluki,
79    /// The vendored Datadog config schema defines the `SchemaEntry`.
80    Datadog,
81}
82
83/// Schema-derived metadata for a single configuration key.
84#[derive(Debug)]
85pub struct SchemaEntry {
86    /// The source of truth from which this entry was derived.
87    #[allow(dead_code)]
88    pub(crate) schema: Schema,
89
90    /// Canonical dot-separated YAML path for this key (for example, `"proxy.http"`).
91    pub yaml_path: &'static str,
92
93    /// Environment variables that deliver this value, as declared in the schema.
94    pub env_vars: &'static [&'static str],
95
96    /// Shape of the value.
97    pub value_type: ValueType,
98
99    /// JSON-encoded default value from the Agent schema, if present.
100    pub default: Option<&'static str>,
101}
102
103/// Saluki-specific annotation for a single configuration key.
104#[derive(Debug)]
105pub struct SalukiAnnotation {
106    /// The schema entry this annotation enriches.
107    pub schema: &'static SchemaEntry,
108
109    /// How well saluki supports this key.
110    pub support_level: SupportLevel,
111
112    /// Additional YAML paths beyond the canonical one in the schema (aliases).
113    pub additional_yaml_paths: &'static [&'static str],
114
115    /// Overrides the schema's `env_vars` list entirely when `Some`.
116    pub env_var_override: Option<&'static [&'static str]>,
117
118    /// Configuration consumers that incorporate this key, as [`structs`] constants.
119    pub used_by: &'static [&'static str],
120
121    /// Overrides the schema's `value_type` when `Some`.
122    pub value_type_override: Option<ValueType>,
123
124    /// Overrides the smoke-test injected value entirely when `Some`.
125    pub test_json: Option<&'static str>,
126
127    /// Which pipelines this key affects.
128    pub pipeline_affinity: PipelineAffinity,
129}
130
131/// A reference to a [`SalukiAnnotation`], used as the element type of `ALL` slices generated by
132/// [`declare_annotations!`].
133pub type SalukiAnnotationRef = &'static SalukiAnnotation;
134
135impl SalukiAnnotation {
136    /// The canonical YAML path for this key (from the schema).
137    pub fn yaml_path(&self) -> &'static str {
138        self.schema.yaml_path
139    }
140
141    /// All YAML paths for this key: canonical first, then any aliases.
142    pub fn all_yaml_paths(&self) -> impl Iterator<Item = &'static str> {
143        std::iter::once(self.schema.yaml_path).chain(self.additional_yaml_paths.iter().copied())
144    }
145
146    /// Effective env vars: the override list if set, otherwise the schema's list.
147    pub fn effective_env_vars(&self) -> &'static [&'static str] {
148        self.env_var_override.unwrap_or(self.schema.env_vars)
149    }
150
151    /// Shape of the value: override if set, otherwise from the schema.
152    pub fn value_type(&self) -> ValueType {
153        self.value_type_override.unwrap_or(self.schema.value_type)
154    }
155}
156
157/// A fully resolved configuration key.
158#[derive(Debug)]
159pub struct ConfigKey {
160    /// All dot-separated YAML paths that deliver this value.
161    pub yaml_paths: Vec<&'static str>,
162
163    /// All environment variables that deliver this value.
164    pub env_vars: Vec<&'static str>,
165
166    /// Shape of the value.
167    pub value_type: ValueType,
168
169    /// Configuration consumers that incorporate this key, as [`structs`] constants.
170    pub used_by: &'static [&'static str],
171}
172
173impl From<&SalukiAnnotation> for ConfigKey {
174    fn from(a: &SalukiAnnotation) -> Self {
175        ConfigKey {
176            yaml_paths: a.all_yaml_paths().collect(),
177            env_vars: a.effective_env_vars().to_vec(),
178            value_type: a.value_type(),
179            used_by: a.used_by,
180        }
181    }
182}
183
184mod generated;
185
186pub use self::generated::{ALL_ANNOTATIONS, SUPPORTED_ANNOTATIONS, UNSUPPORTED_ANNOTATIONS};