Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
parent
5378b5f537
commit
3da154882d
22
Cargo.lock
generated
22
Cargo.lock
generated
@ -331,6 +331,9 @@ dependencies = [
|
|||||||
"dagger-sdk",
|
"dagger-sdk",
|
||||||
"eyre",
|
"eyre",
|
||||||
"futures",
|
"futures",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_yaml",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1415,6 +1418,19 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_yaml"
|
||||||
|
version = "0.9.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a15e0ef66bf939a7c890a0bf6d5a733c70202225f9888a89ed5c62298b019129"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
"unsafe-libyaml",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha2"
|
name = "sha2"
|
||||||
version = "0.10.8"
|
version = "0.10.8"
|
||||||
@ -1764,6 +1780,12 @@ dependencies = [
|
|||||||
"void",
|
"void",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unsafe-libyaml"
|
||||||
|
version = "0.2.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
@ -27,3 +27,6 @@ color-eyre = "*"
|
|||||||
clap = {version = "4", features = ["derive"]}
|
clap = {version = "4", features = ["derive"]}
|
||||||
futures = "0.3.29"
|
futures = "0.3.29"
|
||||||
async-scoped = { version = "0.8.0", features = ["tokio", "use-tokio"] }
|
async-scoped = { version = "0.8.0", features = ["tokio", "use-tokio"] }
|
||||||
|
serde_json = { version = "1" }
|
||||||
|
serde_yaml = {version = "0.9"}
|
||||||
|
serde = {version = "1", features = ["derive"]}
|
||||||
|
@ -19,6 +19,9 @@ clap.workspace = true
|
|||||||
async-trait.workspace = true
|
async-trait.workspace = true
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
serde_json.workspace = true
|
||||||
|
serde_yaml.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
129
crates/cuddle-ci/src/cuddle_file.rs
Normal file
129
crates/cuddle-ci/src/cuddle_file.rs
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||||
|
pub struct CuddleFile {
|
||||||
|
pub vars: CuddleVars,
|
||||||
|
pub deployment: Option<CuddleDeployment>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||||
|
pub struct CuddleVars {
|
||||||
|
pub service: String,
|
||||||
|
pub registry: String,
|
||||||
|
|
||||||
|
pub clusters: CuddleClusters,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||||
|
pub struct CuddleDeployment {
|
||||||
|
pub registry: String,
|
||||||
|
pub env: CuddleDeploymentEnv,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||||
|
pub struct CuddleDeploymentEnv(pub BTreeMap<String, CuddleDeploymentCluster>);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||||
|
pub struct CuddleDeploymentCluster {
|
||||||
|
pub clusters: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||||
|
pub struct CuddleClusters(pub BTreeMap<String, CuddleCluster>);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||||
|
pub struct CuddleCluster {
|
||||||
|
pub namespace: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CuddleFile {
|
||||||
|
pub async fn from_cuddle_file() -> eyre::Result<Self> {
|
||||||
|
let cuddle_file_content = tokio::fs::read_to_string("cuddle.yaml").await?;
|
||||||
|
|
||||||
|
Self::parse_cuddle_file(&cuddle_file_content)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_cuddle_file(content: &str) -> eyre::Result<Self> {
|
||||||
|
let cuddle_file: CuddleFile = serde_yaml::from_str(content)?;
|
||||||
|
|
||||||
|
Ok(cuddle_file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use crate::cuddle_file::{
|
||||||
|
CuddleCluster, CuddleClusters, CuddleDeploymentCluster, CuddleDeploymentEnv, CuddleVars,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::CuddleFile;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_file() {
|
||||||
|
let cuddle_file = r#"
|
||||||
|
base: "git@git.front.kjuulh.io:kjuulh/cuddle-base.git"
|
||||||
|
|
||||||
|
vars:
|
||||||
|
service: "infrastructure-example"
|
||||||
|
registry: kasperhermansen
|
||||||
|
|
||||||
|
clusters:
|
||||||
|
clank_prod:
|
||||||
|
replicas: "3"
|
||||||
|
namespace: clank_prod
|
||||||
|
|
||||||
|
deployment:
|
||||||
|
registry: git@git.front.kjuulh.io:kjuulh/clank-clusters
|
||||||
|
env:
|
||||||
|
prod:
|
||||||
|
clusters:
|
||||||
|
- clank_prod
|
||||||
|
|
||||||
|
scripts:
|
||||||
|
render:
|
||||||
|
type: shell
|
||||||
|
args:
|
||||||
|
cluster:
|
||||||
|
name: cluster
|
||||||
|
type: flag
|
||||||
|
image_tag:
|
||||||
|
name: image_tag
|
||||||
|
type: flag"#;
|
||||||
|
|
||||||
|
let res = CuddleFile::parse_cuddle_file(cuddle_file).expect("to parse file");
|
||||||
|
|
||||||
|
let mut clusters = BTreeMap::new();
|
||||||
|
clusters.insert(
|
||||||
|
"clank_prod".into(),
|
||||||
|
CuddleCluster {
|
||||||
|
namespace: "clank_prod".into(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut deployment = BTreeMap::new();
|
||||||
|
deployment.insert(
|
||||||
|
"prod".into(),
|
||||||
|
CuddleDeploymentCluster {
|
||||||
|
clusters: vec!["clank_prod".into()],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let expected = CuddleFile {
|
||||||
|
vars: CuddleVars {
|
||||||
|
service: "infrastructure-example".into(),
|
||||||
|
registry: "kasperhermansen".into(),
|
||||||
|
clusters: CuddleClusters(clusters),
|
||||||
|
},
|
||||||
|
deployment: Some(crate::cuddle_file::CuddleDeployment {
|
||||||
|
registry: "git@git.front.kjuulh.io:kjuulh/clank-cluster".into(),
|
||||||
|
env: CuddleDeploymentEnv(deployment),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(expected, res)
|
||||||
|
}
|
||||||
|
}
|
103
crates/cuddle-ci/src/cuddle_releaser.rs
Normal file
103
crates/cuddle-ci/src/cuddle_releaser.rs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
use async_trait::async_trait;
|
||||||
|
use eyre::Context;
|
||||||
|
|
||||||
|
use crate::{cuddle_file::CuddleFile, MainAction};
|
||||||
|
|
||||||
|
pub struct CuddleReleaser {
|
||||||
|
client: dagger_sdk::Query,
|
||||||
|
env: String,
|
||||||
|
cuddle_file: CuddleFile,
|
||||||
|
|
||||||
|
folder: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CuddleReleaserOptions {
|
||||||
|
upstream: String,
|
||||||
|
cluster: String,
|
||||||
|
namespace: String,
|
||||||
|
app: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CuddleReleaser {
|
||||||
|
pub async fn new(client: dagger_sdk::Query) -> eyre::Result<Self> {
|
||||||
|
let cuddle_file = CuddleFile::from_cuddle_file().await?;
|
||||||
|
|
||||||
|
let env = std::env::var("CUDDLE_ENV").context("CUDDLE_ENV was not set")?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
client,
|
||||||
|
cuddle_file,
|
||||||
|
env,
|
||||||
|
folder: ".cuddle/tmp/k8s".into(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl MainAction for CuddleReleaser {
|
||||||
|
async fn execute_main(&self) -> eyre::Result<()> {
|
||||||
|
let client = self.client.clone();
|
||||||
|
|
||||||
|
if self.cuddle_file.deployment.is_none() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let chosen_cluster = match self
|
||||||
|
.cuddle_file
|
||||||
|
.deployment
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.env
|
||||||
|
.0
|
||||||
|
.get(&self.env.to_string())
|
||||||
|
{
|
||||||
|
Some(c) => match c.clusters.first().take() {
|
||||||
|
Some(c) => c,
|
||||||
|
None => return Ok(()),
|
||||||
|
},
|
||||||
|
None => return Ok(()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let cluster = match self.cuddle_file.vars.clusters.0.get(chosen_cluster) {
|
||||||
|
Some(c) => c,
|
||||||
|
None => eyre::bail!("no cluster found for: {}", chosen_cluster),
|
||||||
|
};
|
||||||
|
|
||||||
|
let options = CuddleReleaserOptions {
|
||||||
|
cluster: chosen_cluster.clone(),
|
||||||
|
namespace: cluster.namespace.clone(),
|
||||||
|
app: self.cuddle_file.vars.service.clone(),
|
||||||
|
upstream: self
|
||||||
|
.cuddle_file
|
||||||
|
.deployment
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.registry
|
||||||
|
.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let cuddle_releaser_image = "docker.io/kasperhermansen:cuddle-releaser:main-1706438736";
|
||||||
|
|
||||||
|
let folder = client.host().directory(&self.folder);
|
||||||
|
|
||||||
|
let cuddle_releaser = client
|
||||||
|
.container()
|
||||||
|
.from(cuddle_releaser_image)
|
||||||
|
.with_mounted_directory("/mnt/templates", folder);
|
||||||
|
|
||||||
|
cuddle_releaser
|
||||||
|
.with_exec(vec![
|
||||||
|
"cuddle-releaser",
|
||||||
|
"release",
|
||||||
|
&format!("--upstream={}", options.upstream),
|
||||||
|
&format!("--folder={}", "/mnt/templates"),
|
||||||
|
&format!("--cluster={}", options.cluster),
|
||||||
|
&format!("--namespace={}", options.namespace),
|
||||||
|
&format!("--app={}", options.app),
|
||||||
|
])
|
||||||
|
.sync()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -1,67 +1,12 @@
|
|||||||
pub mod cli;
|
pub mod cli;
|
||||||
pub mod leptos_service;
|
|
||||||
pub use cli::*;
|
pub use cli::*;
|
||||||
|
|
||||||
pub mod cuddle_please;
|
pub mod leptos_service;
|
||||||
pub mod dagger_middleware;
|
|
||||||
pub mod node_service;
|
pub mod node_service;
|
||||||
pub mod rust_lib;
|
pub mod rust_lib;
|
||||||
pub mod rust_service;
|
pub mod rust_service;
|
||||||
|
|
||||||
pub mod cuddle_releaser {
|
pub mod cuddle_file;
|
||||||
use async_trait::async_trait;
|
pub mod cuddle_please;
|
||||||
|
pub mod cuddle_releaser;
|
||||||
use crate::{rust_service::RustService, MainAction};
|
pub mod dagger_middleware;
|
||||||
|
|
||||||
pub struct CuddleReleaser {
|
|
||||||
client: dagger_sdk::Query,
|
|
||||||
options: CuddleReleaserOptions,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CuddleReleaserOptions {
|
|
||||||
upstream: String,
|
|
||||||
folder: String,
|
|
||||||
cluster: String,
|
|
||||||
namespace: String,
|
|
||||||
app: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CuddleReleaser {
|
|
||||||
pub async fn new(
|
|
||||||
client: dagger_sdk::Query,
|
|
||||||
options: CuddleReleaserOptions,
|
|
||||||
) -> eyre::Result<Self> {
|
|
||||||
Ok(Self { client, options })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl MainAction for CuddleReleaser {
|
|
||||||
async fn execute_main(&self) -> eyre::Result<()> {
|
|
||||||
let client = self.client;
|
|
||||||
|
|
||||||
let cuddle_releaser_image = "docker.io/kasperhermansen:cuddle-releaser:main-1706438736";
|
|
||||||
|
|
||||||
let folder = client.host().directory(self.options.folder);
|
|
||||||
|
|
||||||
let cuddle_releaser = client
|
|
||||||
.container()
|
|
||||||
.from(cuddle_releaser_image)
|
|
||||||
.with_mounted_directory("/mnt/templates", folder);
|
|
||||||
|
|
||||||
cuddle_releaser
|
|
||||||
.with_exec(vec![
|
|
||||||
"cuddle-releaser",
|
|
||||||
"release",
|
|
||||||
&format!("--upstream={}", self.options.upstream),
|
|
||||||
&format!("--folder={}", "/mnt/templates"),
|
|
||||||
&format!("--cluster={}", self.options.cluster),
|
|
||||||
&format!("--namespace={}", self.options.namespace),
|
|
||||||
&format!("--app={}", self.options.app),
|
|
||||||
])
|
|
||||||
.sync()?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -466,13 +466,13 @@ mod test {
|
|||||||
.with_apt(&["git"])
|
.with_apt(&["git"])
|
||||||
.with_cargo_binstall("latest", ["sqlx-cli"])
|
.with_cargo_binstall("latest", ["sqlx-cli"])
|
||||||
.with_mold("2.3.3")
|
.with_mold("2.3.3")
|
||||||
.with_stage(RustServiceStage::BeforeDeps(middleware(|c| {
|
// .with_stage(RustServiceStage::BeforeDeps(middleware(|c| {
|
||||||
async move {
|
// async move {
|
||||||
// Noop
|
// // Noop
|
||||||
Ok(c)
|
// Ok(c)
|
||||||
}
|
// }
|
||||||
.boxed()
|
// .boxed()
|
||||||
})))
|
// })))
|
||||||
.with_clap_sanity_test()
|
.with_clap_sanity_test()
|
||||||
.build_release()
|
.build_release()
|
||||||
.await?;
|
.await?;
|
||||||
|
Loading…
Reference in New Issue
Block a user