Relative paths for included charts and oci support
This commit is contained in:
parent
77f1d0dcb9
commit
ebc93dc6d0
@ -4,14 +4,14 @@ version: latest
|
||||
extensions:
|
||||
- name: Add virtual service to the chartc
|
||||
target_dir: templates/extensions
|
||||
source_dir: ./examples/extensions/vaultwarden
|
||||
source_dir: ../../extensions/vaultwarden
|
||||
patches:
|
||||
- name: Git patch 1
|
||||
git:
|
||||
path: ./examples/patches/git/patch.diff
|
||||
path: ../../patches/git/patch.diff
|
||||
- name: Git patch 2
|
||||
git:
|
||||
path: ./examples/patches/git/patch-2.diff
|
||||
path: ../../patches/git/patch-2.diff
|
||||
- name: yaml-fmt
|
||||
custom_command:
|
||||
commands:
|
||||
|
@ -3,6 +3,9 @@ include:
|
||||
- kind: Charts
|
||||
path: ./examples/use/charts/vaultwardens.yaml
|
||||
repositories:
|
||||
- name: bitnami-oci
|
||||
helm:
|
||||
url: oci://registry-1.docker.io/bitnamicharts/
|
||||
- name: metrics-server
|
||||
helm:
|
||||
url: https://kubernetes-sigs.github.io/metrics-server/
|
||||
@ -18,6 +21,11 @@ repositories:
|
||||
helm:
|
||||
url: https://fluxcd-community.github.io/helm-charts
|
||||
charts:
|
||||
- name: postgresql
|
||||
repository: bitnami-oci
|
||||
version: 13.2.29
|
||||
mirrors:
|
||||
- badhouseplants-git
|
||||
- name: flux2
|
||||
repository: flux-community
|
||||
extensions:
|
||||
|
@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
|
||||
pub(crate) struct Extension {
|
||||
name: Option<String>,
|
||||
target_dir: String,
|
||||
source_dir: String,
|
||||
pub(crate) source_dir: String,
|
||||
}
|
||||
|
||||
impl Extension {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use log::info;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Eq, Hash, PartialEq, Debug, Clone)]
|
||||
pub(crate) enum IncludeTypes {
|
||||
@ -23,33 +23,33 @@ pub(crate) fn apply_includes(config: &mut super::Config) -> Result<(), Box<dyn s
|
||||
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(include.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(include.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(())
|
||||
@ -58,17 +58,74 @@ pub(crate) fn apply_includes(config: &mut super::Config) -> Result<(), Box<dyn s
|
||||
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) {
|
||||
|
||||
let chart_dir = match std::path::Path::new(&path).parent() {
|
||||
Some(dir) => match dir.to_str() {
|
||||
Some(dir) => dir.to_string(),
|
||||
None => {
|
||||
return Err(Box::from(format!(
|
||||
"chart parrent dir not found for {}",
|
||||
path
|
||||
)));
|
||||
}
|
||||
},
|
||||
None => {
|
||||
return Err(Box::from(format!(
|
||||
"chart parrent dir not found for {}",
|
||||
path
|
||||
)));
|
||||
}
|
||||
};
|
||||
|
||||
let mut 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)
|
||||
},
|
||||
vec![chart]
|
||||
}
|
||||
};
|
||||
|
||||
charts.iter_mut().for_each(|chart| {
|
||||
match chart.extensions {
|
||||
Some(ref mut extensions) => extensions.iter_mut().for_each(|extension| {
|
||||
if is_path_relative(extension.source_dir.clone()) {
|
||||
let clean_path = match extension.source_dir.clone().starts_with("./") {
|
||||
true => extension.source_dir.clone().replacen("./", "", 1),
|
||||
false => extension.source_dir.clone(),
|
||||
};
|
||||
if is_path_relative(clean_path.clone()) {
|
||||
let new_path = format!("{}/{}", chart_dir, clean_path);
|
||||
extension.source_dir = new_path;
|
||||
}
|
||||
}
|
||||
}),
|
||||
None => info!("no extensions set, nothing to update"),
|
||||
};
|
||||
match chart.patches {
|
||||
Some(ref mut patches) => patches.iter_mut().for_each(| patch| {
|
||||
if is_path_relative(patch.get_path().clone()) {
|
||||
let clean_path = match patch.get_path().clone().starts_with("./") {
|
||||
true => patch.get_path().clone().replacen("./", "", 1),
|
||||
false => patch.get_path().clone(),
|
||||
};
|
||||
if is_path_relative(clean_path.clone()) {
|
||||
let new_path = format!("{}/{}", chart_dir, clean_path);
|
||||
patch.set_path(new_path);
|
||||
}
|
||||
}
|
||||
}),
|
||||
None => info!("no patch set, nothing to update"),
|
||||
};
|
||||
|
||||
});
|
||||
Ok(charts)
|
||||
}
|
||||
|
||||
fn is_path_relative(path: String) -> bool {
|
||||
!path.starts_with("/")
|
||||
}
|
||||
|
||||
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())?;
|
||||
@ -77,13 +134,15 @@ fn include_mirrors(path: String) -> Result<Vec<super::Mirror>, Box<dyn std::erro
|
||||
Err(_) => {
|
||||
let file = std::fs::File::open(path.clone())?;
|
||||
let chart: super::Mirror = serde_yaml::from_reader(file)?;
|
||||
vec!(chart)
|
||||
},
|
||||
vec![chart]
|
||||
}
|
||||
};
|
||||
Ok(mirrors)
|
||||
}
|
||||
|
||||
fn include_repositories(path: String) -> Result<Vec<super::Repository>, Box<dyn std::error::Error>> {
|
||||
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) {
|
||||
@ -91,9 +150,8 @@ fn include_repositories(path: String) -> Result<Vec<super::Repository>, Box<dyn
|
||||
Err(_) => {
|
||||
let file = std::fs::File::open(path.clone())?;
|
||||
let chart: super::Repository = serde_yaml::from_reader(file)?;
|
||||
vec!(chart)
|
||||
},
|
||||
vec![chart]
|
||||
}
|
||||
};
|
||||
Ok(repositories)
|
||||
}
|
||||
|
||||
|
@ -52,10 +52,25 @@ impl Patch {
|
||||
let patch_action = patch_action_from_definition(self.clone())?;
|
||||
patch_action.apply(chart_local_path)
|
||||
}
|
||||
pub(crate) fn get_path(&self) -> String {
|
||||
let patch_action = patch_action_from_definition(self.clone()).unwrap();
|
||||
patch_action.get_path()
|
||||
}
|
||||
pub(crate) fn set_path(&mut self, path: String) {
|
||||
if let Some(ref mut regexp) = self.regexp {
|
||||
regexp.path = path;
|
||||
} else if let Some(ref mut git) = self.git {
|
||||
git.path = path;
|
||||
} else if let Some(ref mut yq) = self.yq {
|
||||
yq.file = path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait PatchInterface {
|
||||
fn apply(&self, chart_local_path: String) -> Result<(), Box<dyn std::error::Error>>;
|
||||
fn get_path(&self) -> String;
|
||||
fn set_path(&mut self, new_path: String);
|
||||
}
|
||||
|
||||
impl PatchInterface for YqPatch {
|
||||
@ -86,6 +101,14 @@ impl PatchInterface for YqPatch {
|
||||
cli_exec_from_dir(cmd, chart_local_path)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_path(&self) -> String {
|
||||
self.file.clone()
|
||||
}
|
||||
|
||||
fn set_path(&mut self, new_path: String) {
|
||||
self.file = new_path
|
||||
}
|
||||
}
|
||||
|
||||
impl PatchInterface for RegexpPatch {
|
||||
@ -145,6 +168,14 @@ impl PatchInterface for RegexpPatch {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_path(&self) -> String {
|
||||
self.path.clone()
|
||||
}
|
||||
|
||||
fn set_path(&mut self, new_path: String) {
|
||||
self.path = new_path
|
||||
}
|
||||
}
|
||||
|
||||
impl PatchInterface for GitPatch {
|
||||
@ -157,6 +188,14 @@ impl PatchInterface for GitPatch {
|
||||
remove_dir_all(chart_local_path + "/.git")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_path(&self) -> String {
|
||||
self.path.clone()
|
||||
}
|
||||
|
||||
fn set_path(&mut self, new_path: String) {
|
||||
self.path = new_path
|
||||
}
|
||||
}
|
||||
|
||||
impl PatchInterface for CustomCommandPatch {
|
||||
@ -166,6 +205,15 @@ impl PatchInterface for CustomCommandPatch {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_path(&self) -> String {
|
||||
// Empty stings, cause cc patch doesn't have a path
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
fn set_path(&mut self, _new_path: String) {
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
fn patch_action_from_definition(
|
||||
@ -176,9 +224,11 @@ fn patch_action_from_definition(
|
||||
} else if let Some(git) = patch.git {
|
||||
return Ok(Box::new(GitPatch {
|
||||
path: {
|
||||
let path = PathBuf::from(git.path);
|
||||
let can_path = fs::canonicalize(path).ok().unwrap();
|
||||
can_path.into_os_string().into_string().ok().unwrap()
|
||||
let path = PathBuf::from(git.path.clone());
|
||||
match fs::canonicalize(path).ok(){
|
||||
Some(can_path) => can_path.into_os_string().into_string().ok().unwrap(),
|
||||
None => git.path.clone(),
|
||||
}
|
||||
},
|
||||
}));
|
||||
} else if let Some(custom_command) = patch.custom_command {
|
||||
|
@ -46,6 +46,53 @@ impl Helm {
|
||||
}
|
||||
}
|
||||
|
||||
fn pull_oci(
|
||||
&self,
|
||||
workdir_path: String,
|
||||
vars: HashMap<String, String>,
|
||||
) -> Result<ChartLocal, Box<dyn std::error::Error>> {
|
||||
let args = match self.version.as_str() {
|
||||
LATEST_VERSION => "".to_string(),
|
||||
_ => format!("--version {}", self.version.clone()),
|
||||
};
|
||||
let repo = match self.repository_url.ends_with("/"){
|
||||
true => {
|
||||
let mut repo = self.repository_url.clone();
|
||||
repo.pop();
|
||||
repo
|
||||
},
|
||||
false => self.repository_url.clone(),
|
||||
};
|
||||
let cmd = format!(
|
||||
"helm pull {}/{} {} --destination {} --untar",
|
||||
repo, &self.chart, args, workdir_path
|
||||
);
|
||||
cli_exec(cmd)?;
|
||||
// Get the version
|
||||
let cmd = format!("helm show chart {}/{}", workdir_path, &self.chart);
|
||||
let helm_stdout = cli_exec(cmd)?;
|
||||
let old_dir_name = format!("{}/{}", workdir_path, &self.chart);
|
||||
let new_dir_name: String;
|
||||
match serde_yaml::from_str::<super::Version>(&helm_stdout) {
|
||||
Ok(res) => {
|
||||
new_dir_name = format!("{}-{}", old_dir_name, res.version);
|
||||
rename(old_dir_name, new_dir_name.clone())?;
|
||||
}
|
||||
Err(err) => return Err(Box::from(err)),
|
||||
};
|
||||
|
||||
|
||||
let cmd = "helm show chart . | yq '.version'".to_string();
|
||||
let version = cli_exec_from_dir(cmd, new_dir_name.clone())?;
|
||||
Ok(ChartLocal {
|
||||
name: self.chart.clone(),
|
||||
version,
|
||||
path: new_dir_name,
|
||||
repo_url: self.repository_url.clone(),
|
||||
vars,
|
||||
})
|
||||
}
|
||||
|
||||
fn pull_default(
|
||||
&self,
|
||||
workdir_path: String,
|
||||
@ -105,9 +152,7 @@ impl Repo for Helm {
|
||||
let repository_kind = self.repo_kind_from_url()?;
|
||||
let path = match repository_kind {
|
||||
RepoKind::Default => self.pull_default(workdir_path, vars)?,
|
||||
RepoKind::Oci => {
|
||||
todo!()
|
||||
}
|
||||
RepoKind::Oci => self.pull_oci(workdir_path, vars)?,
|
||||
};
|
||||
Ok(path)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user