diff --git a/examples/kubernetes/accesslog/otel-accesslog.yaml b/examples/kubernetes/accesslog/otel-accesslog.yaml index d4a8f4948de..f2d1b8d86d3 100644 --- a/examples/kubernetes/accesslog/otel-accesslog.yaml +++ b/examples/kubernetes/accesslog/otel-accesslog.yaml @@ -19,14 +19,16 @@ spec: telemetry: accessLog: settings: - - format: - type: Text - text: | - [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" - sinks: - - type: OpenTelemetry - openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 - resources: - k8s.cluster.name: "cluster-1" + - format: + type: Text + text: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + sinks: + - type: OpenTelemetry + openTelemetry: + backendRefs: + - name: otel-collector + namespace: monitoring + port: 4317 + resources: + k8s.cluster.name: "cluster-1" diff --git a/examples/kubernetes/tracing/default.yaml b/examples/kubernetes/tracing/default.yaml index ea6caf143e8..c522a93ef77 100644 --- a/examples/kubernetes/tracing/default.yaml +++ b/examples/kubernetes/tracing/default.yaml @@ -21,8 +21,10 @@ spec: # sample 100% of requests samplingRate: 100 provider: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + backendRefs: + - name: otel-collector + namespace: monitoring + port: 4317 type: OpenTelemetry customTags: # This is an example of using a literal as a tag value diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go index bab7c4c17c2..d896eb26b9f 100644 --- a/internal/gatewayapi/listener.go +++ b/internal/gatewayapi/listener.go @@ -8,14 +8,15 @@ package gatewayapi import ( "fmt" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/ir" "github.com/envoyproxy/gateway/internal/utils" "github.com/envoyproxy/gateway/internal/utils/naming" - "github.com/envoyproxy/gateway/internal/utils/net" ) var _ ListenersTranslator = (*Translator)(nil) @@ -43,7 +44,8 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap if resources.EnvoyProxy != nil { infraIR[irKey].Proxy.Config = resources.EnvoyProxy } - t.processProxyObservability(gateway.Gateway, xdsIR[irKey], infraIR[irKey].Proxy.Config) + + t.processProxyObservability(gateway.Gateway, xdsIR[irKey], infraIR[irKey].Proxy.Config, resources) for _, listener := range gateway.listeners { // Process protocol & supported kinds @@ -127,10 +129,10 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap } } -func (t *Translator) processProxyObservability(gw *gwapiv1.Gateway, xdsIR *ir.Xds, envoyProxy *egv1a1.EnvoyProxy) { - xdsIR.AccessLog = processAccessLog(envoyProxy) - xdsIR.Tracing = processTracing(gw, envoyProxy, t.MergeGateways) - xdsIR.Metrics = processMetrics(envoyProxy) +func (t *Translator) processProxyObservability(gw *gwapiv1.Gateway, xdsIR *ir.Xds, envoyProxy *egv1a1.EnvoyProxy, resources *Resources) { + xdsIR.AccessLog = t.processAccessLog(gw, envoyProxy, resources) + xdsIR.Tracing = t.processTracing(gw, envoyProxy, resources) + xdsIR.Metrics = t.processMetrics(envoyProxy) } func (t *Translator) processInfraIRListener(listener *ListenerContext, infraIR InfraIRMap, irKey string, servicePort *protocolPort) { @@ -163,7 +165,7 @@ func (t *Translator) processInfraIRListener(listener *ListenerContext, infraIR I infraIR[irKey].Proxy.Listeners = append(infraIR[irKey].Proxy.Listeners, proxyListener) } -func processAccessLog(envoyproxy *egv1a1.EnvoyProxy) *ir.AccessLog { +func (t *Translator) processAccessLog(gw *gwapiv1.Gateway, envoyproxy *egv1a1.EnvoyProxy, resources *Resources) *ir.AccessLog { if envoyproxy == nil || envoyproxy.Spec.Telemetry == nil || envoyproxy.Spec.Telemetry.AccessLog == nil || @@ -185,7 +187,7 @@ func processAccessLog(envoyproxy *egv1a1.EnvoyProxy) *ir.AccessLog { irAccessLog := &ir.AccessLog{} // translate the access log configuration to the IR for _, accessLog := range envoyproxy.Spec.Telemetry.AccessLog.Settings { - for _, sink := range accessLog.Sinks { + for index, sink := range accessLog.Sinks { switch sink.Type { case egv1a1.ProxyAccessLogSinkTypeFile: if sink.File == nil { @@ -216,18 +218,31 @@ func processAccessLog(envoyproxy *egv1a1.EnvoyProxy) *ir.AccessLog { continue } - // TODO: remove support for Host/Port in v1.2 al := &ir.OpenTelemetryAccessLog{ - Port: uint32(sink.OpenTelemetry.Port), Resources: sink.OpenTelemetry.Resources, + Destination: ir.RouteDestination{ + Name: fmt.Sprintf("accesslog/%s/%s/sink/%d", gw.Namespace, gw.Name, index), + Settings: make([]*ir.DestinationSetting, 0, len(sink.OpenTelemetry.BackendRefs)), + }, } - if sink.OpenTelemetry.Host != nil { - al.Host = *sink.OpenTelemetry.Host + for _, backendRef := range sink.OpenTelemetry.BackendRefs { + al.Destination.Settings = append(al.Destination.Settings, t.processServiceDestination(backendRef, ir.GRPC, envoyproxy, resources)) } - if len(sink.OpenTelemetry.BackendRefs) > 0 { - al.Host, al.Port = net.BackendHostAndPort(sink.OpenTelemetry.BackendRefs[0].BackendObjectReference, envoyproxy.Namespace) + // TODO: remove support for Host/Port in v1.2 + if sink.OpenTelemetry.Host != nil { + al.Destination.Settings = append(al.Destination.Settings, &ir.DestinationSetting{ + Weight: ptr.To(uint32(1)), + Protocol: ir.GRPC, + Endpoints: []*ir.DestinationEndpoint{ + { + Port: uint32(sink.OpenTelemetry.Port), + Host: *sink.OpenTelemetry.Host, + }, + }, + AddressType: ptr.To(ir.FQDN), + }) } switch accessLog.Format.Type { @@ -245,44 +260,55 @@ func processAccessLog(envoyproxy *egv1a1.EnvoyProxy) *ir.AccessLog { return irAccessLog } -func processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.EnvoyProxy, mergeGateways bool) *ir.Tracing { +func (t *Translator) processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.EnvoyProxy, resources *Resources) *ir.Tracing { if envoyproxy == nil || envoyproxy.Spec.Telemetry == nil || envoyproxy.Spec.Telemetry.Tracing == nil { return nil } + tracing := envoyproxy.Spec.Telemetry.Tracing + tr := &ir.Tracing{ + ServiceName: naming.ServiceName(utils.NamespacedName(gw)), + SamplingRate: 100.0, + CustomTags: tracing.CustomTags, + Destination: ir.RouteDestination{ + Name: fmt.Sprintf("tracing/%s/%s", gw.Namespace, gw.Name), + Settings: make([]*ir.DestinationSetting, 0, len(tracing.Provider.BackendRefs)), + }, + } + + for _, backendRef := range tracing.Provider.BackendRefs { + tr.Destination.Settings = append(tr.Destination.Settings, t.processServiceDestination(backendRef, ir.GRPC, envoyproxy, resources)) + } // TODO: remove support for Host/Port in v1.2 - var host string - var port uint32 if tracing.Provider.Host != nil { - host, port = *tracing.Provider.Host, uint32(tracing.Provider.Port) - } - if len(tracing.Provider.BackendRefs) > 0 { - host, port = net.BackendHostAndPort(tracing.Provider.BackendRefs[0].BackendObjectReference, gw.Namespace) + tr.Destination.Settings = append(tr.Destination.Settings, &ir.DestinationSetting{ + Weight: ptr.To(uint32(1)), + Protocol: ir.GRPC, + Endpoints: []*ir.DestinationEndpoint{ + { + Port: uint32(tracing.Provider.Port), + Host: *tracing.Provider.Host, + }, + }, + AddressType: ptr.To(ir.FQDN), + }) } - samplingRate := 100.0 if tracing.SamplingRate != nil { - samplingRate = float64(*tracing.SamplingRate) + tr.SamplingRate = float64(*tracing.SamplingRate) } - serviceName := naming.ServiceName(utils.NamespacedName(gw)) - if mergeGateways { - serviceName = string(gw.Spec.GatewayClassName) + if t.MergeGateways { + tr.ServiceName = string(gw.Spec.GatewayClassName) } - return &ir.Tracing{ - ServiceName: serviceName, - Host: host, - Port: port, - SamplingRate: samplingRate, - CustomTags: tracing.CustomTags, - } + return tr } -func processMetrics(envoyproxy *egv1a1.EnvoyProxy) *ir.Metrics { +func (t *Translator) processMetrics(envoyproxy *egv1a1.EnvoyProxy) *ir.Metrics { if envoyproxy == nil || envoyproxy.Spec.Telemetry == nil || envoyproxy.Spec.Telemetry.Metrics == nil { @@ -293,3 +319,45 @@ func processMetrics(envoyproxy *egv1a1.EnvoyProxy) *ir.Metrics { EnablePerEndpointStats: envoyproxy.Spec.Telemetry.Metrics.EnablePerEndpointStats, } } + +func (t *Translator) processServiceDestination(backendRef egv1a1.BackendRef, protocol ir.AppProtocol, envoyproxy *egv1a1.EnvoyProxy, resources *Resources) *ir.DestinationSetting { + var ( + endpoints []*ir.DestinationEndpoint + addrType *ir.DestinationAddressType + servicePort v1.ServicePort + backendTLS *ir.TLSUpstreamConfig + ) + + // TODO (davidalger) Handle case where Service referenced by backendRef doesn't exist + serviceNamespace := NamespaceDerefOr(backendRef.Namespace, envoyproxy.Namespace) + service := resources.GetService(serviceNamespace, string(backendRef.Name)) + for _, port := range service.Spec.Ports { + if port.Port == int32(*backendRef.Port) { + servicePort = port + break + } + } + + if servicePort.AppProtocol != nil && + *servicePort.AppProtocol == "kubernetes.io/h2c" { + protocol = ir.HTTP2 + } + + // Route to endpoints by default + if !t.EndpointRoutingDisabled { + endpointSlices := resources.GetEndpointSlicesForBackend(serviceNamespace, string(backendRef.Name), KindDerefOr(backendRef.Kind, KindService)) + endpoints, addrType = getIREndpointsFromEndpointSlices(endpointSlices, servicePort.Name, servicePort.Protocol) + } else { + // Fall back to Service ClusterIP routing + ep := ir.NewDestEndpoint(service.Spec.ClusterIP, uint32(*backendRef.Port)) + endpoints = append(endpoints, ep) + } + + return &ir.DestinationSetting{ + Weight: ptr.To(uint32(1)), + Protocol: protocol, + Endpoints: endpoints, + AddressType: addrType, + TLS: backendTLS, + } +} diff --git a/internal/gatewayapi/listener_test.go b/internal/gatewayapi/listener_test.go index 1da6638f9a8..2e47b5791c0 100644 --- a/internal/gatewayapi/listener_test.go +++ b/internal/gatewayapi/listener_test.go @@ -9,7 +9,10 @@ import ( "testing" "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + discoveryv1 "k8s.io/api/discovery/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/utils/ptr" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" @@ -19,11 +22,11 @@ import ( func TestProcessTracing(t *testing.T) { cases := []struct { - gw gwapiv1.Gateway - proxy *egcfgv1a1.EnvoyProxy - mergedgw bool - - expected *ir.Tracing + gw gwapiv1.Gateway + proxy *egcfgv1a1.EnvoyProxy + resources Resources + translator Translator + expected *ir.Tracing }{ {}, { @@ -34,6 +37,10 @@ func TestProcessTracing(t *testing.T) { }, }, proxy: &egcfgv1a1.EnvoyProxy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-ep", + Namespace: "fake-ns", + }, Spec: egcfgv1a1.EnvoyProxySpec{ Telemetry: &egcfgv1a1.ProxyTelemetry{ Tracing: &egcfgv1a1.ProxyTracing{}, @@ -43,6 +50,10 @@ func TestProcessTracing(t *testing.T) { expected: &ir.Tracing{ ServiceName: "fake-gw.fake-ns", SamplingRate: 100.0, + Destination: ir.RouteDestination{ + Name: "tracing/fake-ns/fake-gw", + Settings: []*ir.DestinationSetting{}, + }, }, }, { @@ -62,10 +73,16 @@ func TestProcessTracing(t *testing.T) { }, }, }, - mergedgw: true, + translator: Translator{ + MergeGateways: true, + }, expected: &ir.Tracing{ ServiceName: "fake-gateway-class", SamplingRate: 100.0, + Destination: ir.RouteDestination{ + Name: "tracing/fake-ns/fake-gw", + Settings: []*ir.DestinationSetting{}, + }, }, }, { @@ -76,6 +93,10 @@ func TestProcessTracing(t *testing.T) { }, }, proxy: &egcfgv1a1.EnvoyProxy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-access-log", + Namespace: "envoy-gateway-system", + }, Spec: egcfgv1a1.EnvoyProxySpec{ Telemetry: &egcfgv1a1.ProxyTelemetry{ Tracing: &egcfgv1a1.ProxyTracing{ @@ -90,8 +111,22 @@ func TestProcessTracing(t *testing.T) { expected: &ir.Tracing{ ServiceName: "fake-gw.fake-ns", SamplingRate: 100.0, - Host: "fake-host", - Port: 4317, + Destination: ir.RouteDestination{ + Name: "tracing/fake-ns/fake-gw", + Settings: []*ir.DestinationSetting{ + { + Weight: ptr.To[uint32](1), + Protocol: ir.GRPC, + Endpoints: []*ir.DestinationEndpoint{ + { + Host: "fake-host", + Port: 4317, + }, + }, + AddressType: ptr.To(ir.FQDN), + }, + }, + }, }, }, { @@ -110,8 +145,6 @@ func TestProcessTracing(t *testing.T) { Telemetry: &egcfgv1a1.ProxyTelemetry{ Tracing: &egcfgv1a1.ProxyTracing{ Provider: egcfgv1a1.TracingProvider{ - Host: ptr.To("fake-host"), - Port: 4317, BackendRefs: []egcfgv1a1.BackendRef{ { BackendObjectReference: gwapiv1.BackendObjectReference{ @@ -125,47 +158,78 @@ func TestProcessTracing(t *testing.T) { }, }, }, - expected: &ir.Tracing{ - ServiceName: "fake-gw.fake-ns", - SamplingRate: 100.0, - Host: "fake-name.fake-ns.svc", - Port: 4317, - }, - }, - { - gw: gwapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Name: "fake-gw", - Namespace: "fake-ns", - }, - }, - proxy: &egcfgv1a1.EnvoyProxy{ - ObjectMeta: metav1.ObjectMeta{ - Name: "fake-eproxy", - Namespace: "fake-ns", - }, - Spec: egcfgv1a1.EnvoyProxySpec{ - Telemetry: &egcfgv1a1.ProxyTelemetry{ - Tracing: &egcfgv1a1.ProxyTracing{ - Provider: egcfgv1a1.TracingProvider{ - BackendRefs: []egcfgv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-name", - Port: PortNumPtr(4317), - }, - }, + resources: Resources{ + Services: []*corev1.Service{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-name", + Namespace: "fake-ns", + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Name: "otlp", + Port: 4317, + TargetPort: intstr.IntOrString{IntVal: 4317}, + Protocol: corev1.ProtocolTCP, }, }, }, }, }, + EndpointSlices: []*discoveryv1.EndpointSlice{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-name-1", + Namespace: "fake-ns", + Labels: map[string]string{ + discoveryv1.LabelServiceName: "fake-name", + }, + }, + AddressType: discoveryv1.AddressTypeIPv4, + Endpoints: []discoveryv1.Endpoint{ + { + Addresses: []string{"1.2.3.4"}, + Conditions: discoveryv1.EndpointConditions{Ready: ptr.To(true)}, + }, + { + Addresses: []string{"2.3.4.5"}, + Conditions: discoveryv1.EndpointConditions{Ready: ptr.To(true)}, + }, + }, + Ports: []discoveryv1.EndpointPort{ + { + Name: ptr.To("otlp"), + Port: ptr.To[int32](4317), + Protocol: ptr.To(corev1.ProtocolTCP), + }, + }, + }, + }, }, expected: &ir.Tracing{ ServiceName: "fake-gw.fake-ns", SamplingRate: 100.0, - Host: "fake-name.fake-ns.svc", - Port: 4317, + Destination: ir.RouteDestination{ + Name: "tracing/fake-ns/fake-gw", + Settings: []*ir.DestinationSetting{ + { + Weight: ptr.To[uint32](1), + Protocol: ir.GRPC, + Endpoints: []*ir.DestinationEndpoint{ + { + Host: "1.2.3.4", + Port: 4317, + }, + { + Host: "2.3.4.5", + Port: 4317, + }, + }, + AddressType: ptr.To(ir.IP), + }, + }, + }, }, }, } @@ -173,7 +237,7 @@ func TestProcessTracing(t *testing.T) { for _, c := range cases { c := c t.Run("", func(t *testing.T) { - got := processTracing(&c.gw, c.proxy, c.mergedgw) + got := c.translator.processTracing(&c.gw, c.proxy, &c.resources) assert.Equal(t, c.expected, got) }) } @@ -181,10 +245,10 @@ func TestProcessTracing(t *testing.T) { func TestProcessMetrics(t *testing.T) { cases := []struct { - name string - proxy *egcfgv1a1.EnvoyProxy - - expected *ir.Metrics + name string + proxy *egcfgv1a1.EnvoyProxy + translator Translator + expected *ir.Metrics }{ { name: "nil proxy config", @@ -222,7 +286,7 @@ func TestProcessMetrics(t *testing.T) { } for _, c := range cases { t.Run(c.name, func(t *testing.T) { - got := processMetrics(c.proxy) + got := c.translator.processMetrics(c.proxy) assert.Equal(t, c.expected, got) }) } diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.in.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.in.yaml index 4dccf1a36d3..e589b3fc2e2 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.in.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.in.yaml @@ -87,3 +87,33 @@ gateways: allowedRoutes: namespaces: from: Same +services: +- apiVersion: v1 + kind: Service + metadata: + namespace: monitoring + name: otel-collector + spec: + ports: + - name: otlp + port: 4317 + protocol: TCP + targetPort: 4317 +endpointSlices: +- apiVersion: discovery.k8s.io/v1 + kind: EndpointSlice + metadata: + name: otel-collector-1 + namespace: monitoring + labels: + kubernetes.io/service-name: otel-collector + addressType: IPv4 + ports: + - name: otlp + protocol: TCP + port: 4317 + endpoints: + - addresses: + - "1.2.3.4" + conditions: + ready: true diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.out.yaml index 265b1a19887..39527963b31 100755 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.out.yaml @@ -136,8 +136,15 @@ xdsIR: envoy-gateway/gateway-1: accessLog: openTelemetry: - - host: otel-collector.monitoring.svc - port: 4317 + - destination: + name: accesslog/envoy-gateway/gateway-1/sink/1 + settings: + - addressType: IP + endpoints: + - host: 1.2.3.4 + port: 4317 + protocol: GRPC + weight: 1 resources: k8s.cluster.name: cluster-1 text: | diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog.out.yaml index b219623c2ed..49bf2877744 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog.out.yaml @@ -134,8 +134,15 @@ xdsIR: envoy-gateway/gateway-1: accessLog: openTelemetry: - - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + - destination: + name: accesslog/envoy-gateway/gateway-1/sink/1 + settings: + - addressType: FQDN + endpoints: + - host: otel-collector.monitoring.svc.cluster.local + port: 4317 + protocol: GRPC + weight: 1 resources: k8s.cluster.name: cluster-1 text: | diff --git a/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml b/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml index 08e2e85c06e..fb3b477aff7 100755 --- a/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml +++ b/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml @@ -298,7 +298,14 @@ xdsIR: name: "" prefix: / tracing: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + destination: + name: tracing/envoy-gateway/gateway-2 + settings: + - addressType: FQDN + endpoints: + - host: otel-collector.monitoring.svc.cluster.local + port: 4317 + protocol: GRPC + weight: 1 samplingRate: 100 serviceName: envoy-gateway-class diff --git a/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml b/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml index fb5c6f89acc..87c89b08e91 100755 --- a/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml +++ b/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml @@ -285,8 +285,15 @@ xdsIR: name: "" prefix: / tracing: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + destination: + name: tracing/envoy-gateway/gateway-1 + settings: + - addressType: FQDN + endpoints: + - host: otel-collector.monitoring.svc.cluster.local + port: 4317 + protocol: GRPC + weight: 1 samplingRate: 100 serviceName: gateway-1.envoy-gateway envoy-gateway/gateway-2: @@ -333,7 +340,14 @@ xdsIR: name: "" prefix: / tracing: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + destination: + name: tracing/envoy-gateway/gateway-2 + settings: + - addressType: FQDN + endpoints: + - host: otel-collector.monitoring.svc.cluster.local + port: 4317 + protocol: GRPC + weight: 1 samplingRate: 100 serviceName: gateway-2.envoy-gateway diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 337720f7fb0..d4d35e3f8b3 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -1387,11 +1387,10 @@ type JSONAccessLog struct { // OpenTelemetryAccessLog holds the configuration for OpenTelemetry access logging. // +k8s:deepcopy-gen=true type OpenTelemetryAccessLog struct { - Text *string `json:"text,omitempty" yaml:"text,omitempty"` - Attributes map[string]string `json:"attributes,omitempty" yaml:"attributes,omitempty"` - Host string `json:"host" yaml:"host"` - Port uint32 `json:"port" yaml:"port"` - Resources map[string]string `json:"resources,omitempty" yaml:"resources,omitempty"` + Text *string `json:"text,omitempty" yaml:"text,omitempty"` + Attributes map[string]string `json:"attributes,omitempty" yaml:"attributes,omitempty"` + Destination RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"` + Resources map[string]string `json:"resources,omitempty" yaml:"resources,omitempty"` } // EnvoyPatchPolicy defines the intermediate representation of the EnvoyPatchPolicy resource. @@ -1446,10 +1445,9 @@ type JSONPatchOperation struct { // +k8s:deepcopy-gen=true type Tracing struct { ServiceName string `json:"serviceName"` - Host string `json:"host"` - Port uint32 `json:"port"` SamplingRate float64 `json:"samplingRate,omitempty"` CustomTags map[string]egv1a1.CustomTag `json:"customTags,omitempty"` + Destination RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"` } // Metrics defines the configuration for metrics generated by Envoy diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 5430ef9ce6b..8fe528883cb 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -1500,6 +1500,7 @@ func (in *OpenTelemetryAccessLog) DeepCopyInto(out *OpenTelemetryAccessLog) { (*out)[key] = val } } + in.Destination.DeepCopyInto(&out.Destination) if in.Resources != nil { in, out := &in.Resources, &out.Resources *out = make(map[string]string, len(*in)) @@ -2376,6 +2377,7 @@ func (in *Tracing) DeepCopyInto(out *Tracing) { (*out)[key] = *val.DeepCopy() } } + in.Destination.DeepCopyInto(&out.Destination) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Tracing. diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index 0cdbe5c8f7f..c6da8367a24 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -175,6 +175,11 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques return reconcile.Result{}, err } + // Add all EnvoyProxies to the resourceTree + if err = r.processEnvoyProxies(ctx, managedGC, gwcResource, resourceMappings); err != nil { + return reconcile.Result{}, err + } + // Add all EnvoyPatchPolicies to the resourceTree if err = r.processEnvoyPatchPolicies(ctx, gwcResource); err != nil { return reconcile.Result{}, err @@ -225,26 +230,6 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques gwcResource.Namespaces = append(gwcResource.Namespaces, namespace) } - // Process the parametersRef of the accepted GatewayClass. - if managedGC.Spec.ParametersRef != nil && managedGC.DeletionTimestamp == nil { - if err := r.processParamsRef(ctx, managedGC, gwcResource); err != nil { - msg := fmt.Sprintf("%s: %v", status.MsgGatewayClassInvalidParams, err) - if err := r.updateStatusForGatewayClass(ctx, managedGC, false, string(gwapiv1.GatewayClassReasonInvalidParameters), msg); err != nil { - r.log.Error(err, "unable to update GatewayClass status") - } - r.log.Error(err, "failed to process parametersRef for gatewayclass", "name", managedGC.Name) - return reconcile.Result{}, err - } - } - - if gwcResource.EnvoyProxy != nil && gwcResource.EnvoyProxy.Spec.MergeGateways != nil { - if *gwcResource.EnvoyProxy.Spec.MergeGateways { - r.mergeGateways.Insert(managedGC.Name) - } else { - r.mergeGateways.Delete(managedGC.Name) - } - } - if err := r.updateStatusForGatewayClass(ctx, managedGC, true, string(gwapiv1.GatewayClassReasonAccepted), status.MsgValidGatewayClass); err != nil { r.log.Error(err, "unable to update GatewayClass status") return reconcile.Result{}, err @@ -780,6 +765,86 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g return nil } +// processEnvoyProxies adds EnvoyProxies to the resourceTree +func (r *gatewayAPIReconciler) processEnvoyProxies(ctx context.Context, managedGC *gwapiv1.GatewayClass, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings) error { + // Process the parametersRef of the accepted GatewayClass. + if managedGC.Spec.ParametersRef != nil && managedGC.DeletionTimestamp == nil { + if err := r.processParamsRef(ctx, managedGC, resourceTree); err != nil { + msg := fmt.Sprintf("%s: %v", status.MsgGatewayClassInvalidParams, err) + if err := r.updateStatusForGatewayClass(ctx, managedGC, false, string(gwapiv1.GatewayClassReasonInvalidParameters), msg); err != nil { + r.log.Error(err, "unable to update GatewayClass status") + } + r.log.Error(err, "failed to process parametersRef for gatewayclass", "name", managedGC.Name) + return err + } + } + + if resourceTree.EnvoyProxy != nil && resourceTree.EnvoyProxy.Spec.MergeGateways != nil { + if *resourceTree.EnvoyProxy.Spec.MergeGateways { + r.mergeGateways.Insert(managedGC.Name) + } else { + r.mergeGateways.Delete(managedGC.Name) + } + } + + // Add the referenced Resources in EnvoyProxies to the resourceTree + r.processEnvoyProxyObjectRefs(resourceTree, resourceMap) + + return nil +} + +// processEnvoyProxyObjectRefs adds the referenced resources in EnvoyProxies +// to the resourceTree +// - BackendRefs for AccessLog +// - BackendRefs for Metrics +// - BackendRefs for Tracing +func (r *gatewayAPIReconciler) processEnvoyProxyObjectRefs(resourceTree *gatewayapi.Resources, resourceMap *resourceMappings) { + if resourceTree.EnvoyProxy == nil { + return + } + envoyproxy := resourceTree.EnvoyProxy + + if envoyproxy.Spec.Telemetry != nil { + backendRefs := []egv1a1.BackendRef{} + + // Collect BackendRefs for access log sinks + if envoyproxy.Spec.Telemetry.AccessLog != nil { + for _, settings := range envoyproxy.Spec.Telemetry.AccessLog.Settings { + for _, sink := range settings.Sinks { + if sink.OpenTelemetry != nil { + backendRefs = append(backendRefs, sink.OpenTelemetry.BackendRefs...) + } + } + } + } + + // Collect BackendRefs for metrics sinks + if envoyproxy.Spec.Telemetry.Metrics != nil { + for _, sink := range envoyproxy.Spec.Telemetry.Metrics.Sinks { + if sink.OpenTelemetry != nil { + backendRefs = append(backendRefs, sink.OpenTelemetry.BackendRefs...) + } + } + } + + // Collect BackendRefs for tracing provider + if envoyproxy.Spec.Telemetry.Tracing != nil { + backendRefs = append(backendRefs, envoyproxy.Spec.Telemetry.Tracing.Provider.BackendRefs...) + } + + // Append all referenced BackendRefs to maps + for _, backendRef := range backendRefs { + backendNamespace := gatewayapi.NamespaceDerefOr(backendRef.Namespace, envoyproxy.Namespace) + resourceMap.allAssociatedBackendRefs[gwapiv1.BackendObjectReference{ + Group: backendRef.Group, + Kind: backendRef.Kind, + Namespace: gatewayapi.NamespacePtrV1Alpha2(backendNamespace), + Name: backendRef.Name, + }] = struct{}{} + } + } +} + // processEnvoyPatchPolicies adds EnvoyPatchPolicies to the resourceTree func (r *gatewayAPIReconciler) processEnvoyPatchPolicies(ctx context.Context, resourceTree *gatewayapi.Resources) error { envoyPatchPolicies := egv1a1.EnvoyPatchPolicyList{} @@ -945,6 +1010,9 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M epPredicates...)); err != nil { return err } + if err := addEnvoyProxyIndexers(ctx, mgr); err != nil { + return err + } // Watch Gateway CRUDs and reconcile affected GatewayClass. gPredicates := []predicate.TypedPredicate[*gwapiv1.Gateway]{ diff --git a/internal/provider/kubernetes/indexers.go b/internal/provider/kubernetes/indexers.go index 511802e2e38..711ce1902eb 100644 --- a/internal/provider/kubernetes/indexers.go +++ b/internal/provider/kubernetes/indexers.go @@ -28,6 +28,7 @@ const ( gatewayUDPRouteIndex = "gatewayUDPRouteIndex" secretGatewayIndex = "secretGatewayIndex" targetRefGrantRouteIndex = "targetRefGrantRouteIndex" + backendEnvoyProxyIndex = "backendEnvoyProxyIndex" backendHTTPRouteIndex = "backendHTTPRouteIndex" backendGRPCRouteIndex = "backendGRPCRouteIndex" backendTLSRouteIndex = "backendTLSRouteIndex" @@ -55,6 +56,63 @@ func addReferenceGrantIndexers(ctx context.Context, mgr manager.Manager) error { return nil } +func addEnvoyProxyIndexers(ctx context.Context, mgr manager.Manager) error { + if err := mgr.GetFieldIndexer().IndexField(ctx, &v1alpha1.EnvoyProxy{}, backendEnvoyProxyIndex, backendEnvoyProxyIndexFunc); err != nil { + return err + } + return nil +} + +func backendEnvoyProxyIndexFunc(rawObj client.Object) []string { + envoyproxy := rawObj.(*v1alpha1.EnvoyProxy) + var backendIndex []string + + if envoyproxy.Spec.Telemetry != nil { + backendRefs := []v1alpha1.BackendRef{} + + // Collect BackendRefs for access log sinks + if envoyproxy.Spec.Telemetry.AccessLog != nil { + for _, settings := range envoyproxy.Spec.Telemetry.AccessLog.Settings { + for _, sink := range settings.Sinks { + if sink.OpenTelemetry != nil { + backendRefs = append(backendRefs, sink.OpenTelemetry.BackendRefs...) + } + } + } + } + + // Collect BackendRefs for metrics sinks + if envoyproxy.Spec.Telemetry.Metrics != nil { + for _, sink := range envoyproxy.Spec.Telemetry.Metrics.Sinks { + if sink.OpenTelemetry != nil { + backendRefs = append(backendRefs, sink.OpenTelemetry.BackendRefs...) + } + } + } + + // Collect BackendRefs for tracing provider + if envoyproxy.Spec.Telemetry.Tracing != nil { + backendRefs = append(backendRefs, envoyproxy.Spec.Telemetry.Tracing.Provider.BackendRefs...) + } + + // Append all referenced BackendRefs to maps + for _, backendRef := range backendRefs { + if backendRef.Kind == nil || string(*backendRef.Kind) == gatewayapi.KindService { + // If an explicit Backend namespace is not provided, use the EnvoyProxy namespace to + // lookup the provided Gateway Name. + backendIndex = append(backendIndex, + types.NamespacedName{ + Namespace: gatewayapi.NamespaceDerefOr(backendRef.Namespace, envoyproxy.Namespace), + Name: string(backendRef.Name), + }.String(), + ) + } + } + } + + return backendIndex +} + // addHTTPRouteIndexers adds indexing on HTTPRoute. // - For Service, ServiceImports objects that are referenced in HTTPRoute objects via `.spec.rules.backendRefs`. // This helps in querying for HTTPRoutes that are affected by a particular Service CRUD. diff --git a/internal/provider/kubernetes/predicates.go b/internal/provider/kubernetes/predicates.go index 1c0668f1a9b..fb3faaab097 100644 --- a/internal/provider/kubernetes/predicates.go +++ b/internal/provider/kubernetes/predicates.go @@ -240,15 +240,30 @@ func (r *gatewayAPIReconciler) validateServiceForReconcile(obj client.Object) bo } nsName := utils.NamespacedName(svc) - if r.isRouteReferencingBackend(&nsName) { + switch { + case r.isRouteReferencingBackend(&nsName): + return true + case r.isEnvoyProxyReferencingBackend(&nsName): + return true + case r.isSecurityPolicyReferencingBackend(&nsName): + return true + case r.isEnvoyExtensionPolicyReferencingBackend(&nsName): return true } - if r.isSecurityPolicyReferencingBackend(&nsName) { - return true + return false +} + +func (r *gatewayAPIReconciler) isEnvoyProxyReferencingBackend(nsName *types.NamespacedName) bool { + epList := &egv1a1.EnvoyProxyList{} + if err := r.client.List(context.Background(), epList, &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector(backendEnvoyProxyIndex, nsName.String()), + }); err != nil { + r.log.Error(err, "unable to find associated EnvoyProxy") + return false } - return r.isEnvoyExtensionPolicyReferencingBackend(&nsName) + return len(epList.Items) > 0 } func (r *gatewayAPIReconciler) isSecurityPolicyReferencingBackend(nsName *types.NamespacedName) bool { @@ -332,7 +347,7 @@ func (r *gatewayAPIReconciler) isRouteReferencingBackend(nsName *types.Namespace } // validateEndpointSliceForReconcile returns true if the endpointSlice references -// a service that is referenced by a xRoute +// a service that is referenced by an xRoute, EnvoyProxy, or SecurityPolicy. func (r *gatewayAPIReconciler) validateEndpointSliceForReconcile(obj client.Object) bool { ep, ok := obj.(*discoveryv1.EndpointSlice) if !ok { @@ -356,15 +371,18 @@ func (r *gatewayAPIReconciler) validateEndpointSliceForReconcile(obj client.Obje nsName.Name = multiClusterSvcName } - if r.isRouteReferencingBackend(&nsName) { + switch { + case r.isRouteReferencingBackend(&nsName): return true - } - - if r.isSecurityPolicyReferencingBackend(&nsName) { + case r.isEnvoyProxyReferencingBackend(&nsName): + return true + case r.isSecurityPolicyReferencingBackend(&nsName): + return true + case r.isEnvoyExtensionPolicyReferencingBackend(&nsName): return true } - return r.isEnvoyExtensionPolicyReferencingBackend(&nsName) + return false } // validateDeploymentForReconcile tries finding the owning Gateway of the Deployment diff --git a/internal/xds/bootstrap/bootstrap.go b/internal/xds/bootstrap/bootstrap.go index 68146e2ddaf..db01e1dcdc3 100644 --- a/internal/xds/bootstrap/bootstrap.go +++ b/internal/xds/bootstrap/bootstrap.go @@ -148,6 +148,7 @@ func GetRenderedBootstrapConfig(opts *RenderBootsrapConfigOptions) (string, erro StatsMatcher StatsMatcherParameters ) + // TODO (davidalger) push these through XDS? if opts != nil && opts.ProxyMetrics != nil { proxyMetrics := opts.ProxyMetrics diff --git a/internal/xds/translator/accesslog.go b/internal/xds/translator/accesslog.go index 9f1f17a09d9..ca1e58b60b1 100644 --- a/internal/xds/translator/accesslog.go +++ b/internal/xds/translator/accesslog.go @@ -19,7 +19,6 @@ import ( "golang.org/x/exp/maps" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/structpb" - "k8s.io/utils/ptr" "github.com/envoyproxy/gateway/internal/ir" "github.com/envoyproxy/gateway/internal/xds/types" @@ -138,8 +137,7 @@ func buildXdsAccessLog(al *ir.AccessLog, forListener bool) []*accesslog.AccessLo GrpcService: &cfgcore.GrpcService{ TargetSpecifier: &cfgcore.GrpcService_EnvoyGrpc_{ EnvoyGrpc: &cfgcore.GrpcService_EnvoyGrpc{ - ClusterName: buildClusterName("accesslog", otel.Host, otel.Port), - Authority: otel.Host, + ClusterName: otel.Destination.Name, }, }, }, @@ -148,6 +146,13 @@ func buildXdsAccessLog(al *ir.AccessLog, forListener bool) []*accesslog.AccessLo ResourceAttributes: convertToKeyValueList(otel.Resources, false), } + // TODO: remove support for Host/Port in v1.2 + if len(otel.Destination.Settings) > 0 && + otel.Destination.Settings[0].AddressType != nil && + *otel.Destination.Settings[0].AddressType == ir.FQDN { + al.CommonConfig.GrpcService.TargetSpecifier.(*cfgcore.GrpcService_EnvoyGrpc_).EnvoyGrpc.Authority = otel.Destination.Settings[0].Endpoints[0].Host + } + format := EnvoyTextLogFormat if otel.Text != nil { format = *otel.Text @@ -236,24 +241,26 @@ func processClusterForAccessLog(tCtx *types.ResourceVersionTable, al *ir.AccessL return nil } + // add clusters for Open Telemetry access logs for _, otel := range al.OpenTelemetry { - clusterName := buildClusterName("accesslog", otel.Host, otel.Port) + endpointType := EndpointTypeStatic - ds := &ir.DestinationSetting{ - Weight: ptr.To[uint32](1), - Protocol: ir.GRPC, - Endpoints: []*ir.DestinationEndpoint{ir.NewDestEndpoint(otel.Host, otel.Port)}, + // TODO: remove support for Host/Port in v1.2 + if len(otel.Destination.Settings) > 0 && + otel.Destination.Settings[0].AddressType != nil && + *otel.Destination.Settings[0].AddressType == ir.FQDN { + endpointType = EndpointTypeDNS } + if err := addXdsCluster(tCtx, &xdsClusterArgs{ - name: clusterName, - settings: []*ir.DestinationSetting{ds}, + name: otel.Destination.Name, + settings: otel.Destination.Settings, tSocket: nil, - endpointType: EndpointTypeDNS, + endpointType: endpointType, metrics: metrics, }); err != nil && !errors.Is(err, ErrXdsClusterExists) { return err } - } return nil diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go index bb18a7e0286..a37f2a91170 100644 --- a/internal/xds/translator/cluster.go +++ b/internal/xds/translator/cluster.go @@ -539,13 +539,6 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs) map[string]*anypb. return extensionOptions } -// buildClusterName returns a cluster name for the given `host` and `port`. -// The format is: ||, where type is "accesslog" for access logs. -// It's easy to distinguish when debugging. -func buildClusterName(prefix string, host string, port uint32) string { - return fmt.Sprintf("%s|%s|%d", prefix, host, port) -} - // buildProxyProtocolSocket builds the ProxyProtocol transport socket. func buildProxyProtocolSocket(proxyProtocol *ir.ProxyProtocol, tSocket *corev3.TransportSocket) *corev3.TransportSocket { if proxyProtocol == nil { diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml index ca71bbad491..f0235d18182 100644 --- a/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml @@ -3,44 +3,51 @@ metrics: enablePerEndpointStats: true accesslog: text: - - path: "/dev/stdout" - format: | - [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + - path: "/dev/stdout" + format: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" json: - - path: "/dev/stdout" - json: - start_time: "%START_TIME%" - method: "%REQ(:METHOD)%" - path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%" - protocol: "%PROTOCOL%" - response_code: "%RESPONSE_CODE%" + - path: "/dev/stdout" + json: + start_time: "%START_TIME%" + method: "%REQ(:METHOD)%" + path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%" + protocol: "%PROTOCOL%" + response_code: "%RESPONSE_CODE%" openTelemetry: - - text: | - [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" - attributes: - "response_code": "%RESPONSE_CODE%" - resources: - "cluster_name": "cluster1" - host: otel-collector.default.svc.cluster.local - port: 4317 + - text: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + attributes: + "response_code": "%RESPONSE_CODE%" + resources: + "cluster_name": "cluster1" + destination: + name: accesslog/envoy-gateway/gateway-1/sink/1 + settings: + - addressType: IP + endpoints: + - host: "1.2.3.4" + port: 4317 + protocol: GRPC + weight: 1 http: - - name: "first-listener" - address: "0.0.0.0" - port: 10080 - hostnames: - - "*" - path: - mergeSlashes: true - escapedSlashesAction: UnescapeAndRedirect - routes: - - name: "direct-route" - hostname: "*" - destination: - name: "direct-route-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - directResponse: - body: "Unknown custom filter type: UnsupportedType" - statusCode: 500 +- name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + routes: + - name: "direct-route" + hostname: "*" + destination: + name: "direct-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + directResponse: + body: "Unknown custom filter type: UnsupportedType" + statusCode: 500 diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-invalid.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-invalid.yaml index 37ce0958e73..7dd3ba66b7f 100644 --- a/internal/xds/translator/testdata/in/xds-ir/accesslog-invalid.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-invalid.yaml @@ -19,8 +19,15 @@ accesslog: "response_code": "%RESPONSE_CODE%" resources: "cluster_name": "cluster1" - host: "" - port: 4317 + destination: + name: accesslog/envoy-gateway/gateway-1/sink/1 + settings: + - addressType: FQDN + endpoints: + - host: "" + port: 4317 + protocol: GRPC + weight: 1 http: - name: "first-listener" address: "0.0.0.0" diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog.yaml index f4ec43ac072..a86f3816546 100644 --- a/internal/xds/translator/testdata/in/xds-ir/accesslog.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/accesslog.yaml @@ -19,8 +19,30 @@ accesslog: "response_code": "%RESPONSE_CODE%" resources: "cluster_name": "cluster1" - host: otel-collector.default.svc.cluster.local - port: 4317 + destination: + name: accesslog/envoy-gateway/gateway-1/sink/1 + settings: + - addressType: FQDN + endpoints: + - host: otel-collector.default.svc.cluster.local + port: 4317 + protocol: GRPC + weight: 1 + - text: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + attributes: + "response_code": "%RESPONSE_CODE%" + resources: + "cluster_name": "cluster1" + destination: + name: accesslog/envoy-gateway/gateway-1/sink/2 + settings: + - addressType: IP + endpoints: + - host: "1.2.3.4" + port: 4317 + protocol: GRPC + weight: 1 http: - name: "first-listener" address: "0.0.0.0" diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml index 4a566033560..45a5c21bb0a 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml @@ -19,26 +19,33 @@ tracing: requestHeader: name: "X-Request-Id" defaultValue: "-" - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + destination: + name: tracing/envoy-gateway/gateway-1 + settings: + - addressType: FQDN + endpoints: + - host: "otel-collector.monitoring.svc.cluster.local" + port: 4317 + protocol: GRPC + weight: 1 http: - - name: "first-listener" - address: "0.0.0.0" - port: 10080 - hostnames: - - "*" - path: - mergeSlashes: true - escapedSlashesAction: UnescapeAndRedirect - routes: - - name: "direct-route" - hostname: "*" - destination: - name: "direct-route-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - directResponse: - body: "Unknown custom filter type: UnsupportedType" - statusCode: 500 +- name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + routes: + - name: "direct-route" + hostname: "*" + destination: + name: "direct-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + directResponse: + body: "Unknown custom filter type: UnsupportedType" + statusCode: 500 diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing-invalid.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing-invalid.yaml index d8b23c5d21e..e4cc0bf3980 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tracing-invalid.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tracing-invalid.yaml @@ -17,27 +17,33 @@ tracing: requestHeader: name: "X-Request-Id" defaultValue: "-" - provider: - host: "" - port: 4317 + destination: + name: tracing/envoy-gateway-system/otel-access-logging + settings: + - addressType: FQDN + endpoints: + - host: "" + port: 4317 + protocol: GRPC + weight: 1 http: - - name: "first-listener" - address: "0.0.0.0" - port: 10080 - hostnames: - - "*" - path: - mergeSlashes: true - escapedSlashesAction: UnescapeAndRedirect - routes: - - name: "direct-route" - hostname: "*" - destination: - name: "direct-route-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - directResponse: - body: "Unknown custom filter type: UnsupportedType" - statusCode: 500 +- name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + routes: + - name: "direct-route" + hostname: "*" + destination: + name: "direct-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + directResponse: + body: "Unknown custom filter type: UnsupportedType" + statusCode: 500 diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing.yaml index 674eb66acef..d38ab1722d9 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tracing.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tracing.yaml @@ -17,26 +17,33 @@ tracing: requestHeader: name: "X-Request-Id" defaultValue: "-" - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + destination: + name: tracing/envoy-gateway-system/otel-access-logging + settings: + - addressType: FQDN + endpoints: + - host: otel-collector.monitoring.svc.cluster.local + port: 4317 + protocol: GRPC + weight: 1 http: - - name: "first-listener" - address: "0.0.0.0" - port: 10080 - hostnames: - - "*" - path: - mergeSlashes: true - escapedSlashesAction: UnescapeAndRedirect - routes: - - name: "direct-route" - hostname: "*" - destination: - name: "direct-route-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - directResponse: - body: "Unknown custom filter type: UnsupportedType" - statusCode: 500 +- name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + routes: + - name: "direct-route" + hostname: "*" + destination: + name: "direct-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + directResponse: + body: "Unknown custom filter type: UnsupportedType" + statusCode: 500 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml index ac33653a54f..5cb1ce6da99 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml @@ -24,28 +24,18 @@ localityWeightedLbConfig: {} connectTimeout: 10s dnsLookupFamily: V4_ONLY - dnsRefreshRate: 30s + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: accesslog/envoy-gateway/gateway-1/sink/1 lbPolicy: LEAST_REQUEST - loadAssignment: - clusterName: accesslog|otel-collector.default.svc.cluster.local|4317 - endpoints: - - lbEndpoints: - - endpoint: - address: - socketAddress: - address: otel-collector.default.svc.cluster.local - portValue: 4317 - loadBalancingWeight: 1 - loadBalancingWeight: 1 - locality: - region: accesslog|otel-collector.default.svc.cluster.local|4317/backend/0 - name: accesslog|otel-collector.default.svc.cluster.local|4317 + name: accesslog/envoy-gateway/gateway-1/sink/1 outlierDetection: {} perConnectionBufferLimitBytes: 32768 - respectDnsTtl: true trackClusterStats: perEndpointStats: true - type: STRICT_DNS + type: EDS typedExtensionProtocolOptions: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.endpoints.yaml index 20c80b3aaaa..e381564b321 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.endpoints.yaml @@ -10,3 +10,15 @@ loadBalancingWeight: 1 locality: region: direct-route-dest/backend/0 +- clusterName: accesslog/envoy-gateway/gateway-1/sink/1 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 4317 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: accesslog/envoy-gateway/gateway-1/sink/1/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.listeners.yaml index e6d5535eb15..fde42ca1237 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.listeners.yaml @@ -50,8 +50,7 @@ commonConfig: grpcService: envoyGrpc: - authority: otel-collector.default.svc.cluster.local - clusterName: accesslog|otel-collector.default.svc.cluster.local|4317 + clusterName: accesslog/envoy-gateway/gateway-1/sink/1 logName: otel_envoy_accesslog transportApiVersion: V3 resourceAttributes: @@ -108,8 +107,7 @@ commonConfig: grpcService: envoyGrpc: - authority: otel-collector.default.svc.cluster.local - clusterName: accesslog|otel-collector.default.svc.cluster.local|4317 + clusterName: accesslog/envoy-gateway/gateway-1/sink/1 logName: otel_envoy_accesslog transportApiVersion: V3 resourceAttributes: diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml index 7168156486d..14687f0806c 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml @@ -25,7 +25,7 @@ dnsRefreshRate: 30s lbPolicy: LEAST_REQUEST loadAssignment: - clusterName: accesslog|otel-collector.default.svc.cluster.local|4317 + clusterName: accesslog/envoy-gateway/gateway-1/sink/1 endpoints: - lbEndpoints: - endpoint: @@ -36,8 +36,8 @@ loadBalancingWeight: 1 loadBalancingWeight: 1 locality: - region: accesslog|otel-collector.default.svc.cluster.local|4317/backend/0 - name: accesslog|otel-collector.default.svc.cluster.local|4317 + region: accesslog/envoy-gateway/gateway-1/sink/1/backend/0 + name: accesslog/envoy-gateway/gateway-1/sink/1 outlierDetection: {} perConnectionBufferLimitBytes: 32768 respectDnsTtl: true @@ -47,3 +47,25 @@ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: http2ProtocolOptions: {} +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: accesslog/envoy-gateway/gateway-1/sink/2 + lbPolicy: LEAST_REQUEST + name: accesslog/envoy-gateway/gateway-1/sink/2 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog.endpoints.yaml index 20c80b3aaaa..8b608183d84 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog.endpoints.yaml @@ -10,3 +10,15 @@ loadBalancingWeight: 1 locality: region: direct-route-dest/backend/0 +- clusterName: accesslog/envoy-gateway/gateway-1/sink/2 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 4317 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: accesslog/envoy-gateway/gateway-1/sink/2/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog.listeners.yaml index e6d5535eb15..539d5ff2c8b 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog.listeners.yaml @@ -51,7 +51,39 @@ grpcService: envoyGrpc: authority: otel-collector.default.svc.cluster.local - clusterName: accesslog|otel-collector.default.svc.cluster.local|4317 + clusterName: accesslog/envoy-gateway/gateway-1/sink/1 + logName: otel_envoy_accesslog + transportApiVersion: V3 + resourceAttributes: + values: + - key: cluster_name + value: + stringValue: cluster1 + - filter: + responseFlagFilter: + flags: + - NR + name: envoy.access_loggers.open_telemetry + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.open_telemetry.v3.OpenTelemetryAccessLogConfig + attributes: + values: + - key: k8s.namespace.name + value: + stringValue: '%ENVIRONMENT(ENVOY_GATEWAY_NAMESPACE)%' + - key: k8s.pod.name + value: + stringValue: '%ENVIRONMENT(ENVOY_POD_NAME)%' + - key: response_code + value: + stringValue: '%RESPONSE_CODE%' + body: + stringValue: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + commonConfig: + grpcService: + envoyGrpc: + clusterName: accesslog/envoy-gateway/gateway-1/sink/2 logName: otel_envoy_accesslog transportApiVersion: V3 resourceAttributes: @@ -109,7 +141,35 @@ grpcService: envoyGrpc: authority: otel-collector.default.svc.cluster.local - clusterName: accesslog|otel-collector.default.svc.cluster.local|4317 + clusterName: accesslog/envoy-gateway/gateway-1/sink/1 + logName: otel_envoy_accesslog + transportApiVersion: V3 + resourceAttributes: + values: + - key: cluster_name + value: + stringValue: cluster1 + - name: envoy.access_loggers.open_telemetry + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.open_telemetry.v3.OpenTelemetryAccessLogConfig + attributes: + values: + - key: k8s.namespace.name + value: + stringValue: '%ENVIRONMENT(ENVOY_GATEWAY_NAMESPACE)%' + - key: k8s.pod.name + value: + stringValue: '%ENVIRONMENT(ENVOY_POD_NAME)%' + - key: response_code + value: + stringValue: '%RESPONSE_CODE%' + body: + stringValue: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + commonConfig: + grpcService: + envoyGrpc: + clusterName: accesslog/envoy-gateway/gateway-1/sink/2 logName: otel_envoy_accesslog transportApiVersion: V3 resourceAttributes: diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml index 24a732d8e70..e111d8eec1a 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml @@ -27,7 +27,7 @@ dnsRefreshRate: 30s lbPolicy: LEAST_REQUEST loadAssignment: - clusterName: tracing|otel-collector.monitoring.svc.cluster.local|4317 + clusterName: tracing/envoy-gateway/gateway-1 endpoints: - lbEndpoints: - endpoint: @@ -38,8 +38,8 @@ loadBalancingWeight: 1 loadBalancingWeight: 1 locality: - region: tracing|otel-collector.monitoring.svc.cluster.local|4317/backend/0 - name: tracing|otel-collector.monitoring.svc.cluster.local|4317 + region: tracing/envoy-gateway/gateway-1/backend/0 + name: tracing/envoy-gateway/gateway-1 outlierDetection: {} perConnectionBufferLimitBytes: 32768 respectDnsTtl: true diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.listeners.yaml index c8277f1e190..d2957be860f 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.listeners.yaml @@ -52,7 +52,7 @@ grpcService: envoyGrpc: authority: otel-collector.monitoring.svc.cluster.local - clusterName: tracing|otel-collector.monitoring.svc.cluster.local|4317 + clusterName: tracing/envoy-gateway/gateway-1 serviceName: fake-name.fake-ns randomSampling: value: 90 diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml index eea2936ce62..d57cbef050e 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml @@ -25,7 +25,7 @@ dnsRefreshRate: 30s lbPolicy: LEAST_REQUEST loadAssignment: - clusterName: tracing|otel-collector.monitoring.svc.cluster.local|4317 + clusterName: tracing/envoy-gateway-system/otel-access-logging endpoints: - lbEndpoints: - endpoint: @@ -36,8 +36,8 @@ loadBalancingWeight: 1 loadBalancingWeight: 1 locality: - region: tracing|otel-collector.monitoring.svc.cluster.local|4317/backend/0 - name: tracing|otel-collector.monitoring.svc.cluster.local|4317 + region: tracing/envoy-gateway-system/otel-access-logging/backend/0 + name: tracing/envoy-gateway-system/otel-access-logging outlierDetection: {} perConnectionBufferLimitBytes: 32768 respectDnsTtl: true diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing.listeners.yaml index c8277f1e190..722ca60a725 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tracing.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tracing.listeners.yaml @@ -52,7 +52,7 @@ grpcService: envoyGrpc: authority: otel-collector.monitoring.svc.cluster.local - clusterName: tracing|otel-collector.monitoring.svc.cluster.local|4317 + clusterName: tracing/envoy-gateway-system/otel-access-logging serviceName: fake-name.fake-ns randomSampling: value: 90 diff --git a/internal/xds/translator/tracing.go b/internal/xds/translator/tracing.go index 44e80681c59..6c927f214b7 100644 --- a/internal/xds/translator/tracing.go +++ b/internal/xds/translator/tracing.go @@ -16,7 +16,6 @@ import ( tracingtype "github.com/envoyproxy/go-control-plane/envoy/type/tracing/v3" xdstype "github.com/envoyproxy/go-control-plane/envoy/type/v3" "google.golang.org/protobuf/types/known/wrapperspb" - "k8s.io/utils/ptr" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/ir" @@ -33,14 +32,20 @@ func buildHCMTracing(tracing *ir.Tracing) (*hcm.HttpConnectionManager_Tracing, e GrpcService: &corev3.GrpcService{ TargetSpecifier: &corev3.GrpcService_EnvoyGrpc_{ EnvoyGrpc: &corev3.GrpcService_EnvoyGrpc{ - ClusterName: buildClusterName("tracing", tracing.Host, tracing.Port), - Authority: tracing.Host, + ClusterName: tracing.Destination.Name, }, }, }, ServiceName: tracing.ServiceName, } + // TODO: remove support for Host/Port in v1.2 + if len(tracing.Destination.Settings) > 0 && + tracing.Destination.Settings[0].AddressType != nil && + *tracing.Destination.Settings[0].AddressType == ir.FQDN { + oc.GrpcService.TargetSpecifier.(*corev3.GrpcService_EnvoyGrpc_).EnvoyGrpc.Authority = tracing.Destination.Settings[0].Endpoints[0].Host + } + ocAny, err := protocov.ToAnyWithError(oc) if err != nil { return nil, fmt.Errorf("failed to marshal OpenTelemetryConfig: %w", err) @@ -124,18 +129,20 @@ func processClusterForTracing(tCtx *types.ResourceVersionTable, tracing *ir.Trac return nil } - clusterName := buildClusterName("tracing", tracing.Host, tracing.Port) + endpointType := EndpointTypeStatic - ds := &ir.DestinationSetting{ - Weight: ptr.To[uint32](1), - Protocol: ir.GRPC, - Endpoints: []*ir.DestinationEndpoint{ir.NewDestEndpoint(tracing.Host, tracing.Port)}, + // TODO: remove support for Host/Port in v1.2 + if len(tracing.Destination.Settings) > 0 && + tracing.Destination.Settings[0].AddressType != nil && + *tracing.Destination.Settings[0].AddressType == ir.FQDN { + endpointType = EndpointTypeDNS } + if err := addXdsCluster(tCtx, &xdsClusterArgs{ - name: clusterName, - settings: []*ir.DestinationSetting{ds}, + name: tracing.Destination.Name, + settings: tracing.Destination.Settings, tSocket: nil, - endpointType: EndpointTypeDNS, + endpointType: endpointType, metrics: metrics, }); err != nil && !errors.Is(err, ErrXdsClusterExists) { return err diff --git a/tools/make/kube.mk b/tools/make/kube.mk index eec42ea2395..3932c17459d 100644 --- a/tools/make/kube.mk +++ b/tools/make/kube.mk @@ -98,7 +98,7 @@ kube-demo-undeploy: ## Uninstall the Kubernetes resources installed from the `ma # tools/hack/run-kube-local.sh .PHONY: conformance -conformance: create-cluster kube-install-image kube-deploy run-conformance delete-cluster ## Create a kind cluster, deploy EG into it, run Gateway API conformance, and clean up. +conformance: create-cluster kube-install-image kube-deploy install-e2e-telemetry run-conformance delete-cluster ## Create a kind cluster, deploy EG into it, run Gateway API conformance, and clean up. .PHONY: experimental-conformance ## Create a kind cluster, deploy EG into it, run Gateway API experimental conformance, and clean up. experimental-conformance: create-cluster kube-install-image kube-deploy run-experimental-conformance delete-cluster ## Create a kind cluster, deploy EG into it, run Gateway API conformance, and clean up.