fix: helmfile and argocd are working again
- The tool was totally broken, not it works again - Development has been moved to my Gitea server - A basic test for helmfile is added - A basic drone pipeline is added
This commit is contained in:
parent
7adb5f0a4a
commit
1c29b32407
26
.drone.yml
Normal file
26
.drone.yml
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
kind: pipeline
|
||||
type: kubernetes
|
||||
name: Tests
|
||||
|
||||
trigger:
|
||||
event:
|
||||
- push
|
||||
|
||||
steps:
|
||||
- name: Prepare helm and helmfile
|
||||
image: ghcr.io/helmfile/helmfile:canary
|
||||
commands:
|
||||
- mkdir -p bin
|
||||
- cp $(which helm) ./bin/helm
|
||||
- cp $(which helmfile) ./bin/helmfile
|
||||
|
||||
- name: Unit tests
|
||||
image: rust:slim
|
||||
environment:
|
||||
CARGO_BUILD_JOBS: 1
|
||||
commands:
|
||||
- export PATH=$PWD/bin:$PATH
|
||||
- helm
|
||||
- helmfile
|
||||
- cargo test
|
41
Cargo.lock
generated
41
Cargo.lock
generated
@ -57,6 +57,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"tabled",
|
||||
"tempfile",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
@ -175,6 +176,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
@ -242,6 +252,15 @@ dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.2"
|
||||
@ -406,6 +425,15 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.6.0"
|
||||
@ -539,6 +567,19 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"redox_syscall",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.3"
|
||||
|
@ -17,3 +17,5 @@ tabled = "0.10.0"
|
||||
handlebars = "4.3.1"
|
||||
clap_complete = "4.0.6"
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3.4.0"
|
||||
|
18
examples/argocd/application.yaml
Normal file
18
examples/argocd/application.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: sealed-secrets
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
chart: argo-cd
|
||||
repoURL: https://argoproj.github.io/argo-helm
|
||||
targetRevision: 5.23.3
|
||||
helm:
|
||||
releaseName: sealed-secrets
|
||||
syncPolicy:
|
||||
automated: {}
|
||||
destination:
|
||||
server: "https://kubernetes.default.svc"
|
||||
namespace: argocd
|
@ -1,14 +1,15 @@
|
||||
repositories:
|
||||
- name: keel
|
||||
url: https://charts.keel.sh
|
||||
- name: argo
|
||||
url: https://argoproj.github.io/argo-helm
|
||||
|
||||
releases:
|
||||
# -----------------------------
|
||||
# -- Keel
|
||||
# -----------------------------
|
||||
- name: keel
|
||||
- name: argocd
|
||||
installed: true
|
||||
namespace: keel-system
|
||||
namespace: argocd
|
||||
createNamespace: true
|
||||
chart: keel/keel
|
||||
version: 0.9.10
|
||||
chart: argo/argo-cd
|
||||
version: 5.23.3
|
||||
values:
|
||||
- server:
|
||||
extraArgs:
|
||||
- --insecure
|
||||
|
@ -15,7 +15,7 @@ impl Connector for Argo {
|
||||
type ConnectorType = Argo;
|
||||
|
||||
fn get_app(&self) -> Result<Vec<types::HelmChart>> {
|
||||
let cmd: String = "argocd app list -o json | jq '[.[] | {chart: .spec.source.chart, version: .spec.source.targetRevision}]'".to_string();
|
||||
let cmd: String = "argocd app list -o json | jq '[.[] | {chart: .spec.source.chart, version: .spec.source.targetRevision, name: .spec.source.helm.releaseName}]'".to_string();
|
||||
|
||||
debug!("executing '${}'", cmd);
|
||||
let output = Command::new("bash")
|
||||
@ -27,7 +27,7 @@ impl Connector for Argo {
|
||||
|
||||
match from_str::<Vec<types::HelmChart>>(Borrow::borrow(&helm_stdout)) {
|
||||
Ok(mut charts) => {
|
||||
charts.dedup();
|
||||
charts.iter_mut().for_each(|chart| {chart.chart = Some(format!("{}/{}", chart.chart.clone().unwrap(), chart.chart.clone().unwrap()))});
|
||||
Ok(charts)
|
||||
}
|
||||
Err(err) => Err(err.into()),
|
||||
|
@ -14,7 +14,7 @@ pub(crate) struct Helmfile {
|
||||
impl Connector for Helmfile {
|
||||
fn get_app(&self) -> Result<Vec<types::HelmChart>> {
|
||||
let cmd: String = format!(
|
||||
"helmfile -f {} -e {} list --output json | jq '[.[] | {{chart: .name, version: .version}}]'",
|
||||
"helmfile -f {} -e {} list --output json | jq '[.[] | {{chart: .chart, version: .version, name: .name}}]'",
|
||||
self.path,
|
||||
self.env
|
||||
)
|
||||
@ -48,8 +48,48 @@ impl Connector for Helmfile {
|
||||
|
||||
type ConnectorType = Helmfile;
|
||||
}
|
||||
|
||||
impl Helmfile {
|
||||
pub(crate) fn init(path: String, env: String) -> Self {
|
||||
Self {path, env}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use tempfile::NamedTempFile;
|
||||
use std::io::Write;
|
||||
use crate::connectors::{Helmfile, Connector};
|
||||
use crate::types;
|
||||
|
||||
static HELMFILE_EXAMPLE: &str = "repositories:\n
|
||||
- name: argo\n
|
||||
url: https://argoproj.github.io/argo-helm\n
|
||||
releases:\n
|
||||
- name: argocd\n
|
||||
installed: true\n
|
||||
namespace: argocd\n
|
||||
createNamespace: true\n
|
||||
chart: argo/argo-cd\n
|
||||
version: 5.23.3\n
|
||||
values:\n
|
||||
- server:\n
|
||||
extraArgs:\n
|
||||
- --insecure";
|
||||
|
||||
#[test]
|
||||
fn test_helmfile() {
|
||||
let mut file = NamedTempFile::new().unwrap();
|
||||
writeln!(file, "{}", HELMFILE_EXAMPLE.clone()).unwrap();
|
||||
let path = file.into_temp_path();
|
||||
let helmfile_app = Helmfile::init(path.to_string_lossy().to_string(), "default".to_string()).get_app().unwrap();
|
||||
let app = types::HelmChart{
|
||||
chart: Some("argo/argo-cd".to_string()),
|
||||
name: Some("argocd".to_string()),
|
||||
version: Some("5.23.3".to_string()),
|
||||
};
|
||||
let apps: Vec<types::HelmChart> = vec![app];
|
||||
assert_eq!(apps, helmfile_app);
|
||||
path.close().unwrap();
|
||||
}
|
||||
}
|
||||
|
22
src/main.rs
22
src/main.rs
@ -109,6 +109,7 @@ fn main() {
|
||||
}
|
||||
|
||||
charts.iter().for_each(|a| {
|
||||
debug!("{:?}", a);
|
||||
check_chart(&mut result, a).unwrap();
|
||||
});
|
||||
|
||||
@ -128,9 +129,9 @@ fn main() {
|
||||
}
|
||||
|
||||
fn check_chart(result: &mut Vec<ExecResult>, local_chart: &types::HelmChart) -> Result<()> {
|
||||
if local_chart.name.is_some() {
|
||||
if local_chart.chart.is_some() {
|
||||
let version = local_chart.version.clone().unwrap();
|
||||
let chart = local_chart.name.clone().unwrap();
|
||||
let chart = local_chart.chart.clone().unwrap();
|
||||
return match version.is_empty() {
|
||||
true => {
|
||||
warn!(
|
||||
@ -142,8 +143,8 @@ fn check_chart(result: &mut Vec<ExecResult>, local_chart: &types::HelmChart) ->
|
||||
false => {
|
||||
info!("checking {} - {}", chart, version);
|
||||
let cmd = format!(
|
||||
"helm search repo {}/{} --versions --output json",
|
||||
chart, chart
|
||||
"helm search repo {} --versions --output json",
|
||||
chart,
|
||||
);
|
||||
debug!("executing '${}'", cmd);
|
||||
let output = Command::new("bash")
|
||||
@ -156,6 +157,8 @@ fn check_chart(result: &mut Vec<ExecResult>, local_chart: &types::HelmChart) ->
|
||||
// Remove "v" from version definitions
|
||||
let mut versions: Vec<HelmChart> = from_str(helm_stdout.borrow()).unwrap();
|
||||
versions.iter_mut().for_each(|f| {
|
||||
f.name = local_chart.name.clone();
|
||||
f.chart = local_chart.chart.clone();
|
||||
if f.version.is_some() {
|
||||
f.version = Some(f.version.as_ref().unwrap().replace('v', ""));
|
||||
}
|
||||
@ -172,8 +175,10 @@ fn check_chart(result: &mut Vec<ExecResult>, local_chart: &types::HelmChart) ->
|
||||
);
|
||||
}
|
||||
let remote = Version::from(current_version.as_str()).unwrap();
|
||||
debug!("{:?}", versions);
|
||||
let status: Status = if versions.contains(&HelmChart {
|
||||
name: Some(format!("{}/{}", chart.clone(), chart.clone())),
|
||||
chart: Some(chart.clone()),
|
||||
name: local_chart.name.clone(),
|
||||
version: Some(version.clone()),
|
||||
}) {
|
||||
match local.compare(remote.clone()) {
|
||||
@ -187,6 +192,7 @@ fn check_chart(result: &mut Vec<ExecResult>, local_chart: &types::HelmChart) ->
|
||||
};
|
||||
|
||||
result.push(ExecResult::new(
|
||||
local_chart.name.clone().unwrap(),
|
||||
chart.clone(),
|
||||
current_version.clone(),
|
||||
version.clone(),
|
||||
@ -214,21 +220,21 @@ fn handle_result(
|
||||
}
|
||||
for r in result.clone() {
|
||||
match r.status {
|
||||
Status::Uptodate => info!("{} is up-to-date", r.name),
|
||||
Status::Uptodate => info!("{} is up-to-date", r.chart),
|
||||
Status::Outdated => {
|
||||
if outdated_fail {
|
||||
failed = true
|
||||
}
|
||||
warn!(
|
||||
"{} is outdated. Current version is {}, but the latest is {}",
|
||||
r.name, r.current_version, r.latest_version
|
||||
r.chart, r.current_version, r.latest_version
|
||||
);
|
||||
}
|
||||
Status::Missing => {
|
||||
failed = true;
|
||||
error!(
|
||||
"{} is broken. Current version is {}, but it can't be found in the repo",
|
||||
r.name, r.current_version
|
||||
r.chart, r.current_version
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,10 @@ use tabled::Tabled;
|
||||
/// Struct for parsing charts info from helmfile
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||
pub(crate) struct HelmChart {
|
||||
#[serde(alias = "name", alias = "chart")]
|
||||
// #[serde(alias = "name", alias = "chart")]
|
||||
pub(crate) name: Option<String>,
|
||||
// #[serde(alias = "name", alias = "chart")]
|
||||
pub(crate) chart: Option<String>,
|
||||
pub(crate) version: Option<String>,
|
||||
}
|
||||
|
||||
@ -36,6 +38,7 @@ impl fmt::Display for Status {
|
||||
#[derive(Clone, Tabled, Serialize, Deserialize)]
|
||||
pub(crate) struct ExecResult {
|
||||
pub(crate) name: String,
|
||||
pub(crate) chart: String,
|
||||
pub(crate) latest_version: String,
|
||||
pub(crate) current_version: String,
|
||||
pub(crate) status: Status,
|
||||
@ -44,12 +47,14 @@ pub(crate) struct ExecResult {
|
||||
impl ExecResult {
|
||||
pub(crate) fn new(
|
||||
name: String,
|
||||
chart: String,
|
||||
latest_version: String,
|
||||
current_version: String,
|
||||
status: Status,
|
||||
) -> Self {
|
||||
Self {
|
||||
name,
|
||||
chart,
|
||||
latest_version,
|
||||
current_version,
|
||||
status,
|
||||
|
Reference in New Issue
Block a user