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

difftreelog

source

src/keys.rs1.6 KiBsourcehistory
1use crate::{2	command::CommandExt,3	host::{FleetConfig, Host},4};5use anyhow::Result;6use log::warn;7use std::{8	fs::{create_dir_all, metadata, read, read_dir, write},9	path::PathBuf,10};1112impl FleetConfig {13	fn host_keys_dir(&self) -> Result<PathBuf> {14		let mut out = self.data_dir().clone();15		out.push("host_keys");16		create_dir_all(&out)?;17		Ok(out)18	}1920	fn host_key_file(&self, host: &str) -> Result<PathBuf> {21		let mut dir = self.host_keys_dir()?;22		dir.push(format!("{}.asc", host));23		Ok(dir)24	}2526	pub fn list_orphaned_keys(&self) -> Result<Vec<(String, PathBuf)>> {27		let mut out = Vec::new();28		let host_names = self.list_host_names()?;29		for file in read_dir(&self.host_keys_dir()?)? {30			let file = file?;31			anyhow::ensure!(32				file.file_type()?.is_file(),33				"host_keys dir should contain only files"34			);35			let name = file.file_name();36			let name = name.to_str().unwrap();37			if let Some(hostname) = name.strip_suffix(".asc") {38				if !host_names.contains(&hostname.to_owned()) {39					out.push((hostname.to_owned(), file.path()))40				}41			} else {42				out.push(("<unknown>".to_owned(), file.path()))43			}44		}4546		Ok(out)47	}48}4950impl Host {51	pub fn key(&self) -> anyhow::Result<String> {52		let key_path = self.fleet_config.host_key_file(&self.hostname)?;53		if metadata(&key_path).map(|m| m.is_file()).unwrap_or(false) {54			Ok(String::from_utf8(read(key_path)?)?)55		} else {56			warn!("Loading key for {}", self.hostname);57			let key = self58				.command_on("cat", false)59				.arg("/etc/ssh/ssh_host_ed25519_key.pub")60				.run_string()?;61			write(key_path, key.clone())?;62			Ok(key)63		}64	}65}