alien-core 3.3.54

Deploy software into your customers' cloud accounts and keep it fully managed
Documentation
use alien_core::{ErrorData, Resource};
use serde_json::{json, Value};

fn resource(kind: &str, key: Option<&str>) -> Resource {
    let mut config = match kind {
        "container" => json!({
            "type": "container", "id": "cache", "links": [], "ports": [],
            "code": {"type": "image", "image": "redis:7"},
            "cpu": {"min": "0.5", "desired": "0.5"},
            "memory": {"min": "512Mi", "desired": "512Mi"},
            "permissions": "execution", "stateful": true,
            "persistentStorage": {"size": "10Gi", "mountPath": "/data"}
        }),
        _ => json!({"type": kind, "id": "data"}),
    };
    if let Some(key) = key {
        let storage = if kind == "container" {
            &mut config["persistentStorage"]
        } else {
            &mut config
        };
        storage["encryptionKey"] = json!({"type": "key", "id": key});
    }
    serde_json::from_value(config).expect("valid resource configuration")
}

#[test]
fn existing_data_resources_reject_key_addition_removal_and_replacement() {
    for kind in ["postgres", "storage", "container"] {
        for before in [None, Some("first"), Some("second")] {
            for after in [None, Some("first"), Some("second")] {
                let original = resource(kind, before);
                let desired = resource(kind, after);
                let result = original.validate_update(&desired);
                if before == after {
                    result.expect("unchanged encryption must remain updateable");
                } else {
                    let error = result
                        .expect_err("must not silently change the key protecting existing data");
                    assert!(matches!(
                        error.error,
                        Some(ErrorData::InvalidResourceUpdate { .. })
                    ));
                }
            }
        }
    }
}

#[test]
fn encrypted_volume_allows_image_updates_with_the_same_key() {
    let original = resource("container", Some("first"));
    let mut desired: Value = serde_json::to_value(&original).unwrap();
    desired["code"]["image"] = json!("redis:8");
    original
        .validate_update(&serde_json::from_value(desired).unwrap())
        .expect("an image update must preserve the volume encryption selection");
}