Skip to main content

validate_crd/
validate_crd.rs

1//! Validate Kubernetes objects against CRD schema CEL rules.
2//!
3//! Run with: `cargo run --example validate_crd --features validation`
4
5use kube_cel::Validator;
6use serde_json::json;
7
8fn main() {
9    let schema = json!({
10        "type": "object",
11        "properties": {
12            "spec": {
13                "type": "object",
14                "properties": {
15                    "replicas": {
16                        "type": "integer",
17                        "x-kubernetes-validations": [
18                            {"rule": "self >= 0", "message": "replicas must be non-negative"}
19                        ]
20                    }
21                },
22                "x-kubernetes-validations": [
23                    {"rule": "self.replicas >= 1", "message": "at least one replica required"}
24                ]
25            }
26        }
27    });
28
29    let validator = Validator::new();
30
31    // Valid object
32    let valid = json!({"spec": {"replicas": 3}});
33    match validator.validate(&schema, &valid, None) {
34        Ok(()) => println!("Valid object: OK"),
35        Err(errors) => println!("Valid object: {} errors", errors.len()),
36    }
37
38    // Invalid object
39    let invalid = json!({"spec": {"replicas": -1}});
40    if let Err(errors) = validator.validate(&schema, &invalid, None) {
41        println!("\nInvalid object: {} errors", errors.len());
42        for err in &errors {
43            println!("  [{path}] {msg}", path = err.field_path, msg = err.message);
44        }
45    }
46
47    // Transition rule (update check)
48    let transition_schema = json!({
49        "type": "object",
50        "x-kubernetes-validations": [{
51            "rule": "self.replicas >= oldSelf.replicas",
52            "message": "cannot scale down"
53        }],
54        "properties": {
55            "replicas": {"type": "integer"}
56        }
57    });
58
59    let new_obj = json!({"replicas": 2});
60    let old_obj = json!({"replicas": 5});
61
62    // Create (no old object): transition rule skipped
63    match validator.validate(&transition_schema, &new_obj, None) {
64        Ok(()) => println!("\nCreate (no old): OK"),
65        Err(errors) => println!("\nCreate (no old): {} errors", errors.len()),
66    }
67
68    // Update (scale down): transition rule fires
69    if let Err(errors) = validator.validate(&transition_schema, &new_obj, Some(&old_obj)) {
70        println!("Update (scale down): {} errors", errors.len());
71        for err in &errors {
72            println!("  {}", err);
73        }
74    }
75}