Skip to content

Conversation

@mohit-pal-kohli
Copy link

Part 1 of implementing explicit wildcard support for xds-control-plane.

Context

We leverage the Snapshot Cache in go-control-plane, where delta for a node ID snapshot is proliferated to Envoys with that node ID when there is a change. This is acceptable in the current state where Fabric Proxy declares the destinations (clusters) it needs at start time in YAML.

The introduction of ODCDS makes the current state unpalatable, even though it is functional. The issue is that we do not want a mass proliferation of new clusters to all Envoys with node ID X when one pod with that node ID X requests a resource. Not solving this could create significant load on our control plane, especially for Fabric Proxy users with hundreds or thousands of destinations.

To solve this, we should add support for resource-level wildcard support for control plane. By default, a snapshot resource will be considered wildcard (OnDemandOnly = false) and proliferated to all Envoys with the relevant node ID. By contrast, we will allow certain resources to not be wildcard, allowing ODCDS clusters to only be proliferated on demand.

Implementation details

This PR aims to make changes in a way that are fully backward compatible for Delta and SoTW. Users using the deprecated cache will have all resources default to wildcard-eligible. Users using the new cache will be able to specify OnDemandOnly. If not specified, then OnDemandOnly=false, meaning that the resource is wildcard-eligible.

snapshot, _ := types.NewSnapshot("v1", map[string][]types.SnapshotResource{
    resource.ClusterType: {
        // Wildcard-eligible: Default case
        {
            Name: "core-service",
            Resource: &cluster.Cluster{Name: "core-service"},
        },
        // Wildcard-eligible: Explicitly defined
        {
            Name: "core-service",
            Resource: &cluster.Cluster{Name: "core-service"},
            OnDemandOnly: false,
        },
        // On-demand only: sent only when explicitly requested
        {
            Name: "analytics-cluster",
            Resource: &cluster.Cluster{Name: "analytics-cluster"},
            OnDemandOnly: true,
        },
    },
})

@mohit-pal-kohli mohit-pal-kohli self-assigned this Dec 3, 2025
@mohit-pal-kohli mohit-pal-kohli requested review from a team and valerian-roche December 3, 2025 20:52
@mohit-pal-kohli mohit-pal-kohli requested a review from a team December 4, 2025 21:44
Copy link

@zhiyanfoo zhiyanfoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM mostly some nits

// cacheVersion is the version of the cache at the time of last update, used in sotw.
cacheVersion string

// onDemandOnly indicates if this resource is only sent when explicitly requested (ODCDS support).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove reference to the ODCDS part. As Valerian mentioned this could apply to Listeners as well.

Suggested change
// onDemandOnly indicates if this resource is only sent when explicitly requested (ODCDS support).
// onDemandOnly indicates if this resource is only sent when explicitly requested: for example when performing ODCDS (on-demand cluster discovery).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair - Making it more use case agnostic is probably better for when we upstream this.

return func(r *CachedResource) { r.ttl = ttl }
}

// OnDemandOnly marks the resource as on-demand only (for ODCDS support).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// OnDemandOnly marks the resource as on-demand only (for ODCDS support).
// OnDemandOnly marks the resource as on-demand only

resourcesToReturn = make(map[string]*internal.CachedResource, len(resources))
for _, res := range resources {
addResource(res)
// Include wildcard-eligible resources for wildcard subscriptions (ODCDS support)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Include wildcard-eligible resources for wildcard subscriptions (ODCDS support)
// Include wildcard-eligible resources for wildcard subscriptions

_, known := knownResources[name]
if known {
for name, res := range resources {
// Include wildcard-eligible resources for wildcard subscriptions (ODCDS support)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Include wildcard-eligible resources for wildcard subscriptions (ODCDS support)
// Include wildcard-eligible resources for wildcard subscriptions

}

if watch.subscription.IsWildcard() {
if watch.subscription.IsWildcard() && !res.OnDemandOnly() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if watch.subscription.IsWildcard() && !res.OnDemandOnly() {
// the only case where we can keep a resource if it's a not explicitly subscribed is when we are a wildcard subscription and the resource is also a wildcard resource.
if watch.subscription.IsWildcard() && !res.OnDemandOnly() {

for _, res := range resources {
if err := addIfChanged(res); err != nil {
return nil, fmt.Errorf("failed to compute resource version for %s: %w", res.Name, err)
// Include wildcard-eligible resources for wildcard subscriptions (ODCDS support)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Include wildcard-eligible resources for wildcard subscriptions (ODCDS support)
// Include wildcard-eligible resources for wildcard subscriptions

for name, resource := range resources {
resourcesToReturn = append(resourcesToReturn, resource)
returnedResources[name] = version
// Include wildcard-eligible resources for wildcard subscriptions (ODCDS support)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Include wildcard-eligible resources for wildcard subscriptions (ODCDS support)
// Include wildcard-eligible resources for wildcard subscriptions

continue
}

if watch.subscription.IsWildcard() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can do the same pattern here as for the delta wildcard requests

Suggested change
if watch.subscription.IsWildcard() {
// the only case where we can keep a resource if it's a not explicitly subscribed is when we are a wildcard subscription and the resource is also a wildcard resource.
if watch.subscription.IsWildcard() && !res.OnDemandOnly() {

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch, updating

@mohit-pal-kohli mohit-pal-kohli changed the base branch from vr/snapshot-v2 to vr/delta-resource December 5, 2025 19:46
@valerian-roche
Copy link

valerian-roche commented Dec 7, 2025

@mohit-pal-kohli can you rebase the PR on the upstream branches and confirm when tested?
I raised envoyproxy#1356 for the first branch

@mohit-pal-kohli mohit-pal-kohli changed the base branch from vr/delta-resource to main December 22, 2025 18:28
@mohit-pal-kohli mohit-pal-kohli merged commit 611973d into main Dec 22, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants