Add variables and template mirror url

This commit is contained in:
Nikolai Rodionov 2024-01-10 15:50:56 +01:00
parent b36bde0b83
commit 0f936a645c
Signed by: allanger
GPG Key ID: 0AA46A90E25592AD
8 changed files with 64 additions and 25 deletions

View File

@ -1,12 +1,13 @@
use log::{info, warn}; use log::{info, warn};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fs::File; use std::{fs::File, collections::HashMap};
pub(crate) mod extension; pub(crate) mod extension;
pub(crate) mod patch; pub(crate) mod patch;
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub(crate) struct Config { pub(crate) struct Config {
pub(crate) variables: Option<HashMap<String, String>>,
pub(crate) repositories: Vec<Repository>, pub(crate) repositories: Vec<Repository>,
pub(crate) charts: Vec<Chart>, pub(crate) charts: Vec<Chart>,
pub(crate) mirrors: Vec<Mirror>, pub(crate) mirrors: Vec<Mirror>,
@ -54,6 +55,7 @@ pub(crate) struct GitMirror {
pub(crate) path: Option<String>, pub(crate) path: Option<String>,
pub(crate) branch: String, pub(crate) branch: String,
pub(crate) commit: Option<String>, pub(crate) commit: Option<String>,
pub(crate) git_dir: Option<String>,
} }
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
@ -82,6 +84,7 @@ pub(crate) struct Chart {
// A repository object // A repository object
pub(crate) extensions: Option<Vec<extension::Extension>>, pub(crate) extensions: Option<Vec<extension::Extension>>,
pub(crate) patches: Option<Vec<patch::Patch>>, pub(crate) patches: Option<Vec<patch::Patch>>,
pub(crate) variables: Option<HashMap<String, String>>,
#[serde(skip_serializing)] #[serde(skip_serializing)]
pub(crate) repository_obj: Option<Repository>, pub(crate) repository_obj: Option<Repository>,
#[serde(skip_serializing)] #[serde(skip_serializing)]
@ -89,6 +92,18 @@ pub(crate) struct Chart {
} }
impl Chart { impl Chart {
pub(crate) fn populate_variables(&mut self, global_variables: Option<HashMap<String, String>>) {
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( pub(crate) fn populate_repository(
&mut self, &mut self,
repositories: Vec<Repository>, repositories: Vec<Repository>,

View File

@ -61,19 +61,22 @@ trait PatchInterface {
impl PatchInterface for YqPatch { impl PatchInterface for YqPatch {
fn apply(&self, chart_local_path: String) -> Result<(), Box<dyn std::error::Error>> { fn apply(&self, chart_local_path: String) -> Result<(), Box<dyn std::error::Error>> {
let cmd = match self.op { let cmd = match self.op {
YqOperations::Add => format!( YqOperations::Add => {
"yq -i '{} += \"{}\"' {}", let value = match self.value.clone().unwrap().starts_with(['{', '[', '\"', '\'']) {
self.key, true => self.value.clone().unwrap(),
self.value.clone().unwrap(), false => format!("\"{}\"", self.value.clone().unwrap()),
self.file };
), format!("yq -i '{} += {}' {}", self.key, value, self.file)
}
YqOperations::Delete => format!("yq -i \'del({})\' {}", self.key, self.file), YqOperations::Delete => format!("yq -i \'del({})\' {}", self.key, self.file),
YqOperations::Replace => format!( YqOperations::Replace => {
"yq e -i \'{} = \"{}\"\' {}", let value = match self.value.clone().unwrap().starts_with(['{', '[']) {
self.key, true => self.value.clone().unwrap(),
self.value.clone().unwrap(), false => format!("\"{}\"", self.value.clone().unwrap()),
self.file };
),
format!("yq e -i '{} = {}' {}", self.key, value, self.file)
}
}; };
cli_exec_from_dir(cmd, chart_local_path)?; cli_exec_from_dir(cmd, chart_local_path)?;
Ok(()) Ok(())

View File

@ -6,6 +6,7 @@ pub(crate) mod source;
use clap::Parser; use clap::Parser;
use log::{error, info}; use log::{error, info};
use std::collections::HashMap;
use std::fs; use std::fs;
use std::{fs::create_dir, path::PathBuf, process::exit}; use std::{fs::create_dir, path::PathBuf, process::exit};
use tempfile::TempDir; use tempfile::TempDir;
@ -77,6 +78,7 @@ fn main() {
}; };
for mut chart in config.clone().charts { for mut chart in config.clone().charts {
chart.populate_variables(config.variables.clone());
match chart.populate_repository(config.repositories.clone()) { match chart.populate_repository(config.repositories.clone()) {
Ok(_) => { Ok(_) => {
info!("repo is populated for chart {}", chart.name); info!("repo is populated for chart {}", chart.name);
@ -102,7 +104,11 @@ fn main() {
exit(1); 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) => { Ok(res) => {
info!( info!(
"succesfully pulled chart {} into {}", "succesfully pulled chart {} into {}",

View File

@ -18,12 +18,19 @@ impl Target for Git {
chart_local: ChartLocal, chart_local: ChartLocal,
dry_run: bool, dry_run: bool,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
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())?; 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 // Prepare branch
let mut reg = super::register_handlebars();
reg.register_template_string("branch", self.branch.clone())?; reg.register_template_string("branch", self.branch.clone())?;
let branch = reg.render("branch", &chart_local)?; let branch = reg.render("branch", &chart_local)?;
let cmd = format!("git checkout {}", branch); let cmd = format!("git checkout {}", branch);

View File

@ -21,7 +21,10 @@ pub(crate) fn mirror_from_mirror_obj(
) -> Result<Box<dyn Target>, Box<dyn std::error::Error>> { ) -> Result<Box<dyn Target>, Box<dyn std::error::Error>> {
if let Some(git) = mirror.git { if let Some(git) = mirror.git {
return Ok(Box::from(git::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, url: git.url,
path: match git.path { path: match git.path {
Some(path) => path, Some(path) => path,

View File

@ -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 crate::helpers::cli::{cli_exec, cli_exec_from_dir};
use base64::{engine::general_purpose, Engine as _}; use base64::{engine::general_purpose, Engine as _};
@ -24,7 +24,7 @@ impl From<crate::config::Chart> for Git {
} }
impl Repo for Git { impl Repo for Git {
fn pull(&self, workdir_path: String) -> Result<ChartLocal, Box<dyn std::error::Error>> { fn pull(&self, workdir_path: String, vars: HashMap<String, String>) -> Result<ChartLocal, Box<dyn std::error::Error>> {
let repo_local_name = general_purpose::STANDARD_NO_PAD.encode(self.git_url.clone()); let repo_local_name = general_purpose::STANDARD_NO_PAD.encode(self.git_url.clone());
let cmd = format!( let cmd = format!(
"git clone {} {}/{}", "git clone {} {}/{}",
@ -64,6 +64,7 @@ impl Repo for Git {
version, version,
path: new_dir_name, path: new_dir_name,
repo_url: self.git_url.clone(), repo_url: self.git_url.clone(),
vars,
}) })
} }
} }

View File

@ -1,7 +1,7 @@
use super::{ChartLocal, Repo}; use super::{ChartLocal, Repo};
use crate::helpers::cli::{cli_exec, cli_exec_from_dir}; use crate::helpers::cli::{cli_exec, cli_exec_from_dir};
use base64::{engine::general_purpose, Engine as _}; use base64::{engine::general_purpose, Engine as _};
use std::fs::rename; use std::{fs::rename, collections::HashMap};
pub(crate) enum RepoKind { pub(crate) enum RepoKind {
Default, Default,
@ -46,7 +46,7 @@ impl Helm {
} }
} }
fn pull_default(&self, workdir_path: String) -> Result<ChartLocal, Box<dyn std::error::Error>> { fn pull_default(&self, workdir_path: String, vars: HashMap<String, String>) -> Result<ChartLocal, Box<dyn std::error::Error>> {
// Add repo and update // Add repo and update
let repo_local_name = general_purpose::STANDARD_NO_PAD.encode(self.repository_url.clone()); 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); let cmd = format!("helm repo add {} {}", repo_local_name, self.repository_url);
@ -87,15 +87,16 @@ impl Helm {
version, version,
path: new_dir_name, path: new_dir_name,
repo_url: self.repository_url.clone(), repo_url: self.repository_url.clone(),
vars,
}) })
} }
} }
impl Repo for Helm { impl Repo for Helm {
fn pull(&self, workdir_path: String) -> Result<ChartLocal, Box<dyn std::error::Error>> { fn pull(&self, workdir_path: String, vars: HashMap<String, String>) -> Result<ChartLocal, Box<dyn std::error::Error>> {
let repository_kind = self.repo_kind_from_url()?; let repository_kind = self.repo_kind_from_url()?;
let path = match repository_kind { let path = match repository_kind {
RepoKind::Default => self.pull_default(workdir_path)?, RepoKind::Default => self.pull_default(workdir_path, vars)?,
RepoKind::Oci => { RepoKind::Oci => {
todo!() todo!()
} }

View File

@ -1,3 +1,5 @@
use std::collections::HashMap;
use crate::config::Chart; use crate::config::Chart;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -10,6 +12,7 @@ pub(crate) struct ChartLocal {
pub(crate) version: String, pub(crate) version: String,
pub(crate) path: String, pub(crate) path: String,
pub(crate) repo_url: String, pub(crate) repo_url: String,
pub(crate) vars: HashMap<String, String>
} }
impl ChartLocal { impl ChartLocal {
@ -19,7 +22,7 @@ impl ChartLocal {
} }
pub(crate) trait Repo { pub(crate) trait Repo {
fn pull(&self, workdir_path: String) -> Result<ChartLocal, Box<dyn std::error::Error>>; fn pull(&self, workdir_path: String, vars: HashMap<String, String>) -> Result<ChartLocal, Box<dyn std::error::Error>>;
} }
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]