Relative paths for included charts and oci support
This commit is contained in:
parent
77f1d0dcb9
commit
ebc93dc6d0
@ -4,14 +4,14 @@ version: latest
|
|||||||
extensions:
|
extensions:
|
||||||
- name: Add virtual service to the chartc
|
- name: Add virtual service to the chartc
|
||||||
target_dir: templates/extensions
|
target_dir: templates/extensions
|
||||||
source_dir: ./examples/extensions/vaultwarden
|
source_dir: ../../extensions/vaultwarden
|
||||||
patches:
|
patches:
|
||||||
- name: Git patch 1
|
- name: Git patch 1
|
||||||
git:
|
git:
|
||||||
path: ./examples/patches/git/patch.diff
|
path: ../../patches/git/patch.diff
|
||||||
- name: Git patch 2
|
- name: Git patch 2
|
||||||
git:
|
git:
|
||||||
path: ./examples/patches/git/patch-2.diff
|
path: ../../patches/git/patch-2.diff
|
||||||
- name: yaml-fmt
|
- name: yaml-fmt
|
||||||
custom_command:
|
custom_command:
|
||||||
commands:
|
commands:
|
||||||
|
@ -3,6 +3,9 @@ include:
|
|||||||
- kind: Charts
|
- kind: Charts
|
||||||
path: ./examples/use/charts/vaultwardens.yaml
|
path: ./examples/use/charts/vaultwardens.yaml
|
||||||
repositories:
|
repositories:
|
||||||
|
- name: bitnami-oci
|
||||||
|
helm:
|
||||||
|
url: oci://registry-1.docker.io/bitnamicharts/
|
||||||
- name: metrics-server
|
- name: metrics-server
|
||||||
helm:
|
helm:
|
||||||
url: https://kubernetes-sigs.github.io/metrics-server/
|
url: https://kubernetes-sigs.github.io/metrics-server/
|
||||||
@ -18,6 +21,11 @@ repositories:
|
|||||||
helm:
|
helm:
|
||||||
url: https://fluxcd-community.github.io/helm-charts
|
url: https://fluxcd-community.github.io/helm-charts
|
||||||
charts:
|
charts:
|
||||||
|
- name: postgresql
|
||||||
|
repository: bitnami-oci
|
||||||
|
version: 13.2.29
|
||||||
|
mirrors:
|
||||||
|
- badhouseplants-git
|
||||||
- name: flux2
|
- name: flux2
|
||||||
repository: flux-community
|
repository: flux-community
|
||||||
extensions:
|
extensions:
|
||||||
|
@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
pub(crate) struct Extension {
|
pub(crate) struct Extension {
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
target_dir: String,
|
target_dir: String,
|
||||||
source_dir: String,
|
pub(crate) source_dir: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Extension {
|
impl Extension {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use log::info;
|
use log::info;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Eq, Hash, PartialEq, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Eq, Hash, PartialEq, Debug, Clone)]
|
||||||
pub(crate) enum IncludeTypes {
|
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) => {
|
Some(mut existing_charts) => {
|
||||||
existing_charts.append(&mut charts);
|
existing_charts.append(&mut charts);
|
||||||
existing_charts
|
existing_charts
|
||||||
},
|
}
|
||||||
None => charts,
|
None => charts,
|
||||||
};
|
};
|
||||||
config.charts = Some(extended_charts);
|
config.charts = Some(extended_charts);
|
||||||
},
|
}
|
||||||
IncludeTypes::Mirrors => {
|
IncludeTypes::Mirrors => {
|
||||||
let mut mirrors = include_mirrors(include.path)?;
|
let mut mirrors = include_mirrors(include.path)?;
|
||||||
let extended_mirrors = match config.mirrors.clone() {
|
let extended_mirrors = match config.mirrors.clone() {
|
||||||
Some(mut existing_mirrors) => {
|
Some(mut existing_mirrors) => {
|
||||||
existing_mirrors.append(&mut mirrors);
|
existing_mirrors.append(&mut mirrors);
|
||||||
existing_mirrors
|
existing_mirrors
|
||||||
},
|
}
|
||||||
None => mirrors,
|
None => mirrors,
|
||||||
};
|
};
|
||||||
config.mirrors = Some(extended_mirrors);
|
config.mirrors = Some(extended_mirrors);
|
||||||
},
|
}
|
||||||
IncludeTypes::Repositories => {
|
IncludeTypes::Repositories => {
|
||||||
let mut repositories = include_repositories(include.path)?;
|
let mut repositories = include_repositories(include.path)?;
|
||||||
let extended_repositories = match config.repositories.clone() {
|
let extended_repositories = match config.repositories.clone() {
|
||||||
Some(mut existing_repositories) => {
|
Some(mut existing_repositories) => {
|
||||||
existing_repositories.append(&mut repositories);
|
existing_repositories.append(&mut repositories);
|
||||||
existing_repositories
|
existing_repositories
|
||||||
},
|
}
|
||||||
None => repositories,
|
None => repositories,
|
||||||
};
|
};
|
||||||
config.repositories = Some(extended_repositories);
|
config.repositories = Some(extended_repositories);
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Ok(())
|
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>> {
|
fn include_chart(path: String) -> Result<Vec<super::Chart>, Box<dyn std::error::Error>> {
|
||||||
info!("trying to include chart from {}", path.clone());
|
info!("trying to include chart from {}", path.clone());
|
||||||
let file = std::fs::File::open(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,
|
Ok(res) => res,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let file = std::fs::File::open(path.clone())?;
|
let file = std::fs::File::open(path.clone())?;
|
||||||
let chart: super::Chart = serde_yaml::from_reader(file)?;
|
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)
|
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>> {
|
fn include_mirrors(path: String) -> Result<Vec<super::Mirror>, Box<dyn std::error::Error>> {
|
||||||
info!("trying to include chart from {}", path.clone());
|
info!("trying to include chart from {}", path.clone());
|
||||||
let file = std::fs::File::open(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(_) => {
|
Err(_) => {
|
||||||
let file = std::fs::File::open(path.clone())?;
|
let file = std::fs::File::open(path.clone())?;
|
||||||
let chart: super::Mirror = serde_yaml::from_reader(file)?;
|
let chart: super::Mirror = serde_yaml::from_reader(file)?;
|
||||||
vec!(chart)
|
vec![chart]
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
Ok(mirrors)
|
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());
|
info!("trying to include chart from {}", path.clone());
|
||||||
let file = std::fs::File::open(path.clone())?;
|
let file = std::fs::File::open(path.clone())?;
|
||||||
let repositories: Vec<super::Repository> = match serde_yaml::from_reader(file) {
|
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(_) => {
|
Err(_) => {
|
||||||
let file = std::fs::File::open(path.clone())?;
|
let file = std::fs::File::open(path.clone())?;
|
||||||
let chart: super::Repository = serde_yaml::from_reader(file)?;
|
let chart: super::Repository = serde_yaml::from_reader(file)?;
|
||||||
vec!(chart)
|
vec![chart]
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
Ok(repositories)
|
Ok(repositories)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,10 +52,25 @@ impl Patch {
|
|||||||
let patch_action = patch_action_from_definition(self.clone())?;
|
let patch_action = patch_action_from_definition(self.clone())?;
|
||||||
patch_action.apply(chart_local_path)
|
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 {
|
trait PatchInterface {
|
||||||
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>>;
|
||||||
|
fn get_path(&self) -> String;
|
||||||
|
fn set_path(&mut self, new_path: String);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PatchInterface for YqPatch {
|
impl PatchInterface for YqPatch {
|
||||||
@ -86,6 +101,14 @@ impl PatchInterface for YqPatch {
|
|||||||
cli_exec_from_dir(cmd, chart_local_path)?;
|
cli_exec_from_dir(cmd, chart_local_path)?;
|
||||||
Ok(())
|
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 {
|
impl PatchInterface for RegexpPatch {
|
||||||
@ -145,6 +168,14 @@ impl PatchInterface for RegexpPatch {
|
|||||||
}
|
}
|
||||||
Ok(())
|
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 {
|
impl PatchInterface for GitPatch {
|
||||||
@ -157,6 +188,14 @@ impl PatchInterface for GitPatch {
|
|||||||
remove_dir_all(chart_local_path + "/.git")?;
|
remove_dir_all(chart_local_path + "/.git")?;
|
||||||
Ok(())
|
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 {
|
impl PatchInterface for CustomCommandPatch {
|
||||||
@ -166,6 +205,15 @@ impl PatchInterface for CustomCommandPatch {
|
|||||||
}
|
}
|
||||||
Ok(())
|
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(
|
fn patch_action_from_definition(
|
||||||
@ -176,9 +224,11 @@ fn patch_action_from_definition(
|
|||||||
} else if let Some(git) = patch.git {
|
} else if let Some(git) = patch.git {
|
||||||
return Ok(Box::new(GitPatch {
|
return Ok(Box::new(GitPatch {
|
||||||
path: {
|
path: {
|
||||||
let path = PathBuf::from(git.path);
|
let path = PathBuf::from(git.path.clone());
|
||||||
let can_path = fs::canonicalize(path).ok().unwrap();
|
match fs::canonicalize(path).ok(){
|
||||||
can_path.into_os_string().into_string().ok().unwrap()
|
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 {
|
} 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(
|
fn pull_default(
|
||||||
&self,
|
&self,
|
||||||
workdir_path: String,
|
workdir_path: String,
|
||||||
@ -105,9 +152,7 @@ impl Repo for Helm {
|
|||||||
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, vars)?,
|
RepoKind::Default => self.pull_default(workdir_path, vars)?,
|
||||||
RepoKind::Oci => {
|
RepoKind::Oci => self.pull_oci(workdir_path, vars)?,
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
Ok(path)
|
Ok(path)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user