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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use super::Result;
use std::collections::{BTreeMap, BTreeSet};
#[derive(Serialize, Deserialize, Clone, Default, Debug)]
#[serde(default)]
pub struct EnvVars {
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
pub plain: BTreeMap<String, String>,
#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
pub secrets: BTreeSet<String>,
}
impl EnvVars {
pub fn new(env: BTreeMap<String, String>) -> Self {
EnvVars {
plain: env,
secrets: Default::default(),
}
}
fn is_vault_secret(value: &str) -> bool {
value == "IN_VAULT"
}
fn template_secret_value(value: &str) -> Option<String> {
let prefix = "SHIPCAT_SECRET::";
if value.starts_with(prefix) {
Some(value.to_string().split_off(prefix.len()))
} else {
None
}
}
pub fn verify(&self) -> Result<()> {
for k in self.plain.keys() {
if k != &k.to_uppercase() {
bail!("Env vars need to be uppercase, found: {}", k);
}
}
Ok(())
}
pub fn vault_secrets(&mut self) -> BTreeSet<String> {
let mut plain = BTreeMap::new();
let mut vs = BTreeSet::new();
for (k, v) in self.plain.iter() {
if EnvVars::is_vault_secret(&v) {
vs.insert(k.to_string());
self.secrets.insert(k.to_string());
} else {
plain.insert(k.to_string(), v.to_string());
}
}
self.plain = plain;
vs
}
pub fn template_secrets(&mut self) -> BTreeMap<String, String> {
let mut plain = BTreeMap::new();
let mut ts = BTreeMap::new();
for (k, v) in self.plain.iter() {
match EnvVars::template_secret_value(v) {
Some(x) => {
ts.insert(k.to_string(), x);
self.secrets.insert(k.to_string());
}
None => {
plain.insert(k.to_string(), v.to_string());
}
};
}
self.plain = plain;
ts
}
}