greentic_dev/
secrets_seed.rs1use std::collections::HashMap;
2use std::fs;
3use std::path::Path;
4
5use anyhow::{Context, Result, bail};
6use base64::Engine;
7use base64::engine::general_purpose::STANDARD as B64_STANDARD;
8use serde::Deserialize;
9use serde_json::Value as JsonValue;
10use serde_yaml_bw as serde_yaml;
11
12#[derive(Debug, Deserialize)]
13struct SeedDoc {
14 entries: Vec<SeedEntry>,
15}
16
17#[derive(Debug, Deserialize)]
18struct SeedEntry {
19 uri: String,
20 #[serde(default)]
21 text: Option<String>,
22 #[serde(default)]
23 json: Option<JsonValue>,
24 #[serde(default, rename = "bytes_b64")]
25 bytes_b64: Option<String>,
26 #[serde(default)]
27 value: Option<JsonValue>,
28}
29
30pub fn load_seed_file(path: &Path) -> Result<HashMap<String, Vec<u8>>> {
31 let data = fs::read_to_string(path)
32 .with_context(|| format!("failed to read secrets seed at {}", path.display()))?;
33 if let Ok(doc) = serde_yaml::from_str::<SeedDoc>(&data) {
35 let mut map = HashMap::new();
36 for entry in doc.entries {
37 let (uri, bytes) = seed_entry_to_bytes(entry)?;
38 map.insert(uri, bytes);
39 }
40 return Ok(map);
41 }
42 if let Ok(map) = serde_yaml::from_str::<HashMap<String, JsonValue>>(&data) {
44 let mut out = HashMap::new();
45 for (uri, val) in map {
46 let bytes = match val {
47 JsonValue::String(s) => s.into_bytes(),
48 other => serde_json::to_vec(&other)
49 .context("failed to serialize seed value to JSON bytes")?,
50 };
51 out.insert(uri, bytes);
52 }
53 return Ok(out);
54 }
55
56 bail!("failed to parse secrets seed (unsupported format)")
57}
58
59fn seed_entry_to_bytes(entry: SeedEntry) -> Result<(String, Vec<u8>)> {
60 let bytes = if let Some(text) = entry.text {
61 text.into_bytes()
62 } else if let Some(json) = entry.json {
63 serde_json::to_vec(&json).context("failed to serialize seed json value")?
64 } else if let Some(b64) = entry.bytes_b64 {
65 B64_STANDARD
66 .decode(b64.as_bytes())
67 .context("failed to decode seed bytes_b64")?
68 } else if let Some(val) = entry.value {
69 match val {
70 JsonValue::String(s) => s.into_bytes(),
71 other => serde_json::to_vec(&other).context("failed to serialize seed value")?,
72 }
73 } else {
74 bail!("seed entry {} missing value", entry.uri);
75 };
76 Ok((entry.uri, bytes))
77}