diff --git a/examples/use/charts/vaultwarden.yaml b/examples/use/charts/vaultwarden.yaml new file mode 100644 index 0000000..9dec3cc --- /dev/null +++ b/examples/use/charts/vaultwarden.yaml @@ -0,0 +1,27 @@ +name: vaultwarden +repository: badhouseplants +version: latest +extensions: + - name: Add virtual service to the chartc + target_dir: templates/extensions + source_dir: ./examples/extensions/vaultwarden +patches: + - name: Git patch 1 + git: + path: ./examples/patches/git/patch.diff + - name: Git patch 2 + git: + path: ./examples/patches/git/patch-2.diff + - name: yaml-fmt + custom_command: + commands: + - |- + cat <> .yamlfmt + formatter: + pad_line_comments: 2 + EOT + - yamlfmt values.yaml --conf ./yamlfmt.yaml + - rm -f yamlfmt.yaml +mirrors: + - badhouseplants-git + - custom-command diff --git a/helmule.yaml b/helmule.yaml index 2b75afb..b2dd0ec 100644 --- a/helmule.yaml +++ b/helmule.yaml @@ -1,4 +1,6 @@ # mirror charts +include: + Charts: ./examples/use/charts/vaultwarden.yaml repositories: - name: metrics-server helm: @@ -15,33 +17,6 @@ repositories: helm: url: https://fluxcd-community.github.io/helm-charts charts: - - name: vaultwarden - repository: badhouseplants - version: latest - extensions: - - name: Add virtual service to the chartc - target_dir: templates/extensions - source_dir: ./examples/extensions/vaultwarden - patches: - - name: Git patch 1 - git: - path: ./examples/patches/git/patch.diff - - name: Git patch 2 - git: - path: ./examples/patches/git/patch-2.diff - - name: yaml-fmt - custom_command: - commands: - - |- - cat <> .yamlfmt - formatter: - pad_line_comments: 2 - EOT - - yamlfmt values.yaml --conf ./yamlfmt.yaml - - rm -f yamlfmt.yaml - mirrors: - - badhouseplants-git - - custom-command - name: flux2 repository: flux-community extensions: diff --git a/src/config/include.rs b/src/config/include.rs new file mode 100644 index 0000000..09f6354 --- /dev/null +++ b/src/config/include.rs @@ -0,0 +1,93 @@ +use log::info; +use serde::{Serialize, Deserialize}; + +#[derive(Serialize, Deserialize, Eq, Hash, PartialEq, Debug, Clone)] +pub(crate) enum IncludeTypes { + Charts, + Mirrors, + Repositories, +} + +pub(crate) fn apply_includes(config: &mut super::Config) -> Result<(), Box> { + for (kind, path) in config.include.clone().unwrap() { + match kind { + IncludeTypes::Charts => { + let mut charts = include_chart(path)?; + let extended_charts = match config.charts.clone() { + Some(mut existing_charts) => { + existing_charts.append(&mut charts); + existing_charts + }, + None => charts, + }; + config.charts = Some(extended_charts); + }, + IncludeTypes::Mirrors => { + let mut mirrors = include_mirrors(path)?; + let extended_mirrors = match config.mirrors.clone() { + Some(mut existing_mirrors) => { + existing_mirrors.append(&mut mirrors); + existing_mirrors + }, + None => mirrors, + }; + config.mirrors = Some(extended_mirrors); + }, + IncludeTypes::Repositories => { + let mut repositories = include_repositories(path)?; + let extended_repositories = match config.repositories.clone() { + Some(mut existing_repositories) => { + existing_repositories.append(&mut repositories); + existing_repositories + }, + None => repositories, + }; + config.repositories = Some(extended_repositories); + }, + }; + } + Ok(()) +} + +fn include_chart(path: String) -> Result, Box> { + info!("trying to include chart from {}", path.clone()); + let file = std::fs::File::open(path.clone())?; + let charts: Vec = match serde_yaml::from_reader(file) { + Ok(res) => res, + Err(_) => { + let file = std::fs::File::open(path.clone())?; + let chart: super::Chart = serde_yaml::from_reader(file)?; + vec!(chart) + }, + }; + Ok(charts) +} + +fn include_mirrors(path: String) -> Result, Box> { + info!("trying to include chart from {}", path.clone()); + let file = std::fs::File::open(path.clone())?; + let mirrors: Vec = match serde_yaml::from_reader(file) { + Ok(res) => res, + Err(_) => { + let file = std::fs::File::open(path.clone())?; + let chart: super::Mirror = serde_yaml::from_reader(file)?; + vec!(chart) + }, + }; + Ok(mirrors) +} + +fn include_repositories(path: String) -> Result, Box> { + info!("trying to include chart from {}", path.clone()); + let file = std::fs::File::open(path.clone())?; + let repositories: Vec = match serde_yaml::from_reader(file) { + Ok(res) => res, + Err(_) => { + let file = std::fs::File::open(path.clone())?; + let chart: super::Repository = serde_yaml::from_reader(file)?; + vec!(chart) + }, + }; + Ok(repositories) +} + diff --git a/src/config/mod.rs b/src/config/mod.rs index a1a523f..8192d77 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -4,20 +4,25 @@ use std::{collections::HashMap, fs::File}; pub(crate) mod extension; pub(crate) mod patch; +pub(crate) mod include; #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub(crate) struct Config { + pub(crate) include: Option>, pub(crate) variables: Option>, - pub(crate) repositories: Vec, - pub(crate) charts: Vec, - pub(crate) mirrors: Vec, + pub(crate) repositories: Option>, + pub(crate) charts: Option>, + pub(crate) mirrors: Option>, } impl Config { pub(crate) fn new(config_path: String) -> Result> { info!("reading the config file"); let config_content = File::open(config_path)?; - let config: Config = serde_yaml::from_reader(config_content)?; + let mut config: Config = serde_yaml::from_reader(config_content)?; + if config.include.is_some() { + include::apply_includes(&mut config)?; + } Ok(config) } } diff --git a/src/main.rs b/src/main.rs index 0b9c320..1b77519 100644 --- a/src/main.rs +++ b/src/main.rs @@ -100,106 +100,123 @@ fn main() { exit(1); } }; - - 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); - } - Err(err) => { - error!("{}", err); - exit(1); - } - } - match chart.populate_mirrors(config.mirrors.clone()) { - Ok(_) => { - info!("mirrors arepopulated for chart {}", chart.name) - } - Err(err) => { - error!("{}", err); - exit(1); - } - } - let chart_repo = match source::repo_from_chart(chart.clone()) { - Ok(res) => res, - Err(err) => { - error!("{}", err); - exit(1); - } - }; - 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 {}", - chart.name.clone(), - res.path, - ); - if let Some(extensions) = chart.extensions.clone() { - for extension in extensions { - if let Err(err) = extension.apply(res.clone().path) { - error!("{}", err); - exit(1); - } + if let Some(charts) = config.clone().charts { + for mut chart in charts { + chart.populate_variables(config.variables.clone()); + match config.repositories.clone() { + Some(repositories) => match chart.populate_repository(repositories) { + Ok(_) => { + info!("repo is populated for chart {}", chart.name); } - } - if let Some(patches) = chart.patches.clone() { - for patch in patches { - if let Err(err) = patch.apply(res.clone().path) { - error!("{}", err); - exit(1); - } + Err(err) => { + error!("{}", err); + exit(1); } + }, + None => { + error!("repositories are not defined in the config"); + exit(1); } - if let Some(init_git_patch) = args.init_git_patch.clone() { - if init_git_patch.contains(&chart.name) { - info!( - "init git patch mode is enabled, go to {} to make your changes", - res.path - ); - match init_git_repo(res.path) { - Ok(_) => { - info!("not mirroring, because of the init git patch mode"); - } - Err(err) => { - error!("{}", err); - exit(1); - } - }; - break; + }; + match config.mirrors.clone() { + Some(mirrors) => match chart.populate_mirrors(mirrors) { + Ok(_) => { + info!("mirrors arepopulated for chart {}", chart.name) } + Err(err) => { + error!("{}", err); + exit(1); + } + }, + None => { + error!("mirrors are not defined in the config"); + exit(1); } - if let Some(mirrors) = chart.mirror_objs.clone() { - for mirror_obj in mirrors { - match mirror::mirror_from_mirror_obj(mirror_obj.clone()) { - Ok(mirror) => { - match mirror.push(workdir_path.clone(), res.clone(), args.dry_run) { - Ok(_) => info!( - "mirrored {} to {}", - chart.name.clone(), - mirror_obj.name - ), - Err(err) => { - error!("{}", err); - exit(1); - } - }; - } - Err(err) => { + }; + let chart_repo = match source::repo_from_chart(chart.clone()) { + Ok(res) => res, + Err(err) => { + error!("{}", err); + exit(1); + } + }; + 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 {}", + chart.name.clone(), + res.path, + ); + if let Some(extensions) = chart.extensions.clone() { + for extension in extensions { + if let Err(err) = extension.apply(res.clone().path) { error!("{}", err); exit(1); } } } + if let Some(patches) = chart.patches.clone() { + for patch in patches { + if let Err(err) = patch.apply(res.clone().path) { + error!("{}", err); + exit(1); + } + } + } + if let Some(init_git_patch) = args.init_git_patch.clone() { + if init_git_patch.contains(&chart.name) { + info!( + "init git patch mode is enabled, go to {} to make your changes", + res.path + ); + match init_git_repo(res.path) { + Ok(_) => { + info!("not mirroring, because of the init git patch mode"); + } + Err(err) => { + error!("{}", err); + exit(1); + } + }; + break; + } + } + if let Some(mirrors) = chart.mirror_objs.clone() { + for mirror_obj in mirrors { + match mirror::mirror_from_mirror_obj(mirror_obj.clone()) { + Ok(mirror) => { + match mirror.push( + workdir_path.clone(), + res.clone(), + args.dry_run, + ) { + Ok(_) => info!( + "mirrored {} to {}", + chart.name.clone(), + mirror_obj.name + ), + Err(err) => { + error!("{}", err); + exit(1); + } + }; + } + Err(err) => { + error!("{}", err); + exit(1); + } + } + } + } + } + Err(err) => { + error!("{}", err); + exit(1); } - } - Err(err) => { - error!("{}", err); - exit(1); } } }