6 Commits

Author SHA1 Message Date
e071381e03 Format Rust code using rustfmt 2023-07-25 16:20:32 +00:00
ad2d36bb35 Fixed string expansion 2023-07-25 19:18:45 +03:00
4f1657c37c Fixed string expansion 2023-07-25 19:17:32 +03:00
a28d1a3a38 WIP 2023-07-03 18:51:06 +03:00
502d206dc7 Cleanup 2023-07-03 15:52:55 +03:00
e661349034 add string expanshions 2023-07-03 15:19:29 +03:00
3 changed files with 58 additions and 21 deletions

2
Cargo.lock generated
View File

@ -1043,7 +1043,7 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
[[package]] [[package]]
name = "rexec" name = "rexec"
version = "1.0.1" version = "1.0.2"
dependencies = [ dependencies = [
"brace-expand", "brace-expand",
"clap 4.3.4", "clap 4.3.4",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "rexec" name = "rexec"
version = "1.0.1" version = "1.0.3"
edition = "2021" edition = "2021"
description = "Parallel SSH executor" description = "Parallel SSH executor"
repository = "https://github.com/house-of-vanity/rexec" repository = "https://github.com/house-of-vanity/rexec"

View File

@ -1,4 +1,13 @@
use brace_expand::brace_expand; #[macro_use]
extern crate log;
use std::collections::HashMap;
use std::fs::read_to_string;
use std::hash::Hash;
use std::net::IpAddr;
use std::process;
use clap::Parser;
use colored::*; use colored::*;
use dialoguer::Confirm; use dialoguer::Confirm;
use dns_lookup::lookup_host; use dns_lookup::lookup_host;
@ -7,17 +16,6 @@ use itertools::Itertools;
use log::{error, info}; use log::{error, info};
use massh::{MasshClient, MasshConfig, MasshHostConfig, SshAuth}; use massh::{MasshClient, MasshConfig, MasshHostConfig, SshAuth};
use regex::Regex; use regex::Regex;
use std::collections::HashMap;
use std::fs::read_to_string;
use std::hash::Hash;
use std::net::IpAddr;
use std::process;
#[macro_use]
extern crate log;
use clap::Parser;
// Define args // Define args
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
@ -29,7 +27,11 @@ struct Args {
#[arg(short, long, help = "Use known_hosts to build servers list")] #[arg(short, long, help = "Use known_hosts to build servers list")]
known_hosts: bool, known_hosts: bool,
#[arg(short, long, help = "Expression to build server list")] #[arg(
short,
long,
help = "Expression to build server list. List and range expansion available. Example: 'web-[1:12]-io-{prod,dev}'"
)]
expression: String, expression: String,
#[arg(short, long, help = "Command to execute on servers")] #[arg(short, long, help = "Command to execute on servers")]
@ -75,16 +77,51 @@ fn read_known_hosts() -> Vec<Host> {
result result
} }
fn expand_expression(expr: &str) -> Vec<Host> { fn expand_range(start: i32, end: i32) -> Vec<String> {
let mut result: Vec<Host> = Vec::new(); (start..=end).map(|i| i.to_string()).collect()
}
for hostname in brace_expand(expr) { fn expand_list(list: &str) -> Vec<String> {
result.push(Host { list.split(',').map(|s| s.to_string()).collect()
}
fn expand_string(s: &str) -> Vec<Host> {
let mut hosts: Vec<Host> = Vec::new();
let mut result = vec![s.to_string()];
while let Some(r) = result.iter().find(|s| s.contains('[')) {
let r = r.clone();
let start = r.find('[').unwrap();
let end = r.find(']').unwrap();
let colon = r.find(':').unwrap();
let low = r[start + 1..colon].parse::<i32>().unwrap();
let high = r[colon + 1..end].parse::<i32>().unwrap();
result.retain(|s| s != &r);
for val in expand_range(low, high) {
let new_str = format!("{}{}{}", &r[..start], val, &r[end + 1..]);
result.push(new_str);
}
}
while let Some(r) = result.iter().find(|s| s.contains('{')) {
let r = r.clone();
let start = r.find('{').unwrap();
let end = r.find('}').unwrap();
let list = &r[start + 1..end];
result.retain(|s| s != &r);
for val in expand_list(list) {
let new_str = format!("{}{}{}", &r[..start], val, &r[end + 1..]);
result.push(new_str);
}
}
for hostname in result {
hosts.push(Host {
name: hostname.to_string(), name: hostname.to_string(),
ip: None, ip: None,
}) })
} }
result hosts
} }
fn main() { fn main() {
@ -112,7 +149,7 @@ fn main() {
.collect() .collect()
} else { } else {
info!("Using string expansion to build server list."); info!("Using string expansion to build server list.");
expand_expression(&args.expression) expand_string(&args.expression)
}; };
// Dedup hosts from known_hosts file // Dedup hosts from known_hosts file