From 0f936a645c22291f59eb2d46c436b2926fb26355 Mon Sep 17 00:00:00 2001 From: Nikolai Rodionov Date: Wed, 10 Jan 2024 15:50:56 +0100 Subject: [PATCH] Add variables and template mirror url --- src/config/mod.rs | 17 ++++++++++++++++- src/config/patch.rs | 27 +++++++++++++++------------ src/main.rs | 8 +++++++- src/mirror/git.rs | 13 ++++++++++--- src/mirror/mod.rs | 5 ++++- src/source/git.rs | 5 +++-- src/source/helm.rs | 9 +++++---- src/source/mod.rs | 5 ++++- 8 files changed, 64 insertions(+), 25 deletions(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index 2d53d2d..0f25cf0 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,12 +1,13 @@ use log::{info, warn}; use serde::{Deserialize, Serialize}; -use std::fs::File; +use std::{fs::File, collections::HashMap}; pub(crate) mod extension; pub(crate) mod patch; #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub(crate) struct Config { + pub(crate) variables: Option>, pub(crate) repositories: Vec, pub(crate) charts: Vec, pub(crate) mirrors: Vec, @@ -54,6 +55,7 @@ pub(crate) struct GitMirror { pub(crate) path: Option, pub(crate) branch: String, pub(crate) commit: Option, + pub(crate) git_dir: Option, } #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] @@ -82,6 +84,7 @@ pub(crate) struct Chart { // A repository object pub(crate) extensions: Option>, pub(crate) patches: Option>, + pub(crate) variables: Option>, #[serde(skip_serializing)] pub(crate) repository_obj: Option, #[serde(skip_serializing)] @@ -89,6 +92,18 @@ pub(crate) struct Chart { } impl Chart { + pub(crate) fn populate_variables(&mut self, global_variables: Option>) { + if let Some(global_vars) = global_variables { + self.variables = match self.variables.clone() { + Some(mut vars) => { + vars.extend(global_vars); + Some(vars) + }, + None => Some(global_vars), + } + }; + } + pub(crate) fn populate_repository( &mut self, repositories: Vec, diff --git a/src/config/patch.rs b/src/config/patch.rs index d298c51..9aacb9c 100644 --- a/src/config/patch.rs +++ b/src/config/patch.rs @@ -61,19 +61,22 @@ trait PatchInterface { impl PatchInterface for YqPatch { fn apply(&self, chart_local_path: String) -> Result<(), Box> { let cmd = match self.op { - YqOperations::Add => format!( - "yq -i '{} += \"{}\"' {}", - self.key, - self.value.clone().unwrap(), - self.file - ), + YqOperations::Add => { + let value = match self.value.clone().unwrap().starts_with(['{', '[', '\"', '\'']) { + true => self.value.clone().unwrap(), + false => format!("\"{}\"", self.value.clone().unwrap()), + }; + format!("yq -i '{} += {}' {}", self.key, value, self.file) + } YqOperations::Delete => format!("yq -i \'del({})\' {}", self.key, self.file), - YqOperations::Replace => format!( - "yq e -i \'{} = \"{}\"\' {}", - self.key, - self.value.clone().unwrap(), - self.file - ), + YqOperations::Replace => { + let value = match self.value.clone().unwrap().starts_with(['{', '[']) { + true => self.value.clone().unwrap(), + false => format!("\"{}\"", self.value.clone().unwrap()), + }; + + format!("yq e -i '{} = {}' {}", self.key, value, self.file) + } }; cli_exec_from_dir(cmd, chart_local_path)?; Ok(()) diff --git a/src/main.rs b/src/main.rs index b5a0089..87cf7d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ pub(crate) mod source; use clap::Parser; use log::{error, info}; +use std::collections::HashMap; use std::fs; use std::{fs::create_dir, path::PathBuf, process::exit}; use tempfile::TempDir; @@ -77,6 +78,7 @@ fn main() { }; for mut chart in config.clone().charts { + chart.populate_variables(config.variables.clone()); match chart.populate_repository(config.repositories.clone()) { Ok(_) => { info!("repo is populated for chart {}", chart.name); @@ -102,7 +104,11 @@ fn main() { exit(1); } }; - match chart_repo.pull(workdir_path.clone()) { + let vars = match chart.variables { + Some(vars) => vars, + None => HashMap::new(), + }; + match chart_repo.pull(workdir_path.clone(), vars) { Ok(res) => { info!( "succesfully pulled chart {} into {}", diff --git a/src/mirror/git.rs b/src/mirror/git.rs index 40f17c7..bd97eab 100644 --- a/src/mirror/git.rs +++ b/src/mirror/git.rs @@ -18,12 +18,19 @@ impl Target for Git { chart_local: ChartLocal, dry_run: bool, ) -> Result<(), Box> { - let cmd = format!("git clone {} {}", self.url, self.git_dir); + let mut reg = super::register_handlebars(); + // Prepare the URL + reg.register_template_string("url", self.url.clone())?; + let url = reg.render("url", &chart_local)?; + //Prepare the git dir + reg.register_template_string("git_dir", self.git_dir.clone())?; + let git_dir = reg.render("git_dir", &chart_local)?; + + let cmd = format!("git clone {} {}", url, git_dir); cli_exec_from_dir(cmd, workdir_path.clone())?; - let git_repo_path = format!("{}/{}", workdir_path, self.git_dir); + let git_repo_path = format!("{}/{}", workdir_path, git_dir); // Prepare branch - let mut reg = super::register_handlebars(); reg.register_template_string("branch", self.branch.clone())?; let branch = reg.render("branch", &chart_local)?; let cmd = format!("git checkout {}", branch); diff --git a/src/mirror/mod.rs b/src/mirror/mod.rs index 55fd873..b9731c3 100644 --- a/src/mirror/mod.rs +++ b/src/mirror/mod.rs @@ -21,7 +21,10 @@ pub(crate) fn mirror_from_mirror_obj( ) -> Result, Box> { if let Some(git) = mirror.git { return Ok(Box::from(git::Git { - git_dir: mirror.name.clone(), + git_dir: match git.git_dir { + Some(dir) => dir, + None => mirror.name, + }, url: git.url, path: match git.path { Some(path) => path, diff --git a/src/source/git.rs b/src/source/git.rs index 9b6da1c..efacf47 100644 --- a/src/source/git.rs +++ b/src/source/git.rs @@ -1,4 +1,4 @@ -use std::fs::{self, rename}; +use std::{fs::{self, rename}, collections::HashMap}; use crate::helpers::cli::{cli_exec, cli_exec_from_dir}; use base64::{engine::general_purpose, Engine as _}; @@ -24,7 +24,7 @@ impl From for Git { } impl Repo for Git { - fn pull(&self, workdir_path: String) -> Result> { + fn pull(&self, workdir_path: String, vars: HashMap) -> Result> { let repo_local_name = general_purpose::STANDARD_NO_PAD.encode(self.git_url.clone()); let cmd = format!( "git clone {} {}/{}", @@ -64,6 +64,7 @@ impl Repo for Git { version, path: new_dir_name, repo_url: self.git_url.clone(), + vars, }) } } diff --git a/src/source/helm.rs b/src/source/helm.rs index fb1b71f..7ee2755 100644 --- a/src/source/helm.rs +++ b/src/source/helm.rs @@ -1,7 +1,7 @@ use super::{ChartLocal, Repo}; use crate::helpers::cli::{cli_exec, cli_exec_from_dir}; use base64::{engine::general_purpose, Engine as _}; -use std::fs::rename; +use std::{fs::rename, collections::HashMap}; pub(crate) enum RepoKind { Default, @@ -46,7 +46,7 @@ impl Helm { } } - fn pull_default(&self, workdir_path: String) -> Result> { + fn pull_default(&self, workdir_path: String, vars: HashMap) -> Result> { // Add repo and update let repo_local_name = general_purpose::STANDARD_NO_PAD.encode(self.repository_url.clone()); let cmd = format!("helm repo add {} {}", repo_local_name, self.repository_url); @@ -87,15 +87,16 @@ impl Helm { version, path: new_dir_name, repo_url: self.repository_url.clone(), + vars, }) } } impl Repo for Helm { - fn pull(&self, workdir_path: String) -> Result> { + fn pull(&self, workdir_path: String, vars: HashMap) -> Result> { let repository_kind = self.repo_kind_from_url()?; let path = match repository_kind { - RepoKind::Default => self.pull_default(workdir_path)?, + RepoKind::Default => self.pull_default(workdir_path, vars)?, RepoKind::Oci => { todo!() } diff --git a/src/source/mod.rs b/src/source/mod.rs index d675ef5..dac7c0b 100644 --- a/src/source/mod.rs +++ b/src/source/mod.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use crate::config::Chart; use serde::{Deserialize, Serialize}; @@ -10,6 +12,7 @@ pub(crate) struct ChartLocal { pub(crate) version: String, pub(crate) path: String, pub(crate) repo_url: String, + pub(crate) vars: HashMap } impl ChartLocal { @@ -19,7 +22,7 @@ impl ChartLocal { } pub(crate) trait Repo { - fn pull(&self, workdir_path: String) -> Result>; + fn pull(&self, workdir_path: String, vars: HashMap) -> Result>; } #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]