difftreelog
feat info subcommand
in: trunk
4 files changed
cmds/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(())
+ }
+}
cmds/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;
cmds/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()
cmds/fleet/src/main.rsdiffbeforeafterboth1pub 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}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}