1use std::collections::BTreeSet;23use anyhow::{ensure, Result};4use clap::Parser;5use fleet_base::host::Config;6use nix_eval::nix_go_json;78#[derive(Parser)]9pub struct Info {10 #[clap(long)]11 json: bool,12 #[clap(subcommand)]13 cmd: InfoCmd,14}1516#[derive(Parser)]17pub enum InfoCmd {18 19 ListHosts {20 #[clap(long)]21 tagged: Vec<String>,22 },23 24 HostIps {25 host: String,26 #[clap(long)]27 external: bool,28 #[clap(long)]29 internal: bool,30 },31}3233impl Info {34 pub async fn run(self, config: &Config) -> Result<()> {35 let mut data = Vec::new();36 match self.cmd {37 InfoCmd::ListHosts { ref tagged } => {38 'host: for host in config.list_hosts().await? {39 if !tagged.is_empty() {40 let config = &config.config_field;41 let tags: Vec<String> = nix_go_json!(config.hosts[{ host.name }].tags);42 for tag in tagged {43 if !tags.contains(tag) {44 continue 'host;45 }46 }47 }48 data.push(host.name);49 }50 }51 InfoCmd::HostIps {52 host,53 external,54 internal,55 } => {56 ensure!(57 external || internal,58 "at leas one of --external or --internal must be set"59 );60 let mut out = <BTreeSet<String>>::new();61 let host = config.system_config(&host).await?;62 if external {63 let data: Vec<String> = nix_go_json!(host.network.externalIps);64 out.extend(data);65 }66 if internal {67 let data: Vec<String> = nix_go_json!(host.network.internalIps);68 out.extend(data);69 }70 for ip in out {71 data.push(ip);72 }73 }74 }7576 if self.json {77 let v = serde_json::to_string_pretty(&data)?;78 print!("{}", v);79 } else {80 for v in data {81 println!("{}", v);82 }83 }84 Ok(())85 }86}