use log::{info, warn}; use serde::{Deserialize, Serialize}; use std::{collections::HashMap, fs::File}; pub(crate) mod extension; pub(crate) mod patch; #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub(crate) struct Config { pub(crate) variables: Option>, pub(crate) repositories: Vec, pub(crate) charts: Vec, pub(crate) mirrors: Vec, } 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)?; Ok(config) } } pub(crate) enum RepositoryKind { Helm, Git, } #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub(crate) struct Repository { // A name of the repository to be references by charts pub(crate) name: String, // Helm repository data pub(crate) helm: Option, pub(crate) git: Option, } #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub(crate) struct Mirror { pub(crate) name: String, pub(crate) git: Option, pub(crate) custom_command: Option, } #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub(crate) struct CustomCommandsMirror { pub(crate) package: Vec, pub(crate) upload: Vec, } #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub(crate) struct GitMirror { pub(crate) url: String, pub(crate) path: Option, pub(crate) branch: String, pub(crate) commit: Option, pub(crate) git_dir: Option, } #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub(crate) struct Helm { // A url of the helm repository pub(crate) url: String, } #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub(crate) struct Git { pub(crate) url: String, #[serde(alias = "ref")] pub(crate) git_ref: String, pub(crate) path: String, } #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub(crate) struct Chart { // A name of the helm chart pub(crate) name: String, // A reference to repository by name pub(crate) repository: String, pub(crate) mirrors: Vec, // Versions to be mirrored pub(crate) version: Option, // A repository object pub(crate) extensions: Option>, pub(crate) patches: Option>, pub(crate) variables: Option>, #[serde(skip_serializing)] pub(crate) repository_obj: Option, #[serde(skip_serializing)] pub(crate) mirror_objs: Option>, } impl Chart { pub(crate) fn populate_variables(&mut self, global_variables: Option>) { 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( &mut self, repositories: Vec, ) -> Result<(), Box> { for repository in repositories { if repository.name == self.repository { self.repository_obj = Some(repository); return Ok(()); } } //let err = error!("repo {} is not found in the repo list", self.repository); let error_msg = format!("repo {} is not found in the repo list", self.repository); return Err(Box::from(error_msg)); } // TODO: Handle the "mirror not found" error pub(crate) fn populate_mirrors( &mut self, mirrors: Vec, ) -> Result<(), Box> { let mut mirror_objs: Vec = vec![]; for mirror_global in mirrors.clone() { for mirror_name in self.mirrors.clone() { if mirror_name == mirror_global.name.clone() { mirror_objs.push(mirror_global.clone()); } } } if mirror_objs.len() > 0 { self.mirror_objs = Some(mirror_objs); } Ok(()) } pub(crate) fn get_helm_repository_url(&self) -> String { match self.repository_obj.clone() { Some(res) => res.helm.unwrap().url, None => { warn!("repository object is not filled for chart {}", self.name); return "".to_string(); } } } pub(crate) fn get_git_repository_url(&self) -> String { match self.repository_obj.clone() { Some(res) => res.git.unwrap().url, None => { warn!("repository object is not filled for chart {}", self.name); return "".to_string(); } } } pub(crate) fn get_git_repository_ref(&self) -> String { match self.repository_obj.clone() { Some(res) => res.git.unwrap().git_ref, None => { warn!("repository object is not filled for chart {}", self.name); return "".to_string(); } } } pub(crate) fn get_git_repository_path(&self) -> String { match self.repository_obj.clone() { Some(res) => res.git.unwrap().path, None => { warn!("repository object is not filled for chart {}", self.name); return "".to_string(); } } } pub(crate) fn get_repo_kind(&self) -> Result> { match &self.repository_obj { Some(res) => { if res.helm.is_some() { return Ok(RepositoryKind::Helm); } else if res.git.is_some() { return Ok(RepositoryKind::Git); } else { return Err(Box::from("unknown repository kind is found")); } } None => { return Err(Box::from( "repository object is not filled up for the chart", )); } } } }