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

difftreelog

feat info subcommand

Yaroslav Bolyukin2021-10-01parent: #5fd92ba.patch.diff
in: trunk

4 files changed

addedcmds/fleet/src/cmds/info.rsdiffbeforeafterboth
--- /dev/null
+++ b/cmds/fleet/src/cmds/info.rs
@@ -0,0 +1,81 @@
+use std::collections::BTreeSet;
+
+use crate::host::Config;
+use anyhow::{ensure, Result};
+use structopt::StructOpt;
+
+#[derive(StructOpt)]
+pub struct Info {
+	#[structopt(long)]
+	json: bool,
+	#[structopt(subcommand)]
+	cmd: InfoCmd,
+}
+
+#[derive(StructOpt)]
+pub enum InfoCmd {
+	/// List hosts
+	ListHosts {
+		#[structopt(long)]
+		tagged: Vec<String>,
+	},
+	/// List ips
+	HostIps {
+		host: String,
+		#[structopt(long)]
+		external: bool,
+		#[structopt(long)]
+		internal: bool,
+	},
+}
+
+impl Info {
+	pub fn run(self, config: &Config) -> Result<()> {
+		let mut data = Vec::new();
+		match self.cmd {
+			InfoCmd::ListHosts { ref tagged } => {
+				'host: for host in config.list_hosts()? {
+					if !tagged.is_empty() {
+						let tags: Vec<String> = config.config_attr(&host, "tags")?;
+						for tag in tagged {
+							if !tags.contains(&tag) {
+								continue 'host;
+							}
+						}
+					}
+					data.push(host);
+				}
+			}
+			InfoCmd::HostIps {
+				host,
+				external,
+				internal,
+			} => {
+				ensure!(
+					external || internal,
+					"at leas one of --external or --internal must be set"
+				);
+				let mut out = <BTreeSet<String>>::new();
+				if external {
+					out.extend(config.config_attr::<Vec<String>>(&host, "network.externalIps")?);
+				}
+				if internal {
+					out.extend(config.config_attr::<Vec<String>>(&host, "network.internalIps")?);
+				}
+				for ip in out {
+					data.push(ip);
+				}
+			}
+		}
+
+		if self.json {
+			let v = serde_json::to_string_pretty(&data)?;
+			print!("{}", v);
+		} else {
+			for v in data {
+				println!("{}", v);
+			}
+		}
+		Ok(())
+	}
+}
modifiedcmds/fleet/src/cmds/mod.rsdiffbeforeafterboth
--- a/cmds/fleet/src/cmds/mod.rs
+++ b/cmds/fleet/src/cmds/mod.rs
@@ -1,2 +1,3 @@
 pub mod build_systems;
 pub mod secrets;
+pub mod info;
modifiedcmds/fleet/src/host.rsdiffbeforeafterboth
--- a/cmds/fleet/src/host.rs
+++ b/cmds/fleet/src/host.rs
@@ -9,6 +9,7 @@
 };
 
 use anyhow::Result;
+use serde::de::DeserializeOwned;
 use structopt::clap::ArgGroup;
 use structopt::StructOpt;
 
@@ -80,6 +81,17 @@
 			.inherit_stdio()
 			.run_json()
 	}
+	pub fn config_attr<T: DeserializeOwned>(&self, host: &str, attr: &str) -> Result<T> {
+		Command::new("nix")
+			.arg("eval")
+			.arg(self.full_attr_name(&format!(
+				"fleetConfigurations.default.configuredSystems.{}.config.{}",
+				host, attr
+			)))
+			.args(&["--json", "--show-trace"])
+			.inherit_stdio()
+			.run_json()
+	}
 
 	pub fn data(&self) -> Ref<FleetData> {
 		self.data.borrow()
modifiedcmds/fleet/src/main.rsdiffbeforeafterboth
before · cmds/fleet/src/main.rs
1pub mod command;2pub mod host;3pub mod keys;45pub mod cmds;6pub mod nix;78mod fleetdata;910use anyhow::Result;11use structopt::clap::AppSettings::*;12use structopt::StructOpt;1314use cmds::{build_systems::BuildSystems, secrets::Secrets};15use host::{Config, FleetOpts};1617#[derive(StructOpt)]18enum Opts {19	/// Prepare systems for deployments20	BuildSystems(BuildSystems),21	/// Secret management22	Secrets(Secrets),23}2425#[derive(StructOpt)]26#[structopt(27	version = "1.0",28	author,29	global_setting(ColorAuto),30	global_setting(ColoredHelp)31)]32struct RootOpts {33	#[structopt(flatten)]34	fleet_opts: FleetOpts,35	#[structopt(subcommand)]36	command: Opts,37}3839fn run_command(config: &Config, command: Opts) -> Result<()> {40	match command {41		Opts::BuildSystems(c) => c.run(config)?,42		Opts::Secrets(s) => s.run(config)?,43	};44	Ok(())45}4647fn main() -> Result<()> {48	env_logger::Builder::new()49		.filter_level(log::LevelFilter::Info)50		.init();51	let opts = RootOpts::from_args();52	let config = opts.fleet_opts.build()?;5354	match run_command(&config, opts.command) {55		Ok(()) => {56			config.save()?;57			Ok(())58		}59		Err(e) => {60			let _ = config.save();61			Err(e)62		}63	}64}
after · cmds/fleet/src/main.rs
1pub mod command;2pub mod host;3pub mod keys;45pub mod cmds;6pub mod nix;78mod fleetdata;910use anyhow::Result;11use structopt::clap::AppSettings::*;12use structopt::StructOpt;1314use cmds::{build_systems::BuildSystems, info::Info, secrets::Secrets};15use host::{Config, FleetOpts};1617#[derive(StructOpt)]18enum Opts {19	/// Prepare systems for deployments20	BuildSystems(BuildSystems),21	/// Secret management22	Secrets(Secrets),23	/// Config parsing24	Info(Info),25}2627#[derive(StructOpt)]28#[structopt(29	version = "1.0",30	author,31	global_setting(ColorAuto),32	global_setting(ColoredHelp)33)]34struct RootOpts {35	#[structopt(flatten)]36	fleet_opts: FleetOpts,37	#[structopt(subcommand)]38	command: Opts,39}4041fn run_command(config: &Config, command: Opts) -> Result<()> {42	match command {43		Opts::BuildSystems(c) => c.run(config)?,44		Opts::Secrets(s) => s.run(config)?,45		Opts::Info(i) => i.run(config)?,46	};47	Ok(())48}4950fn main() -> Result<()> {51	env_logger::Builder::new()52		.filter_level(log::LevelFilter::Info)53		.init();54	let opts = RootOpts::from_args();55	let config = opts.fleet_opts.build()?;5657	match run_command(&config, opts.command) {58		Ok(()) => {59			config.save()?;60			Ok(())61		}62		Err(e) => {63			let _ = config.save();64			Err(e)65		}66	}67}