message_expression/message_expression.rs
1//! Dynamic validation messages with `messageExpression`.
2//!
3//! A CRD validation rule can carry a `messageExpression` — a CEL expression that
4//! produces the failure message at evaluation time, so the message can embed the
5//! offending value (mirroring the apiserver's `messageExpression` support). When
6//! present and it evaluates to a string, kube-cel uses it; otherwise it falls back
7//! to the static `message`.
8//!
9//! Run with: `cargo run --example message_expression --features validation`
10
11use kube_cel::Validator;
12use serde_json::json;
13
14fn main() {
15 let schema = json!({
16 "type": "object",
17 "properties": {
18 "spec": {
19 "type": "object",
20 "properties": {
21 "replicas": {"type": "integer"}
22 },
23 "x-kubernetes-validations": [{
24 "rule": "self.replicas <= 5",
25 // Static fallback, used if messageExpression is absent/non-string.
26 "message": "too many replicas",
27 // Dynamic message: embeds the actual value and the limit.
28 "messageExpression":
29 "'requested ' + string(self.replicas) + ' replicas, max allowed is 5'"
30 }]
31 }
32 }
33 });
34
35 let validator = Validator::new();
36
37 // Two invalid objects: the dynamic message differs per object.
38 for replicas in [8, 20] {
39 let object = json!({"spec": {"replicas": replicas}});
40 if let Err(errors) = validator.validate(&schema, &object, None) {
41 for err in &errors {
42 // Note the message reflects this object's value, not a fixed string.
43 println!("replicas={replicas}: {}", err.message);
44 }
45 }
46 }
47
48 // A valid object produces no errors (and so no message at all).
49 let ok = json!({"spec": {"replicas": 3}});
50 match validator.validate(&schema, &ok, None) {
51 Ok(()) => println!("replicas=3: 0 error(s)"),
52 Err(errors) => println!("replicas=3: {} error(s)", errors.len()),
53 }
54}