From 9fca2d83347b41a860677abd52c165a258667be8 Mon Sep 17 00:00:00 2001 From: bartvanbenthem Date: Tue, 4 Jul 2023 18:11:31 +0200 Subject: [PATCH] update err for input mismatch --- Cargo.toml | 1 + README.md | 12 +++-- project/example-var.json | 4 +- project/example-var.yaml | 4 +- project/invalid-input | 1 + run.sh | 4 +- src/main.rs | 101 ++++++++++++++++++++++++++++----------- 7 files changed, 91 insertions(+), 36 deletions(-) create mode 100644 project/invalid-input diff --git a/Cargo.toml b/Cargo.toml index 444ad63..ab60632 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,4 @@ handlebars = "4.3.7" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" clap = "2.33" +serde_yaml = "0.8" diff --git a/README.md b/README.md index c6068c9..3133a01 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # manifestgen-rs -CLI tool for generating configuration manifests. +CLI tool for generating configuration manifests. Both JSON and YAML are valid input types that can be converted from template to manifest. # usage manual ```bash @@ -27,10 +27,16 @@ OPTIONS: # read variables from stdin and write manifest to a file cat project/example-var.json | ./target/debug/manifestgen -t project/targets.tmpl -o project/config.yaml -# read variables from a file and write manifest to stdout +# read JSON variables from a file and write manifest to stdout ./target/debug/manifestgen -v project/example-var.json -t project/targets.tmpl -# read variables from stdin and write manifest to stdout +# read YAML variables from a file and write manifest to stdout +./target/debug/manifestgen -v project/example-var.yaml -t project/targets.tmpl + +# read JSON variables from stdin and write manifest to stdout cat project/example-var.json | ./target/debug/manifestgen --template project/targets.tmpl +# read YAML variables from stdin and write manifest to stdout +cat project/example-var.yaml | ./target/debug/manifestgen --template project/targets.tmpl + ``` \ No newline at end of file diff --git a/project/example-var.json b/project/example-var.json index 262b0e8..8f7b472 100644 --- a/project/example-var.json +++ b/project/example-var.json @@ -1,4 +1,4 @@ { - "policy_name": "test-policy", - "pool_name": "poc-pool" + "policy_name": "test-policy-json-input", + "pool_name": "poc-pool-json-input" } \ No newline at end of file diff --git a/project/example-var.yaml b/project/example-var.yaml index b026c3e..93ec410 100644 --- a/project/example-var.yaml +++ b/project/example-var.yaml @@ -1,2 +1,2 @@ -policy_name: test-policy -pool_name: poc-pool \ No newline at end of file +policy_name: test-policy-yaml-input +pool_name: poc-pool-yaml-input \ No newline at end of file diff --git a/project/invalid-input b/project/invalid-input new file mode 100644 index 0000000..7c02577 --- /dev/null +++ b/project/invalid-input @@ -0,0 +1 @@ +dfgyyrtyhdhfgh \ No newline at end of file diff --git a/run.sh b/run.sh index 1ba492a..8c05e12 100755 --- a/run.sh +++ b/run.sh @@ -1,6 +1,8 @@ #!/bin/bash cargo test cargo build + # run example to stdout cat project/example-var.json | ./target/debug/manifestgen --template project/targets.tmpl -#cat project/example-var.yaml | ./target/debug/manifestgen --template project/targets.tmpl \ No newline at end of file +#cat project/example-var.yaml | ./target/debug/manifestgen --template project/targets.tmpl +#cat project/invalid-input | ./target/debug/manifestgen --template project/targets.tmpl \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index e876f64..d8545ca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,12 @@ use std::collections::BTreeMap; use std::fs; use serde::{Deserialize, Serialize}; -use serde_json; +use serde_json::{Value}; +use serde_yaml; use std::env; use std::error::Error; use std::io::{self, Read, Write}; +use std::process; use handlebars::Handlebars; use clap::{App, Arg}; @@ -19,33 +21,21 @@ struct Config { variables_file: String, } + fn main() -> Result<(), Box> { // Get command-line arguments let config = get_args().unwrap(); - - // initialize KeyValuePair type - let key_value_pairs: KeyValuePairs; - - if config.variables_file.is_empty() { - // Process the JSON value trough stdin - let mut input = String::new(); - io::stdin().read_to_string(&mut input)?; - key_value_pairs = serde_json::from_str(&input)?; - } else { - // Read JSON file - let json_content = fs::read_to_string(config.variables_file)?; - key_value_pairs = serde_json::from_str(&json_content)?; - } - - // Load template file - let template_content = fs::read_to_string(config.template_file)?; - // Initialize the templating engine - let mut handlebars = Handlebars::new(); - handlebars.register_template_string("template", &template_content)?; + let input_type_result = parse_input_type(&config); + let input_type = match input_type_result { + Ok(input_type) => input_type, + Err(_) => { + eprintln!("No valid JSON or YAML input type, restart the Manifestgen with valid input!"); + process::exit(1) + }, + }; - // Render the template - let rendered_template = handlebars.render("template", &key_value_pairs.0)?; + let rendered_template = render_config(&input_type, &config)?; // write to disk or stdout based on the provided output param if let Err(err) = manifest_writer(&config.output_file, &rendered_template) { @@ -93,6 +83,66 @@ fn get_args() -> Result> { }) } +fn parse_input_type(config: &Config) -> Result> { + // initialize KeyValuePair type + let key_value_pairs: KeyValuePairs; + + if config.variables_file.is_empty() { + // Process the JSON value trough stdin + let mut input = String::new(); + io::stdin().read_to_string(&mut input)?; + if is_valid_json(&input) { + key_value_pairs = serde_json::from_str(&input)?; + } else if is_valid_yaml(&input){ + key_value_pairs = serde_yaml::from_str(&input)?; + } else { + panic!("No valid JSON or YAML input type!") + } + } else { + // Read JSON file + let var_file = fs::read_to_string(&config.variables_file)?; + if is_valid_json(&var_file) { + key_value_pairs = serde_json::from_str(&var_file)?; + } else if is_valid_yaml(&var_file){ + key_value_pairs = serde_yaml::from_str(&var_file)?; + } else { + panic!("No valid JSON or YAML input type!") + } + } + + Ok(key_value_pairs) + +} + +fn is_valid_json(input: &str) -> bool { + match serde_json::from_str::(input) { + Ok(_) => true, + Err(_) => false, + } +} + +fn is_valid_yaml(input: &str) -> bool { + match serde_yaml::from_str::(input) { + Ok(_) => true, + Err(_) => false, + } +} + +// -------------------------------------------------- +fn render_config(key_value_pairs: &KeyValuePairs, config: &Config) -> Result> { + // Load template file + let template_content = fs::read_to_string(&config.template_file)?; + + // Initialize the templating engine + let mut handlebars = Handlebars::new(); + handlebars.register_template_string("template", &template_content)?; + + // Render the template + let rendered_template = handlebars.render("template", &key_value_pairs.0)?; + + Ok(rendered_template) +} + // -------------------------------------------------- fn manifest_writer(output: &String, template: &String) -> Result<(), Box> { if output.is_empty() { @@ -115,11 +165,6 @@ fn manifest_writer(output: &String, template: &String) -> Result<(), Box Result<(), Box> { -// -// Ok(()) -//} - // -------------------------------------------------- fn print_current_dir() { if let Ok(current_dir) = env::current_dir() {