diff options
| author | Irene Knapp <ireneista@internetsafetylabs.org> | 2025-12-18 17:53:47 -0800 |
|---|---|---|
| committer | Irenes <ireneista@internetsafetylabs.org> | 2025-12-18 17:58:33 -0800 |
| commit | 911c00714295c13c7e9ec29941b9bbcc87705776 (patch) | |
| tree | 5c378938766d2ae87ab3c985dac3625d06fa07f1 | |
| parent | d15feffcdb262f5e4686297e156319591895a945 (diff) | |
parse the returned JSON from the nix subcommand
this produces a list of secrets, although it doesn't yet do any of the checking to see if the files actually exist, when they were modified, etc. it just prints the parsed data structure. this was kind of a pain to test, I had to make a fake machine config with some secrets and point it to it. we should figure out a way to use Rust's test framework to do that automatically, but that can be in a future CL, and I don't necessarily have to be the one to write it. Change-Id: I4c7d579d61e8f3694fe879998dae0f95baaeea05
| -rw-r--r-- | src/main.rs | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/src/main.rs b/src/main.rs index 2ebc97c..eff64b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,10 +3,13 @@ use crate::commands::{ Command, CommandMap, Mode }; use crate::error::*; +use std::collections::HashMap; use std::io::Write; use std::process; use ::clap::Parser; +use ::json::{ self, JsonValue }; + mod commands; mod error; @@ -45,8 +48,9 @@ impl TopLevelMode { }))?; command_map.insert(Command::<TopLevelMode>::new("list", |mode, _params| { - let _secrets = read_secret_metadata(&mode.flake_path, + let secrets = read_secret_metadata(&mode.flake_path, &mode.configuration_name)?; + println!("{:?}", secrets); // TODO do something with them Ok(Some(mode)) @@ -88,6 +92,13 @@ fn default_empty_command() -> Result<()> { } +#[derive(Debug)] +struct Secret { + path: String, + script: String, +} + + fn main() -> () { match main_h() { Ok(()) => { }, @@ -133,7 +144,7 @@ fn prompt(raw: &str) -> Result<Option<String>> { fn read_secret_metadata(flake_path: &str, configuration_name: &str) - -> Result<()> + -> Result<HashMap<String, Secret>> { let mut nix_expression = String::new(); nix_expression.push_str("let config = (builtins.getFlake \""); @@ -164,10 +175,41 @@ fn read_secret_metadata(flake_path: &str, configuration_name: &str) } let nix_json = String::from_utf8(nix_output.stdout)?; + let mut nix_json = json::parse(&nix_json).map_err(|e| Error::Internal( + "nix subprocess returned invalid JSON".to_string()))?; + if !nix_json.is_object() { + return Err(Error::Internal( + "nix subprocess returned non-object for JSON".to_string())); + } - println!("{}", nix_json); - // TODO parse the JSON + let mut secrets = HashMap::new(); + for (name, body) in nix_json.entries_mut() { + if !body.is_object() { + return Err(Error::Internal( + "nix subprocess returned non-object for secret definition" + .to_string())); + } - Ok(()) + if !body.has_key("path") { + return Err(Error::Internal( + "nix subprocess returned secret definition with missing path value" + .to_string())); + } + let path = body["path"].take_string().ok_or(Error::Internal( + "nix subprocess returned non-string for path value".to_string()))?; + + if !body.has_key("script") { + return Err(Error::Internal( + "nix subprocess returned secret definition with missing script value" + .to_string())); + } + let script = body["script"].take_string().ok_or(Error::Internal( + "nix subprocess returned non-string for script value" + .to_string()))?; + + secrets.insert(name.to_string(), Secret { path, script }); + } + + Ok(secrets) } |