Files
cuddle-clusters/crates/cuddle-clusters/src/catalog/cluster_vars.rs
kjuulh 3956366d28
All checks were successful
continuous-integration/drone/push Build is passing
feat/add-postgres-database (#20)
feat: add postgres database

Signed-off-by: kjuulh <contact@kjuulh.io>

feat: add postgres and more templates

Signed-off-by: kjuulh <contact@kjuulh.io>

Reviewed-on: https://git.front.kjuulh.io/kjuulh/cuddle-clusters/pulls/20
Co-authored-by: kjuulh <contact@kjuulh.io>
Co-committed-by: kjuulh <contact@kjuulh.io>
2024-11-29 09:05:50 +01:00

221 lines
7.2 KiB
Rust

use std::collections::{BTreeMap, HashMap};
use serde_yaml::Value;
use crate::Component;
use super::cuddle_vars::CuddleVariables;
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum RawClusterVariable {
Map(RawClusterVariables),
List(RawClusterVariableList),
String(String),
Bool(bool),
}
#[derive(Clone, PartialEq, Eq, Debug, Default)]
pub struct RawClusterVariables(BTreeMap<String, RawClusterVariable>);
#[derive(Clone, PartialEq, Eq, Debug, Default)]
pub struct RawClusterVariableList(Vec<RawClusterVariable>);
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum ClusterVariable {
String(String),
}
#[derive(PartialEq, Eq, Debug, Clone, Default)]
pub struct ClusterEnv {
vars: HashMap<String, ClusterVariable>,
}
#[derive(PartialEq, Eq, Debug, Clone, Default)]
pub struct ClusterVariables {
env: ClusterEnv,
name: String,
namespace: String,
replicas: u64,
raw: RawClusterVariables,
// raw: CuddleVariables,
}
#[derive(Default)]
pub struct ClusterVars {}
impl Component for ClusterVars {
fn name(&self) -> String {
"cluster/vars".into()
}
fn validate(&self, _value: &serde_yaml::Value) -> anyhow::Result<()> {
Ok(())
}
fn render_value(
&self,
environment: &str,
value: &serde_yaml::Value,
) -> Option<anyhow::Result<minijinja::Value>> {
let mut vars = ClusterVariables {
replicas: 3,
..Default::default()
};
if let Some(mapping) = value.as_mapping() {
if let Some(env) = mapping.get("env") {
if let Some(env_entries) = env.as_mapping() {
for (name, value) in env_entries {
if let (Some(name), Some(value)) = (name.as_str(), value.as_str()) {
vars.env
.vars
.insert(name.to_string(), ClusterVariable::String(value.into()));
}
}
}
}
if let Some(replicas) = mapping.get("replicas") {
if let Some(replicas) = replicas.as_u64() {
vars.replicas = replicas;
}
}
}
vars.raw = value.into();
vars.name = environment.into();
vars.namespace = environment.into();
Some(Ok(minijinja::Value::from_object(vars)))
}
}
impl minijinja::value::Object for ClusterVariables {
fn get_value(self: &std::sync::Arc<Self>, key: &minijinja::Value) -> Option<minijinja::Value> {
let out = match key.as_str()? {
"env" => minijinja::Value::from_object(self.env.clone()),
"name" => minijinja::Value::from_safe_string(self.name.clone()),
"namespace" => minijinja::Value::from_safe_string(self.namespace.clone()),
"replicas" => minijinja::Value::from_safe_string(self.replicas.to_string()),
"raw" => {
tracing::info!("returning raw: {:?}", self.raw);
minijinja::Value::from_object(self.raw.clone())
}
_ => return None,
};
Some(out)
}
}
impl minijinja::value::Object for ClusterEnv {
fn get_value(self: &std::sync::Arc<Self>, key: &minijinja::Value) -> Option<minijinja::Value> {
let var = self.vars.get(key.as_str()?)?;
match var {
ClusterVariable::String(s) => Some(minijinja::Value::from_safe_string(s.clone())),
}
}
fn enumerate(self: &std::sync::Arc<Self>) -> minijinja::value::Enumerator {
minijinja::value::Enumerator::Values(
self.vars
.keys()
.map(|key| minijinja::Value::from_safe_string(key.clone()))
.collect::<Vec<_>>(),
)
}
}
impl From<&Value> for RawClusterVariables {
fn from(value: &Value) -> Self {
match value {
Value::Mapping(mapping) => RawClusterVariables(
mapping
.into_iter()
.map(|(k, v)| {
(
k.as_str()
.expect("keys to always be valid strings")
.to_string(),
v.into(),
)
})
.collect(),
),
Value::Null => RawClusterVariables::default(),
_ => todo!(),
}
}
}
impl From<&Value> for RawClusterVariable {
fn from(value: &Value) -> Self {
match value {
Value::Null => Self::Map(RawClusterVariables::default()),
Value::Bool(b) => Self::Bool(*b),
Value::Number(number) => Self::String(number.to_string()),
Value::String(s) => Self::String(s.into()),
Value::Sequence(vec) => Self::List(RawClusterVariableList(
vec.iter().map(|i| i.into()).collect(),
)),
Value::Mapping(mapping) => Self::Map(RawClusterVariables(
mapping
.into_iter()
.map(|(k, v)| {
(
k.as_str()
.expect("keys to always be valid strings")
.to_string(),
v.into(),
)
})
.collect(),
)),
Value::Tagged(_tagged_value) => todo!(),
}
}
}
impl minijinja::value::Object for RawClusterVariables {
fn get_value(self: &std::sync::Arc<Self>, key: &minijinja::Value) -> Option<minijinja::Value> {
self.0.get(key.as_str()?).map(|o| match o {
RawClusterVariable::Map(raw_cluster_variables) => {
minijinja::Value::from_object(raw_cluster_variables.clone())
}
RawClusterVariable::List(list) => minijinja::Value::from_object(list.clone()),
RawClusterVariable::String(s) => minijinja::Value::from_safe_string(s.clone()),
RawClusterVariable::Bool(b) => minijinja::Value::from_safe_string(b.to_string()),
})
}
fn enumerate(self: &std::sync::Arc<Self>) -> minijinja::value::Enumerator {
minijinja::value::Enumerator::Values(
self.0
.keys()
.map(|key| minijinja::Value::from_safe_string(key.clone()))
.collect::<Vec<_>>(),
)
}
}
impl minijinja::value::Object for RawClusterVariableList {
fn enumerate(self: &std::sync::Arc<Self>) -> minijinja::value::Enumerator {
minijinja::value::Enumerator::Values(
self.0
.iter()
.map(|i| match i {
RawClusterVariable::Map(raw_cluster_variables) => {
minijinja::Value::from_object(raw_cluster_variables.clone())
}
RawClusterVariable::List(list) => minijinja::Value::from_object(list.clone()),
RawClusterVariable::String(s) => minijinja::Value::from_safe_string(s.clone()),
RawClusterVariable::Bool(b) => {
minijinja::Value::from_safe_string(b.to_string())
}
})
.collect(),
)
}
}