Skip to main content

tatara_process/
routing_edge_resource.rs

1//! Closed-set of routing-edge K8s resource kinds emitted by the
2//! tatara reconciler's `render_routing` pipeline + typed projections
3//! for their `(apiVersion, kind)` pair — the substrate primitive that
4//! owns the workspace-wide (variant → wire-form identity) mapping
5//! every routing-edge site would otherwise restate by hand.
6//!
7//! Pre-lift the `(apiVersion, kind)` pairing was hand-authored across
8//! SIX production sites in `tatara-reconciler::edges` past the ★★
9//! PRIME-DIRECTIVE ≥ 2 duplication threshold, split across two edge
10//! variants:
11//!
12//! * `Ingress` — three production sites:
13//!     * `IngressEdge::kind()` — the `Edge` trait method returns the
14//!       bare `"Ingress"` PascalCase identifier for per-edge logging
15//!       + label composition.
16//!     * `IngressEdge::render` — the emitted
17//!       `json!({"apiVersion": "networking.k8s.io/v1",
18//!       "kind": "Ingress", ...})` block's `apiVersion` slot.
19//!     * `IngressEdge::render` — the same block's `kind` slot,
20//!       byte-identical to the trait method's return.
21//! * `DnsEndpoint` — three production sites:
22//!     * `DnsEndpointEdge::kind()` — the `Edge` trait method returns
23//!       the bare `"DNSEndpoint"` PascalCase identifier.
24//!     * `DnsEndpointEdge::render` — the emitted
25//!       `json!({"apiVersion": "externaldns.k8s.io/v1alpha1",
26//!       "kind": "DNSEndpoint", ...})` block's `apiVersion` slot.
27//!     * `DnsEndpointEdge::render` — the same block's `kind` slot,
28//!       byte-identical to the trait method's return.
29//!
30//! Every pre-lift site restated the axis-typed `&'static str` slot
31//! byte-identically; a regression that renamed the K8s Kind at ONE
32//! callsite (say the trait method's return but not the emitted JSON
33//! slot) would silently bifurcate the wire-form identity operators
34//! grep for against the K8s API server — a `HTTPRoute` migration
35//! that reached the trait but not the emitter (or vice versa) is a
36//! 404 at wire time. Post-lift every axis binds at ONE closed-set
37//! owner and rustc enforces every consumer reads the pair from the
38//! SAME variant.
39//!
40//! Sibling to the same-shape [`crate::flux_resource::FluxResource`]
41//! closed set on the FluxCD wire-form axis: both project a closed set
42//! of variant → wire-form identity slots through named per-variant
43//! methods; `FluxResource` covers the Flux controllers' emitted CRs
44//! (Kustomization, HelmRelease, OCIRepository) while
45//! `RoutingEdgeResource` covers the routing edges the reconciler
46//! renders (Ingress, DNSEndpoint). Both share the same `const fn`
47//! per-variant projection idiom + `ALL` sweep-enumerable seed +
48//! injectivity + const-reachability pins.
49//!
50//! Extension: a future edge variant (a Gateway API `HTTPRoute` /
51//! `Gateway`, a `NetworkPolicy` edge, a Cloudflare API CR, a
52//! `TCPRoute` for L4 routing) lands as ONE variant + ONE
53//! `api_version` arm + ONE `kind` arm + ONE `ALL` entry, all four
54//! exhaustively enforced by rustc's match coverage. Every downstream
55//! routing-edge consumer (the trait method, the emitted JSON, any
56//! future coherence sweep) inherits the extension mechanically
57//! through the same `RoutingEdgeResource::X.api_version()` / `.kind()`
58//! dispatch pair.
59//!
60//! Theory grounding: THEORY.md §VI.1 (generation over composition —
61//! the (apiVersion, kind) pairing recurred at six hand-authored sites
62//! past the PRIME-DIRECTIVE ≥ 2 duplication trigger, and is lifted to
63//! ONE closed-set owner per axis here). THEORY.md §II.1 invariant 5
64//! (composition preserves proofs — the two per-axis mappings live at
65//! ONE typed algebra projection apiece; a regression that drifted the
66//! apiVersion at ONE consumer would fail-loudly at this module's byte-
67//! shape pins rather than as silent trait-vs-emit skew at the
68//! reconciler wire).
69
70/// Closed set of K8s resource kinds the tatara reconciler emits as
71/// external routing edges. The two variants partition the current
72/// routing-edge surface:
73///
74/// * `Ingress` — `networking.k8s.io/v1` Ingress, backed by a Service,
75///   matched by the operator's ingress controller (nginx / Contour /
76///   HAProxy). Emitted by `IngressEdge` in
77///   `tatara-reconciler::edges`.
78/// * `DnsEndpoint` — `externaldns.k8s.io/v1alpha1` DNSEndpoint,
79///   picked up by external-dns and written to the operator's
80///   configured DNS provider (Cloudflare / Route53 / etc.). Emitted
81///   by `DnsEndpointEdge` in `tatara-reconciler::edges`.
82///
83/// Every variant carries a stable `(api_version, kind)` pair through
84/// its typed projections; both projections are `const fn` so the
85/// pair reduces to a `&'static str` slot at every callsite with no
86/// runtime overhead.
87#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
88pub enum RoutingEdgeResource {
89    Ingress,
90    DnsEndpoint,
91}
92
93impl RoutingEdgeResource {
94    /// The closed set of routing-edge resource variants this
95    /// substrate binds. Enumerable so a sweep-test (or a future
96    /// coherence check) can walk every variant without a hand-
97    /// maintained list on the caller side. A future third variant
98    /// (a Gateway API `HTTPRoute`, a `NetworkPolicy` edge) added
99    /// without an `ALL` entry surfaces at the
100    /// `all_enumerates_every_variant_exactly_once` pin.
101    pub const ALL: [Self; 2] = [Self::Ingress, Self::DnsEndpoint];
102
103    /// K8s wire-form `apiVersion` string for this routing-edge
104    /// resource variant. Matches the canonical group+version pair the
105    /// K8s / external-dns controllers expose today:
106    ///
107    /// * `Ingress`     → `networking.k8s.io/v1`
108    /// * `DnsEndpoint` → `externaldns.k8s.io/v1alpha1`
109    ///
110    /// A future controller upgrade that bumps a group's version
111    /// lands at ONE arm here; every downstream emit or fetch site
112    /// inherits the upgrade mechanically through the same
113    /// `.api_version()` call.
114    pub const fn api_version(self) -> &'static str {
115        match self {
116            Self::Ingress => "networking.k8s.io/v1",
117            Self::DnsEndpoint => "externaldns.k8s.io/v1alpha1",
118        }
119    }
120
121    /// K8s wire-form `kind` string for this routing-edge resource
122    /// variant — the PascalCase identifier the K8s API server matches
123    /// against the resource's `kind:` slot. The trait method
124    /// `Edge::kind` at each downstream impl delegates to this
125    /// projection so the diagnostic label and the emitted JSON slot
126    /// cannot drift.
127    ///
128    /// A regression that misspelled either PascalCase identifier
129    /// would silently mis-route SSA-fetch against SSA-apply (an
130    /// `Ingess` emit against an `Ingress` fetch is a 404 at wire
131    /// time); post-lift a rename lands at ONE arm here rather than
132    /// at every emit or trait-method site.
133    pub const fn kind(self) -> &'static str {
134        match self {
135            Self::Ingress => "Ingress",
136            Self::DnsEndpoint => "DNSEndpoint",
137        }
138    }
139
140    /// Project this variant onto the typed
141    /// [`crate::k8s_wire_identity::K8sWireIdentity`] pair — the
142    /// substrate primitive that owns the workspace-wide
143    /// `(apiVersion, kind)` pairing every emit or fetch site
144    /// composes against. Pre-lift the reconciler's two
145    /// `IngressEdge::render` / `DnsEndpointEdge::render` emit sites
146    /// hand-authored the pair as two adjacent `json!` slots
147    /// (`"apiVersion": RoutingEdgeResource::X.api_version(), "kind":
148    /// RoutingEdgeResource::X.kind()`) mentioning the same variant
149    /// twice; post-lift the emit site names the variant ONCE via
150    /// `.wire_identity().resource_json(json!({...}))` and the pair
151    /// binds structurally at the closed-set owner.
152    ///
153    /// `const fn` so a caller can bind the pair into a `const` slot
154    /// — sibling to [`crate::flux_resource::FluxResource::wire_identity`]
155    /// on the FluxCD wire-form axis; both project through the same
156    /// closed-set → typed-pair idiom.
157    pub const fn wire_identity(self) -> crate::k8s_wire_identity::K8sWireIdentity {
158        crate::k8s_wire_identity::K8sWireIdentity::new(self.api_version(), self.kind())
159    }
160}
161
162#[cfg(test)]
163mod tests {
164    use super::*;
165
166    #[test]
167    fn all_enumerates_every_variant_exactly_once() {
168        // A future 3rd variant added without an `ALL` entry (or a
169        // duplicate entry that skewed the sweep) surfaces here.
170        assert_eq!(RoutingEdgeResource::ALL.len(), 2);
171        // Every variant appears exactly once — no duplicates, no gaps.
172        let mut seen = std::collections::HashSet::new();
173        for v in RoutingEdgeResource::ALL {
174            assert!(seen.insert(v), "duplicate variant in ALL: {v:?}");
175        }
176    }
177
178    #[test]
179    fn ingress_api_version_is_networking_k8s_io_v1() {
180        // Byte-identity pin: the exact wire-form string every pre-lift
181        // callsite hand-authored (both `IngressEdge::render` at the
182        // json! slot and any downstream selector matching against
183        // this apiVersion). A drift that renamed the group or bumped
184        // the version at ONE site would silently mis-route the
185        // fetch-vs-apply pairing.
186        assert_eq!(
187            RoutingEdgeResource::Ingress.api_version(),
188            "networking.k8s.io/v1"
189        );
190    }
191
192    #[test]
193    fn dns_endpoint_api_version_is_externaldns_k8s_io_v1alpha1() {
194        assert_eq!(
195            RoutingEdgeResource::DnsEndpoint.api_version(),
196            "externaldns.k8s.io/v1alpha1"
197        );
198    }
199
200    #[test]
201    fn ingress_kind_is_pascalcase_ingress() {
202        assert_eq!(RoutingEdgeResource::Ingress.kind(), "Ingress");
203    }
204
205    #[test]
206    fn dns_endpoint_kind_is_pascalcase_dns_endpoint() {
207        assert_eq!(RoutingEdgeResource::DnsEndpoint.kind(), "DNSEndpoint");
208    }
209
210    #[test]
211    fn every_variants_api_version_and_kind_are_distinct_across_the_closed_set() {
212        // Cross-variant coherence pin: no two variants may share an
213        // `api_version` or a `kind`. A future extension that added a
214        // variant duplicating an existing wire-form pair (e.g. a
215        // hypothetical `IngressRoute` variant that reused the
216        // `networking.k8s.io/v1` apiVersion in a copy-paste) would
217        // surface here.
218        let mut api_versions = std::collections::HashSet::new();
219        let mut kinds = std::collections::HashSet::new();
220        for v in RoutingEdgeResource::ALL {
221            assert!(
222                api_versions.insert(v.api_version()),
223                "duplicate api_version at {v:?}: {}",
224                v.api_version()
225            );
226            assert!(
227                kinds.insert(v.kind()),
228                "duplicate kind at {v:?}: {}",
229                v.kind()
230            );
231        }
232    }
233
234    #[test]
235    fn api_version_and_kind_are_const_fn_reachable() {
236        // Compile-time reachability pin: every variant's projections
237        // are `const fn`, so a caller can bind them into a `const`
238        // slot. A regression that dropped the `const` qualifier
239        // would fail-loudly here rather than as a wrong-slot runtime
240        // dispatch at every callsite.
241        const I_AV: &str = RoutingEdgeResource::Ingress.api_version();
242        const I_K: &str = RoutingEdgeResource::Ingress.kind();
243        const D_AV: &str = RoutingEdgeResource::DnsEndpoint.api_version();
244        const D_K: &str = RoutingEdgeResource::DnsEndpoint.kind();
245        assert_eq!(I_AV, "networking.k8s.io/v1");
246        assert_eq!(I_K, "Ingress");
247        assert_eq!(D_AV, "externaldns.k8s.io/v1alpha1");
248        assert_eq!(D_K, "DNSEndpoint");
249    }
250
251    #[test]
252    fn wire_identity_pairs_api_version_and_kind_per_variant() {
253        // Projection pin: every variant's `wire_identity()` binds
254        // the SAME closed-set variant's `api_version` and `kind`
255        // into a typed pair. Peer to the sibling `FluxResource`
256        // pin — both closed sets project through the same shape,
257        // and a regression that skewed the pair at one variant
258        // (say the `DnsEndpoint` projection accidentally returned
259        // `Ingress.kind()`) would surface here rather than at the
260        // reconciler wire.
261        for v in RoutingEdgeResource::ALL {
262            let id = v.wire_identity();
263            assert_eq!(id.api_version, v.api_version());
264            assert_eq!(id.kind, v.kind());
265        }
266    }
267
268    #[test]
269    fn wire_identity_is_const_reachable() {
270        // Compile-time reachability pin: `wire_identity` is `const
271        // fn` so a caller (any emit site or future coherence sweep)
272        // can bind the pair into a `const` slot. A regression that
273        // dropped the `const` qualifier would fail-loudly here.
274        const I: crate::k8s_wire_identity::K8sWireIdentity =
275            RoutingEdgeResource::Ingress.wire_identity();
276        const D: crate::k8s_wire_identity::K8sWireIdentity =
277            RoutingEdgeResource::DnsEndpoint.wire_identity();
278        assert_eq!(I.api_version, "networking.k8s.io/v1");
279        assert_eq!(I.kind, "Ingress");
280        assert_eq!(D.api_version, "externaldns.k8s.io/v1alpha1");
281        assert_eq!(D.kind, "DNSEndpoint");
282    }
283
284    #[test]
285    fn projections_are_pure_functions_of_the_variant() {
286        // Purity pin: calling the projections repeatedly on the same
287        // variant returns byte-identical `&'static str`s. Guards
288        // against an implementation that lazily materialized an
289        // interned key per-call and hashed against runtime state.
290        for v in RoutingEdgeResource::ALL {
291            assert_eq!(v.api_version(), v.api_version());
292            assert_eq!(v.kind(), v.kind());
293        }
294    }
295}