summary refs log tree commit diff
path: root/src/main.rs
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@internetsafetylabs.org>2025-12-17 15:16:20 -0800
committerIrene Knapp <ireneista@internetsafetylabs.org>2025-12-18 13:37:52 -0800
commitd15feffcdb262f5e4686297e156319591895a945 (patch)
tree9bf3fd01d8885c0cfba7fec810dca4bb28bf0552 /src/main.rs
parent01b7b60dc260aa7cf1dab6c15db13a88d5d92ada (diff)
implement the secret-list command
Change-Id: I5e1570940fedf52bb560fd824270e201757004ed
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs95
1 files changed, 85 insertions, 10 deletions
diff --git a/src/main.rs b/src/main.rs
index 80645df..2ebc97c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,22 +1,39 @@
 #![forbid(unsafe_code)]
+#![feature(gethostname)]
 use crate::commands::{ Command, CommandMap, Mode };
 use crate::error::*;
 
 use std::io::Write;
+use std::process;
+
+use ::clap::Parser;
 
 mod commands;
 mod error;
 
 
+#[derive(Parser, Debug)]
+struct CommandLineParameters {
+  flake_path: String,
+
+  #[arg(long = "store")]
+  nix_store_path: Option<String>,
+}
+
+
 struct TopLevelMode {
+  flake_path: String,
+  configuration_name: String,
   command_map: Box<CommandMap<TopLevelMode>>,
 }
 
 impl TopLevelMode {
-  fn new() -> Result<Self> {
+  fn new(flake_path: String, configuration_name: String) -> Result<Self> {
     let mut command_map = Box::new(CommandMap::new());
 
     command_map.insert(Command::new("help", |mode, _params| {
+      println!("list        List all defined secrets.");
+      println!("");
       println!("help        Print this message.");
       println!("quit        Exit the program.");
 
@@ -27,7 +44,15 @@ impl TopLevelMode {
       Ok(None)
     }))?;
 
-    Ok(TopLevelMode { command_map })
+    command_map.insert(Command::<TopLevelMode>::new("list", |mode, _params| {
+      let _secrets = read_secret_metadata(&mode.flake_path,
+                                          &mode.configuration_name)?;
+      // TODO do something with them
+
+      Ok(Some(mode))
+    }))?;
+
+    Ok(TopLevelMode { flake_path, configuration_name, command_map })
   }
 }
 
@@ -63,11 +88,26 @@ fn default_empty_command() -> Result<()> {
 }
 
 
-fn main() -> Result<()> {
-  help();
+fn main() -> () {
+  match main_h() {
+    Ok(()) => { },
+    Err(error) => {
+      println!("{}", error.to_string());
+    },
+  }
+}
+
+
+fn main_h() -> Result<()> {
+  let options = CommandLineParameters::try_parse()?;
+  println!("{:?}", options);
+
+  let hostname: String = std::net::hostname()?
+                             .into_string().map_err(|_| Error::UTF8)?;
 
   let mut current_mode: Option<Box<dyn Mode>>
-    = Some(Box::new(TopLevelMode::new()?));
+    = Some(Box::new(TopLevelMode::new(options.flake_path.clone(),
+                                      hostname)?));
 
   while let Some(mode) = current_mode {
     if let Some(input) = prompt(mode.prompt_text()?)? {
@@ -83,11 +123,6 @@ fn main() -> Result<()> {
 }
 
 
-fn help() {
-  println!("Type a command (there are none yet)");
-}
-
-
 fn prompt(raw: &str) -> Result<Option<String>> {
   let mut stdout = std::io::stdout();
   stdout.write_all(format!("\n{} ", raw).as_bytes())?;
@@ -96,3 +131,43 @@ fn prompt(raw: &str) -> Result<Option<String>> {
   Ok(std::io::stdin().lines().next().transpose()?)
 }
 
+
+fn read_secret_metadata(flake_path: &str, configuration_name: &str)
+     -> Result<()>
+{
+  let mut nix_expression = String::new();
+  nix_expression.push_str("let config = (builtins.getFlake \"");
+  nix_expression.push_str(flake_path);
+  nix_expression.push_str("\")");
+  nix_expression.push_str(".nixosConfigurations.");
+  nix_expression.push_str(configuration_name);
+  nix_expression.push_str(".config; in ");
+  nix_expression.push_str("if config ? \"secrets\" ");
+  nix_expression.push_str("then config.secrets.export ");
+  nix_expression.push_str("else { }");
+
+  let nix_output = process::Command::new("nix")
+                       .env_clear()
+                       .args([
+                         "--extra-experimental-features",
+                         "nix-command",
+                         "eval",
+                         "--impure",
+                         "--json",
+                         "--expr",
+                         &nix_expression,
+                       ])
+                       .output()?;
+  if !nix_output.status.success() {
+    println!("{}", String::from_utf8(nix_output.stderr)?);
+    return Err(Error::Internal("nix subprocess failed".to_string()));
+  }
+
+  let nix_json = String::from_utf8(nix_output.stdout)?;
+
+  println!("{}", nix_json);
+  // TODO parse the JSON
+
+  Ok(())
+}
+