Skip to main content

PlacedInNamespace

Trait PlacedInNamespace 

Source
pub trait PlacedInNamespace: Resource<DynamicType = ()> + Sized {
    // Provided method
    fn in_namespace(self, namespace: impl Into<String>) -> Self { ... }
}
Expand description

Substrate-primitive trait for the place-in-namespace fluent builder every consumer of a kube::Resource restated as let mut cr = <CRD>::new(name, spec); cr.meta_mut().namespace = Some(ns.into()); cr on the freshly-minted resource whose derive-supplied ::new(name, spec) constructor stamps metadata.name alone and leaves metadata.namespace at None.

Pre-lift the pattern was hand-authored across THREE tatara-owned axes past the ★★ PRIME-DIRECTIVE ≥ 2 duplication threshold:

  • tatara-reconciler::render::tests::render_through_top_level_intent_dispatch — the ONE remaining hand-authored site on the Process CRD (the sibling Process::new_in was not opened in the prior pool/allocation sweep because no Process-side pool fixture restated the pattern at ≥ 2 sites in isolation).
  • crate::pool::EphemeralPool::new_in — a per-CRD inherent composer opened in commit a5dbb26 that inlined the identical Self::new(name, spec); metadata.namespace = Some(namespace.into()) body on the EphemeralPool axis.
  • crate::allocation::EphemeralAllocation::new_in — the sister inherent composer opened in the same commit on the EphemeralAllocation axis with the byte-identical body.

Post-lift the substrate owns the metadata.namespace stamp at ONE trait method with a blanket impl over every kube::Resource<DynamicType = ()>, so:

  • The two per-CRD new_in composers forward through Self::new(name, spec).in_namespace(namespace) — three substrate copies of the mutation collapse to one. The composers keep their ergonomic per-CRD signatures so existing callers stay unchanged; only the body threads through here.
  • The tatara-reconciler::render fixture routes through Process::new(...).in_namespace(...) on the SAME trait method, closing the last hand-authored site on the tatara CRD trio.
  • Any future tatara CRD (a routing-edge object, a receipt registry, a fleet-wide claim registry) inherits the builder at its own operator-facing factory + its own test-fixture site with zero per-CRD lift work — the same solve-once discipline NamespacedApiCoordinates established for the paired coordinate extractor and DeletionTombstoned established for the deletion-tombstone probe.
  • Any K8s built-in CRD (ConfigMap, Job, Ingress) inherits the builder too — the sibling Annotated blanket already covers the same category on the annotation-read axis, so an emitter that composes a ConfigMap in a specific namespace can now write <owner-composer>().in_namespace(ns) on the SAME finished value.

Return-form axis: Self (owned, by-value) — the builder consumes self and returns the mutated value so chained composers read left-to-right as <CRD>::new(name, spec) .in_namespace(ns) in the ONE natural composition order operators reach for. Peer to the borrow-form observer Annotated::annotation on the (mutation direction × ObjectMeta-slot family) axis pair; both traits close their respective ObjectMeta-slot corners at ONE trait method with a blanket impl over the SAME kube::Resource<DynamicType = ()> bound so a future consumer that alternates between reading an annotation and stamping a namespace never sees two different trait-import spellings.

A future normalization step (a per-fleet virtual-cluster prefix rewrite on the namespace slot, a per-cluster canonical case-fold pass, an operator-scoped default namespace for cluster-local test rigs, a promotion to a typed Namespace newtype that carries K8s DNS-1123 validation as a phantom-type guard) lands at ONE substrate trait method here — every downstream consumer routed through .in_namespace(...) picks up the upgrade mechanically, and the two per-CRD new_in composers inherit it for free through their one-line forwarders.

Theory anchor: THEORY.md §II.1 invariant 5 (composition preserves proofs — the pins bind <CRD>::new(name, spec).in_namespace(ns) .metadata.namespace == Some(ns.to_string()) on every corner of the (CRD ∈ {Process, EphemeralPool, EphemeralAllocation, ConfigMap} × input form ∈ {&str, String}) input matrix PLUS the overwrite corner where .in_namespace(a).in_namespace(b) binds b, so a regression that skewed either surface surfaces at placed_in_namespace_tests::* rather than as silent operator-facing skew between the tatara-reconciler render fixture, the two per-CRD new_in composers, and any future CRD-adjacent namespace-stamping consumer). THEORY.md §VI.1 (generation over composition — the mutation recurred as three substrate copies past the ★★ PRIME-DIRECTIVE ≥ 2 duplication trigger).

Provided Methods§

Source

fn in_namespace(self, namespace: impl Into<String>) -> Self

Stamp namespace onto self.metadata.namespace and return the mutated value by-value. See the trait-level docs for the axis-family context, peer trait, and future-normalization anchor.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl<T> PlacedInNamespace for T
where T: Resource<DynamicType = ()>,