Add an initial version of include property

This commit is contained in:
Nikolai Rodionov 2024-01-11 16:54:58 +01:00
parent 4bb04c7a98
commit 2ca5e7394b
Signed by: allanger
GPG Key ID: 0AA46A90E25592AD
5 changed files with 237 additions and 120 deletions

View File

@ -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 <<EOT >> .yamlfmt
formatter:
pad_line_comments: 2
EOT
- yamlfmt values.yaml --conf ./yamlfmt.yaml
- rm -f yamlfmt.yaml
mirrors:
- badhouseplants-git
- custom-command

View File

@ -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 <<EOT >> .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:

93
src/config/include.rs Normal file
View File

@ -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<dyn std::error::Error>> {
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<Vec<super::Chart>, Box<dyn std::error::Error>> {
info!("trying to include chart from {}", path.clone());
let file = std::fs::File::open(path.clone())?;
let charts: Vec<super::Chart> = 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<Vec<super::Mirror>, Box<dyn std::error::Error>> {
info!("trying to include chart from {}", path.clone());
let file = std::fs::File::open(path.clone())?;
let mirrors: Vec<super::Mirror> = 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<Vec<super::Repository>, Box<dyn std::error::Error>> {
info!("trying to include chart from {}", path.clone());
let file = std::fs::File::open(path.clone())?;
let repositories: Vec<super::Repository> = 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)
}

View File

@ -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<HashMap::<include::IncludeTypes, String>>,
pub(crate) variables: Option<HashMap<String, String>>,
pub(crate) repositories: Vec<Repository>,
pub(crate) charts: Vec<Chart>,
pub(crate) mirrors: Vec<Mirror>,
pub(crate) repositories: Option<Vec<Repository>>,
pub(crate) charts: Option<Vec<Chart>>,
pub(crate) mirrors: Option<Vec<Mirror>>,
}
impl Config {
pub(crate) fn new(config_path: String) -> Result<Self, Box<dyn std::error::Error>> {
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)
}
}

View File

@ -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);
}
}
}