Skip to content

Commit

Permalink
feat!: Add support for chart lock files
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian May committed Nov 20, 2024
1 parent 5c4f952 commit 891a522
Show file tree
Hide file tree
Showing 20 changed files with 1,874 additions and 498 deletions.
567 changes: 435 additions & 132 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,13 @@ tap = "1.0.1"
reqwest = { version = "=0.12.9", default-features = false, features = ["json", "rustls-tls"] }
nondestructive = "0.0.25"
rustls = "0.23.16"
thiserror = "2.0.3"
sha256 = "1.5.0"
docker_credential = "1.3.1"
oci-client = { version = "0.14.0", default-features = false, features = [ "rustls-tls"] }
tempfile = "3.14.0"
bytes = "1.8.0"
flate2 = "1.0.35"
tar = "0.4.43"
tokio-util = "0.7.12"
futures-util = "0.3.31"
51 changes: 25 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ Add `--output text` (gitlab flavoured text), `--output slack` or `--output tui`

The `tui` full screen text mode has the following keyboard bindings:

* `q`: Request exit when all processes finished. This won't kill processes currently running.
* `ctrl-c`: Same as above.
* `l`: List installations.
* `ESC`: From installations, toggle stop requested. From commands, go to installations.
* `up`/`down`: select next/previous item.
* `enter`: From installations, show commands for the selected item.
* `pg up`/`pg down`: Scroll the details pane up/down.
* `left`/`right` scroll the details pane left/right.
- `q`: Request exit when all processes finished. This won't kill processes currently running.
- `ctrl-c`: Same as above.
- `l`: List installations.
- `ESC`: From installations, toggle stop requested. From commands, go to installations.
- `up`/`down`: select next/previous item.
- `enter`: From installations, show commands for the selected item.
- `pg up`/`pg down`: Scroll the details pane up/down.
- `left`/`right` scroll the details pane left/right.

Run commands such as:

Expand Down Expand Up @@ -90,7 +90,7 @@ cat example/helm-values/envs/dev/config.yaml
locked: false
```
* Setting `locked` to true disables all releases under the env.
- Setting `locked` to true disables all releases under the env.

The name of the directory corresponds to the name of the environment. In the above case it will be called `dev`.

Expand All @@ -103,8 +103,8 @@ context: 1234-dev-cluster
locked: false
```

* `context` is the `--kube-context` parameter passed to helm.
* Setting `locked` to true disables all releases under the cluster dir.
- `context` is the `--kube-context` parameter passed to helm.
- Setting `locked` to true disables all releases under the cluster dir.

The name of the directory corresponds to the name of the cluster. Which can be different from the context value provided. In the above example, the cluster is called `dev-cluster` and uses the parameter `--kube-context 1234-dev-cluster`.

