fix: carry a network's fabric identity to every location it reaches - #17
Merged
Conversation
An identity required in two locations reached only one of them, so the two halves of one network were two networks on the fabric -- the exact split deriving the VPC identifier from a shared identity exists to prevent. Placement wrote one ClusterPropagationPolicy per location, each selecting identities by a location label. An identity needed in several locations carries several of those labels, so several policies select it. Karmada binds a resource to exactly one policy, so only the winner's placement took effect and the rest were silently ignored. Each identity now gets one policy that names it and lists every location it is required at, so no two policies can contend for one object. The per-location policies are swept on startup, identified by selecting without naming a resource, because they keep competing for as long as they exist. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ecv
approved these changes
Aug 27, 2026
5 tasks
privateip
approved these changes
Aug 27, 2026
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.
What was wrong
A network present in two locations had a different VPC identifier in each, so its two halves were two VPCs on the fabric with different route targets and no connectivity between them. This is the split that deriving the identifier from a shared fabric identity exists to prevent.
Seen in the staging lab:
taptestis2inus-central-1andAty7F5rGinus-east-1. The identity object exists only inus-central-1, andus-east-1has the CRD registered with no objects and no Karmada work at all.Why
Placement wrote one
ClusterPropagationPolicyper location, each selecting identities by acloud.datumapis.com/location-<location>label. An identity required in several locations carries several of those labels, so several policies select the same object. Karmada binds a resource to exactly one policy, so only one placement ever took effect and the others were silently ignored.The controller was doing its part correctly — it computed both locations and stamped both labels, and applied both policies without error. The model was the problem: carrying one object to N clusters cannot be expressed as N single-location policies, because they compete for the object instead of composing.
It only shows up once a network reaches a second location, which is why it survived until now.
What changed
namespace+name) and lists every location it is required at, via atopology.datum.net/location In [...]placement. Naming the object makes contention impossible.collectremoves that policy along with the identity, so a deleted network doesn't leave one behind.The location labels stay. Nothing selects on them now, but they remain the readable record of where an identity is needed.
Note for the rollout
This is necessary but not sufficient to align an existing split. A VPC that already has an identifier keeps it — deliberately, since renumbering renames a live VRF and moves routes under running traffic. Any VPC allocated before the fabric identity mechanism holds a legacy random value and needs a deliberate renumber; deleting the
VPCobject lets its owningNetworkContextrebuild it and re-derive.Test plan
go build,go vet, fullgo test ./...