Skip to content

fix: validate tracing provider completeness after EnvoyProxy merge instead of at admission - #9641

Open
kadircanyildirm-crypto wants to merge 7 commits into
envoyproxy:mainfrom
kadircanyildirm-crypto:fix/tracing-cel-strategic-merge
Open

fix: validate tracing provider completeness after EnvoyProxy merge instead of at admission#9641
kadircanyildirm-crypto wants to merge 7 commits into
envoyproxy:mainfrom
kadircanyildirm-crypto:fix/tracing-cel-strategic-merge

Conversation

@kadircanyildirm-crypto

@kadircanyildirm-crypto kadircanyildirm-crypto commented Aug 2, 2026

Copy link
Copy Markdown

What this PR does

Fixes the three merge problems that stop a per-Gateway EnvoyProxy from overriding a single tracing field (e.g. serviceName) and inheriting the rest via mergeType:

  • The host or backendRefs needs to be set CEL rule is removed from TracingProvider. Completeness is checked in processTracing after the GatewayClass-level and Gateway-level configs are merged. A provider that is still incomplete logs and skips tracing for that Gateway instead of blocking admission or provisioning.
  • The provider type and port are no longer defaulted by admission, so a partial override no longer replaces the type or port inherited from the GatewayClass level. Both still default to OpenTelemetry / 4317 during translation.
  • Telemetry backendRefs (tracing provider, accessLog and metrics sinks) inherited from the GatewayClass-level EnvoyProxy that omit a namespace are pinned to that EnvoyProxy's namespace before the merge, so they resolve where they were defined instead of in the Gateway's namespace.

Follows the approach suggested by @zirain in the issue.

Fixes #9527

Notes

  • The same CEL rule exists on the metrics sink and access log sink types; left untouched to keep this diff small — happy to follow up if wanted.
  • Developed with AI assistance (Claude Code), reviewed and understood per the contributing guide's generative AI policy.

🤖 Generated with Claude Code

@netlify

netlify Bot commented Aug 2, 2026

Copy link
Copy Markdown

Deploy Preview for cerulean-figolla-1f9435 ready!

Name Link
🔨 Latest commit 6fdac97
🔍 Latest deploy log https://app.netlify.com/projects/cerulean-figolla-1f9435/deploys/6a994428cbcb560008dc339d
😎 Deploy Preview https://deploy-preview-9641--cerulean-figolla-1f9435.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@arkodg
arkodg requested a review from zirain August 3, 2026 01:17
@codecov

codecov Bot commented Aug 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.36364% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.31%. Comparing base (3cb03be) to head (82ba8b8).

Files with missing lines Patch % Lines
internal/gatewayapi/envoyproxy_merge.go 94.11% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9641      +/-   ##
==========================================
- Coverage   81.31%   81.31%   -0.01%     
==========================================
  Files         263      263              
  Lines       40870    40911      +41     
==========================================
+ Hits        33233    33265      +32     
- Misses       7637     7646       +9     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@kadircanyildirm-crypto
kadircanyildirm-crypto marked this pull request as ready for review August 4, 2026 12:07
@kadircanyildirm-crypto
kadircanyildirm-crypto requested a review from a team as a code owner August 4, 2026 12:07
@zirain

zirain commented Aug 5, 2026

Copy link
Copy Markdown
Member

@codex review

