diff --git a/argocd-config/values-override.yaml b/argocd-config/values-post.yaml similarity index 73% rename from argocd-config/values-override.yaml rename to argocd-config/values-post.yaml index 4e64ad4..dce0c89 100644 --- a/argocd-config/values-override.yaml +++ b/argocd-config/values-post.yaml @@ -1,5 +1,5 @@ # Overrides done by argocd-diff-preview -# These will happen after the values.yaml file is loaded +# These will happen AFTER the values.yaml file is loaded notifications: enabled: false dex: diff --git a/argocd-config/values-pre.yaml b/argocd-config/values-pre.yaml new file mode 100644 index 0000000..a5886f4 --- /dev/null +++ b/argocd-config/values-pre.yaml @@ -0,0 +1,9 @@ +# Overrides done by argocd-diff-preview +# These will happen BEFORE the values.yaml file is loaded +notifications: + enabled: false +dex: + enabled: false +configs: + params: + application.namespaces: "*" \ No newline at end of file diff --git a/src/argo_resource.rs b/src/argo_resource.rs index 1eae0ac..2076940 100644 --- a/src/argo_resource.rs +++ b/src/argo_resource.rs @@ -19,6 +19,7 @@ pub struct ArgoResource { pub yaml: serde_yaml::Value, pub kind: ApplicationKind, pub name: String, + pub namespace: String, // Where the resource was found pub file_name: String, } @@ -36,11 +37,6 @@ impl PartialEq for ArgoResource { } impl ArgoResource { - pub fn set_namespace(mut self, namespace: &str) -> ArgoResource { - self.yaml["metadata"]["namespace"] = serde_yaml::Value::String(namespace.to_string()); - self - } - pub fn set_project_to_default(mut self) -> Result> { let spec = match self.kind { ApplicationKind::Application => self.yaml["spec"].as_mapping_mut(), @@ -209,11 +205,16 @@ impl ArgoResource { _ => None, })?; + let namespace = k8s_resource.yaml["metadata"]["namespace"] + .as_str() + .unwrap_or("default"); + match k8s_resource.yaml["metadata"]["name"].as_str() { Some(name) => Some(ArgoResource { kind, file_name: k8s_resource.file_name, name: name.to_string(), + namespace: namespace.to_string(), yaml: k8s_resource.yaml, }), _ => None, diff --git a/src/argocd.rs b/src/argocd.rs index 1ecb915..32c51bf 100644 --- a/src/argocd.rs +++ b/src/argocd.rs @@ -32,32 +32,40 @@ impl ArgoCDInstallation { self.version.clone().unwrap_or("latest".to_string()) ); - let (values, values_override) = match std::fs::read_dir(&self.config_path) { + let (values_pre, values, values_post) = match std::fs::read_dir(&self.config_path) { Ok(dir) => { - debug!("📂 Files in folder '{}':", self.config_path); + debug!("📂 Files in folder 'argocd-config':"); for file in dir { debug!("- 📄 {:?}", file.unwrap().file_name()); } - let values_exist = std::fs::metadata(format!("{}/values.yaml", self.config_path)) + let values_pre = std::fs::metadata(format!("{}/values-pre.yaml", self.config_path)) + .is_ok() + .then_some(format!("-f {}/values-pre.yaml", self.config_path)); + let values = std::fs::metadata(format!("{}/values.yaml", self.config_path)) .is_ok() .then_some(format!("-f {}/values.yaml", self.config_path)); - let values_override_exist = - std::fs::metadata(format!("{}/values-override.yaml", self.config_path)) + let values_post = + std::fs::metadata(format!("{}/values-post.yaml", self.config_path)) .is_ok() - .then_some(format!("-f {}/values-override.yaml", self.config_path)); - (values_exist, values_override_exist) + .then_some(format!("-f {}/values-post.yaml", self.config_path)); + (values, values_pre, values_post) } Err(_e) => { - info!("📂 Folder '{}' doesn't exist. Installing Argo CD Helm Chart with default configuration", self.config_path); - (None, None) + info!( + "📂 Folder '{}' doesn't exist. Installing Argo CD Helm Chart with default configuration", + self.config_path + ); + (None, None, None) } }; // add argo repo to helm - run_command("helm repo add argo https://argoproj.github.io/argo-helm").map_err(|e| { - error!("❌ Failed to add argo repo"); - CommandError::new(e) - })?; + run_command("helm repo add argo https://argoproj.github.io/argo-helm").map_err( + |e| { + error!("❌ Failed to add argo repo"); + CommandError::new(e) + }, + )?; // helm update run_command("helm repo update").map_err(|e| { @@ -66,10 +74,11 @@ impl ArgoCDInstallation { })?; let helm_install_command = format!( - "helm install argocd argo/argo-cd -n {} {} {} {}", + "helm install argocd argo/argo-cd -n {} {} {} {} {}", self.namespace, values.unwrap_or_default(), - values_override.unwrap_or_default(), + values_pre.unwrap_or_default(), + values_post.unwrap_or_default(), self.version .clone() .map(|a| format!("--version {}", a)) diff --git a/src/main.rs b/src/main.rs index 6d29e71..1240f07 100644 --- a/src/main.rs +++ b/src/main.rs @@ -288,8 +288,8 @@ async fn run() -> Result<(), Box> { // remove .git from repo let repo = repo.trim_end_matches(".git"); + let (base_apps, target_apps) = parsing::get_applications_for_branches( - &argocd_namespace, &base_branch, &target_branch, &file_regex, @@ -310,14 +310,24 @@ async fn run() -> Result<(), Box> { return Ok(()); } + let unique_namespaces = base_apps + .iter() + .map(|a| a.namespace.clone()) + .chain(target_apps.iter().map(|a| a.namespace.clone())) + .collect::>(); match cluster_tool { ClusterTool::Kind => kind::create_cluster(&cluster_name)?, ClusterTool::Minikube => minikube::create_cluster()?, } + // create Argo CD namespace create_namespace(&argocd_namespace)?; - create_folder_if_not_exists(secrets_folder)?; + // Create a namespace for each application + for namespace in unique_namespaces { + create_namespace(&namespace)?; + } + match apply_folder(secrets_folder) { Ok(count) if count > 0 => info!("🤫 Applied {} secrets", count), Ok(_) => info!("🤷 No secrets found in {}", secrets_folder), diff --git a/src/parsing.rs b/src/parsing.rs index 741e38d..d5c0471 100644 --- a/src/parsing.rs +++ b/src/parsing.rs @@ -24,7 +24,6 @@ impl Clone for K8sResource { } pub fn get_applications_for_branches( - argo_cd_namespace: &str, base_branch: &Branch, target_branch: &Branch, regex: &Option, @@ -34,7 +33,6 @@ pub fn get_applications_for_branches( ignore_invalid_watch_pattern: bool, ) -> Result<(Vec, Vec), Box> { let base_apps = get_applications( - argo_cd_namespace, base_branch, regex, selector, @@ -43,7 +41,6 @@ pub fn get_applications_for_branches( ignore_invalid_watch_pattern, )?; let target_apps = get_applications( - argo_cd_namespace, target_branch, regex, selector, @@ -115,7 +112,6 @@ pub fn get_applications_for_branches( } fn get_applications( - argo_cd_namespace: &str, branch: &Branch, regex: &Option, selector: &Option>, @@ -133,7 +129,7 @@ fn get_applications( ); if !applications.is_empty() { info!("🤖 Patching Application[Sets] for branch: {}", branch.name); - let apps = patch_applications(argo_cd_namespace, applications, branch, repo)?; + let apps = patch_applications(applications, branch, repo)?; info!( "🤖 Patching {} Argo CD Application[Sets] for branch: {}", apps.len(), @@ -227,14 +223,12 @@ fn parse_yaml(directory: &str, files: Vec) -> Vec { } fn patch_application( - argo_cd_namespace: &str, application: ArgoResource, branch: &Branch, repo: &str, ) -> Result> { let app_name = application.name.clone(); let app = application - .set_namespace(argo_cd_namespace) .remove_sync_policy() .set_project_to_default() .and_then(|a| a.point_destination_to_in_cluster()) @@ -249,14 +243,13 @@ fn patch_application( } fn patch_applications( - argo_cd_namespace: &str, applications: Vec, branch: &Branch, repo: &str, ) -> Result, Box> { applications .into_iter() - .map(|a| patch_application(argo_cd_namespace, a, branch, repo)) + .map(|a| patch_application(a, branch, repo)) .collect() } @@ -379,7 +372,7 @@ pub fn generate_apps_from_app_set( }) }) .collect::>(); - patch_applications(&argocd.namespace, apps, branch, repo) + patch_applications( apps, branch, repo) } }; diff --git a/src/utils.rs b/src/utils.rs index 6b61b42..fa72990 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -46,6 +46,7 @@ pub fn run_command_in_dir( command: &str, current_dir: &str, ) -> Result { + debug!("Running command: {}", command); let args = command.split_whitespace().collect::>(); run_command_from_list(args, Some(current_dir), None) }