git.delta.rocks / jrsonnet / refs/commits / f48f507511e2

difftreelog

source

src/cmds/secrets/mod.rs2.1 KiBsourcehistory
1use crate::{fleetdata::FleetSecret, host::Config};2use anyhow::{bail, Result};3use clap::Clap;4use std::{5	collections::BTreeMap,6	io::{Cursor, Read},7};89#[derive(Clap)]10pub enum Secrets {11	/// Force load keys for all defined hosts12	ForceKeys,13	/// Add secret, data should be provided in stdin14	Add {15		/// Secret name16		name: String,17		/// Secret owners18		machines: Vec<String>,19		/// Override secret if already present20		#[clap(long)]21		force: bool,22	},23}2425impl Secrets {26	pub fn run(self, config: &Config) -> Result<()> {27		match self {28			Secrets::ForceKeys => {29				for host in config.list_hosts()? {30					if config.should_skip(&host) {31						continue;32					}33					config.key(&host)?;34				}35			}36			Secrets::Add {37				machines,38				name,39				force,40			} => {41				let recipients = machines42					.iter()43					.map(|m| config.recipient(&m))44					.collect::<Result<Vec<_>>>()?;4546				let secret_data = {47					let mut input = vec![];48					std::io::stdin().read_to_end(&mut input)?;4950					let data: BTreeMap<String, String> = serde_json::from_slice(&input)?;51					let mut transformed_data: BTreeMap<String, String> = BTreeMap::new();52					for (k, v) in data {53						if k.ends_with("_pub") {54							transformed_data.insert(k, v);55						} else if k.ends_with("_secret") {56							let mut encrypted = vec![];57							let recipients = recipients58								.iter()59								.cloned()60								.map(|r| Box::new(r) as Box<dyn age::Recipient>)61								.collect();62							let mut encryptor = age::Encryptor::with_recipients(recipients)63								.wrap_output(&mut encrypted)?;64							std::io::copy(&mut Cursor::new(v.as_bytes()), &mut encryptor)?;65							drop(encryptor);6667							transformed_data.insert(k, ascii85::encode(&encrypted));68						} else {69							bail!("unknown key type: {:?}", k);70						}71					}72					transformed_data73				};7475				let mut data = config.data_mut();76				if data.secrets.contains_key(&name) && !force {77					bail!("secret already defined");78				}79				data.secrets.insert(80					name,81					FleetSecret {82						owners: machines.clone(),83						expire_at: None,84						data: secret_data,85					},86				);87			}88		}89		Ok(())90	}91}