3 Commits

Author SHA1 Message Date
c699bf1849 Format Rust code using rustfmt 2023-07-03 12:54:56 +00: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 74 additions and 30 deletions

20
Cargo.lock generated
View File

@ -1043,17 +1043,17 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
[[package]]
name = "rexec"
version = "1.0.1"
version = "1.0.2"
dependencies = [
"brace-expand",
"clap 4.3.4",
"colored",
"dialoguer",
"dns-lookup",
"env_logger",
"itertools",
"lazy-st",
"log",
"brace-expand",
"clap 4.3.4",
"colored",
"dialoguer",
"dns-lookup",
"env_logger",
"itertools",
"lazy-st",
"log",
"massh",
"regex",
"whoami",

View File

@ -1,6 +1,6 @@
[package]
name = "rexec"
version = "1.0.1"
version = "1.0.2"
edition = "2021"
description = "Parallel SSH executor"
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 dialoguer::Confirm;
use dns_lookup::lookup_host;
@ -7,17 +16,6 @@ use itertools::Itertools;
use log::{error, info};
use massh::{MasshClient, MasshConfig, MasshHostConfig, SshAuth};
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
#[derive(Parser, Debug)]
@ -29,7 +27,11 @@ struct Args {
#[arg(short, long, help = "Use known_hosts to build servers list")]
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,
#[arg(short, long, help = "Command to execute on servers")]
@ -75,16 +77,58 @@ fn read_known_hosts() -> Vec<Host> {
result
}
fn expand_expression(expr: &str) -> Vec<Host> {
let mut result: Vec<Host> = Vec::new();
fn expand_string(string: String) -> Vec<Host> {
let mut result: Vec<String> = Vec::new();
let mut _result: Vec<String> = Vec::new();
let mut hosts: Vec<Host> = Vec::new();
for hostname in brace_expand(expr) {
result.push(Host {
if let Some(open_bracket_index) = string.find('[') {
if let Some(close_bracket_index) = string.find(']') {
let prefix = &string[..open_bracket_index];
let range = &string[open_bracket_index + 1..close_bracket_index];
let postfix = &string[close_bracket_index + 1..];
let parts: Vec<&str> = range.split(':').collect();
if parts.len() == 2 {
if let Ok(start) = parts[0].parse::<u32>() {
if let Ok(end) = parts[1].parse::<u32>() {
for num in start..=end {
_result.push(format!("{}{}{}", prefix, num, postfix));
}
}
}
}
}
} else {
_result.push(String::from(string));
}
for string in _result {
if let Some(open_brace_index) = string.find('{') {
if let Some(close_brace_index) = string.find('}') {
let prefix = &string[..open_brace_index];
let list = &string[open_brace_index + 1..close_brace_index];
let postfix = &string[close_brace_index + 1..];
let items: Vec<&str> = list.split(',').collect();
for item in items {
result.push(format!("{}{}{}", prefix, item, postfix));
}
}
} else {
result.push(String::from(string));
}
}
for hostname in result {
hosts.push(Host {
name: hostname.to_string(),
ip: None,
})
}
result
hosts
}
fn main() {
@ -112,7 +156,7 @@ fn main() {
.collect()
} else {
info!("Using string expansion to build server list.");
expand_expression(&args.expression)
expand_string(args.expression)
};
// Dedup hosts from known_hosts file