diff --git a/config.toml b/config.toml deleted file mode 100644 index 2e9276b..0000000 --- a/config.toml +++ /dev/null @@ -1,13 +0,0 @@ -[default_logins] -username="monitor" -password="HewoWorld" - -[[host]] -name="Example1" -ip="127.0.0.1" - -[[host]] -name="Example2" -ip="127.0.0.2" -username="admin" -password="password123" diff --git a/src/config/cli.rs b/src/config/cli.rs index d24d336..fc63fbc 100644 --- a/src/config/cli.rs +++ b/src/config/cli.rs @@ -1,4 +1,6 @@ -#[derive(Debug, Clone, Default, clap::Parser)] +use clap::ArgGroup; + +#[derive(Debug, Clone, clap::Parser, Default)] pub struct CliArgs { /// Configuration file path #[arg(long = "config", short = 'C', default_value = "./config.toml")] @@ -7,4 +9,71 @@ pub struct CliArgs { /// Output more information in logs #[arg(long = "verbose", short = 'v')] pub verbose: bool, + + #[command(subcommand)] + pub command: CliCommand, +} + +#[derive(Debug, Clone, clap::Subcommand, Default)] +pub enum CliCommand { + /// Run command once + #[command( + group( + ArgGroup::new("devs") + .args(["all", "devices"]) + .required(true) + ) + )] + Run { + /// Run on ALL devices + #[arg(long, short = 'a')] + all: bool, + /// Run on all specified devices + #[arg(long, short = 'd')] + devices: Vec, + /// Command to run + #[arg(long, short = 'c')] + command: String, + }, + /// Run command continuosly + #[command( + group( + ArgGroup::new("devs") + .args(["all", "devices"]) + .required(true) + ) + )] + Monitor { + /// Run on ALL devices + #[arg(long, short = 'a')] + all: bool, + /// Run on all specified devices + #[arg(long, short = 'd')] + devices: Vec, + /// Command to run + #[arg(long, short = 'c')] + command: String, + #[arg(long, short = 'i')] + /// Interval to run the commands at + interval: f32, + }, + /// Manage devices + Device { + #[command(subcommand)] + command: CliDeviceCommand, + }, + + #[default] + #[clap(skip)] + None, +} + +#[derive(Debug, Clone, clap::Subcommand, Default)] +pub enum CliDeviceCommand { + /// List devices + List, + + #[default] + #[clap(skip)] + None, } diff --git a/src/config/mod.rs b/src/config/mod.rs index 2db1162..8538dc5 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -3,11 +3,11 @@ use std::net::{IpAddr, Ipv4Addr}; use clap::Parser; use serde::{Deserialize, Serialize}; -use crate::config::cli::CliArgs; +use crate::config::cli::{CliArgs, CliCommand}; const DEFAULT_CONFIG: &'static str = include_str!("../../config.default.toml"); -mod cli; +pub mod cli; #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct Config { diff --git a/src/main.rs b/src/main.rs index a9e4062..3d51a7b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,81 @@ +use std::{net::IpAddr, str::FromStr}; + +use crate::config::cli::CliCommand; + mod config; mod mt_commander; -fn main() -> anyhow::Result<()> { +#[tokio::main] +async fn main() -> anyhow::Result<()> { let cfg = config::Config::parse()?; dbg!(&cfg); + + mt_commander::MtCommander::init(cfg.clone())?; + + match &cfg.cli.command { + CliCommand::Run { + all, + devices, + command, + } => { + let mut hosts = Vec::new(); + if *all { + hosts.clone_from(&cfg.hosts); + } else { + let mut errored = false; + for dev in devices { + let Ok(ip) = IpAddr::from_str(dev) else { + log::error!("Unable to parse {dev} as an IP"); + errored = true; + continue; + }; + let found_hosts = cfg.hosts.iter().filter(|h| h.ip == ip).collect::>(); + let Some(host) = found_hosts.first() else { + log::error!("Could not find host with IP {dev}"); + errored = true; + continue; + }; + hosts.push((**host).clone()); + } + if errored { + return Ok(()); + } + } + mt_commander::MtCommander::run_command_on_hosts(&hosts, command).await?; + } + CliCommand::Monitor { + all, + devices, + command, + interval, + } => { + let mut hosts = Vec::new(); + if *all { + hosts.clone_from(&cfg.hosts); + } else { + let mut errored = false; + for dev in devices { + let Ok(ip) = IpAddr::from_str(dev) else { + log::error!("Unable to parse {dev} as an IP"); + errored = true; + continue; + }; + let found_hosts = cfg.hosts.iter().filter(|h| h.ip == ip).collect::>(); + let Some(host) = found_hosts.first() else { + log::error!("Could not find host with IP {dev}"); + errored = true; + continue; + }; + hosts.push((**host).clone()); + } + if errored { + return Ok(()); + } + } + mt_commander::MtCommander::run_command_on_hosts(&hosts, command).await?; + } + CliCommand::Device { command } => {} + CliCommand::None => unreachable!(), + } Ok(()) }