Comment thread internal/gatewayapi/listener.go Outdated
// Validated here instead of by a CRD CEL rule so that a partial provider
// (e.g. only serviceName) can be completed by the GatewayClass-level and
// Gateway-level EnvoyProxy merge before the check runs.
if tracing.Provider.Host == nil {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

will this block the whole fleet provisioning, can we add a warning message instead of blocking it?

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4ded8cc6f1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +39 to +42
// A provider is only required to set host or backendRefs after the
// GatewayClass-level and Gateway-level EnvoyProxy configs are merged
// (see EnvoyProxySpec.MergeType), so completeness is validated during
// translation instead of by a CEL rule here.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the inherited tracing provider type

With this admission relaxation, a Gateway EnvoyProxy can now set only provider.serviceName and rely on merge to inherit the rest, but provider.type is still defaulted to OpenTelemetry before the EnvoyProxy merge. If the GatewayClass provider is Datadog or Zipkin and the Gateway override omits type, the stored override carries type: OpenTelemetry, so the merge changes the provider kind instead of only overriding serviceName; xDS generation then builds the wrong tracing provider. The merge path needs to distinguish an omitted/defaulted type from an intentional override, or this partial-provider path should not be allowed for inherited non-OpenTelemetry providers.

Useful? React with 👍 / 👎.

Comment thread internal/gatewayapi/listener.go Outdated
Comment on lines +997 to +999
// Validated here instead of by a CRD CEL rule so that a partial provider
// (e.g. only serviceName) can be completed by the GatewayClass-level and
// Gateway-level EnvoyProxy merge before the check runs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Resolve inherited backendRefs in their source namespace

This new partial-provider path is documented as being completed by the GatewayClass/Gateway EnvoyProxy merge, but inherited backendRefs with no explicit namespace are later resolved relative to the merged EnvoyProxy's namespace. When a Gateway override now sets only serviceName and inherits a GatewayClass provider whose backendRef omits namespace, the merged object has the Gateway-level EnvoyProxy namespace, so the collector is looked up in the Gateway namespace and the Gateway is marked invalid even though the class-level reference was valid. Preserve the source EnvoyProxy namespace for inherited refs or rewrite/default namespaces during merge.

Useful? React with 👍 / 👎.

@kadircanyildirm-crypto
kadircanyildirm-crypto force-pushed the fix/tracing-cel-strategic-merge branch from 4ded8cc to 1e85b90 Compare August 6, 2026 08:12
@kadircanyildirm-crypto

Copy link
Copy Markdown
Author

Rebased onto current main, no content change.

The red checks on the previous run were not from this PR. BackendTLSPolicySANValidation fails the same way on main (run 31067661691), osv-scan was flagging dependency versions that main has since bumped, and the five e2e jobs each failed on a different unrelated test (MultipleGC, PreserveCase, WeightedRoute, OIDC, RateLimitGlobalSharedCidrMatch). None of those configure tracing, so processTracing never runs for them.

@zirain this is ready whenever you have time.

@kadircanyildirm-crypto

Copy link
Copy Markdown
Author

@zirain switched to a warning — an incomplete provider now logs and skips tracing for that Gateway instead of setting Accepted=False, so provisioning is not blocked.

Codex's two findings are both real. I reproduced them with the exact config from #9527: class proxy with type: Datadog and backendRefs in envoy-gateway-system, Gateway proxy in app-ns overriding only serviceName. The merged result is:

mergedNamespace="app-ns"  type="OpenTelemetry"  serviceName="my-custom-service"  backendRefs=1
backendRef namespace=<nil>

type is +kubebuilder:default=OpenTelemetry with no omitempty, so it is always present in the merge patch and replaces Datadog; and the merged proxy carries the Gateway proxy's namespace, so the inherited backendRef is looked up in app-ns instead of envoy-gateway-system. Relaxing the CEL rule alone does not make the issue's own example work.

Do you want the type fix in this PR (make it optional and default it during translation), and the namespace one as a separate PR since it applies to accessLog and metrics backendRefs too?

@zirain zirain added this to the v1.9.0-rc.1 Release milestone Aug 6, 2026
@arkodg arkodg modified the milestones: v1.9.0 Release, Backlog Aug 14, 2026
@kadircanyildirm-crypto

Copy link
Copy Markdown
Author

/retest

@zirain
zirain force-pushed the fix/tracing-cel-strategic-merge branch from 14f4852 to ac71f9f Compare August 21, 2026 01:07
@zirain

zirain commented Aug 21, 2026

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ac71f9fdf3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +39 to +43
// A provider is only required to set host or backendRefs after the
// GatewayClass-level and Gateway-level EnvoyProxy configs are merged
// (see EnvoyProxySpec.MergeType), so completeness is checked during
// translation instead of by a CEL rule here. A provider that is still
// incomplete after the merge turns tracing off for that Gateway.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the inherited tracing port

When a Gateway override supplies only serviceName, admission also materializes the provider's port default of 4317, so both StrategicMerge and JSONMerge treat that value as an explicit override. Consequently, a GatewayClass OpenTelemetry provider using host with a custom port such as 4318 is completed by the merge but silently redirected to port 4317. The partial-provider path needs to distinguish the defaulted port from an intentional override, just as it must for other defaulted provider fields.

Useful? React with 👍 / 👎.

@kadircanyildirm-crypto

Copy link
Copy Markdown
Author

Went ahead with the type fix in this PR after all, since Codex's new finding is the same defect on port — both were non-pointer fields with a kubebuilder default, so admission materialized them and neither StrategicMerge nor JSONMerge could tell them apart from an explicit override.

Both are optional now and default during translation instead (OpenTelemetry / 4317, unchanged). The openTelemetry CEL rule tolerates an absent type, and the xDS translator resolves the default again so an IR built without an explicit provider type still works.

The backendRef-namespace finding is still not addressed here — it applies to accessLog and metrics backendRefs too, so it still looks like a separate PR to me.

@zirain if you would rather see the type/port change split out of this PR, say so and I will pull it into its own.

@zirain

zirain commented Aug 21, 2026

Copy link
Copy Markdown
Member

is it possible fix all merge issue in one PR? if so, prefer to see them happen here.

@arkodg
arkodg requested a review from zirain August 24, 2026 04:53
@zirain zirain modified the milestones: Backlog, v1.10.0-rc.1 Release Aug 25, 2026
@kadircanyildirm-crypto

Copy link
Copy Markdown
Author

@zirain sorry for the slow reply. Yes, I will fix the backendRef namespace issue here as well.

Plan: before the merge, stamp the GatewayClass EnvoyProxy's namespace onto its telemetry backendRefs that do not set one (tracing, accessLog and metrics sinks), so inherited refs keep resolving where they were defined. Will rebase onto main and push shortly.

@kadircanyildirm-crypto
kadircanyildirm-crypto force-pushed the fix/tracing-cel-strategic-merge branch from f0fff20 to 82ba8b8 Compare September 2, 2026 23:07
@kadircanyildirm-crypto

Copy link
Copy Markdown
Author

@zirain pushed. Inherited telemetry backendRefs are now pinned to the GatewayClass EnvoyProxy's namespace before the merge; the fixture reproduces the exact config from #9527. Rebased onto main.

@zirain

zirain commented Sep 3, 2026

Copy link
Copy Markdown
Member
Summary
Commit sha: [b2b9001](https://github.com/envoyproxy/gateway/pull/9641/commits/b2b9001c316b7f67ac32663daa05065f1a17d489), Author: Kadir Can Yildirim, Committer: Kadir Can Yildirim; The sign-off is missing.
Commit sha: [64cf3f3](https://github.com/envoyproxy/gateway/pull/9641/commits/64cf3f37e9310637778fcf27d5e74b24f3d9b925), Author: Kadir Can Yildirim, Committer: Kadir Can Yildirim; The sign-off is missing.
Commit sha: [82ba8b8](https://github.com/envoyproxy/gateway/pull/9641/commits/82ba8b8d6ccc6ff428b20d962a0e224ce75e0242), Author: Kadir Can Yildirim, Committer: Kadir Can Yildirim; The sign-off is missing.

Drop the 'host or backendRefs needs to be set' CEL rule from
TracingProvider so a per-Gateway EnvoyProxy can override a single
field (e.g. serviceName) and inherit the rest via mergeType. The
completeness check now runs in processTracing after the
GatewayClass-level and Gateway-level configs are merged, surfacing
an InvalidParameters Gateway condition instead of an admission error.

Fixes envoyproxy#9527

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Kadir Can Yildirim <252162627+kadircanyildirm-crypto@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Kadir Can Yildirim <252162627+kadircanyildirm-crypto@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Kadir Can Yildirim <252162627+kadircanyildirm-crypto@users.noreply.github.com>
An incomplete tracing provider now turns tracing off for that Gateway
instead of setting Accepted=False, so an observability misconfiguration
does not stop the proxy from being provisioned.

Signed-off-by: Kadir Can Yildirim <252162627+kadircanyildirm-crypto@users.noreply.github.com>
A Gateway-level EnvoyProxy that overrides only part of the tracing
provider still had `type` and `port` materialized by admission, because
both carried a kubebuilder default. Once those values are stored they are
indistinguishable from an explicit override, so StrategicMerge and
JSONMerge replaced the type and port inherited from the GatewayClass
level: a Datadog provider became OpenTelemetry, and an OpenTelemetry
provider on a custom port such as 4318 was redirected to 4317.

Both fields are now optional, and the defaults are applied during
translation instead, where the merge has already happened. The defaults
themselves are unchanged (OpenTelemetry and 4317) and live next to the
type as DefaultTracingProviderType and DefaultTracingProviderPort.

The openTelemetry CEL rule is relaxed to tolerate an absent type, and the
xDS translator resolves the default again so an IR built without an
explicit provider type keeps working.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Kadir Can Yildirim <252162627+kadircanyildirm-crypto@users.noreply.github.com>
main now rejects ptr.To through forbidigo in favour of the new(expr)
builtin, so the tracing provider defaults and their tests follow suit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbWe5JJNQYR3HvVFAPheNP
Signed-off-by: Kadir Can Yildirim <252162627+kadircanyildirm-crypto@users.noreply.github.com>
…re defined in

The merged EnvoyProxy carries the Gateway-level object's metadata, so a
backendRef inherited from the GatewayClass-level EnvoyProxy without an
explicit namespace was looked up in the Gateway's namespace, and the
Gateway was marked invalid even though the class-level reference was
valid. This affected the tracing provider as well as the accessLog and
metrics sinks.

Before merging, every telemetry backendRef of the base EnvoyProxy that
omits a namespace is now set to the base's own namespace, which is where
it resolves when that EnvoyProxy is used on its own. Refs written on the
Gateway-level EnvoyProxy are untouched and keep resolving in the
Gateway's namespace. The shared GatewayClass object is not modified; a
copy is merged instead.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbWe5JJNQYR3HvVFAPheNP
Signed-off-by: Kadir Can Yildirim <252162627+kadircanyildirm-crypto@users.noreply.github.com>
@kadircanyildirm-crypto
kadircanyildirm-crypto force-pushed the fix/tracing-cel-strategic-merge branch from 82ba8b8 to 6fdac97 Compare September 3, 2026 09:55
// +kubebuilder:default=OpenTelemetry
Type TracingProviderType `json:"type"`
// +optional
Type *TracingProviderType `json:"type,omitempty"`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

let's do this first in a seperated PR, WDYT?

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.

EnvoyProxy CRD validation blocks per-Gateway tracing overrides that rely on merged backendRefs

4 participants