difftreelog
feat fleet secret prune command implementation
in: trunk
1 file changed
cmds/fleet/src/cmds/secrets.rsdiffbeforeafterboth1use std::collections::BTreeSet;1use std::io::{Write as _, stdout};2use std::io::{Write as _, stdout};233use anyhow::{Context as _, Result, anyhow, bail};4use anyhow::{Context as _, Result, anyhow, bail};34 #[clap(short = 'm', long)]35 #[clap(short = 'm', long)]35 machine: Vec<String>,36 machine: Vec<String>,3738 /// If set - distributions containing the specified machines will be pruned fully39 #[clap(long)]40 whole_dist: bool,36 },41 },37 /// Ensure secret is generated and not expired42 /// Ensure secret is generated and not expired38 Ensure {43 Ensure {159 */164 */160 todo!()165 todo!()161 }166 }162 Secret::Prune { name, machine } => todo!(),167 Secret::Prune {168 name,169 machine,170 whole_dist,171 } => {172 let mut secrets = config.data.secrets.write().expect("not poisoned");173 let Some(dists) = secrets.get_mut(&name) else {174 bail!("secret {name} not found");175 };176 if machine.is_empty() && whole_dist {177 for dist in dists.distributions_mut() {178 dist.prune("manual prune".to_owned());179 }180 } else if machine.is_empty() {181 let dist = dists182 .distributions_mut()183 .exactly_one()184 .map_err(|e| anyhow!("{e}"))185 .context(186 "with no machine specified, there should be exactly one distribution",187 )?;188 dist.prune("manual prune".to_owned());189 } else if whole_dist {190 for dist in dists.distributions_mut() {191 if machine192 .iter()193 .any(|m| dist.owners().any(|o| o.as_host() == Some(m.as_str())))194 {195 dist.prune(format!(196 "manual prune of distribution containing {}",197 machine.join(", ")198 ));199 }200 }201 } else {202 let owners: BTreeSet<SecretOwner> =203 machine.iter().map(SecretOwner::host).collect();204 for dist in dists.distributions_mut() {205 dist.prune_owners(&owners, "manual prune".to_owned());206 }207 }208 }163 Secret::Ensure { name, machine } => todo!(),209 Secret::Ensure { name, machine } => todo!(),164 }210 }165 Ok(())211 Ok(())166 }212 }167}213}168169/*170async fn edit_temp_file(171 builder: tempfile::Builder<'_, '_>,172 r: Vec<u8>,173 header: &str,174 comment: &str,175) -> Result<(Vec<u8>, Option<String>), anyhow::Error> {176 if !stdin().is_tty() {177 // TODO: Also try to open /dev/tty directly?178 bail!("stdin is not tty, can't open editor");179 }180181 use std::fmt::Write;182 let mut file = builder.tempfile()?;183184 let mut full_header = String::new();185 let mut had = false;186 for line in header.trim_end().lines() {187 had = true;188 writeln!(&mut full_header, "{comment}{line}")?;189 }190 if had {191 writeln!(&mut full_header, "{}", comment.trim_end())?;192 }193 writeln!(194 &mut full_header,195 "{comment}Do not touch this header! It will be removed automatically"196 )?;197198 file.write_all(full_header.as_bytes())?;199 file.write_all(&r)?;200201 let abs_path = file.into_temp_path();202 let editor = std::env::var_os("VISUAL")203 .or_else(|| std::env::var_os("EDITOR"))204 .unwrap_or_else(|| "vi".into());205 let editor_args = shlex::bytes::split(editor.as_encoded_bytes())206 .ok_or_else(|| anyhow!("EDITOR env var has wrong syntax"))?;207 let editor_args = editor_args208 .into_iter()209 .map(|v| {210 // Only ASCII subsequences are replaced211 unsafe { OsString::from_encoded_bytes_unchecked(v) }212 })213 .collect_vec();214 let Some((editor, args)) = editor_args.split_first() else {215 bail!("EDITOR env var has no command");216 };217 let mut command = Command::new(editor);218 command.args(args);219220 let path_arg = abs_path.canonicalize()?;221222 // TODO: Save full state, using tcget/_getmode/_setmode223 let was_raw = terminal::is_raw_mode_enabled()?;224 terminal::enable_raw_mode()?;225226 let status = command.arg(path_arg).status().await;227228 if !was_raw {229 terminal::disable_raw_mode()?;230 }231232 let success = match status {233 Ok(s) => s.success(),234 Err(e) if e.kind() == io::ErrorKind::NotFound => {235 bail!("editor not found")236 }237 Err(e) => bail!("editor spawn error: {e}"),238 };239240 let mut file = std::fs::read(&abs_path).context("read editor output")?;241 let Some(v) = file.strip_prefix(full_header.as_bytes()) else {242 todo!();243 };244 todo!();245246 // Ok((success, abs_path))247}248*/249214