Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
11155f0
feat: trace watchable messages
shreealt Oct 31, 2025
f66879c
license header
shreealt Oct 31, 2025
2c0d0a1
lint
shreealt Oct 31, 2025
4777f57
default traces
shreealt Oct 31, 2025
0af47d1
disability
shreealt Oct 31, 2025
c620c6e
deepcopy errors
shreealt Oct 31, 2025
aa6b91b
lint
shreealt Oct 31, 2025
2ad7399
e2e
shreealt Nov 1, 2025
f8d9f42
Merge branch 'main' of github.com:envoyproxy/gateway into feat/tracing
shreealt Nov 1, 2025
ff03fd5
doc
shreealt Nov 1, 2025
bf58e55
minor fixes
shreealt Nov 2, 2025
c0846eb
rc
shreealt Nov 2, 2025
1c5e52e
generate
shreealt Nov 2, 2025
623406e
fix coverage tests
shreealt Nov 2, 2025
fd41925
fix: e2e config
shreealt Nov 2, 2025
8392b41
runner test fix
shreealt Nov 2, 2025
934dca2
Merge branch 'main' into feat/tracing
shreealt Nov 2, 2025
fcadab2
logger
shreealt Nov 4, 2025
afc0812
mod
shreealt Nov 4, 2025
0480ec5
mod
shreealt Nov 4, 2025
8b834a9
trace config cleanup
shreealt Nov 4, 2025
8ca0a2c
lint
shreealt Nov 4, 2025
1be27d3
testing cleanup
shreealt Nov 4, 2025
37107cd
lint
shreealt Nov 4, 2025
f0ab998
snapshot cache
shreealt Nov 4, 2025
8ee0225
rename
shreealt Nov 4, 2025
0c2b09e
Merge branch 'main' of github.com:envoyproxy/gateway into feat/tracing
shreealt Nov 5, 2025
10fe843
Merge branch 'main' of github.com:envoyproxy/gateway into feat/tracing
shreealt Nov 7, 2025
3728b82
fix
shreealt Nov 7, 2025
6c9d222
Merge branch 'main' into feat/tracing
shreealt Nov 9, 2025
3d3340b
Merge branch 'main' into feat/tracing
shreealt Nov 15, 2025
d4b7eb4
revert api
shreealt Nov 15, 2025
b59ff0d
Merge branch 'feat/tracing' of github.com-work:shreealt/gateway into …
shreealt Nov 15, 2025
c4b00c1
rm type
shreealt Nov 15, 2025
58ec2e2
Merge branch 'main' into feat/tracing
shreealt Nov 16, 2025
3edaaf4
Merge branch 'main' of github.com:envoyproxy/gateway into feat/tracing
shreealt Nov 17, 2025
520a840
Merge branch 'feat/tracing' of github.com-work:shreealt/gateway into …
shreealt Nov 17, 2025
93f2ace
more spans and cleanups
shreealt Nov 21, 2025
3bf3309
lint
shreealt Nov 21, 2025
1e1322b
equal and tests
shreealt Nov 23, 2025
cd7fdd6
equal and tests
shreealt Nov 23, 2025
9836161
no otel things in translator
shreealt Nov 23, 2025
d96ac3a
review comments
shreealt Nov 27, 2025
be8f839
nil check
shreealt Nov 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ require (
go.opentelemetry.io/otel/metric v1.38.0
go.opentelemetry.io/otel/sdk v1.38.0
go.opentelemetry.io/otel/sdk/metric v1.38.0
go.opentelemetry.io/otel/trace v1.38.0
go.opentelemetry.io/proto/otlp v1.9.0
go.uber.org/zap v1.27.0
golang.org/x/exp v0.0.0-20250718183923-645b1fa84792
Expand Down Expand Up @@ -290,7 +291,6 @@ require (
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect
go.opentelemetry.io/otel/trace v1.38.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
Expand Down
8 changes: 4 additions & 4 deletions internal/admin/console/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,14 @@ func (h *Handler) loadConfigDump() ConfigDumpInfo {

if h.providerResources != nil {
// Load controller resources directly from the provider resources
controllerResources := h.providerResources.GatewayAPIResources.LoadAll()
controllerResourcesContext := h.providerResources.GatewayAPIResources.LoadAll()

for _, resources := range controllerResources {
if resources == nil {
for _, resourcesContext := range controllerResourcesContext {
if resourcesContext == nil {
continue
}

for _, res := range *resources {
for _, res := range *resourcesContext.Resources {
if res == nil {
continue
}
Expand Down
2 changes: 1 addition & 1 deletion internal/admin/console/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func TestLoadConfigDumpWithData(t *testing.T) {
// This test focuses on the basic functionality
providerRes := &message.ProviderResources{}
// Initialize empty watchable map
providerRes.GatewayAPIResources = watchable.Map[string, *resource.ControllerResources]{}
providerRes.GatewayAPIResources = watchable.Map[string, *resource.ControllerResourcesContext]{}

// Skip storing to avoid watchable copy issues
// providerResources.Store("test", providerRes)
Expand Down
5 changes: 5 additions & 0 deletions internal/cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/envoyproxy/gateway/internal/message"
"github.com/envoyproxy/gateway/internal/metrics"
providerrunner "github.com/envoyproxy/gateway/internal/provider/runner"
"github.com/envoyproxy/gateway/internal/traces"
xdsrunner "github.com/envoyproxy/gateway/internal/xds/runner"
)

Expand Down Expand Up @@ -156,6 +157,10 @@ func startRunners(ctx context.Context, cfg *config.Server) (err error) {
runners := []struct {
runner Runner
}{
{
// Start the Traces Server
runner: traces.New(cfg),
},
{
// Start the Provider Service
// It fetches the resources from the configured provider type
Expand Down
43 changes: 43 additions & 0 deletions internal/gatewayapi/resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
package resource

import (
"context"
"reflect"
"sort"

certificatesv1b1 "k8s.io/api/certificates/v1beta1"
Expand Down Expand Up @@ -208,6 +210,47 @@ func (r *Resources) GetEndpointSlicesForBackend(svcNamespace, svcName, backendKi
// ControllerResources holds all the GatewayAPI resources per GatewayClass
type ControllerResources []*Resources

// ControllerResourcesContext wraps ControllerResources with trace context
// for propagating spans across async message boundaries
type ControllerResourcesContext struct {
Resources *ControllerResources
Context context.Context
}

// DeepCopy creates a new ControllerResourcesContext.
// The Context field is preserved (not deep copied) since contexts are meant to be passed around.
func (c *ControllerResourcesContext) DeepCopy() *ControllerResourcesContext {
if c == nil {
return nil
}
var resourcesCopy *ControllerResources
if c.Resources != nil {
resourcesCopy = c.Resources.DeepCopy()
}
return &ControllerResourcesContext{
Resources: resourcesCopy,
Context: c.Context,
}
}

// Equal compares two Resources objects for equality.
func (c *ControllerResourcesContext) Equal(other *ControllerResourcesContext) bool {
if c == nil && other == nil {
return true
}
if c == nil || other == nil {
return false
}
if c.Resources == nil && other.Resources == nil {
return true
}
if c.Resources == nil || other.Resources == nil {
return false
}

return reflect.DeepEqual(c.Resources, other.Resources)
}

// DeepCopy creates a new ControllerResources.
// It is handwritten since the tooling was unable to copy into a new slice
func (c *ControllerResources) DeepCopy() *ControllerResources {
Expand Down
171 changes: 171 additions & 0 deletions internal/gatewayapi/resource/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package resource

import (
"context"
"testing"

"github.com/google/go-cmp/cmp"
Expand Down Expand Up @@ -130,6 +131,38 @@ func TestEqualXds(t *testing.T) {
}
}

func TestEqualControllerResourcesContext(t *testing.T) {
c1 := context.Background()
c2 := context.TODO()
r1 := &ControllerResourcesContext{
Resources: &ControllerResources{
{
GatewayClass: &gwapiv1.GatewayClass{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
},
},
},
},
Context: c1,
}
r2 := &ControllerResourcesContext{
Resources: &ControllerResources{
{
GatewayClass: &gwapiv1.GatewayClass{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
},
},
},
},
Context: c2,
}

assert.True(t, r1.Equal(r2))
assert.True(t, r2.Equal(r1))
}

func TestGetEndpointSlicesForBackendDualStack(t *testing.T) {
// Test data setup
dualStackService := &discoveryv1.EndpointSlice{
Expand Down Expand Up @@ -205,3 +238,141 @@ func TestGetEndpointSlicesForBackendDualStack(t *testing.T) {
}
})
}

func TestControllerResourcesContextDeepCopy(t *testing.T) {
tests := []struct {
name string
ctx *ControllerResourcesContext
}{
{
name: "nil context",
ctx: nil,
},
{
name: "empty context",
ctx: &ControllerResourcesContext{
Resources: &ControllerResources{},
Context: context.Background(),
},
},
{
name: "context with resources",
ctx: &ControllerResourcesContext{
Resources: &ControllerResources{
{
GatewayClass: &gwapiv1.GatewayClass{
ObjectMeta: metav1.ObjectMeta{
Name: "test-gateway-class",
},
},
},
},
Context: context.Background(),
},
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
copied := tc.ctx.DeepCopy()

if tc.ctx == nil {
assert.Nil(t, copied)
return
}

// Verify the copy is not nil
require.NotNil(t, copied)

// Verify the copy is a different object
assert.NotSame(t, tc.ctx, copied)

// Verify Resources are deep copied
if tc.ctx.Resources != nil {
require.NotNil(t, copied.Resources)
assert.NotSame(t, tc.ctx.Resources, copied.Resources)

// Verify the contents are equal
assert.Len(t, *copied.Resources, len(*tc.ctx.Resources))
}

// Verify Context is preserved (not deep copied, same reference)
assert.Equal(t, tc.ctx.Context, copied.Context)
})
}
}

func TestControllerResourcesDeepCopy(t *testing.T) {
tests := []struct {
name string
resources *ControllerResources
}{
{
name: "nil resources",
resources: nil,
},
{
name: "empty resources",
resources: &ControllerResources{},
},
{
name: "resources with gateway class",
resources: &ControllerResources{
{
GatewayClass: &gwapiv1.GatewayClass{
ObjectMeta: metav1.ObjectMeta{
Name: "test-gateway-class",
},
},
},
},
},
{
name: "multiple resources",
resources: &ControllerResources{
{
GatewayClass: &gwapiv1.GatewayClass{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway-class-1",
},
},
},
{
GatewayClass: &gwapiv1.GatewayClass{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway-class-2",
},
},
},
},
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
copied := tc.resources.DeepCopy()

if tc.resources == nil {
assert.Nil(t, copied)
return
}

// Verify the copy is not nil
require.NotNil(t, copied)

// Verify the copy is a different object
assert.NotSame(t, tc.resources, copied)

// Verify the length is the same
assert.Len(t, *copied, len(*tc.resources))

// Verify each resource is deep copied
for i := range *tc.resources {
if (*tc.resources)[i] != nil {
require.NotNil(t, (*copied)[i])
assert.NotSame(t, (*tc.resources)[i], (*copied)[i])
}
}
})
}
}
Loading
Loading