git.delta.rocks / jrsonnet / refs/commits / 89d35672dcfd

difftreelog

source

cmds/fleet/src/keys.rs1.6 KiBsourcehistory
1use std::str::FromStr;23use crate::command::MyCommand;4use crate::host::Config;5use anyhow::{anyhow, Result};6use itertools::Itertools;7use tracing::warn;89impl Config {10	pub fn cached_key(&self, host: &str) -> Option<String> {11		let data = self.data();12		let key = data.hosts.get(host).map(|h| &h.encryption_key);13		if let Some(key) = key {14			if key.is_empty() {15				return None;16			}17		}18		key.cloned()19	}20	pub fn update_key(&self, host: &str, key: String) {21		let mut data = self.data_mut();22		let host = data.hosts.entry(host.to_string()).or_default();23		host.encryption_key = key.trim().to_string();24	}2526	pub async fn key(&self, host: &str) -> anyhow::Result<String> {27		if let Some(key) = self.cached_key(host) {28			Ok(key)29		} else {30			warn!("Loading key for {}", host);31			let mut cmd = MyCommand::new("cat");32			cmd.arg("/etc/ssh/ssh_host_ed25519_key.pub");33			let key = self.run_string_on(host, cmd, false).await?;34			self.update_key(host, key.clone());35			Ok(key)36		}37	}38	/// Insecure, requires root39	pub async fn recipient(&self, host: &str) -> anyhow::Result<age::ssh::Recipient> {40		let key = self.key(host).await?;41		age::ssh::Recipient::from_str(&key).map_err(|e| anyhow!("parse recipient error: {:?}", e))42	}4344	#[allow(dead_code)]45	pub async fn orphaned_data(&self) -> Result<Vec<String>> {46		let mut out = Vec::new();47		let host_names = self48			.list_hosts()49			.await?50			.into_iter()51			.map(|h| h.name)52			.collect_vec();53		for hostname in self54			.data()55			.hosts56			.iter()57			.filter(|(_, host)| !host.encryption_key.is_empty())58			.map(|(n, _)| n)59		{60			if !host_names.contains(hostname) {61				out.push(hostname.to_owned())62			}63		}6465		Ok(out)66	}67}