-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathconfig.rs
More file actions
83 lines (72 loc) · 2.31 KB
/
Copy pathconfig.rs
File metadata and controls
83 lines (72 loc) · 2.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use std::path::{Path, PathBuf};
use std::str::FromStr;
use serde::Deserialize;
use crate::policy;
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Config {
pub server: ServerConfig,
pub observability: ObservabilityConfig,
pub policy: PolicyConfig,
}
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ServerConfig {
pub listen_addr: String,
pub tls_cert_path: PathBuf,
pub tls_key_path: PathBuf,
pub client_ca_path: PathBuf,
}
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ObservabilityConfig {
pub log_level: String,
pub otlp_endpoint: Option<String>,
}
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct PolicyConfig {
pub client_ext_oid: String,
pub rules: Vec<PolicyRule>,
}
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct PolicyRule {
pub extension_value: String,
pub allowed_destinations: Vec<String>,
}
impl Config {
pub fn load(path: &Path) -> anyhow::Result<Self> {
let contents = std::fs::read_to_string(path)?;
let config: Config = toml::from_str(&contents)?;
config.validate()?;
Ok(config)
}
fn validate(&self) -> anyhow::Result<()> {
self.server
.listen_addr
.parse::<std::net::SocketAddr>()
.map_err(|e| anyhow::anyhow!("invalid server.listen_addr: {e}"))?;
let _oid =
x509_parser::oid_registry::Oid::from_str(&self.policy.client_ext_oid)
.map_err(|e| anyhow::anyhow!("invalid policy.client_ext_oid: {e:?}"))?;
for (i, rule) in self.policy.rules.iter().enumerate() {
anyhow::ensure!(
!rule.extension_value.is_empty(),
"policy.rules[{i}].extension_value must not be empty"
);
anyhow::ensure!(
!rule.allowed_destinations.is_empty(),
"policy.rules[{i}].allowed_destinations must not be empty"
);
for (j, dest) in rule.allowed_destinations.iter().enumerate() {
policy::normalize_destination(dest).map_err(|e| {
anyhow::anyhow!(
"policy.rules[{i}].allowed_destinations[{j}]: {e}"
)
})?;
}
}
Ok(())
}
}