manta_shared/common/config/
types.rs1use std::collections::HashMap;
2
3use crate::common::audit::Auditor;
4
5use manta_backend_dispatcher::types::K8sDetails;
6use serde::{Deserialize, Serialize};
7
8#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
10#[serde(rename_all = "lowercase")]
11pub enum BackendTechnology {
12 Csm,
14 Ochami,
16}
17
18impl BackendTechnology {
19 pub fn as_str(&self) -> &'static str {
21 match self {
22 Self::Csm => "csm",
23 Self::Ochami => "ochami",
24 }
25 }
26}
27
28#[derive(Serialize, Deserialize, Debug)]
29pub struct Site {
37 pub backend: BackendTechnology,
38 pub socks5_proxy: Option<String>,
39 pub shasta_base_url: String,
40 pub k8s: Option<K8sDetails>,
41 pub root_ca_cert_file: String,
42}
43
44#[derive(Serialize, Deserialize, Debug)]
50pub struct CliConfiguration {
51 pub log: String,
52 pub audit_file: String,
53 pub site: String,
58 pub parent_hsm_group: String,
59 pub manta_server_url: String,
63 pub socks5_proxy: Option<String>,
66 pub auditor: Option<Auditor>,
67}
68
69#[derive(Serialize, Deserialize, Debug)]
72pub struct ServerSettings {
73 pub listen_address: String,
75 pub port: u16,
77 pub cert: Option<String>,
79 pub key: Option<String>,
81 pub console_inactivity_timeout_secs: u64,
84 pub auth_rate_limit_per_minute: Option<u32>,
88}
89
90#[derive(Serialize, Deserialize, Debug)]
95pub struct ServerConfiguration {
96 pub log: String,
97 pub audit_file: String,
98 pub server: ServerSettings,
99 pub sites: HashMap<String, Site>,
100 pub auditor: Option<Auditor>,
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn site_deserialize_missing_backend_fails() {
109 let bad_toml = r#"
110 shasta_base_url = "https://api.example.com"
111 root_ca_cert_file = "cert.pem"
112 # missing backend
113 "#;
114 let result = toml::from_str::<Site>(bad_toml);
115 assert!(result.is_err());
116 }
117
118 #[test]
119 fn backend_technology_as_str() {
120 assert_eq!(BackendTechnology::Csm.as_str(), "csm");
121 assert_eq!(BackendTechnology::Ochami.as_str(), "ochami");
122 }
123
124 #[test]
125 fn backend_technology_roundtrip_toml() {
126 #[derive(Serialize, Deserialize)]
128 struct Wrapper {
129 backend: BackendTechnology,
130 }
131 let w = Wrapper {
132 backend: BackendTechnology::Csm,
133 };
134 let s = toml::to_string(&w).unwrap();
135 assert!(s.contains("\"csm\"") || s.contains("csm"));
136 let parsed: Wrapper = toml::from_str(&s).unwrap();
137 assert_eq!(parsed.backend, BackendTechnology::Csm);
138 }
139
140 fn make_minimal_site() -> Site {
141 Site {
142 backend: BackendTechnology::Csm,
143 socks5_proxy: None,
144 shasta_base_url: "https://api.example.com".to_string(),
145 k8s: None,
146 root_ca_cert_file: "cert.pem".to_string(),
147 }
148 }
149
150 #[test]
151 fn cli_configuration_roundtrip_toml_minimal() {
152 let cfg = CliConfiguration {
153 log: "info".to_string(),
154 audit_file: "/tmp/cli-audit.log".to_string(),
155 site: "alps".to_string(),
156 parent_hsm_group: "nodes_free".to_string(),
157 manta_server_url: "https://manta-server.cscs.ch:8443".to_string(),
158 socks5_proxy: Some("socks5h://127.0.0.1:1080".to_string()),
159 auditor: None,
160 };
161 let toml_str = toml::to_string(&cfg).unwrap();
162 let parsed: CliConfiguration = toml::from_str(&toml_str).unwrap();
163 assert_eq!(parsed.site, "alps");
164 assert_eq!(parsed.parent_hsm_group, "nodes_free");
165 assert_eq!(parsed.manta_server_url, "https://manta-server.cscs.ch:8443");
166 assert_eq!(
167 parsed.socks5_proxy.as_deref(),
168 Some("socks5h://127.0.0.1:1080")
169 );
170 }
171
172 #[test]
173 fn cli_configuration_socks5_proxy_optional() {
174 let toml_str = r#"
175 log = "info"
176 audit_file = "/tmp/cli-audit.log"
177 site = "alps"
178 parent_hsm_group = ""
179 manta_server_url = "https://manta-server.cscs.ch:8443"
180 "#;
181 let parsed: CliConfiguration = toml::from_str(toml_str).unwrap();
182 assert!(parsed.socks5_proxy.is_none());
183 }
184
185 #[test]
186 fn cli_configuration_missing_manta_server_url_fails() {
187 let bad_toml = r#"
188 log = "info"
189 audit_file = "/tmp/cli-audit.log"
190 site = "alps"
191 parent_hsm_group = ""
192 # missing manta_server_url
193 "#;
194 let result = toml::from_str::<CliConfiguration>(bad_toml);
195 assert!(result.is_err());
196 }
197
198 #[test]
199 fn server_configuration_roundtrip_toml_minimal() {
200 let mut sites = HashMap::new();
201 sites.insert("alps".to_string(), make_minimal_site());
202 let cfg = ServerConfiguration {
203 log: "info".to_string(),
204 audit_file: "/var/log/manta/server-audit.log".to_string(),
205 server: ServerSettings {
206 listen_address: "0.0.0.0".to_string(),
207 port: 8443,
208 cert: Some("/etc/manta/tls/server.crt".to_string()),
209 key: Some("/etc/manta/tls/server.key".to_string()),
210 console_inactivity_timeout_secs: 1800,
211 auth_rate_limit_per_minute: Some(60),
212 },
213 sites,
214 auditor: None,
215 };
216 let toml_str = toml::to_string(&cfg).unwrap();
217 let parsed: ServerConfiguration = toml::from_str(&toml_str).unwrap();
218 assert_eq!(parsed.server.port, 8443);
219 assert_eq!(parsed.server.listen_address, "0.0.0.0");
220 assert_eq!(parsed.server.console_inactivity_timeout_secs, 1800);
221 assert_eq!(
222 parsed.server.cert.as_deref(),
223 Some("/etc/manta/tls/server.crt")
224 );
225 }
226
227 #[test]
228 fn server_configuration_deserialize_missing_server_section_fails() {
229 let bad_toml = r#"
230 log = "info"
231 audit_file = "/tmp/server.log"
232 [sites]
233 "#;
234 let result = toml::from_str::<ServerConfiguration>(bad_toml);
235 assert!(result.is_err());
236 }
237
238 #[test]
239 fn server_settings_optional_tls_paths() {
240 let toml_str = r#"
243 listen_address = "0.0.0.0"
244 port = 8443
245 console_inactivity_timeout_secs = 1800
246 "#;
247 let parsed: ServerSettings = toml::from_str(toml_str).unwrap();
248 assert!(parsed.cert.is_none());
249 assert!(parsed.key.is_none());
250 }
251}