|
use std::env; |
|
use std::fs; |
|
use std::fs::File; |
|
use std::io::prelude::*; |
|
|
|
extern crate glob; |
|
use self::glob::glob; |
|
|
|
use std::path::Path; |
|
|
|
extern crate clap; |
|
use clap::{App, Arg}; |
|
|
|
extern crate dotenv; |
|
use dotenv::dotenv; |
|
|
|
use std::collections::HashMap; |
|
|
|
extern crate handlebars; |
|
#[macro_use] |
|
extern crate serde_json; |
|
use handlebars::Handlebars; |
|
|
|
fn string_to_static_str(s: &String) -> &'static str { |
|
Box::leak(s.to_owned().into_boxed_str()) |
|
} |
|
|
|
fn main() -> std::io::Result<()> { |
|
dotenv().ok(); |
|
let env: Vec<(String, String)> = dotenv::vars().collect(); |
|
|
|
let reg = Handlebars::new(); |
|
|
|
// init key-value store |
|
let mut store = HashMap::new(); |
|
|
|
// flatten the structure to make it accessible for handlebars |
|
for c in &env { |
|
// do something with `c` |
|
let (key, value) = c; |
|
|
|
// assign to key-value store |
|
store.insert(key.to_string(), value.to_string()); |
|
} |
|
|
|
|
|
let _is_in_production = env::var("PRODUCTION").is_ok(); |
|
// get the directory from the args |
|
let matches = App::new("Rget") |
|
.version("0.1.0") |
|
.author("BransonGitomeh <[email protected]>") |
|
.about("Combine kube files and env variables to create recreatable clusters") |
|
.arg( |
|
Arg::with_name("PATH") |
|
.required(true) |
|
.takes_value(true) |
|
.index(1) |
|
.help("Path to work with..."), |
|
) |
|
.arg( |
|
Arg::with_name("FILE") |
|
.required(true) |
|
.takes_value(true) |
|
.index(2) |
|
.help("Final manifest to write to..."), |
|
) |
|
.get_matches(); |
|
|
|
let path = matches.value_of("PATH").unwrap(); |
|
let manifest_path = matches.value_of("FILE").unwrap(); |
|
println!("Base path is {}", path); |
|
println!("Manifest path is {}", manifest_path); |
|
|
|
// remove the existing manifest |
|
let f = fs::remove_file(Path::new(manifest_path)); |
|
|
|
let _f = match f { |
|
Ok(_file) => { |
|
println!("Removed existing manifest {}", manifest_path) |
|
}, |
|
Err(error) => { |
|
let error = format!( |
|
"No {manifest_path} found to delete, creating new one: {error}", |
|
manifest_path = &manifest_path, |
|
error = &error |
|
); |
|
println!("{}", error) |
|
} |
|
}; |
|
|
|
let mut manifest = String::new(); |
|
|
|
fn process_file(path: &Path) -> String { |
|
let mut contents = String::new(); |
|
let mut file = File::open(&path).unwrap(); |
|
file.read_to_string(&mut contents).unwrap(); |
|
contents |
|
} |
|
|
|
let divider = "\n---\n"; |
|
let base_path = format!("{path}**/*.yaml", path = &path); |
|
println!("Glob to match is {}", base_path); |
|
// read all files in path |
|
for entry in glob(&base_path).expect("Failed to read glob pattern") { |
|
match entry { |
|
Ok(path) => { |
|
manifest.push_str(divider); |
|
manifest.push_str(string_to_static_str(&process_file(&path))); |
|
} |
|
Err(e) => println!("{:?}", e), |
|
} |
|
} |
|
|
|
println!("Manifest writing complete"); |
|
|
|
let mut file = File::create("./manifest.yaml").unwrap(); |
|
|
|
let processed_manifest = reg |
|
.render_template(string_to_static_str(&manifest), &json!(store)) |
|
.unwrap(); |
|
file.write_all(processed_manifest.as_bytes())?; |
|
|
|
Ok(()) |
|
} |
|
|
|
#[test] |
|
fn should_fail() { |
|
unimplemented!(); |
|
} |