diff --git a/internal/gatewayapi/globalresources.go b/internal/gatewayapi/globalresources.go new file mode 100644 index 0000000000..f3488ecf19 --- /dev/null +++ b/internal/gatewayapi/globalresources.go @@ -0,0 +1,58 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package gatewayapi + +import ( + "fmt" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/envoyproxy/gateway/internal/gatewayapi/resource" + "github.com/envoyproxy/gateway/internal/ir" +) + +const envoyTLSSecretName = "envoy" + +// ProcessGlobalResources processes global resources that are not tied to a specific listener or route +func (t *Translator) ProcessGlobalResources(resources *resource.Resources, xdsIRs resource.XdsIRMap) error { + // Get the envoy client TLS secret. It is used for envoy to establish a TLS connection with control plane components, + // including the rate limit server and the wasm HTTP server. + envoyTLSSecret := resources.GetSecret(t.ControllerNamespace, envoyTLSSecretName) + if envoyTLSSecret == nil { + return fmt.Errorf("envoy TLS secret %s/%s not found", t.ControllerNamespace, envoyTLSSecretName) + } + + for _, xdsIR := range xdsIRs { + // TODO zhaohuabing: this is also required by WASM + if containsGlobalRateLimit(xdsIR.HTTP) { + xdsIR.GlobalResources = &ir.GlobalResources{} + xdsIR.GlobalResources.EnvoyClientCertificate = &ir.TLSCertificate{ + Name: irGlobalConfigName(envoyTLSSecret), + Certificate: envoyTLSSecret.Data[corev1.TLSCertKey], + PrivateKey: envoyTLSSecret.Data[corev1.TLSPrivateKeyKey], + } + } + } + return nil +} + +func irGlobalConfigName(object metav1.Object) string { + return fmt.Sprintf("%s/%s", object.GetNamespace(), object.GetName()) +} + +func containsGlobalRateLimit(httpListeners []*ir.HTTPListener) bool { + for _, httpListener := range httpListeners { + for _, route := range httpListener.Routes { + if route.Traffic != nil && + route.Traffic.RateLimit != nil && + route.Traffic.RateLimit.Global != nil { + return true + } + } + } + return false +} diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-strategic-merge-global-ratelimit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-strategic-merge-global-ratelimit.out.yaml index c70c9d724a..19958cfec3 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-strategic-merge-global-ratelimit.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-strategic-merge-global-ratelimit.out.yaml @@ -300,6 +300,11 @@ xdsIR: accessLog: json: - path: /dev/stdout + globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: '[redacted]' + serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= http: - address: 0.0.0.0 hostnames: @@ -379,6 +384,11 @@ xdsIR: accessLog: json: - path: /dev/stdout + globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: '[redacted]' + serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= http: - address: 0.0.0.0 hostnames: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml index 435096820c..a19232df09 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml @@ -278,6 +278,11 @@ xdsIR: accessLog: json: - path: /dev/stdout + globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: '[redacted]' + serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= http: - address: 0.0.0.0 hostnames: @@ -338,6 +343,11 @@ xdsIR: accessLog: json: - path: /dev/stdout + globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: '[redacted]' + serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= http: - address: 0.0.0.0 hostnames: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-shared-ratelimit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-shared-ratelimit.out.yaml index 90a365156f..283ee24b68 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-shared-ratelimit.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-shared-ratelimit.out.yaml @@ -279,6 +279,11 @@ xdsIR: accessLog: json: - path: /dev/stdout + globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: '[redacted]' + serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= http: - address: 0.0.0.0 hostnames: @@ -340,6 +345,11 @@ xdsIR: accessLog: json: - path: /dev/stdout + globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: '[redacted]' + serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= http: - address: 0.0.0.0 hostnames: diff --git a/internal/gatewayapi/testdata/base/base.yaml b/internal/gatewayapi/testdata/base/base.yaml new file mode 100644 index 0000000000..ff9ba1abee --- /dev/null +++ b/internal/gatewayapi/testdata/base/base.yaml @@ -0,0 +1,11 @@ +# This file contains the base configuration shared by all tests. So we don't need to repeat it in each test. +secrets: + - apiVersion: v1 + kind: Secret + metadata: + namespace: envoy-gateway-system + name: envoy + type: kubernetes.io/tls + data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index 7666322d76..0dd30d3a08 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -6,6 +6,7 @@ package gatewayapi import ( + "errors" "sort" "golang.org/x/exp/maps" @@ -160,6 +161,8 @@ func newTranslateResult(gateways []*GatewayContext, } func (t *Translator) Translate(resources *resource.Resources) (*TranslateResult, error) { + var errs error + // Get Gateways belonging to our GatewayClass. acceptedGateways, failedGateways := t.GetRelevantGateways(resources) @@ -231,8 +234,16 @@ func (t *Translator) Translate(resources *resource.Resources) (*TranslateResult, envoyExtensionPolicies := t.ProcessEnvoyExtensionPolicies( resources.EnvoyExtensionPolicies, acceptedGateways, routes, resources, xdsIR) - extServerPolicies, translateErrs := t.ProcessExtensionServerPolicies( + extServerPolicies, err := t.ProcessExtensionServerPolicies( resources.ExtensionServerPolicies, acceptedGateways, xdsIR) + if err != nil { + errs = errors.Join(errs, err) + } + + // Process global resources that are not tied to a specific listener or route + if err := t.ProcessGlobalResources(resources, xdsIR); err != nil { + errs = errors.Join(errs, err) + } // Sort xdsIR based on the Gateway API spec sortXdsIRMap(xdsIR) @@ -253,7 +264,7 @@ func (t *Translator) Translate(resources *resource.Resources) (*TranslateResult, return newTranslateResult(allGateways, httpRoutes, grpcRoutes, tlsRoutes, tcpRoutes, udpRoutes, clientTrafficPolicies, backendTrafficPolicies, securityPolicies, resources.BackendTLSPolicies, envoyExtensionPolicies, - extServerPolicies, backends, xdsIR, infraIR), translateErrs + extServerPolicies, backends, xdsIR, infraIR), errs } // GetRelevantGateways returns GatewayContexts, containing a copy of the original diff --git a/internal/gatewayapi/translator_test.go b/internal/gatewayapi/translator_test.go index 5193944295..bcbf93ab64 100644 --- a/internal/gatewayapi/translator_test.go +++ b/internal/gatewayapi/translator_test.go @@ -68,6 +68,10 @@ func TestTranslate(t *testing.T) { inputFiles, err := filepath.Glob(filepath.Join("testdata", "*.in.yaml")) require.NoError(t, err) + base, err := os.ReadFile("testdata/base/base.yaml") + require.NoError(t, err) + baseResources := &resource.Resources{} + mustUnmarshal(t, base, baseResources) for _, inputFile := range inputFiles { t.Run(testName(inputFile), func(t *testing.T) { @@ -76,6 +80,9 @@ func TestTranslate(t *testing.T) { resources := &resource.Resources{} mustUnmarshal(t, input, resources) + // Merge base resources with test resources + // Only secrets are in the base resources, we may have more in the future + resources.Secrets = append(resources.Secrets, baseResources.Secrets...) envoyPatchPolicyEnabled := true backendEnabled := true gatewayNamespaceMode := false @@ -893,6 +900,7 @@ func xdsWithoutEqual(a *ir.Xds) any { UDP []*ir.UDPListener EnvoyPatchPolicies []*ir.EnvoyPatchPolicy FilterOrder []egv1a1.FilterPosition + GlobalResources *ir.GlobalResources }{ ReadyListener: a.ReadyListener, AccessLog: a.AccessLog, @@ -903,6 +911,7 @@ func xdsWithoutEqual(a *ir.Xds) any { UDP: a.UDP, EnvoyPatchPolicies: a.EnvoyPatchPolicies, FilterOrder: a.FilterOrder, + GlobalResources: a.GlobalResources, } // Ensure we didn't drop an exported field. diff --git a/internal/ir/xds.go b/internal/ir/xds.go index b3759e45fd..61621c0f0d 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -151,6 +151,8 @@ type Xds struct { EnvoyPatchPolicies []*EnvoyPatchPolicy `json:"envoyPatchPolicies,omitempty" yaml:"envoyPatchPolicies,omitempty"` // FilterOrder holds the custom order of the HTTP filters FilterOrder []egv1a1.FilterPosition `json:"filterOrder,omitempty" yaml:"filterOrder,omitempty"` + // GlobalResources holds the global resources used by the Envoy, for example, the envoy client certificate and the OIDC HMAC secret + GlobalResources *GlobalResources `json:"globalResources,omitempty" yaml:"globalResources,omitempty"` } // Equal implements the Comparable interface used by watchable.DeepEqual to skip unnecessary updates. @@ -2093,12 +2095,21 @@ type RateLimit struct { // GlobalRateLimit holds the global rate limiting configuration. // +k8s:deepcopy-gen=true type GlobalRateLimit struct { - // TODO zhaohuabing: add default values for Global rate limiting. - // Rules for rate limiting. Rules []*RateLimitRule `json:"rules,omitempty" yaml:"rules,omitempty" patchStrategy:"merge" patchMergeKey:"name"` } +// GlobalResources holds the global resources used by the Envoy that are not specific to any listener or route. +// +k8s:deepcopy-gen=true +type GlobalResources struct { + // EnvoyClientCertificate holds the client certificate secret for envoy to use when establishing a TLS connection to + // control plane components. For example, the rate limit service, WASM HTTP server, etc. + EnvoyClientCertificate *TLSCertificate `json:"envoyClientCertificate,omitempty" yaml:"envoyClientCertificate,omitempty"` + // HMACSecret holds the HMAC Secret used by the OIDC. + // TODO: zhaohuabing move HMACSecret here + // HMACSecret PrivateBytes +} + // LocalRateLimit holds the local rate limiting configuration. // +k8s:deepcopy-gen=true type LocalRateLimit struct { diff --git a/internal/ir/xds_test.go b/internal/ir/xds_test.go index 4cd6d8b630..1437856122 100644 --- a/internal/ir/xds_test.go +++ b/internal/ir/xds_test.go @@ -1452,6 +1452,13 @@ func TestRedaction(t *testing.T) { { name: "explicit string check", input: Xds{ + GlobalResources: &GlobalResources{ + EnvoyClientCertificate: &TLSCertificate{ + Name: "test", + Certificate: []byte("Certificate"), + PrivateKey: PrivateBytes([]byte("PrivateBytes")), + }, + }, HTTP: []*HTTPListener{{ TLS: &TLSConfig{ Certificates: []TLSCertificate{{ @@ -1492,7 +1499,8 @@ func TestRedaction(t *testing.T) { `"apiKeyAuth":{"credentials":{"client-id":"[redacted]"},"extractFrom":null},` + `"basicAuth":{"name":"","users":"[redacted]"}` + `}}],` + - `"isHTTP2":false,"path":{"mergeSlashes":false,"escapedSlashesAction":""}}]}`, + `"isHTTP2":false,"path":{"mergeSlashes":false,"escapedSlashesAction":""}}],` + + `"globalResources":{"envoyClientCertificate":{"name":"test","serverCertificate":"Q2VydGlmaWNhdGU=","privateKey":"[redacted]"}}}`, }, } for _, test := range tests { diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index eb5f63edb8..6a4594e7bc 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -1318,6 +1318,26 @@ func (in *GlobalRateLimit) DeepCopy() *GlobalRateLimit { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlobalResources) DeepCopyInto(out *GlobalResources) { + *out = *in + if in.EnvoyClientCertificate != nil { + in, out := &in.EnvoyClientCertificate, &out.EnvoyClientCertificate + *out = new(TLSCertificate) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalResources. +func (in *GlobalResources) DeepCopy() *GlobalResources { + if in == nil { + return nil + } + out := new(GlobalResources) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTP10Settings) DeepCopyInto(out *HTTP10Settings) { *out = *in @@ -4014,6 +4034,11 @@ func (in *Xds) DeepCopyInto(out *Xds) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.GlobalResources != nil { + in, out := &in.GlobalResources, &out.GlobalResources + *out = new(GlobalResources) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Xds. diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index b4eb87c0f3..5fed6f49e5 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -775,6 +775,34 @@ func (r *gatewayAPIReconciler) processOIDCHMACSecret(ctx context.Context, resour } } +// processEnvoyTLSSecret adds the Envoy TLS Secret to the resourceTree. +// The Envoy TLS Secret is created by the CertGen job and is used by envoy to establish +// TLS connections to the rate limit service. +func (r *gatewayAPIReconciler) processEnvoyTLSSecret(ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings) { + var ( + secret corev1.Secret + err error + ) + + err = r.client.Get(ctx, + types.NamespacedName{Namespace: r.namespace, Name: envoyTLSSecretName}, + &secret, + ) + if err != nil { + r.log.Error(err, + "failed to process Envoy TLS Secret", + "namespace", r.namespace, "name", envoyTLSSecretName) + return + } + + key := utils.NamespacedName(&secret).String() + if !resourceMap.allAssociatedSecrets.Has(key) { + resourceMap.allAssociatedSecrets.Insert(key) + resourceTree.Secrets = append(resourceTree.Secrets, &secret) + r.log.Info("processing Envoy TLS Secret", "namespace", r.namespace, "name", envoyTLSSecretName) + } +} + // processSecretRef adds the referenced Secret to the resourceTree if it's valid. // - If it exists in the same namespace as the owner. // - If it exists in a different namespace, and there is a ReferenceGrant. @@ -1244,6 +1272,9 @@ func (r *gatewayAPIReconciler) processSecurityPolicies( // Add the OIDC HMAC Secret to the resourceTree r.processOIDCHMACSecret(ctx, resourceTree, resourceMap) + + // Add the Envoy TLS Secret to the resourceTree + r.processEnvoyTLSSecret(ctx, resourceTree, resourceMap) return nil } diff --git a/internal/provider/kubernetes/predicates.go b/internal/provider/kubernetes/predicates.go index 1ec83ee0fa..ae18b3f039 100644 --- a/internal/provider/kubernetes/predicates.go +++ b/internal/provider/kubernetes/predicates.go @@ -31,7 +31,10 @@ import ( ) // nolint: gosec -const oidcHMACSecretName = "envoy-oidc-hmac" +const ( + oidcHMACSecretName = "envoy-oidc-hmac" + envoyTLSSecretName = "envoy" +) // hasMatchingController returns true if the provided object is a GatewayClass // with a Spec.Controller string matching this Envoy Gateway's controller string, @@ -161,6 +164,10 @@ func (r *gatewayAPIReconciler) validateSecretForReconcile(obj client.Object) boo return true } + if r.isEnvoyTLSSecret(&nsName) { + return true + } + if r.epCRDExists { if r.isEnvoyProxyReferencingSecret(&nsName) { return true @@ -302,6 +309,14 @@ func (r *gatewayAPIReconciler) isOIDCHMACSecret(nsName *types.NamespacedName) bo return *nsName == oidcHMACSecret } +func (r *gatewayAPIReconciler) isEnvoyTLSSecret(nsName *types.NamespacedName) bool { + envoyTLSSecret := types.NamespacedName{ + Namespace: r.namespace, + Name: envoyTLSSecretName, + } + return *nsName == envoyTLSSecret +} + // validateServiceForReconcile tries finding the owning Gateway of the Service // if it exists, finds the Gateway's Deployment, and further updates the Gateway // status Ready condition. All Services are pushed for reconciliation. diff --git a/internal/xds/translator/globalresources.go b/internal/xds/translator/globalresources.go new file mode 100644 index 0000000000..bb4f7ce9ec --- /dev/null +++ b/internal/xds/translator/globalresources.go @@ -0,0 +1,125 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package translator + +import ( + "errors" + + corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" + tlsv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" + resourcev3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3" + "github.com/envoyproxy/go-control-plane/pkg/wellknown" + "google.golang.org/protobuf/types/known/anypb" + "k8s.io/utils/ptr" + + "github.com/envoyproxy/gateway/internal/ir" + "github.com/envoyproxy/gateway/internal/xds/types" +) + +const ( + // rateLimitClientTLSCACertFilename is the ratelimit ca cert file. + rateLimitClientTLSCACertFilename = "/certs/ca.crt" +) + +// patchGlobalResources builds and appends the global resources that are shared across listeners and routes. +// for example, the envoy client certificate and the OIDC HMAC secret. +func (t *Translator) patchGlobalResources(tCtx *types.ResourceVersionTable, irXds *ir.Xds) error { + var errs error + + if irXds.GlobalResources != nil && irXds.GlobalResources.EnvoyClientCertificate != nil { + // Create the envoy client TLS secret. It is used for envoy to establish a TLS connection with control plane components. + if err := createEnvoyClientTLSCertSecret(tCtx, irXds.GlobalResources); err != nil { + errs = errors.Join(errs, err) + } + + if containsGlobalRateLimit(irXds.HTTP) { + if err := t.createRateLimitServiceCluster(tCtx, irXds.GlobalResources.EnvoyClientCertificate, irXds.Metrics); err != nil { + errs = errors.Join(errs, err) + } + } + } + return errs +} + +func containsGlobalRateLimit(httpListeners []*ir.HTTPListener) bool { + for _, httpListener := range httpListeners { + for _, route := range httpListener.Routes { + if route.Traffic != nil && + route.Traffic.RateLimit != nil && + route.Traffic.RateLimit.Global != nil { + return true + } + } + } + return false +} + +func createEnvoyClientTLSCertSecret(tCtx *types.ResourceVersionTable, globalResources *ir.GlobalResources) error { + if err := tCtx.AddXdsResource( + resourcev3.SecretType, + buildXdsTLSCertSecret(*globalResources.EnvoyClientCertificate)); err != nil { + return err + } + return nil +} + +func (t *Translator) createRateLimitServiceCluster(tCtx *types.ResourceVersionTable, envoyClientCertificate *ir.TLSCertificate, metrics *ir.Metrics) error { + clusterName := getRateLimitServiceClusterName() + // Create cluster if it does not exist + host, port := t.getRateLimitServiceGrpcHostPort() + ds := &ir.DestinationSetting{ + Weight: ptr.To[uint32](1), + Protocol: ir.GRPC, + Endpoints: []*ir.DestinationEndpoint{ir.NewDestEndpoint(host, port, false, nil)}, + Name: destinationSettingName(clusterName), + } + + tSocket, err := buildRateLimitTLSocket(envoyClientCertificate) + if err != nil { + return err + } + + return addXdsCluster(tCtx, &xdsClusterArgs{ + name: clusterName, + settings: []*ir.DestinationSetting{ds}, + tSocket: tSocket, + endpointType: EndpointTypeDNS, + metrics: metrics, + }) +} + +// buildRateLimitTLSocket builds the TLS socket for the rate limit service. +func buildRateLimitTLSocket(envoyClientCertificate *ir.TLSCertificate) (*corev3.TransportSocket, error) { + tlsCtx := &tlsv3.UpstreamTlsContext{ + CommonTlsContext: &tlsv3.CommonTlsContext{ + ValidationContextType: &tlsv3.CommonTlsContext_ValidationContext{ + ValidationContext: &tlsv3.CertificateValidationContext{ + TrustedCa: &corev3.DataSource{ + Specifier: &corev3.DataSource_Filename{Filename: rateLimitClientTLSCACertFilename}, + }, + }, + }, + TlsCertificateSdsSecretConfigs: []*tlsv3.SdsSecretConfig{ + { + Name: envoyClientCertificate.Name, + SdsConfig: makeConfigSource(), + }, + }, + }, + } + + tlsCtxAny, err := anypb.New(tlsCtx) + if err != nil { + return nil, err + } + + return &corev3.TransportSocket{ + Name: wellknown.TransportSocketTls, + ConfigType: &corev3.TransportSocket_TypedConfig{ + TypedConfig: tlsCtxAny, + }, + }, nil +} diff --git a/internal/xds/translator/ratelimit.go b/internal/xds/translator/ratelimit.go index e2d8ff8f77..56a9e6c49e 100644 --- a/internal/xds/translator/ratelimit.go +++ b/internal/xds/translator/ratelimit.go @@ -17,7 +17,6 @@ import ( routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" ratelimitfilterv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/ratelimit/v3" hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" - tlsv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" "github.com/envoyproxy/go-control-plane/pkg/wellknown" rlsconfv3 "github.com/envoyproxy/go-control-plane/ratelimit/config/ratelimit/v3" "github.com/envoyproxy/ratelimit/src/config" @@ -25,20 +24,9 @@ import ( "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/wrapperspb" goyaml "gopkg.in/yaml.v3" // nolint: depguard - "k8s.io/utils/ptr" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/ir" - "github.com/envoyproxy/gateway/internal/xds/types" -) - -const ( - // rateLimitClientTLSCertFilename is the ratelimit tls cert file. - rateLimitClientTLSCertFilename = "/certs/tls.crt" - // rateLimitClientTLSKeyFilename is the ratelimit key file. - rateLimitClientTLSKeyFilename = "/certs/tls.key" - // rateLimitClientTLSCACertFilename is the ratelimit ca cert file. - rateLimitClientTLSCACertFilename = "/certs/ca.crt" ) // patchHCMWithRateLimit builds and appends the Rate Limit Filter to the HTTP connection manager @@ -747,73 +735,6 @@ func buildRateLimitServiceDescriptors(route *ir.HTTPRoute) []*rlsconfv3.RateLimi return pbDescriptors } -// buildRateLimitTLSocket builds the TLS socket for the rate limit service. -func buildRateLimitTLSocket() (*corev3.TransportSocket, error) { - tlsCtx := &tlsv3.UpstreamTlsContext{ - CommonTlsContext: &tlsv3.CommonTlsContext{ - TlsCertificates: []*tlsv3.TlsCertificate{}, - ValidationContextType: &tlsv3.CommonTlsContext_ValidationContext{ - ValidationContext: &tlsv3.CertificateValidationContext{ - TrustedCa: &corev3.DataSource{ - Specifier: &corev3.DataSource_Filename{Filename: rateLimitClientTLSCACertFilename}, - }, - }, - }, - }, - } - - tlsCert := &tlsv3.TlsCertificate{ - CertificateChain: &corev3.DataSource{ - Specifier: &corev3.DataSource_Filename{Filename: rateLimitClientTLSCertFilename}, - }, - PrivateKey: &corev3.DataSource{ - Specifier: &corev3.DataSource_Filename{Filename: rateLimitClientTLSKeyFilename}, - }, - } - tlsCtx.CommonTlsContext.TlsCertificates = append(tlsCtx.CommonTlsContext.TlsCertificates, tlsCert) - - tlsCtxAny, err := anypb.New(tlsCtx) - if err != nil { - return nil, err - } - - return &corev3.TransportSocket{ - Name: wellknown.TransportSocketTls, - ConfigType: &corev3.TransportSocket_TypedConfig{ - TypedConfig: tlsCtxAny, - }, - }, nil -} - -func (t *Translator) createRateLimitServiceCluster(tCtx *types.ResourceVersionTable, irListener *ir.HTTPListener, metrics *ir.Metrics) error { - // Return early if rate limits don't exist. - if !t.isRateLimitPresent(irListener) { - return nil - } - clusterName := getRateLimitServiceClusterName() - // Create cluster if it does not exist - host, port := t.getRateLimitServiceGrpcHostPort() - ds := &ir.DestinationSetting{ - Weight: ptr.To[uint32](1), - Protocol: ir.GRPC, - Endpoints: []*ir.DestinationEndpoint{ir.NewDestEndpoint(host, port, false, nil)}, - Name: destinationSettingName(clusterName), - } - - tSocket, err := buildRateLimitTLSocket() - if err != nil { - return err - } - - return addXdsCluster(tCtx, &xdsClusterArgs{ - name: clusterName, - settings: []*ir.DestinationSetting{ds}, - tSocket: tSocket, - endpointType: EndpointTypeDNS, - metrics: metrics, - }) -} - // getDomainSharedName returns the shared domain (stripped policy name), stripRuleIndexSuffix is used to remove the rule index suffix. func getDomainSharedName(route *ir.HTTPRoute) string { return stripRuleIndexSuffix(route.Traffic.RateLimit.Global.Rules[0].Name) diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml index 4ffd1d9565..a15418d7e4 100644 --- a/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml @@ -1,3 +1,8 @@ +globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] http: - name: "first-listener" address: "::" diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml index 173e12ec4d..a1a46b1295 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-custom-domain.yaml @@ -1,3 +1,8 @@ +globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] http: - name: "first-listener" address: "::" diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-disable-headers.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-disable-headers.yaml index 428371929c..1af34ac929 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-disable-headers.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-disable-headers.yaml @@ -1,3 +1,8 @@ +globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] http: - name: "first-listener" address: "::" diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml index 9a0722b359..3afdb73463 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml @@ -1,3 +1,8 @@ +globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] metrics: enablePerEndpointStats: true http: diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-global-shared.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-global-shared.yaml index 2b36d593e7..458bff02c3 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-global-shared.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-global-shared.yaml @@ -1,3 +1,8 @@ +globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] metrics: enablePerEndpointStats: true http: diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-headers-and-cidr.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-headers-and-cidr.yaml index a9f5a34ef5..acf04f0a1e 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-headers-and-cidr.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-headers-and-cidr.yaml @@ -1,3 +1,8 @@ +globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] http: - name: "first-listener" address: "::" diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-multi-global-shared.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-multi-global-shared.yaml index ebd57e1ad4..22218744ce 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-multi-global-shared.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-multi-global-shared.yaml @@ -1,3 +1,8 @@ +globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] metrics: enablePerEndpointStats: true http: diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml index 734e09cb3a..0da657f640 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-sourceip.yaml @@ -1,3 +1,9 @@ +globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] + http: - name: "first-listener" address: "::" diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml index cf20291f97..b22f6e8b4b 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit.yaml @@ -1,3 +1,8 @@ +globalResources: + envoyClientCertificate: + name: envoy-gateway-system/envoy + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] http: - name: "first-listener" address: "::" diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml index 8b1b88c530..65926cf2e6 100644 --- a/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml @@ -105,11 +105,11 @@ typedConfig: '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext commonTlsContext: - tlsCertificates: - - certificateChain: - filename: /certs/tls.crt - privateKey: - filename: /certs/tls.key + tlsCertificateSdsSecretConfigs: + - name: envoy-gateway-system/envoy + sdsConfig: + ads: {} + resourceApiVersion: V3 validationContext: trustedCa: filename: /certs/ca.crt diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.secrets.yaml new file mode 100644 index 0000000000..fb08915118 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.secrets.yaml @@ -0,0 +1,6 @@ +- name: envoy-gateway-system/envoy + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml index 17f4be022c..604afcec0c 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml @@ -79,11 +79,11 @@ typedConfig: '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext commonTlsContext: - tlsCertificates: - - certificateChain: - filename: /certs/tls.crt - privateKey: - filename: /certs/tls.key + tlsCertificateSdsSecretConfigs: + - name: envoy-gateway-system/envoy + sdsConfig: + ads: {} + resourceApiVersion: V3 validationContext: trustedCa: filename: /certs/ca.crt diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.secrets.yaml new file mode 100644 index 0000000000..fb08915118 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.secrets.yaml @@ -0,0 +1,6 @@ +- name: envoy-gateway-system/envoy + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml index 231bd6c6f3..2011d47d3b 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml @@ -79,11 +79,11 @@ typedConfig: '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext commonTlsContext: - tlsCertificates: - - certificateChain: - filename: /certs/tls.crt - privateKey: - filename: /certs/tls.key + tlsCertificateSdsSecretConfigs: + - name: envoy-gateway-system/envoy + sdsConfig: + ads: {} + resourceApiVersion: V3 validationContext: trustedCa: filename: /certs/ca.crt diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.secrets.yaml new file mode 100644 index 0000000000..fb08915118 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.secrets.yaml @@ -0,0 +1,6 @@ +- name: envoy-gateway-system/envoy + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml index 87afaadd1c..581dd8f8b5 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml @@ -87,11 +87,11 @@ typedConfig: '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext commonTlsContext: - tlsCertificates: - - certificateChain: - filename: /certs/tls.crt - privateKey: - filename: /certs/tls.key + tlsCertificateSdsSecretConfigs: + - name: envoy-gateway-system/envoy + sdsConfig: + ads: {} + resourceApiVersion: V3 validationContext: trustedCa: filename: /certs/ca.crt diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.secrets.yaml new file mode 100644 index 0000000000..fb08915118 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.secrets.yaml @@ -0,0 +1,6 @@ +- name: envoy-gateway-system/envoy + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-global-shared.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-global-shared.clusters.yaml index 046bf98cb9..05aa374a64 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-global-shared.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-global-shared.clusters.yaml @@ -106,11 +106,11 @@ typedConfig: '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext commonTlsContext: - tlsCertificates: - - certificateChain: - filename: /certs/tls.crt - privateKey: - filename: /certs/tls.key + tlsCertificateSdsSecretConfigs: + - name: envoy-gateway-system/envoy + sdsConfig: + ads: {} + resourceApiVersion: V3 validationContext: trustedCa: filename: /certs/ca.crt diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-global-shared.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-global-shared.secrets.yaml new file mode 100644 index 0000000000..fb08915118 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-global-shared.secrets.yaml @@ -0,0 +1,6 @@ +- name: envoy-gateway-system/envoy + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.clusters.yaml index 231bd6c6f3..2011d47d3b 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.clusters.yaml @@ -79,11 +79,11 @@ typedConfig: '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext commonTlsContext: - tlsCertificates: - - certificateChain: - filename: /certs/tls.crt - privateKey: - filename: /certs/tls.key + tlsCertificateSdsSecretConfigs: + - name: envoy-gateway-system/envoy + sdsConfig: + ads: {} + resourceApiVersion: V3 validationContext: trustedCa: filename: /certs/ca.crt diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.secrets.yaml new file mode 100644 index 0000000000..fb08915118 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-headers-and-cidr.secrets.yaml @@ -0,0 +1,6 @@ +- name: envoy-gateway-system/envoy + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-multi-global-shared.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-multi-global-shared.clusters.yaml index 87afaadd1c..581dd8f8b5 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-multi-global-shared.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-multi-global-shared.clusters.yaml @@ -87,11 +87,11 @@ typedConfig: '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext commonTlsContext: - tlsCertificates: - - certificateChain: - filename: /certs/tls.crt - privateKey: - filename: /certs/tls.key + tlsCertificateSdsSecretConfigs: + - name: envoy-gateway-system/envoy + sdsConfig: + ads: {} + resourceApiVersion: V3 validationContext: trustedCa: filename: /certs/ca.crt diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-multi-global-shared.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-multi-global-shared.secrets.yaml new file mode 100644 index 0000000000..fb08915118 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-multi-global-shared.secrets.yaml @@ -0,0 +1,6 @@ +- name: envoy-gateway-system/envoy + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml index 0a576f1867..4f2b44ba81 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml @@ -96,11 +96,11 @@ typedConfig: '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext commonTlsContext: - tlsCertificates: - - certificateChain: - filename: /certs/tls.crt - privateKey: - filename: /certs/tls.key + tlsCertificateSdsSecretConfigs: + - name: envoy-gateway-system/envoy + sdsConfig: + ads: {} + resourceApiVersion: V3 validationContext: trustedCa: filename: /certs/ca.crt diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.secrets.yaml new file mode 100644 index 0000000000..fb08915118 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.secrets.yaml @@ -0,0 +1,6 @@ +- name: envoy-gateway-system/envoy + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml index 0a576f1867..4f2b44ba81 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml @@ -96,11 +96,11 @@ typedConfig: '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext commonTlsContext: - tlsCertificates: - - certificateChain: - filename: /certs/tls.crt - privateKey: - filename: /certs/tls.key + tlsCertificateSdsSecretConfigs: + - name: envoy-gateway-system/envoy + sdsConfig: + ads: {} + resourceApiVersion: V3 validationContext: trustedCa: filename: /certs/ca.crt diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit.secrets.yaml new file mode 100644 index 0000000000..fb08915118 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit.secrets.yaml @@ -0,0 +1,6 @@ +- name: envoy-gateway-system/envoy + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index 5118ffd329..9f307cb9e4 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -123,6 +123,14 @@ func (t *Translator) Translate(xdsIR *ir.Xds) (*types.ResourceVersionTable, erro errs = errors.Join(errs, err) } + // Patch global resources that are shared across listeners and routes. + // - the envoy client certificate + // - the OIDC HMAC secret + // - the rate limit server cluster + if err := t.patchGlobalResources(tCtx, xdsIR); err != nil { + errs = errors.Join(errs, err) + } + // Check if an extension want to inject any clusters/secrets // If no extension exists (or it doesn't subscribe to this hook) then this is a quick no-op if err := processExtensionPostTranslationHook(tCtx, t.ExtensionManager); err != nil { @@ -413,13 +421,6 @@ func (t *Translator) processHTTPListenerXdsTranslation( if err = patchResources(tCtx, httpListener.Routes); err != nil { errs = errors.Join(errs, err) } - - // RateLimit filter is handled separately because it relies on the global - // rate limit server configuration. - // Check if a ratelimit cluster exists, if not, add it, if it's needed. - if err = t.createRateLimitServiceCluster(tCtx, httpListener, metrics); err != nil { - errs = errors.Join(errs, err) - } } return errs diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 2d2ae0ffaa..3243165086 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -66,18 +66,6 @@ func TestE2E(t *testing.T) { skipTests = append(skipTests, tests.HTTPWasmTest.ShortName, tests.OCIWasmTest.ShortName, - - // Skip RateLimit tests because they are not supported in GatewayNamespaceMode - tests.RateLimitCIDRMatchTest.ShortName, - tests.RateLimitHeaderMatchTest.ShortName, - tests.GlobalRateLimitHeaderInvertMatchTest.ShortName, - tests.RateLimitHeadersDisabled.ShortName, - tests.RateLimitBasedJwtClaimsTest.ShortName, - tests.RateLimitMultipleListenersTest.ShortName, - tests.RateLimitHeadersAndCIDRMatchTest.ShortName, - tests.UsageRateLimitTest.ShortName, - tests.RateLimitGlobalSharedCidrMatchTest.ShortName, - tests.RateLimitGlobalSharedGatewayHeaderMatchTest.ShortName, ) }