feat: add reverse downstream namespace lookup - #769
Draft
scotwells wants to merge 1 commit into
Draft
Conversation
Downstream clusters see resources under ns-<upstream-namespace-uid> namespaces. Consumers of downstream data — federated audit and event ingestion in particular — need the opposite direction: given a downstream namespace name, which upstream cluster and namespace does it belong to? Every such consumer was left to re-derive that from the meta.datumapis.com/* labels itself, and each one had to decide independently what to do when the answer is not known yet. Add UpstreamNamespaceResolver alongside MappedNamespaceResourceStrategy so the mapping is owned once, in both directions, with a fail-closed contract callers cannot get wrong by accident. Key changes: - UpstreamNamespaceResolver returns distinct ErrCacheNotSynced (retry) and ErrUpstreamNamespaceUnknown (terminal) errors, so a cold cache is never mistaken for an unknown tenant and misattributed - RetainingNamespaceIndex builds the index from upstream namespace informers, so no credential into the downstream cluster is required - Index entries are never removed and can be snapshotted and restored, because records about a deleted namespace must keep resolving for their full retention window - HasSynced covers every registered source and reports false when none are registered, so readiness gates on cache sync rather than on a listener being bound
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Downstream clusters hold a project's projected resources under
ns-<upstream-namespace-uid>namespaces. Anything reading that data back out needs the reverse — which upstream cluster and namespace does this belong to? Every consumer re-derives that from themeta.datumapis.com/*labels itself today, and each one independently decides what to do when the answer isn't known yet. That's the risk: "the cache hasn't synced" and "this belongs to nobody" are different claims, and a consumer that collapses them attributes a customer's data to no tenant at all — which, for anything tenant-scoped, publishes it where every operator can read it.This adds a resolver alongside the existing strategy so the mapping is owned once, in both directions, with a fail-closed contract callers can't get wrong by accident: distinct retryable and terminal errors, neither of which may be read as "attribute to the platform". The index is built from upstream namespace informers, so no credential into the downstream cluster is needed and a compromised downstream site can't influence what a namespace resolves to. Entries are never removed and can be persisted across restarts, because records about a deleted namespace must keep resolving for their full retention window. Readiness gates on cache sync rather than on a listener being bound, and an index with no registered sources reports unsynced so a misconfigured deployment fails its probe instead of silently failing every lookup closed.
Additive — no existing behaviour changes.
Note
The first consumer is edge audit ingest in milo-os/activity#229, which carries a mirrored copy of this code with a TODO to delete it. It can't import this until a Milo release contains it, since taking the module today would pull
k8s.io/kubernetesinto an aggregated API server's build graph. Merging and releasing here is what removes the duplicate.Test plan
go build ./...andgo vet ./pkg/downstreamclient/...— both exit 0go test ./pkg/downstreamclient/... -count=1— 6 tests pass/Notes for review
#627 also touches this package (
mappednamespace.go) for the controller-runtime v0.23 upgrade. No file overlap, but the new file importscontroller-runtime/pkg/cache, so whichever lands second may want a look.