Start working on the task definition parsing grammar, pretty easy.

This commit is contained in:
R Tyler Croy 2020-12-30 14:27:33 -08:00
parent 97ae0d52a6
commit 904bf007ce
11 changed files with 350 additions and 20 deletions

207
Cargo.lock generated
View File

@ -1,5 +1,16 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.1"
@ -12,6 +23,39 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "block-buffer"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
dependencies = [
"block-padding",
"byte-tools",
"byteorder",
"generic-array",
]
[[package]]
name = "block-padding"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
dependencies = [
"byte-tools",
]
[[package]]
name = "byte-tools"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
[[package]]
name = "byteorder"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
[[package]]
name = "cc"
version = "1.0.66"
@ -24,18 +68,6 @@ 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"
@ -45,12 +77,47 @@ dependencies = [
"bitflags",
]
[[package]]
name = "colored"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
dependencies = [
"atty",
"lazy_static",
"winapi",
]
[[package]]
name = "digest"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
dependencies = [
"generic-array",
]
[[package]]
name = "dtoa"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e"
[[package]]
name = "fake-simd"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]]
name = "generic-array"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
dependencies = [
"typenum",
]
[[package]]
name = "gumdrop"
version = "0.8.0"
@ -71,12 +138,27 @@ dependencies = [
"syn",
]
[[package]]
name = "hermit-abi"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
dependencies = [
"libc",
]
[[package]]
name = "itoa"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.81"
@ -124,6 +206,18 @@ dependencies = [
"scopeguard",
]
[[package]]
name = "maplit"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]]
name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
[[package]]
name = "openssl-sys"
version = "0.9.60"
@ -161,6 +255,49 @@ dependencies = [
"winapi",
]
[[package]]
name = "pest"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
dependencies = [
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "pest_meta"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
dependencies = [
"maplit",
"pest",
"sha-1",
]
[[package]]
name = "pkg-config"
version = "0.3.19"
@ -246,6 +383,18 @@ dependencies = [
"yaml-rust",
]
[[package]]
name = "sha-1"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
dependencies = [
"block-buffer",
"digest",
"fake-simd",
"opaque-debug",
]
[[package]]
name = "smallvec"
version = "1.5.1"
@ -275,6 +424,18 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "typenum"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
[[package]]
name = "ucd-trie"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
[[package]]
name = "unicode-xid"
version = "0.2.1"
@ -317,3 +478,25 @@ checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "zap"
version = "0.1.0"
dependencies = [
"colored",
"gumdrop",
"serde",
"serde_derive",
"serde_json",
"serde_yaml",
"ssh2",
"zap-parser",
]
[[package]]
name = "zap-parser"
version = "0.1.0"
dependencies = [
"pest",
"pest_derive",
]

View File

@ -1,4 +1,5 @@
[workspace]
members = [
'cli',
'parser',
]

View File

@ -64,10 +64,12 @@ task Install {
required = true
}
// Unless should be implied on every task
unless {
type = string
help = "Script which when returns zero if the package has been installed, i.e. `test -f /usr/bin/nginx`"
}
// provides should be implied on every task
}
// Parameters exposed as environment variables

View File

@ -1,14 +1,11 @@
[package]
name = "cli"
name = "zap"
version = "0.1.0"
authors = ["R. Tyler Croy <rtyler@brokenco.de>"]
edition = "2018"
[[bin]]
name = "zap"
path = "src/main.rs"
[dependencies]
colored = "2"
gumdrop = "~0.8.0"
# Needed for deserializing JSON messages _and_ managing our configuration
# effectively
@ -17,3 +14,4 @@ serde_derive = "~1.0"
serde_json = "~1.0"
serde_yaml = "~0.8"
ssh2 = "~0.9.0"
zap-parser = { path = "../parser" }

View File

