Skip to main content

namespaced

Function namespaced 

Source
pub fn namespaced<K>(client: Client, ns: &str) -> Api<K>
where K: Resource<DynamicType = (), Scope = NamespaceResourceScope>,
Expand description

Bind a namespace-scoped typed Api<K> handle from an owned Client + &str namespace for any K that satisfies the standard kube::Resource projection with a zero-sized DynamicType (every derive-generated CRD + every K8s built-in Rust binding meets this bound).

Sibling to all on the (scope × K) axis pair: all owns the cluster-scoped Api::all(<client>) shape at any K; this owns the namespace-scoped Api::namespaced(<client>, <ns>) shape at any K. Both primitives fix the scope choice structurally at the function name — a caller writes api::all(client) for the cluster-wide posture or api::namespaced(client, ns) for the namespace-scoped posture, and a regression that silently drifted one for the other (a stray Api::all where a namespace-scoped dependency lookup was intended, an Api::namespaced where a cluster-wide watch was intended) fails at the callsite’s scope-word rather than as silent operator-facing skew.

The K type parameter is inferred from the callsite’s return- type annotation (or its enclosing -> Api<K> signature). Fixed-K namespaced binders already open at crate::process_api::namespaced (K = Process) and crate::configmap::namespaced (K = ConfigMap) delegate through THIS primitive post-lift, so a future normalization of the ns-scoped Api posture (a default-injected tracing span for handle construction, a client-side QPS budget, a per-namespace retry budget, a fixture-backed client for CI/smoke- tests, a wired-in PatchParams field manager for status writes) lands at THIS ONE function and every downstream consumer inherits the upgrade mechanically.

§Pre-lift call-site history

The Api::namespaced(<client>.clone(), <ns>) chain recurred at SIX hand-authored production sites past the ★★ PRIME-DIRECTIVE ≥ 2 duplication threshold spanning four crates and five distinct K bindings — three tatara CRDs and two K8s built-ins:

  • tatara_pool_reconciler::context::PoolContext::pool_api — the namespace-scoped Api<EphemeralPool> binder every pool-side reconcile handler rides through.
  • tatara_pool_reconciler::context::PoolContext::allocation_api — the namespace-scoped Api<EphemeralAllocation> binder every pool-side reconcile handler rides through.
  • tatara_pool_reconciler::context::PoolContext::process_api — the namespace-scoped Api<Process> binder every pool-side reconcile handler rides through when it patches a bound member’s overlay.
  • tatara_github_watcher::handler::HandlerState::allocation_api — the github-watcher’s per-request namespace-scoped Api<EphemeralAllocation> binder.
  • tatara_reconciler::phase_machine::classify_export_jobs — the namespace-scoped Api<Job> binder for the export-watching Verifying-arm reconcile step.
  • tatara_process::process_api::namespaced + tatara_process::configmap::namespaced — the two fixed-K siblings already lifted (K = Process, K = ConfigMap), which now delegate through THIS primitive rather than restating Api::namespaced(client, ns) at their own bodies.

Each pre-lift site restated Api::namespaced(self.kube.clone(), ns) verbatim, with the .clone() on the ambient Client field feeding the primitive’s owned-Client slot. Post-lift each consumer reads tatara_process::api::namespaced::<K>(client, ns) (or delegates through a fixed-K sibling that itself routes here) and the ns-scoped typed-handle binding lives at ONE substrate owner across every CRD binding.

Theory anchor: THEORY.md §VI.1 (generation over composition — the 1-link Api::namespaced::<K>(<client>, <ns>) chain recurred at 6 hand-authored sites past the ★★ PRIME-DIRECTIVE ≥ 2 duplication trigger and is lifted onto the ONE workspace-wide substrate owner here). THEORY.md §II.1 invariant 5 (composition preserves proofs — the pin block below binds the primitive at fail-before-pass-after granularity, so a regression that drifted the scope slot from Api::namespaced to Api::all — silently widening a namespace-scoped dependency lookup into a cluster-wide sweep — surfaces at api::tests::* rather than as silent operator-facing skew across the six consumer sites).