use greentic_deploy_spec::Environment;
use serde_json::Value;
use super::K8sDeployerHandler;
use super::manifests::{self, K8sParams, has_cluster_presence};
use crate::env_packs::render::{ManifestRenderer, RenderError};
impl ManifestRenderer for K8sDeployerHandler {
fn render_environment(
&self,
env: &Environment,
answers: Option<&serde_json::Value>,
) -> Result<Vec<Value>, RenderError> {
let params = K8sParams::from_answers(env, answers).map_err(RenderError::InvalidAnswers)?;
let mut objects = manifests::render_environment_manifests(env, ¶ms);
for revision in &env.revisions {
if has_cluster_presence(revision.lifecycle) {
objects.extend(manifests::render_worker_manifests(env, revision, ¶ms));
}
}
Ok(objects)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::env_packs::EnvPackHandler;
use crate::env_packs::deployer::conformance::build_fixture_env;
fn rendered_names(objects: &[Value]) -> Vec<String> {
objects
.iter()
.map(|o| {
o.pointer("/metadata/name")
.and_then(Value::as_str)
.expect("every rendered object has metadata.name")
.to_string()
})
.collect()
}
#[test]
fn handler_exposes_manifest_renderer() {
let h = K8sDeployerHandler::default();
assert!(
(&h as &dyn EnvPackHandler).as_manifest_renderer().is_some(),
"EnvPackHandler::as_manifest_renderer must surface the K8s renderer"
);
}
#[test]
fn renders_env_level_set_then_present_revision_workers() {
let env = build_fixture_env();
let params = K8sParams::for_env(&env);
let env_level = manifests::render_environment_manifests(&env, ¶ms);
let handler = K8sDeployerHandler::default();
let objects = handler.render_environment(&env, None).unwrap();
assert_eq!(
&objects[..env_level.len()],
&env_level[..],
"env-level objects come first, unchanged from the apply path"
);
assert_eq!(objects.len(), env_level.len() + 2 * 2);
let names = rendered_names(&objects);
for revision in &env.revisions {
let worker = manifests::worker_name(revision);
let expected = has_cluster_presence(revision.lifecycle);
assert_eq!(
names.iter().filter(|n| **n == worker).count() == 2,
expected,
"revision `{}` ({:?}) presence mismatch",
revision.revision_id,
revision.lifecycle
);
}
}
#[test]
fn render_environment_is_deterministic() {
let env = build_fixture_env();
let handler = K8sDeployerHandler::default();
assert_eq!(
handler.render_environment(&env, None).unwrap(),
handler.render_environment(&env, None).unwrap()
);
}
#[test]
fn invalid_answers_surface_render_error() {
let env = build_fixture_env();
let handler = K8sDeployerHandler::default();
let bad = serde_json::json!("not an object");
let err = handler.render_environment(&env, Some(&bad)).unwrap_err();
assert!(
matches!(err, RenderError::InvalidAnswers(_)),
"expected InvalidAnswers, got {err:?}"
);
}
}