Play around with simple SSH commands
This commit is contained in:
parent
523491eed4
commit
b66d6824bc
|
@ -0,0 +1,319 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "cli"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"gumdrop",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"ssh2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e"
|
||||
|
||||
[[package]]
|
||||
name = "gumdrop"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46571f5d540478cf70d2a42dd0d6d8e9f4b9cc7531544b93311e657b86568a0b"
|
||||
dependencies = [
|
||||
"gumdrop_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gumdrop_derive"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "915ef07c710d84733522461de2a734d4d62a3fd39a4d4f404c2f385ef8618d05"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
|
||||
|
||||
[[package]]
|
||||
name = "libssh2-sys"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df40b13fe7ea1be9b9dffa365a51273816c345fc1811478b57ed7d964fbfc4ce"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"libz-sys",
|
||||
"openssl-sys",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cloudabi",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.118"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.118"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.8.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7baae0a99f1a324984bcdc5f0718384c1f69775f1c7eec8b859b71b443e3fd7"
|
||||
dependencies = [
|
||||
"dtoa",
|
||||
"linked-hash-map",
|
||||
"serde",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae524f056d7d770e174287294f562e95044c68e88dec909a00d2094805db9d75"
|
||||
|
||||
[[package]]
|
||||
name = "ssh2"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed024de0a5e6944fe3080a3745e7a5649c5517ea2a6cfb16333f94f89c248985"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
"libssh2-sys",
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9802ddde94170d186eeee5005b798d9c159fa970403f1be19976d0cfb939b72"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[workspace]
|
||||
members = [
|
||||
'cli',
|
||||
]
|
|
@ -0,0 +1,20 @@
|
|||
= Zap
|
||||
|
||||
A simple cross-platform orchestration and configuration management tool.
|
||||
|
||||
The main goal for Zap is to a simple mechanism for managing groups of computers
|
||||
with varying configurations and needs. Zap accomplishes this with "tasks" which
|
||||
can be composed into "plans" or run standalone. These tasks can be collections
|
||||
of scripts or a statically linked binaries, which will be pushed to the target
|
||||
machine(s) and executed.
|
||||
|
||||
Zap borrows ideas from
|
||||
link:https://puppet.com/docs/bolt/latest/bolt.html[Puppet Bolt]. but leaves
|
||||
some of the Puppet-based legacy from Bolt behind.
|
||||
|
||||
|
||||
== Goals
|
||||
|
||||
* Support BSD and Linux with ease
|
||||
* Make creating a plan very easy, including adding some simple logic
|
||||
* Explore tags-based task assignment
|
|
@ -0,0 +1,19 @@
|
|||
[package]
|
||||
name = "cli"
|
||||
version = "0.1.0"
|
||||
authors = ["R. Tyler Croy <rtyler@brokenco.de>"]
|
||||
edition = "2018"
|
||||
|
||||
[[bin]]
|
||||
name = "zap"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
gumdrop = "~0.8.0"
|
||||
# Needed for deserializing JSON messages _and_ managing our configuration
|
||||
# effectively
|
||||
serde = { version = "~1.0", features = ["derive", "rc"] }
|
||||
serde_derive = "~1.0"
|
||||
serde_json = "~1.0"
|
||||
serde_yaml = "~0.8"
|
||||
ssh2 = "~0.9.0"
|
|
@ -0,0 +1,110 @@
|
|||
use gumdrop::Options;
|
||||
use serde::Deserialize;
|
||||
use std::io::BufReader;
|
||||
use std::io::prelude::*;
|
||||
use std::net::{TcpStream};
|
||||
use ssh2::Session;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
struct Inventory {
|
||||
targets: Vec<Target>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
struct Target {
|
||||
name: String,
|
||||
uri: String,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let opts = MyOptions::parse_args_default_or_exit();
|
||||
|
||||
if opts.command.is_none() {
|
||||
println!("Must specify a subcommand!");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let file = std::fs::File::open("inventory.yml").expect("Failed to load the inventory.ymll file");
|
||||
let reader = BufReader::new(file);
|
||||
let inventory: Inventory = serde_yaml::from_reader(reader).expect("Failed to read intenvory");
|
||||
|
||||
match opts.command.unwrap() {
|
||||
Command::Cmd(runopts) => {
|
||||
if let Some(target) = inventory.targets.iter().find(|t| t.name == runopts.targets) {
|
||||
println!("run a command: {:?}", runopts);
|
||||
std::process::exit(run(&runopts.command, &target));
|
||||
}
|
||||
else {
|
||||
println!("Couldn't find a target named `{}`", runopts.targets);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn run(command: &str, target: &Target) -> i32 {
|
||||
// Connect to the local SSH server
|
||||
let tcp = TcpStream::connect(format!("{}:22", target.uri)).unwrap();
|
||||
let mut sess = Session::new().unwrap();
|
||||
sess.set_tcp_stream(tcp);
|
||||
sess.handshake().unwrap();
|
||||
sess.userauth_agent(&std::env::var("USER").unwrap()).unwrap();
|
||||
|
||||
let mut channel = sess.channel_session().unwrap();
|
||||
channel.exec(command).unwrap();
|
||||
let mut s = String::new();
|
||||
channel.read_to_string(&mut s).unwrap();
|
||||
print!("{}", s);
|
||||
channel.wait_close().expect("Failed to close the channel");
|
||||
return channel.exit_status().unwrap();
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Options)]
|
||||
struct MyOptions {
|
||||
// Options here can be accepted with any command (or none at all),
|
||||
// but they must come before the command name.
|
||||
#[options(help = "print help message")]
|
||||
help: bool,
|
||||
#[options(help = "be verbose")]
|
||||
verbose: bool,
|
||||
|
||||
// The `command` option will delegate option parsing to the command type,
|
||||
// starting at the first free argument.
|
||||
#[options(command)]
|
||||
command: Option<Command>,
|
||||
}
|
||||
|
||||
// The set of commands and the options each one accepts.
|
||||
//
|
||||
// Each variant of a command enum should be a unary tuple variant with only
|
||||
// one field. This field must implement `Options` and is used to parse arguments
|
||||
// that are given after the command name.
|
||||
#[derive(Debug, Options)]
|
||||
enum Command {
|
||||
// Command names are generated from variant names.
|
||||
// By default, a CamelCase name will be converted into a lowercase,
|
||||
// hyphen-separated name; e.g. `FooBar` becomes `foo-bar`.
|
||||
//
|
||||
// Names can be explicitly specified using `#[options(name = "...")]`
|
||||
#[options(help = "show help for a command")]
|
||||
Help(HelpOpts),
|
||||
#[options(help="Run a single command on a target(s)")]
|
||||
Cmd(RunOpts),
|
||||
}
|
||||
|
||||
#[derive(Debug, Options)]
|
||||
struct HelpOpts {
|
||||
#[options(free)]
|
||||
free: Vec<String>,
|
||||
}
|
||||
|
||||
// Options accepted for the `make` command
|
||||
#[derive(Debug, Options)]
|
||||
struct RunOpts {
|
||||
#[options(free, help="Command to execute on the target(s)")]
|
||||
command: String,
|
||||
#[options(help = "Name of a target or group")]
|
||||
targets: String,
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
groups:
|
||||
- name: containers
|
||||
targets:
|
||||
- freebsd-tor
|
||||
- gopher
|
||||
|
||||
targets:
|
||||
- name: freebsd-tor
|
||||
uri: 192.168.1.41
|
||||
- name: gopher
|
||||
uri: 192.168.1.41
|
||||
|
||||
config:
|
||||
transport: ssh
|
Loading…
Reference in New Issue