timestamp_duration/
timestamp_duration.rs1use kube_cel::{compile_schema, validate, validate_compiled};
6use serde_json::json;
7
8fn main() {
9 let schema = json!({
11 "type": "object",
12 "properties": {
13 "spec": {
14 "type": "object",
15 "properties": {
16 "expiresAt": {
17 "type": "string",
18 "format": "date-time"
19 },
20 "timeout": {
21 "type": "string",
22 "format": "duration"
23 }
24 },
25 "x-kubernetes-validations": [
26 {
27 "rule": "self.expiresAt > timestamp('2024-01-01T00:00:00Z')",
28 "message": "must expire after 2024-01-01"
29 },
30 {
31 "rule": "self.timeout <= duration('1h')",
32 "message": "timeout must be at most 1 hour"
33 }
34 ]
35 }
36 }
37 });
38
39 println!("=== Schema-based validation ===\n");
42
43 let valid = json!({
44 "spec": {
45 "expiresAt": "2025-06-15T12:00:00Z",
46 "timeout": "30m"
47 }
48 });
49 let errors = validate(&schema, &valid, None);
50 println!("Valid object: {} errors", errors.len());
51
52 let invalid = json!({
53 "spec": {
54 "expiresAt": "2023-06-15T12:00:00Z",
55 "timeout": "2h"
56 }
57 });
58 let errors = validate(&schema, &invalid, None);
59 println!("Invalid object: {} errors", errors.len());
60 for err in &errors {
61 println!(" [{path}] {msg}", path = err.field_path, msg = err.message);
62 }
63
64 println!("\n=== Compiled schema validation ===\n");
67
68 let compiled = compile_schema(&schema);
69
70 let objects = [
71 json!({"spec": {"expiresAt": "2025-01-01T00:00:00Z", "timeout": "30s"}}),
72 json!({"spec": {"expiresAt": "2023-12-31T23:59:59Z", "timeout": "45m"}}),
73 json!({"spec": {"expiresAt": "2025-06-15T00:00:00Z", "timeout": "90m"}}),
74 ];
75
76 for (i, obj) in objects.iter().enumerate() {
77 let errors = validate_compiled(&compiled, obj, None);
78 if errors.is_empty() {
79 println!("Object {i}: OK");
80 } else {
81 println!("Object {i}: {} error(s)", errors.len());
82 for err in &errors {
83 println!(" [{path}] {msg}", path = err.field_path, msg = err.message);
84 }
85 }
86 }
87
88 println!("\n=== Transition rule (expiration cannot move earlier) ===\n");
91
92 let transition_schema = json!({
93 "type": "object",
94 "properties": {
95 "expiresAt": {
96 "type": "string",
97 "format": "date-time"
98 }
99 },
100 "x-kubernetes-validations": [{
101 "rule": "self.expiresAt >= oldSelf.expiresAt",
102 "message": "expiration cannot be moved earlier"
103 }]
104 });
105
106 let new_obj = json!({"expiresAt": "2025-12-01T00:00:00Z"});
107 let old_obj = json!({"expiresAt": "2025-06-01T00:00:00Z"});
108
109 let errors = validate(&transition_schema, &new_obj, Some(&old_obj));
110 println!("Extend expiration: {} errors", errors.len());
111
112 let bad_obj = json!({"expiresAt": "2025-01-01T00:00:00Z"});
113 let errors = validate(&transition_schema, &bad_obj, Some(&old_obj));
114 println!("Shorten expiration: {} errors", errors.len());
115 for err in &errors {
116 println!(" {err}");
117 }
118}