git.delta.rocks / jrsonnet / refs/commits / 353ae3be2d27

difftreelog

source

cmds/fleet/src/keys.rs1.5 KiBsourcehistory
1use std::str::FromStr;23use crate::command::MyCommand;4use crate::host::Config;5use anyhow::{anyhow, Result};6use tracing::warn;78impl Config {9	pub fn cached_key(&self, host: &str) -> Option<String> {10		let data = self.data();11		let key = data.hosts.get(host).map(|h| &h.encryption_key);12		if let Some(key) = key {13			if key.is_empty() {14				return None;15			}16		}17		key.cloned()18	}19	pub fn update_key(&self, host: &str, key: String) {20		let mut data = self.data_mut();21		let host = data.hosts.entry(host.to_string()).or_default();22		host.encryption_key = key.trim().to_string();23	}2425	pub async fn key(&self, host: &str) -> anyhow::Result<String> {26		if let Some(key) = self.cached_key(host) {27			Ok(key)28		} else {29			warn!("Loading key for {}", host);30			let mut cmd = MyCommand::new("cat");31			cmd.arg("/etc/ssh/ssh_host_ed25519_key.pub");32			let key = self.run_string_on(host, cmd, false).await?;33			self.update_key(host, key.clone());34			Ok(key)35		}36	}37	/// Insecure, requires root38	pub async fn recipient(&self, host: &str) -> anyhow::Result<age::ssh::Recipient> {39		let key = self.key(host).await?;40		age::ssh::Recipient::from_str(&key).map_err(|e| anyhow!("parse recipient error: {:?}", e))41	}4243	pub async fn orphaned_data(&self) -> Result<Vec<String>> {44		let mut out = Vec::new();45		let host_names = self.list_hosts().await?;46		for hostname in self47			.data()48			.hosts49			.iter()50			.filter(|(_, host)| !host.encryption_key.is_empty())51			.map(|(n, _)| n)52		{53			if !host_names.contains(hostname) {54				out.push(hostname.to_owned())55			}56		}5758		Ok(out)59	}60}