kopiur_api/schema.rs
1//! Schema helper for embedding a large Kubernetes `core/v1` sub-object.
2//!
3//! schemars inlines the *entire* structural schema of an embedded `k8s-openapi`
4//! type. The worst offender is the hooks `JobSpec`, which pulls in the full
5//! `PodSpec`: inlined, it makes a single `SnapshotPolicy` CRD ~1.2 MB (~85% of the
6//! whole bundle), which bloats Helm releases and breaks large-CRD apply paths (e.g.
7//! client-side apply's 256 KB `last-applied-configuration` annotation limit).
8//!
9//! [`preserve_unknown_object`] renders such a field as an opaque object the
10//! apiserver passes through verbatim (`x-kubernetes-preserve-unknown-fields: true`)
11//! instead of inlining its schema. The Rust field stays its concrete typed
12//! `k8s-openapi` type — kube still deserializes into it (so scalar type errors are
13//! still rejected at admission) and the apiserver structurally validates the actual
14//! object when the controller creates it (e.g. the hook Job at Job-creation time) —
15//! so only *apply-time* structural validation of that field is deferred.
16//!
17//! Used **only** for the outsized hooks `jobSpec` ([`crate::snapshot_policy::RunJobHook`]).
18//! The smaller embedded `core/v1` objects (mover/server `securityContext`,
19//! `podSecurityContext`, `resources`, `affinity`) are deliberately left inlined so
20//! the apiserver keeps validating them at apply time — the size they add is modest
21//! and the early validation is worth keeping for a backup operator.
22
23use schemars::{Schema, SchemaGenerator};
24
25/// Render an embedded `core/v1` object field as
26/// `{ type: object, x-kubernetes-preserve-unknown-fields: true }` rather than
27/// inlining its full k8s-openapi schema. Use via
28/// `#[schemars(schema_with = "crate::schema::preserve_unknown_object")]`. Reserved
29/// for the outsized hooks `jobSpec`; see the module docs for why the smaller
30/// embedded objects are left inlined.
31pub fn preserve_unknown_object(_: &mut SchemaGenerator) -> Schema {
32 schemars::json_schema!({
33 "type": "object",
34 "x-kubernetes-preserve-unknown-fields": true,
35 })
36}