Expand All @@ -126,12 +126,12 @@ release_chart:
depends: []
```

* Setting `auto` to false disables deploys unless using `--auto=all` parameter.
* Setting `locked` to false disables all deploys.
* `namespace` is the kubernetes namespace to use for deploys.
* `release` is the release name for the helm chart.
* `depends` is a list of releases that must be installed first. `$namespace/$release` format.
* `release_chart` is how to find the chart to install (see below).
- Setting `auto` to false disables deploys unless using `--auto=all` parameter.
- Setting `locked` to false disables all deploys.
- `namespace` is the kubernetes namespace to use for deploys.
- `release` is the release name for the helm chart.
- `depends` is a list of releases that must be installed first. `$namespace/$release` format.
- `release_chart` is how to find the chart to install (see below).

Note: the value of the `release` is used as the release name, not the name of the directory.

Expand Down Expand Up @@ -183,20 +183,19 @@ release_chart:

There are a number of existing solutions of deploying stuff on a kubernetes cluster. The main contenders are:

* [argocd](https://argoproj.github.io/cd/)
* [spinnaker](https://spinnaker.io/)
* [harness](https://docs.harness.io/)
- [argocd](https://argoproj.github.io/cd/)
- [spinnaker](https://spinnaker.io/)
- [harness](https://docs.harness.io/)

Unfortunately, these all had limitations:

* argocd, while it supports helm charts, it does not support saving helm values in git.
* Can overcome this issue by creating git repo of charts containing helm sub-charts, but this is ugly and requires modifying the helm values.
* spinnaker seems rather heavy weight to install, haven't succeeded yet.
* harness is mostly proprietary solution.
- argocd, while it supports helm charts, it does not support saving helm values in git.
- Can overcome this issue by creating git repo of charts containing helm sub-charts, but this is ugly and requires modifying the helm values.
- spinnaker seems rather heavy weight to install, haven't succeeded yet.
- harness is mostly proprietary solution.

As a result a Python program was written as an alternative solution. This is a rewrite of the Python program.

## Current Limitations

* Should be able to save hash of chart to ensure it is not unexpectedly changed upstream.
* No idea how well `text` will work with github, only tested with gitlab.
- No idea how well `text` output will work with github, only tested with gitlab.
26 changes: 24 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use anyhow::{Context, Result};

use serde::de::Error;
use serde::{Deserialize, Serialize, Serializer};
use url::Url;

use crate::utils::filename_to_string;

Expand Down Expand Up @@ -81,20 +82,38 @@ impl Serialize for ReleaseReference {
pub enum ChartReference {
#[serde(rename = "helm")]
Helm {
repo_url: String,
repo_url: Url,
chart_name: String,
chart_version: String,
},
#[serde(rename = "oci")]
Oci {
repo_url: String,
repo_url: Url,
chart_name: String,
chart_version: String,
},
#[serde(rename = "local")]
Local { path: PathBuf },
}

impl std::fmt::Display for ChartReference {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ChartReference::Helm {
repo_url,
chart_name,
chart_version,
} => write!(f, "Helm: {repo_url}/{chart_name}:{chart_version}",),
ChartReference::Oci {
repo_url,
chart_name,
chart_version,
} => write!(f, "Oci: {repo_url}/{chart_name}:{chart_version}",),
ChartReference::Local { path } => write!(f, "Local: {path}", path = path.display()),
}
}
}

#[derive(Clone, Serialize, Deserialize, Debug)]
#[serde(rename_all = "snake_case")]
pub enum AnnouncePolicy {
Expand Down Expand Up @@ -145,6 +164,7 @@ pub struct Release {
pub name: String,
pub dir: PathBuf,
pub config_file: PathBuf,
pub lock_file: PathBuf,
pub config: ReleaseConfig,
}

Expand Down Expand Up @@ -243,6 +263,7 @@ impl Cluster {
pub fn load_release(&self, dir_name: &str, overrides: &Overrides) -> Result<Release> {
let dir = self.dir.join(dir_name);
let config_file = dir.join("config.yaml");
let lock_file = dir.join("lock.json");

let file: String = std::fs::read_to_string(&config_file)
.with_context(|| format!("Reading file {}", config_file.display()))?;
Expand All @@ -257,6 +278,7 @@ impl Cluster {
name: config.release.clone(),
dir,
config_file,
lock_file,
config,
})
}
Expand Down
35 changes: 29 additions & 6 deletions src/depends.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ pub fn is_depends_ok(installation: &Installation, done: &InstallationSet) -> boo

#[cfg(test)]
mod tests {
#![allow(clippy::unwrap_used)]
use std::path::PathBuf;

use crate::config::{AnnouncePolicy, ChartReference};
Expand All @@ -81,11 +82,14 @@ mod tests {
Installation {
name: "ingress-nginx-ext".to_string(),
config_file: "config.yaml".into(),
lock_file: "lock.json".into(),
values_files: vec![],
env_name: "dev".to_string(),
cluster_name: "spartan".to_string(),
chart_reference: ChartReference::Helm {
repo_url: "https://kubernetes.github.io/ingress-nginx".to_string(),
repo_url: "https://kubernetes.github.io/ingress-nginx"
.parse()
.unwrap(),
chart_name: "ingress-nginx".to_string(),
chart_version: "4.0.10".to_string(),
},
Expand All @@ -99,11 +103,14 @@ mod tests {
Installation {
name: "ingress-nginx-ext-2".to_string(),
config_file: "config.yaml".into(),
lock_file: "lock.json".into(),
values_files: vec![],
env_name: "dev".to_string(),
cluster_name: "spartan".to_string(),
chart_reference: ChartReference::Helm {
repo_url: "https://kubernetes.github.io/ingress-nginx".to_string(),
repo_url: "https://kubernetes.github.io/ingress-nginx"
.parse()
.unwrap(),
chart_name: "ingress-nginx".to_string(),
chart_version: "4.0.10".to_string(),
},
Expand All @@ -117,6 +124,7 @@ mod tests {
Installation {
name: "exporter-blackbox".to_string(),
config_file: "config.yaml".into(),
lock_file: "lock.json".into(),
values_files: vec![],
env_name: "dev".to_string(),
cluster_name: "spartan".to_string(),
Expand All @@ -136,6 +144,7 @@ mod tests {
Installation {
name: "exporter-blackbox-2".to_string(),
config_file: "config.yaml".into(),
lock_file: "lock.json".into(),
values_files: vec![],
env_name: "dev".to_string(),
cluster_name: "spartan".to_string(),
Expand Down Expand Up @@ -173,11 +182,14 @@ mod tests {
Installation {
name: "ingress-nginx-ext".to_string(),
config_file: "config.yaml".into(),
lock_file: "lock.json".into(),
values_files: vec![],
env_name: "dev".to_string(),
cluster_name: "spartan".to_string(),
chart_reference: ChartReference::Helm {
repo_url: "https://kubernetes.github.io/ingress-nginx".to_string(),
repo_url: "https://kubernetes.github.io/ingress-nginx"
.parse()
.unwrap(),
chart_name: "ingress-nginx".to_string(),
chart_version: "4.0.10".to_string(),
},
Expand All @@ -191,6 +203,7 @@ mod tests {
Installation {
name: "exporter-blackbox".to_string(),
config_file: "config.yaml".into(),
lock_file: "lock.json".into(),
values_files: vec![],
env_name: "dev".to_string(),
cluster_name: "spartan".to_string(),
Expand Down Expand Up @@ -235,11 +248,14 @@ mod tests {
Installation {
name: "ingress-nginx-ext".to_string(),
config_file: "config.yaml".into(),
lock_file: "lock.json".into(),
values_files: vec![],
env_name: "dev".to_string(),
cluster_name: "spartan".to_string(),
chart_reference: ChartReference::Helm {
repo_url: "https://kubernetes.github.io/ingress-nginx".to_string(),
repo_url: "https://kubernetes.github.io/ingress-nginx"
.parse()
.unwrap(),
chart_name: "ingress-nginx".to_string(),
chart_version: "4.0.10".to_string(),
},
Expand All @@ -256,6 +272,7 @@ mod tests {
Installation {
name: "exporter-blackbox".to_string(),
config_file: "config.yaml".into(),
lock_file: "lock.json".into(),
values_files: vec![],
env_name: "dev".to_string(),
cluster_name: "spartan".to_string(),
Expand Down Expand Up @@ -293,11 +310,14 @@ mod tests {
let todo = vec![Installation {
name: "ingress-nginx-ext".to_string(),
config_file: "config.yaml".into(),
lock_file: "lock.json".into(),
values_files: vec![],
env_name: "dev".to_string(),
cluster_name: "spartan".to_string(),
chart_reference: ChartReference::Helm {
repo_url: "https://kubernetes.github.io/ingress-nginx".to_string(),
repo_url: "https://kubernetes.github.io/ingress-nginx"
.parse()
.unwrap(),
chart_name: "ingress-nginx".to_string(),
chart_version: "4.0.10".to_string(),
},
Expand Down Expand Up @@ -325,11 +345,14 @@ mod tests {
let todo = vec![Installation {
name: "ingress-nginx-ext".to_string(),
config_file: "config.yaml".into(),
lock_file: "lock.json".into(),
values_files: vec![],
env_name: "dev".to_string(),
cluster_name: "spartan".to_string(),
chart_reference: ChartReference::Helm {
repo_url: "https://kubernetes.github.io/ingress-nginx".to_string(),
repo_url: "https://kubernetes.github.io/ingress-nginx"
.parse()
.unwrap(),
chart_name: "ingress-nginx".to_string(),
chart_version: "4.0.10".to_string(),
},
Expand Down
Loading

0 comments on commit 891a522

Please sign in to comment.