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

difftreelog

source

src/keys.rs1.4 KiBsourcehistory
1use std::str::FromStr;23use crate::{command::CommandExt, host::Config};4use anyhow::{anyhow, Result};5use log::warn;67impl Config {8	pub fn cached_key(&self, host: &str) -> Option<String> {9		let data = self.data();10		let key = data.hosts.get(host).map(|h| &h.encryption_key);11		if let Some(key) = key {12			if key.is_empty() {13				return None;14			}15		}16		key.cloned()17	}18	pub fn update_key(&self, host: &str, key: String) {19		let mut data = self.data_mut();20		let host = data.hosts.entry(host.to_string()).or_default();21		host.encryption_key = key.trim().to_string();22	}2324	pub fn key(&self, host: &str) -> anyhow::Result<String> {25		if let Some(key) = self.cached_key(host) {26			Ok(key)27		} else {28			warn!("Loading key for {}", host);29			let key = self30				.command_on(&host, "cat", false)31				.arg("/etc/ssh/ssh_host_ed25519_key.pub")32				.run_string()?;33			self.update_key(host, key.clone());34			Ok(key)35		}36	}37	pub fn recipient(&self, host: &str) -> anyhow::Result<age::ssh::Recipient> {38		let key = self.key(host)?;39		age::ssh::Recipient::from_str(&key).map_err(|e| anyhow!("parse recipient error: {:?}", e))40	}4142	pub fn orphaned_data(&self) -> Result<Vec<String>> {43		let mut out = Vec::new();44		let host_names = self.list_hosts()?;45		for hostname in self46			.data()47			.hosts48			.iter()49			.filter(|(_, host)| !host.encryption_key.is_empty())50			.map(|(n, _)| n)51		{52			if !host_names.contains(&hostname.to_owned()) {53				out.push(hostname.to_owned())54			}55		}5657		Ok(out)58	}59}