git.delta.rocks / jrsonnet / refs/commits / 904d12180e52

difftreelog

source

cmds/fleet/src/keys.rs1.9 KiBsourcehistory
1use std::str::FromStr;23use crate::command::MyCommand;4use crate::host::Config;5use age::Recipient;6use anyhow::{anyhow, Result};7use futures::{StreamExt, TryStreamExt};8use itertools::Itertools;9use tracing::warn;1011impl Config {12	pub fn cached_key(&self, host: &str) -> Option<String> {13		let data = self.data();14		let key = data.hosts.get(host).map(|h| &h.encryption_key);15		if let Some(key) = key {16			if key.is_empty() {17				return None;18			}19		}20		key.cloned()21	}22	pub fn update_key(&self, host: &str, key: String) {23		let mut data = self.data_mut();24		let host = data.hosts.entry(host.to_string()).or_default();25		host.encryption_key = key.trim().to_string();26	}2728	pub async fn key(&self, host: &str) -> anyhow::Result<String> {29		if let Some(key) = self.cached_key(host) {30			Ok(key)31		} else {32			warn!("Loading key for {}", host);33			let mut cmd = MyCommand::new("cat");34			cmd.arg("/etc/ssh/ssh_host_ed25519_key.pub");35			let key = self.run_string_on(host, cmd, false).await?;36			self.update_key(host, key.clone());37			Ok(key)38		}39	}40	/// Insecure, requires root41	pub async fn recipient(&self, host: &str) -> anyhow::Result<impl Recipient> {42		let key = self.key(host).await?;43		age::ssh::Recipient::from_str(&key).map_err(|e| anyhow!("parse recipient error: {:?}", e))44	}4546	pub async fn recipients(&self, hosts: &[&str]) -> Result<Vec<impl Recipient>> {47		futures::stream::iter(hosts.iter())48			.then(|m| self.recipient(m))49			.try_collect::<Vec<_>>()50			.await51	}5253	#[allow(dead_code)]54	pub async fn orphaned_data(&self) -> Result<Vec<String>> {55		let mut out = Vec::new();56		let host_names = self57			.list_hosts()58			.await?59			.into_iter()60			.map(|h| h.name)61			.collect_vec();62		for hostname in self63			.data()64			.hosts65			.iter()66			.filter(|(_, host)| !host.encryption_key.is_empty())67			.map(|(n, _)| n)68		{69			if !host_names.contains(hostname) {70				out.push(hostname.to_owned())71			}72		}7374		Ok(out)75	}76}