@ -1,3 +1,4 @@
use colored::*;
use gumdrop::Options;
use std::io::BufReader;
@ -27,17 +28,16 @@ fn main() {
match opts.command.unwrap() {
Command::Cmd(runopts) => {
println!("run a command: {:?}", runopts);
if let Some(group) = inventory.groups.iter().find(|g| g.name == runopts.targets) {
std::process::exit(runner.run_group(&runopts.command, &group, &inventory));
}
if let Some(target) = inventory.targets.iter().find(|t| t.name == runopts.targets) {
println!("run a command: {:?}", runopts);
println!("{}", format!("run a command: {:?}", runopts).green());
std::process::exit(runner.run(&runopts.command, &target));
}
println!("Couldn't find a target named `{}`", runopts.targets);
println!("{}", format!("Couldn't find a target named `{}`", runopts.targets).red());
}
_ => {}
}

View File

@ -0,0 +1,20 @@
FROM ubuntu:20.04
RUN apt-get update
RUN apt-get install -y openssh-server libssl-dev
RUN mkdir /var/run/sshd
RUN echo 'root:root' |chpasswd
RUN sed -ri 's/^#?PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config
RUN mkdir /root/.ssh
RUN apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
EXPOSE 22
EXPOSE 80
CMD ["/usr/sbin/sshd", "-D"]

View File

@ -0,0 +1,4 @@
= Managing simple web containers
This is an example from the link:https://puppet.com/docs/bolt/latest/getting_started_with_bolt.html[Bolt documentation]

View File

@ -0,0 +1,14 @@
version: '3'
services:
target1:
build: .
ports:
- '3000:80'
- '2000:22'
container_name: target1
target2:
build: .
ports:
- '3001:80'
- '2001:22'
container_name: target2

9
parser/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "zap-parser"
version = "0.1.0"
authors = ["R. Tyler Croy <rtyler@brokenco.de>"]
edition = "2018"
[dependencies]
pest = "~2.1"
pest_derive = "~2.1"

34
parser/src/lib.rs Normal file
View File

@ -0,0 +1,34 @@
#[macro_use]
extern crate pest;
#[macro_use]
extern crate pest_derive;
use pest::Parser;
#[derive(Parser)]
#[grammar="task.pest"]
struct TaskParser;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_simple_script_task() {
let buf = r#"task Install {
parameters {
package {
required = true
help = "Name of package to be installed"
type = string
}
}
script {
inline = "zypper in -y ${ZAP_PACKAGE}"
}
}
"#;
let _task = TaskParser::parse(Rule::task, buf)
.unwrap().next().unwrap();
}
}

65
parser/src/task.pest Normal file
View File

@ -0,0 +1,65 @@
/// This describes the task definition grammar for Zap
taskfile = _{ SOI
~ task+
~ EOI }
task = { "task"
~ identifier
~ opening_brace
~ parameters
~ script
~ closing_brace
}
// An identifier will be used to refer to the task later
identifier = { ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_")* }
parameters = { "parameters"
~ opening_brace
~ parameter+
~ closing_brace
}
parameter = { identifier
~ opening_brace
~ required?
~ help
~ ptype
~ closing_brace
}
required = { "required" ~ equals ~ bool }
help = { "help" ~ equals ~ string }
ptype = { "type" ~ equals ~ typedef }
script = { "script"
~ opening_brace
~ (script_inline)
~ closing_brace
}
script_inline = { "inline" ~ equals ~ string }
opening_brace = { "{" }
closing_brace = { "}" }
equals = { "=" }
quote = { "\"" }
string = { double_quoted }
double_quoted = ${ (quote ~ inner_double_str ~ quote) }
inner_double_str = @{ (!("\"" | "\\") ~ ANY)* ~ (escape ~ inner_double_str)? }
escape = @{ "\\" ~ ("\"" | "\\" | "r" | "n" | "t" | "0" | "'" | code | unicode) }
code = @{ "x" ~ hex_digit{2} }
unicode = @{ "u" ~ opening_brace ~ hex_digit{2, 6} ~ closing_brace }
hex_digit = @{ '0'..'9' | 'a'..'f' | 'A'..'F' }
typedef = { string_type }
string_type = { "string" }
bool = { truthy | falsey }
truthy = { "true" }
falsey = { "false" }
block_comment = _{ "/*" ~ (block_comment | !"*/" ~ ANY)* ~ "*/" }
COMMENT = _{ block_comment | ("//" ~ (!NEWLINE~ ANY)*) }
WHITESPACE = _{ " " | "\t" | NEWLINE }