Skip to main content

genja_core/settings/
inventory.rs

1use super::env_defaults::get_inventory_plugin_config;
2use crate::inventory::TransformFunctionOptions;
3use serde::{Deserialize, Serialize};
4
5/// Optional file paths for hosts, groups, and defaults inventory sources.
6#[derive(Deserialize, Serialize, Clone, Debug, Default)]
7pub struct OptionsConfig {
8    pub(super) hosts_file: Option<String>,
9    pub(super) groups_file: Option<String>,
10    pub(super) defaults_file: Option<String>,
11}
12
13impl OptionsConfig {
14    pub fn builder() -> OptionsConfigBuilder {
15        OptionsConfigBuilder::default()
16    }
17
18    pub fn hosts_file(&self) -> Option<&str> {
19        self.hosts_file.as_deref()
20    }
21
22    pub fn groups_file(&self) -> Option<&str> {
23        self.groups_file.as_deref()
24    }
25
26    pub fn defaults_file(&self) -> Option<&str> {
27        self.defaults_file.as_deref()
28    }
29}
30
31/// Builder for `OptionsConfig`.
32#[derive(Default)]
33pub struct OptionsConfigBuilder {
34    hosts_file: Option<String>,
35    groups_file: Option<String>,
36    defaults_file: Option<String>,
37}
38
39impl OptionsConfigBuilder {
40    pub fn hosts_file(mut self, path: impl Into<String>) -> Self {
41        self.hosts_file = Some(path.into());
42        self
43    }
44
45    pub fn groups_file(mut self, path: impl Into<String>) -> Self {
46        self.groups_file = Some(path.into());
47        self
48    }
49
50    pub fn defaults_file(mut self, path: impl Into<String>) -> Self {
51        self.defaults_file = Some(path.into());
52        self
53    }
54
55    pub fn build(self) -> OptionsConfig {
56        OptionsConfig {
57            hosts_file: self.hosts_file,
58            groups_file: self.groups_file,
59            defaults_file: self.defaults_file,
60        }
61    }
62}
63
64/// Inventory loader configuration.
65///
66/// The plugin name defaults from `GENJA_INVENTORY_PLUGIN`. When present,
67/// `transform_function` is attached to the built `Inventory` after the raw
68/// inventory files are loaded. The transform itself is then applied lazily
69/// when inventory data is accessed or resolved.
70#[derive(Deserialize, Serialize, Clone, Debug)]
71pub struct InventoryConfig {
72    #[serde(default = "get_inventory_plugin_config")]
73    pub(super) plugin: String,
74    pub(super) options: OptionsConfig,
75    pub(super) transform_function: Option<String>,
76    pub(super) transform_function_options: Option<TransformFunctionOptions>,
77}
78
79impl Default for InventoryConfig {
80    fn default() -> Self {
81        InventoryConfig {
82            plugin: get_inventory_plugin_config(),
83            options: OptionsConfig::default(),
84            transform_function: None,
85            transform_function_options: None,
86        }
87    }
88}
89
90impl InventoryConfig {
91    pub fn builder() -> InventoryConfigBuilder {
92        InventoryConfigBuilder::default()
93    }
94
95    pub fn plugin(&self) -> &str {
96        &self.plugin
97    }
98
99    pub fn options(&self) -> &OptionsConfig {
100        &self.options
101    }
102
103    pub fn transform_function(&self) -> Option<&str> {
104        self.transform_function.as_deref()
105    }
106
107    pub fn transform_function_options(&self) -> Option<&TransformFunctionOptions> {
108        self.transform_function_options.as_ref()
109    }
110}
111
112/// Builder for `InventoryConfig`.
113#[derive(Default)]
114pub struct InventoryConfigBuilder {
115    plugin: Option<String>,
116    options: Option<OptionsConfig>,
117    transform_function: Option<String>,
118    transform_function_options: Option<TransformFunctionOptions>,
119}
120
121impl InventoryConfigBuilder {
122    pub fn plugin(mut self, plugin: impl Into<String>) -> Self {
123        self.plugin = Some(plugin.into());
124        self
125    }
126
127    pub fn options(mut self, options: OptionsConfig) -> Self {
128        self.options = Some(options);
129        self
130    }
131
132    pub fn transform_function(mut self, transform: impl Into<String>) -> Self {
133        self.transform_function = Some(transform.into());
134        self
135    }
136
137    pub fn transform_function_options(mut self, options: TransformFunctionOptions) -> Self {
138        self.transform_function_options = Some(options);
139        self
140    }
141
142    pub fn build(self) -> InventoryConfig {
143        InventoryConfig {
144            plugin: self.plugin.unwrap_or_else(get_inventory_plugin_config),
145            options: self.options.unwrap_or_default(),
146            transform_function: self.transform_function,
147            transform_function_options: self.transform_function_options,
148        }
149    }
150}