gitops_operator/files/
files.rs

1use anyhow::Context;
2use anyhow::Error;
3use k8s_openapi::api::apps::v1::Deployment;
4use serde_yaml;
5use std::fs;
6
7use tracing::{info, warn};
8
9fn get_deployment_from_file(file_path: &str) -> Result<Deployment, Error> {
10    let yaml_content =
11        fs::read_to_string(file_path).context("Failed to read deployment YAML file")?;
12
13    let deployment: Deployment = serde_yaml::from_str(&yaml_content)
14        .context("Failed to parse YAML into Kubernetes Deployment")?;
15
16    Ok(deployment)
17}
18
19pub fn needs_patching(file_path: &str, new_sha: &str) -> Result<bool, Error> {
20    info!("Comparing deployment file: {}", file_path);
21    let deployment = get_deployment_from_file(file_path)?;
22
23    if let Some(spec) = deployment.spec {
24        if let Some(template) = spec.template.spec {
25            for container in &template.containers {
26                if container.image.as_ref().unwrap().contains(new_sha) {
27                    info!("Image tag already updated... Aborting mission!");
28                    return Ok(false);
29                }
30            }
31        }
32    }
33
34    Ok(true)
35}
36
37#[tracing::instrument(name = "clone_or_update_repo", skip(), fields())]
38pub fn patch_deployment(file_path: &str, image_name: &str, new_sha: &str) -> Result<(), Error> {
39    info!("Patching image tag in deployment file: {}", file_path);
40    let mut deployment = get_deployment_from_file(file_path)?;
41
42    // Modify deployment specifics
43    if let Some(spec) = deployment.spec.as_mut() {
44        if let Some(template) = spec.template.spec.as_mut() {
45            for container in &mut template.containers {
46                if container.image.as_ref().unwrap().contains(new_sha) {
47                    warn!("Image tag already updated... Aborting mission!");
48                    return Err(anyhow::anyhow!(
49                        "Image tag {} is already up to date",
50                        new_sha
51                    ));
52                }
53                if container.image.as_ref().unwrap().contains(image_name) {
54                    container.image = Some(format!("{}:{}", &image_name, &new_sha));
55                }
56            }
57        }
58    }
59
60    let updated_yaml =
61        serde_yaml::to_string(&deployment).context("Failed to serialize updated deployment")?;
62
63    fs::write(file_path, updated_yaml).context("Failed to write updated YAML back to file")
64}