From 5679e4196df41be14d9a9083c497d48695022f7e Mon Sep 17 00:00:00 2001 From: Huabing Zhao Date: Fri, 15 Mar 2024 08:58:33 +0800 Subject: [PATCH 01/29] Remove duplicated http filters for ExtAuth (#2893) * remove duplicated http filters Signed-off-by: huabing zhao * fix test Signed-off-by: huabing zhao * address comments Signed-off-by: huabing zhao --------- Signed-off-by: huabing zhao Co-authored-by: zirain --- internal/gatewayapi/securitypolicy.go | 12 ++++- ...ith-extauth-with-backendtlspolicy.out.yaml | 2 + .../securitypolicy-with-extauth.in.yaml | 10 +++- .../securitypolicy-with-extauth.out.yaml | 49 +++++++++++++++++-- internal/ir/xds.go | 4 ++ internal/xds/translator/basicauth.go | 3 +- internal/xds/translator/extauth.go | 22 ++++++--- internal/xds/translator/oidc.go | 6 +-- .../testdata/in/xds-ir/ext-auth.yaml | 29 +++++++++++ .../out/xds-ir/basic-auth.listeners.yaml | 2 +- .../out/xds-ir/basic-auth.routes.yaml | 2 +- .../out/xds-ir/ext-auth.listeners.yaml | 4 +- .../testdata/out/xds-ir/ext-auth.routes.yaml | 15 +++++- .../testdata/out/xds-ir/oidc.listeners.yaml | 4 +- .../testdata/out/xds-ir/oidc.routes.yaml | 4 +- internal/xds/translator/utils.go | 25 ++++++---- 16 files changed, 155 insertions(+), 38 deletions(-) diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index 2951d6ff7ec..4a85f726a7f 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -378,7 +378,10 @@ func (t *Translator) translateSecurityPolicyForRoute( } if policy.Spec.ExtAuth != nil { - if extAuth, err = t.buildExtAuth(policy, resources); err != nil { + if extAuth, err = t.buildExtAuth( + utils.NamespacedName(route).String(), + policy, + resources); err != nil { errs = errors.Join(errs, err) } } @@ -458,7 +461,10 @@ func (t *Translator) translateSecurityPolicyForGateway( } if policy.Spec.ExtAuth != nil { - if extAuth, err = t.buildExtAuth(policy, resources); err != nil { + if extAuth, err = t.buildExtAuth( + utils.NamespacedName(gateway).String(), + policy, + resources); err != nil { errs = errors.Join(errs, err) } } @@ -793,6 +799,7 @@ func (t *Translator) buildBasicAuth( } func (t *Translator) buildExtAuth( + name string, policy *egv1a1.SecurityPolicy, resources *Resources) (*ir.ExtAuth, error) { var ( @@ -845,6 +852,7 @@ func (t *Translator) buildExtAuth( } extAuth := &ir.ExtAuth{ + Name: name, HeadersToExtAuth: policy.Spec.ExtAuth.HeadersToExtAuth, } diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml index 5b413d59432..b3dc1299f34 100755 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml @@ -324,6 +324,7 @@ xdsIR: headersToExtAuth: - header1 - header2 + name: default/httproute-1 hostname: www.foo.com isHTTP2: false name: httproute/default/httproute-1/rule/0/match/0/www_foo_com @@ -364,6 +365,7 @@ xdsIR: - header1 - header2 path: /auth + name: default/gateway-1 hostname: www.bar.com isHTTP2: false name: httproute/default/httproute-2/rule/0/match/0/www_bar_com diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml index 12142460fa3..a451b576774 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml @@ -29,10 +29,16 @@ httpRoutes: rules: - matches: - path: - value: /foo + value: /foo1 backendRefs: - name: service-1 port: 8080 + - matches: + - path: + value: /foo2 + backendRefs: + - name: service-2 + port: 8080 - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: @@ -50,7 +56,7 @@ httpRoutes: - path: value: /bar backendRefs: - - name: service-1 + - name: service-3 port: 8080 services: - apiVersion: v1 diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml index 93666da42bb..25a291a8ca3 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml @@ -59,7 +59,13 @@ httpRoutes: port: 8080 matches: - path: - value: /foo + value: /foo1 + - backendRefs: + - name: service-2 + port: 8080 + matches: + - path: + value: /foo2 status: parents: - conditions: @@ -93,7 +99,7 @@ httpRoutes: sectionName: http rules: - backendRefs: - - name: service-1 + - name: service-3 port: 8080 matches: - path: @@ -253,13 +259,49 @@ xdsIR: headersToExtAuth: - header1 - header2 + name: default/httproute-1 hostname: www.foo.com isHTTP2: false name: httproute/default/httproute-1/rule/0/match/0/www_foo_com pathMatch: distinct: false name: "" - prefix: /foo + prefix: /foo1 + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-1/rule/1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + extAuth: + grpc: + authority: grpc-backend.default:9000 + destination: + name: securitypolicy/default/policy-for-http-route/grpc-backend + settings: + - addressType: IP + endpoints: + - host: 8.8.8.8 + port: 9000 + protocol: GRPC + weight: 1 + headersToExtAuth: + - header1 + - header2 + name: default/httproute-1 + hostname: www.foo.com + isHTTP2: false + name: httproute/default/httproute-1/rule/1/match/0/www_foo_com + pathMatch: + distinct: false + name: "" + prefix: /foo2 - backendWeights: invalid: 0 valid: 0 @@ -288,6 +330,7 @@ xdsIR: - header1 - header2 path: /auth + name: default/gateway-1 hostname: www.bar.com isHTTP2: false name: httproute/default/httproute-2/rule/0/match/0/www_bar_com diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 0d7c5df03b2..d2194fb95e8 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -575,6 +575,10 @@ type BasicAuth struct { // // +k8s:deepcopy-gen=true type ExtAuth struct { + // Name is a unique name for an ExtAuth configuration. + // The xds translator only generates one external authorization filter for each unique name. + Name string `json:"name" yaml:"name"` + // GRPC defines the gRPC External Authorization service. // Only one of GRPCService or HTTPService may be specified. GRPC *GRPCExtAuthService `json:"grpc,omitempty"` diff --git a/internal/xds/translator/basicauth.go b/internal/xds/translator/basicauth.go index 6ae7b9163e5..85cd77fa3c3 100644 --- a/internal/xds/translator/basicauth.go +++ b/internal/xds/translator/basicauth.go @@ -129,7 +129,8 @@ func (*basicAuth) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error if irRoute.BasicAuth == nil { return nil } - if err := enableFilterOnRoute(basicAuthFilter, route, irRoute); err != nil { + filterName := basicAuthFilterName(irRoute) + if err := enableFilterOnRoute(route, filterName); err != nil { return err } return nil diff --git a/internal/xds/translator/extauth.go b/internal/xds/translator/extauth.go index 069aac77eb7..28e509253aa 100644 --- a/internal/xds/translator/extauth.go +++ b/internal/xds/translator/extauth.go @@ -55,7 +55,14 @@ func (*extAuth) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPLi continue } - filter, err := buildHCMExtAuthFilter(route) + // Only generates one OAuth2 Envoy filter for each unique name. + // For example, if there are two routes under the same gateway with the + // same OIDC config, only one OAuth2 filter will be generated. + if hcmContainsFilter(mgr, extAuthFilterName(route.ExtAuth)) { + continue + } + + filter, err := buildHCMExtAuthFilter(route.ExtAuth) if err != nil { errs = errors.Join(errs, err) continue @@ -68,8 +75,8 @@ func (*extAuth) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPLi } // buildHCMExtAuthFilter returns an ext_authz HTTP filter from the provided IR HTTPRoute. -func buildHCMExtAuthFilter(route *ir.HTTPRoute) (*hcmv3.HttpFilter, error) { - extAuthProto := extAuthConfig(route.ExtAuth) +func buildHCMExtAuthFilter(extAuth *ir.ExtAuth) (*hcmv3.HttpFilter, error) { + extAuthProto := extAuthConfig(extAuth) if err := extAuthProto.ValidateAll(); err != nil { return nil, err } @@ -80,7 +87,7 @@ func buildHCMExtAuthFilter(route *ir.HTTPRoute) (*hcmv3.HttpFilter, error) { } return &hcmv3.HttpFilter{ - Name: extAuthFilterName(route), + Name: extAuthFilterName(extAuth), Disabled: true, ConfigType: &hcmv3.HttpFilter_TypedConfig{ TypedConfig: extAuthAny, @@ -88,8 +95,8 @@ func buildHCMExtAuthFilter(route *ir.HTTPRoute) (*hcmv3.HttpFilter, error) { }, nil } -func extAuthFilterName(route *ir.HTTPRoute) string { - return perRouteFilterName(extAuthFilter, route.Name) +func extAuthFilterName(extAuth *ir.ExtAuth) string { + return perRouteFilterName(extAuthFilter, extAuth.Name) } func extAuthConfig(extAuth *ir.ExtAuth) *extauthv3.ExtAuthz { @@ -276,7 +283,8 @@ func (*extAuth) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { if irRoute.ExtAuth == nil { return nil } - if err := enableFilterOnRoute(extAuthFilter, route, irRoute); err != nil { + filterName := extAuthFilterName(irRoute.ExtAuth) + if err := enableFilterOnRoute(route, filterName); err != nil { return err } return nil diff --git a/internal/xds/translator/oidc.go b/internal/xds/translator/oidc.go index 58b417f2441..2a10254ec64 100644 --- a/internal/xds/translator/oidc.go +++ b/internal/xds/translator/oidc.go @@ -94,7 +94,7 @@ func buildHCMOAuth2Filter(route *ir.HTTPRoute) (*hcmv3.HttpFilter, error) { } func oauth2FilterName(route *ir.HTTPRoute) string { - return fmt.Sprintf("%s_%s", oauth2Filter, route.Name) + return perRouteFilterName(oauth2Filter, route.Name) } func oauth2Config(route *ir.HTTPRoute) (*oauth2v3.OAuth2, error) { @@ -340,8 +340,8 @@ func (*oidc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { if irRoute.OIDC == nil { return nil } - - if err := enableFilterOnRoute(oauth2Filter, route, irRoute); err != nil { + filterName := oauth2FilterName(irRoute) + if err := enableFilterOnRoute(route, filterName); err != nil { return err } return nil diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml index d1451e968e3..e8dd3181425 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml @@ -19,6 +19,34 @@ http: - host: "10.0.0.1" port: 50000 extAuth: + name: default/httproute-1 + http: + authority: http-backend.envoy-gateway:80 + headersToBackend: + - header1 + - header2 + path: /auth + destination: + name: securitypolicy/default/policy-for-first-route/http-backend + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 80 + protocol: HTTP + weight: 1 + - name: httproute/default/httproute-1/rule/1/match/0/www_example_com + hostname: "*" + pathMatch: + exact: "foo" + destination: + name: httproute/default/httproute-1/rule/0 + settings: + - endpoints: + - host: "10.0.0.1" + port: 50000 + extAuth: + name: default/httproute-1 http: authority: http-backend.envoy-gateway:80 headersToBackend: @@ -45,6 +73,7 @@ http: - host: "10.0.0.2" port: 60000 extAuth: + name: default/gateway-1 grpc: authority: grpc-backend.default:9000 destination: diff --git a/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml index 3b72788ce31..36ab0dbb7ba 100644 --- a/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml @@ -15,7 +15,7 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.basic_auth_first-route + name: envoy.filters.http.basic_auth/first-route typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuth users: diff --git a/internal/xds/translator/testdata/out/xds-ir/basic-auth.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/basic-auth.routes.yaml index f87be11474a..22938d503e2 100644 --- a/internal/xds/translator/testdata/out/xds-ir/basic-auth.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/basic-auth.routes.yaml @@ -13,6 +13,6 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.basic_auth_first-route: + envoy.filters.http.basic_auth/first-route: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml index 52735036294..1fa830a1f83 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml @@ -15,7 +15,7 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.ext_authz_httproute/default/httproute-1/rule/0/match/0/www_example_com + name: envoy.filters.http.ext_authz/default/httproute-1 typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz httpService: @@ -30,7 +30,7 @@ uri: http://http-backend.envoy-gateway:80/auth transportApiVersion: V3 - disabled: true - name: envoy.filters.http.ext_authz_httproute/default/httproute-2/rule/0/match/0/www_example_com + name: envoy.filters.http.ext_authz/default/gateway-1 typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz allowedHeaders: diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth.routes.yaml index 0b039af3da3..7ca5275220c 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-auth.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth.routes.yaml @@ -13,7 +13,18 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_authz_httproute/default/httproute-1/rule/0/match/0/www_example_com: + envoy.filters.http.ext_authz/default/httproute-1: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + - match: + path: foo + name: httproute/default/httproute-1/rule/1/match/0/www_example_com + route: + cluster: httproute/default/httproute-1/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.ext_authz/default/httproute-1: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} - match: @@ -24,6 +35,6 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_authz_httproute/default/httproute-2/rule/0/match/0/www_example_com: + envoy.filters.http.ext_authz/default/gateway-1: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml index 73388e331ed..132b1d06a48 100644 --- a/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml @@ -15,7 +15,7 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.oauth2_first-route + name: envoy.filters.http.oauth2/first-route typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2 config: @@ -56,7 +56,7 @@ timeout: 10s uri: https://oauth.foo.com/token - disabled: true - name: envoy.filters.http.oauth2_second-route + name: envoy.filters.http.oauth2/second-route typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2 config: diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc.routes.yaml index a093d6967ac..d597d98514e 100644 --- a/internal/xds/translator/testdata/out/xds-ir/oidc.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/oidc.routes.yaml @@ -13,7 +13,7 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.oauth2_first-route: + envoy.filters.http.oauth2/first-route: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} - match: @@ -24,6 +24,6 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.oauth2_second-route: + envoy.filters.http.oauth2/second-route: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} diff --git a/internal/xds/translator/utils.go b/internal/xds/translator/utils.go index 8ebcc74c677..64f946373b7 100644 --- a/internal/xds/translator/utils.go +++ b/internal/xds/translator/utils.go @@ -14,9 +14,8 @@ import ( "strings" routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" + hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" "google.golang.org/protobuf/types/known/anypb" - - "github.com/envoyproxy/gateway/internal/ir" ) const ( @@ -80,21 +79,17 @@ func clusterName(host string, port uint32) string { } // enableFilterOnRoute enables a filterType on the provided route. -func enableFilterOnRoute(filterType string, route *routev3.Route, irRoute *ir.HTTPRoute) error { +func enableFilterOnRoute(route *routev3.Route, filterName string) error { if route == nil { return errors.New("xds route is nil") } - if irRoute == nil { - return errors.New("ir route is nil") - } - filterName := perRouteFilterName(filterType, irRoute.Name) filterCfg := route.GetTypedPerFilterConfig() if _, ok := filterCfg[filterName]; ok { // This should not happen since this is the only place where the filter // config is added in a route. return fmt.Errorf("route already contains filter config: %s, %+v", - filterType, route) + filterName, route) } // Enable the corresponding filter for this route. @@ -114,6 +109,16 @@ func enableFilterOnRoute(filterType string, route *routev3.Route, irRoute *ir.HT return nil } -func perRouteFilterName(filterType, routeName string) string { - return fmt.Sprintf("%s_%s", filterType, routeName) +// perRouteFilterName generates a unique filter name for the provided filterType and configName. +func perRouteFilterName(filterType, configName string) string { + return fmt.Sprintf("%s/%s", filterType, configName) +} + +func hcmContainsFilter(mgr *hcmv3.HttpConnectionManager, filterName string) bool { + for _, existingFilter := range mgr.HttpFilters { + if existingFilter.Name == filterName { + return true + } + } + return false } From 6e8862c04642ce2f4c8f20de1f36e2b2c95d151f Mon Sep 17 00:00:00 2001 From: Shyunn <1147212064@qq.com> Date: Fri, 15 Mar 2024 09:00:13 +0800 Subject: [PATCH 02/29] feat: expose prom port in rl svc (#2914) Signed-off-by: ShyunnY <1147212064@qq.com> --- .../kubernetes/ratelimit/resource_provider.go | 10 ++++ .../ratelimit/resource_provider_test.go | 58 ++++++++++++++----- .../envoy-ratelimit-service-default.yaml | 30 ++++++++++ ...nvoy-ratelimit-service-no-prometheus.yaml} | 0 4 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 internal/infrastructure/kubernetes/ratelimit/testdata/services/envoy-ratelimit-service-default.yaml rename internal/infrastructure/kubernetes/ratelimit/testdata/{envoy-ratelimit-service.yaml => services/envoy-ratelimit-service-no-prometheus.yaml} (100%) diff --git a/internal/infrastructure/kubernetes/ratelimit/resource_provider.go b/internal/infrastructure/kubernetes/ratelimit/resource_provider.go index 67c5312b5e3..90f646d014f 100644 --- a/internal/infrastructure/kubernetes/ratelimit/resource_provider.go +++ b/internal/infrastructure/kubernetes/ratelimit/resource_provider.go @@ -103,6 +103,16 @@ func (r *ResourceRender) Service() (*corev1.Service, error) { }, } + if enablePrometheus(r.rateLimit) { + metricsPort := corev1.ServicePort{ + Name: "metrics", + Protocol: corev1.ProtocolTCP, + Port: PrometheusPort, + TargetPort: intstr.IntOrString{IntVal: PrometheusPort}, + } + ports = append(ports, metricsPort) + } + labels := rateLimitLabels() kubernetesServiceSpec := &egv1a1.KubernetesServiceSpec{ Type: egv1a1.GetKubernetesServiceType(egv1a1.ServiceTypeClusterIP), diff --git a/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go b/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go index d322e8c925e..6c56631d9cc 100644 --- a/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go +++ b/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go @@ -126,29 +126,61 @@ func loadServiceAccount() (*corev1.ServiceAccount, error) { } func TestService(t *testing.T) { + cfg, err := config.New() require.NoError(t, err) - cfg.EnvoyGateway.RateLimit = &egv1a1.RateLimit{ - Backend: egv1a1.RateLimitDatabaseBackend{ - Type: egv1a1.RedisBackendType, - Redis: &egv1a1.RateLimitRedisSettings{ - URL: "redis.redis.svc:6379", + cases := []struct { + caseName string + rateLimit *egv1a1.RateLimit + }{ + { + caseName: "default", + rateLimit: &egv1a1.RateLimit{ + Backend: egv1a1.RateLimitDatabaseBackend{ + Type: egv1a1.RedisBackendType, + Redis: &egv1a1.RateLimitRedisSettings{ + URL: "redis.redis.svc:6379", + }, + }, + }, + }, + { + caseName: "no-prometheus", + rateLimit: &egv1a1.RateLimit{ + Backend: egv1a1.RateLimitDatabaseBackend{ + Type: egv1a1.RedisBackendType, + Redis: &egv1a1.RateLimitRedisSettings{ + URL: "redis.redis.svc:6379", + }, + }, + Telemetry: &egv1a1.RateLimitTelemetry{ + Metrics: &egv1a1.RateLimitMetrics{ + Prometheus: &egv1a1.RateLimitMetricsPrometheusProvider{ + Disable: true, + }, + }, + }, }, }, } - r := NewResourceRender(cfg.Namespace, cfg.EnvoyGateway, ownerReferenceUID) - svc, err := r.Service() - require.NoError(t, err) - expected, err := loadService() - require.NoError(t, err) + for _, tc := range cases { + cfg.EnvoyGateway.RateLimit = tc.rateLimit + r := NewResourceRender(cfg.Namespace, cfg.EnvoyGateway, ownerReferenceUID) - assert.Equal(t, expected, svc) + svc, err := r.Service() + require.NoError(t, err) + + expected, err := loadService(tc.caseName) + require.NoError(t, err) + + assert.Equal(t, expected, svc) + } } -func loadService() (*corev1.Service, error) { - serviceYAML, err := os.ReadFile("testdata/envoy-ratelimit-service.yaml") +func loadService(caseName string) (*corev1.Service, error) { + serviceYAML, err := os.ReadFile(fmt.Sprintf("testdata/services/envoy-ratelimit-service-%s.yaml", caseName)) if err != nil { return nil, err } diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/services/envoy-ratelimit-service-default.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/services/envoy-ratelimit-service-default.yaml new file mode 100644 index 00000000000..be6bddc9a41 --- /dev/null +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/services/envoy-ratelimit-service-default.yaml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: envoy-ratelimit + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + name: envoy-ratelimit + namespace: envoy-gateway-system + ownerReferences: + - apiVersion: v1 + kind: Service + name: envoy-gateway + uid: test-owner-reference-uid-for-service +spec: + type: ClusterIP + sessionAffinity: None + ports: + - name: http + port: 8081 + protocol: TCP + targetPort: 8081 + - name: metrics + port: 19001 + protocol: TCP + targetPort: 19001 + selector: + app.kubernetes.io/name: envoy-ratelimit + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/envoy-ratelimit-service.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/services/envoy-ratelimit-service-no-prometheus.yaml similarity index 100% rename from internal/infrastructure/kubernetes/ratelimit/testdata/envoy-ratelimit-service.yaml rename to internal/infrastructure/kubernetes/ratelimit/testdata/services/envoy-ratelimit-service-no-prometheus.yaml From 93b79198f060b5e932516eeeae81380e29e797f0 Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Thu, 14 Mar 2024 18:24:53 -0700 Subject: [PATCH 03/29] blog post for v1.0 (#2923) * blog post for v1.0 Signed-off-by: Arko Dasgupta * rm space Signed-off-by: Arko Dasgupta * fix metadata Signed-off-by: Arko Dasgupta * edits Signed-off-by: Arko Dasgupta --------- Signed-off-by: Arko Dasgupta --- .../en/blog/news/1.0-release/1.0-release.md | 65 +++++++++++++++++++ site/content/en/v1.0.0/releases/v1.0.0.md | 4 +- 2 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 site/content/en/blog/news/1.0-release/1.0-release.md diff --git a/site/content/en/blog/news/1.0-release/1.0-release.md b/site/content/en/blog/news/1.0-release/1.0-release.md new file mode 100644 index 00000000000..25ac83a1c66 --- /dev/null +++ b/site/content/en/blog/news/1.0-release/1.0-release.md @@ -0,0 +1,65 @@ +--- +date: 2024-03-14 +title: Announcing Envoy Gateway’s 1.0 Release! +linkTitle: 1.0 Release +description: > + v1.0.0 is here ! +author: Alice Wasko (Ambassador Labs), Arko Dasgupta (Tetrate), Congqi Zhu (CECloud), Guy Daich (SAP), Huabing Zhao (Tetrate), Jianpeng He (Tetrate), Xunzhuo Liu (Tencent) +--- + +Today we’re ecstatic to announce the 1.0 release of Envoy Gateway (EG) for Kubernetes. A mature version ready for widespread adoption in production that simplifies the use of Envoy for managing North-South traffic. + +After nearly two years with contributions from over 90 engineers we are proud to say EG meets the goals that Matt outlined in the [original post](https://blog.envoyproxy.io/introducing-envoy-gateway-ad385cc59532) introducing the project, summarized here: +* Built around the (then emerging) [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io) +* Addresses common needs with a solution that that is simple to configure and understand +* Provides [great docs](https://gateway.envoyproxy.io/v1.0.0/user/) for common use cases to enable ease of adoption +* Empowers the community and vendors to drive the project forward through an extensible API + +Can’t wait to try it? Visit the EG [user guides](https://gateway.envoyproxy.io/v1.0.0/user/) to get started with Envoy Gateway 1.0 + +## Envoy Gateway 1.0 + +The 1.0 release brings a lot of functionality. In addition to implementing the full Kubernetes Gateway API – including the awesome Envoy L7 features you love like per-request policy, load balancing, and best-in-class observability – it also goes further, Envoy Gateway 1.0: +* Provides support for common features such as Rate Limiting and OAuth2.0 +* Deploys and upgrades Envoy on your behalf, easing operations and lifecycle management +* Introduces extensions to the Kubernetes Gateway API to address [Client](https://gateway.envoyproxy.io/v1.0.0/api/extension_types/#clienttrafficpolicy), [Backend](https://gateway.envoyproxy.io/v1.0.0/api/extension_types/#backendtrafficpolicy), and [Security](https://gateway.envoyproxy.io/v1.0.0/api/extension_types/#securitypolicy) settings and features +* Is easily extensible through the [EnvoyPatchPolicy](https://gateway.envoyproxy.io/v1.0.0/user/extensibility/envoy-patch-policy/) API to allow you to configure any Envoy behavior (including stuff you build yourself!) +* Has a CLI, [egctl](https://gateway.envoyproxy.io/v1.0.0/user/operations/egctl/), for interacting with and debugging the system +* Comes with a large (and growing!) set of user guides to make common use cases straightforward to implement + +## What Does 1.0 Mean for the Project? + +We won’t be slowing down on feature velocity – if anything, we expect more features to ship as many users who have been following the project and waiting on the GA release get involved. For us, 1.0 means two big things: +* A commitment to ensuring stability with releases for CVE fixes. From 1.0 onwards you can have confidence that the configuration you write today will continue to work in the same way for the foreseeable future. +* That the community is confident in the system's readiness for general use by everyone, not just Envoy experts. + +## How We Got Here + +The project has moved so fast it feels like a whirlwind, but a high level recap is in order. + +* 2022 + * In May, Matt Klein published the original post introducing the project + * In November, Envoy Gateway passed the entire Kubernetes Gateway API conformance suite for the first time. + +* 2023 + * We enabled early adopters to understand target use cases by providing configuration escape valves. + * The number of project contributors and early adopters were growing and shaping the direction of Envoy Gateway + * Extensions to Envoy Gateway and the Gateway API to tackle client, backend, and security challenges early adopters were facing, were introduced by the community + +* 2024 + * Envoy Gateway 1.0 is ready for widespread adoption thanks to over 90 contributors and the engagement from early production adopters + +## What’s Next? + +Following the 1.0 release, we’ll be focusing on: +* **Ease of operation**: Continuing to improve the Journey to Production and operability of the system + * Better metrics dashboards for control plane and data plane observability + * Exposing more knobs to fine tune more traffic shaping parameters +* **Features**: More API Gateway features such as authorization (IP Addresses, JWT Claims, API Key, etc.) and compression +* **Scale**: Building out a performance benchmarking tool into our CI +* **Extensibility**: We plan on providing a first-class API for data plane extensions such as Lua, WASM, and Ext Proc to enable users to implement their custom use cases +* **Outside of Kubernetes**: Running Envoy Gateway in non-k8s environments - this has been an [explicit goal](https://gateway.envoyproxy.io/v1.0.0/contributions/design/goals/#all-environments) and we’d like to focus on this in the coming months. Envoy Proxy already supports running on bare metal environments, with Envoy Gateway users getting the added advantage of a simpler API +* **Debug**: And a lot of capabilities with the [egctl CLI](https://gateway.envoyproxy.io/v1.0.0/user/operations/egctl/) + +## Get Started +If you’ve been looking to use Envoy as a Gateway, check out our [quickstart guide](https://gateway.envoyproxy.io/v1.0.0/user/quickstart/) and give it a try! If you’re interested in contributing, check out our [guide for getting involved](https://gateway.envoyproxy.io/v1.0.0/contributions/)! diff --git a/site/content/en/v1.0.0/releases/v1.0.0.md b/site/content/en/v1.0.0/releases/v1.0.0.md index 134a7f23071..22630e9e98c 100644 --- a/site/content/en/v1.0.0/releases/v1.0.0.md +++ b/site/content/en/v1.0.0/releases/v1.0.0.md @@ -1,9 +1,9 @@ --- title: "v1.0.0" -publishdate: 2023-11-01 +publishdate: 2024-03-13 --- -Date: Nov 1, 2023 +Date: March 13, 2024 ## Documentation - Added User Guide for Local Ratelimit From f543bbb45afb9de67be2d7346d0998a39fd9d061 Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Thu, 14 Mar 2024 18:52:56 -0700 Subject: [PATCH 04/29] rm extra "that" from blog (#2928) Signed-off-by: Arko Dasgupta --- site/content/en/blog/news/1.0-release/1.0-release.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/en/blog/news/1.0-release/1.0-release.md b/site/content/en/blog/news/1.0-release/1.0-release.md index 25ac83a1c66..a225457e456 100644 --- a/site/content/en/blog/news/1.0-release/1.0-release.md +++ b/site/content/en/blog/news/1.0-release/1.0-release.md @@ -11,7 +11,7 @@ Today we’re ecstatic to announce the 1.0 release of Envoy Gateway (EG) for Kub After nearly two years with contributions from over 90 engineers we are proud to say EG meets the goals that Matt outlined in the [original post](https://blog.envoyproxy.io/introducing-envoy-gateway-ad385cc59532) introducing the project, summarized here: * Built around the (then emerging) [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io) -* Addresses common needs with a solution that that is simple to configure and understand +* Addresses common needs with a solution that is simple to configure and understand * Provides [great docs](https://gateway.envoyproxy.io/v1.0.0/user/) for common use cases to enable ease of adoption * Empowers the community and vendors to drive the project forward through an extensible API From 36505f4e0773f072952383280a5ce4145be40d77 Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Thu, 14 Mar 2024 19:47:20 -0700 Subject: [PATCH 05/29] docs: `%s/Application/API/g` (#2929) --- site/content/en/_index.md | 4 ++-- site/hugo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/site/content/en/_index.md b/site/content/en/_index.md index 69fbf5e612c..6e0cb9739f3 100644 --- a/site/content/en/_index.md +++ b/site/content/en/_index.md @@ -9,12 +9,12 @@ title: Envoy Gateway CONTRIBUTING -

Manages Envoy Proxy as a Standalone or Kubernetes-based Application Gateway

+

Manages Envoy Proxy as a Standalone or Kubernetes-based API Gateway

{{< blocks/link-down color="white" >}} {{< /blocks/cover >}} {{% blocks/lead color="black" %}} -Manage **Envoy Proxy** as a **Standalone** or **Kubernetes-based** Application Gateway. +Manage **Envoy Proxy** as a **Standalone** or **Kubernetes-based** API Gateway. **Gateway API** are used to **dynamically** provision and configure the managed Envoy Proxies. {{% /blocks/lead %}} diff --git a/site/hugo.toml b/site/hugo.toml index ca33d858ce5..3f4ea92e457 100644 --- a/site/hugo.toml +++ b/site/hugo.toml @@ -64,7 +64,7 @@ languageName ="English" weight = 1 [languages.en.params] title = "Envoy Gateway" -description = "Manages Envoy Proxy as a Standalone or Kubernetes-based Application Gateway" +description = "Manages Envoy Proxy as a Standalone or Kubernetes-based API Gateway" [markup] [markup.goldmark] From f52a6f6c01f30c2b75e023cf5c84552bd648bfb3 Mon Sep 17 00:00:00 2001 From: Huabing Zhao Date: Fri, 15 Mar 2024 17:28:02 +0800 Subject: [PATCH 06/29] Pin version to v1.0.0 in 1.0.0 docs (#2933) pin version to v1.0.0 in 1.0.0 docs Signed-off-by: huabing zhao --- site/content/en/v1.0.0/install/api.md | 3 +-- site/content/en/v1.0.0/install/install-helm.md | 10 +++++----- .../en/v1.0.0/user/operations/deployment-mode.md | 4 ++-- .../en/v1.0.0/user/traffic/multicluster-service.md | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/site/content/en/v1.0.0/install/api.md b/site/content/en/v1.0.0/install/api.md index 165a91d01e6..a1eb0a554f4 100644 --- a/site/content/en/v1.0.0/install/api.md +++ b/site/content/en/v1.0.0/install/api.md @@ -3,7 +3,7 @@ title = "gateway-helm" +++ -![Version: v0.0.0-latest](https://img.shields.io/badge/Version-v0.0.0--latest-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: latest](https://img.shields.io/badge/AppVersion-latest-informational?style=flat-square) +![Version: v1.0.0](https://img.shields.io/badge/Version-v1.0.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: latest](https://img.shields.io/badge/AppVersion-latest-informational?style=flat-square) The Helm chart for Envoy Gateway @@ -53,4 +53,3 @@ The Helm chart for Envoy Gateway | deployment.replicas | int | `1` | | | envoyGatewayMetricsService.port | int | `19001` | | | kubernetesClusterDomain | string | `"cluster.local"` | | - diff --git a/site/content/en/v1.0.0/install/install-helm.md b/site/content/en/v1.0.0/install/install-helm.md index 3f3c57e1db9..923606aa139 100644 --- a/site/content/en/v1.0.0/install/install-helm.md +++ b/site/content/en/v1.0.0/install/install-helm.md @@ -18,7 +18,7 @@ The Envoy Gateway Helm chart is hosted by DockerHub. It is published at `oci://docker.io/envoyproxy/gateway-helm`. {{% alert title="Note" color="primary" %}} -We use `v0.0.0-latest` as the latest development version. +We use `v1.0.0` as the latest development version. You can visit [Envoy Gateway Helm Chart](https://hub.docker.com/r/envoyproxy/gateway-helm/tags) for more releases. {{% /alert %}} @@ -34,7 +34,7 @@ Refer to the [Developer Guide](/latest/contributions/develop) to learn more. Install the Gateway API CRDs and Envoy Gateway: ```shell -helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.0.0-latest -n envoy-gateway-system --create-namespace +helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.0.0 -n envoy-gateway-system --create-namespace ``` Wait for Envoy Gateway to become available: @@ -66,7 +66,7 @@ Some of the quick ways of using the helm install command for envoy gateway insta ### Increase the replicas ```shell -helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.0.0-latest -n envoy-gateway-system --create-namespace --set deployment.replicas=2 +helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.0.0 -n envoy-gateway-system --create-namespace --set deployment.replicas=2 ``` ### Change the kubernetesClusterDomain name @@ -74,7 +74,7 @@ helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.0.0-latest If you have installed your cluster with different domain name you can use below command. ```shell -helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.0.0-latest -n envoy-gateway-system --create-namespace --set kubernetesClusterDomain= +helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.0.0 -n envoy-gateway-system --create-namespace --set kubernetesClusterDomain= ``` **Note**: Above are some of the ways we can directly use for customization of our installation. But if you are looking for more complex changes [values.yaml](https://helm.sh/docs/chart_template_guide/values_files/) comes to rescue. @@ -111,7 +111,7 @@ Here we have made three changes to our values.yaml file. Increase the resources You can use the below command to install the envoy gateway using values.yaml file. ```shell -helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.0.0-latest -n envoy-gateway-system --create-namespace -f values.yaml +helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.0.0 -n envoy-gateway-system --create-namespace -f values.yaml ``` {{% alert title="Helm Chart Values" color="primary" %}} diff --git a/site/content/en/v1.0.0/user/operations/deployment-mode.md b/site/content/en/v1.0.0/user/operations/deployment-mode.md index e82acb2cfd6..26fcb116bc8 100644 --- a/site/content/en/v1.0.0/user/operations/deployment-mode.md +++ b/site/content/en/v1.0.0/user/operations/deployment-mode.md @@ -52,7 +52,7 @@ helm install \ --set config.envoyGateway.provider.kubernetes.watch.type=Namespaces \ --set config.envoyGateway.provider.kubernetes.watch.namespaces={marketing} \ eg-marketing oci://docker.io/envoyproxy/gateway-helm \ ---version v0.0.0-latest -n marketing --create-namespace +--version v1.0.0 -n marketing --create-namespace ``` Lets create a `GatewayClass` linked to the marketing team's Envoy Gateway controller, and as well other resources linked to it, so the `backend` application operated by this team can be exposed to external clients. @@ -230,7 +230,7 @@ helm install \ --set config.envoyGateway.provider.kubernetes.watch.type=Namespaces \ --set config.envoyGateway.provider.kubernetes.watch.namespaces={product} \ eg-product oci://docker.io/envoyproxy/gateway-helm \ ---version v0.0.0-latest -n product --create-namespace +--version v1.0.0 -n product --create-namespace ``` Lets create a `GatewayClass` linked to the product team's Envoy Gateway controller, and as well other resources linked to it, so the `backend` application operated by this team can be exposed to external clients. diff --git a/site/content/en/v1.0.0/user/traffic/multicluster-service.md b/site/content/en/v1.0.0/user/traffic/multicluster-service.md index d0fd7a83fb1..23af5f874c5 100644 --- a/site/content/en/v1.0.0/user/traffic/multicluster-service.md +++ b/site/content/en/v1.0.0/user/traffic/multicluster-service.md @@ -39,7 +39,7 @@ Once the above steps are done and all the pods are up in both the clusters. We a Install the Gateway API CRDs and Envoy Gateway in cluster1: ```shell -helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.0.0-latest -n envoy-gateway-system --create-namespace --kubeconfig output/kubeconfigs/kind-config-cluster1 +helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.0.0 -n envoy-gateway-system --create-namespace --kubeconfig output/kubeconfigs/kind-config-cluster1 ``` Wait for Envoy Gateway to become available: From 62ecf15bbeae2c614bb87366545eb2fa2c54a745 Mon Sep 17 00:00:00 2001 From: Huabing Zhao Date: Fri, 15 Mar 2024 22:55:27 +0800 Subject: [PATCH 07/29] Run certgen when upgrading (#2934) run certgen when upgrading Signed-off-by: huabing zhao --- charts/gateway-helm/templates/certgen.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/gateway-helm/templates/certgen.yaml b/charts/gateway-helm/templates/certgen.yaml index bea4792f242..78d5ec2a28d 100644 --- a/charts/gateway-helm/templates/certgen.yaml +++ b/charts/gateway-helm/templates/certgen.yaml @@ -6,7 +6,7 @@ metadata: labels: {{- include "eg.labels" . | nindent 4 }} annotations: - "helm.sh/hook": pre-install + "helm.sh/hook": pre-install, pre-upgrade {{- if .Values.certgen.job.annotations }} {{- toYaml .Values.certgen.job.annotations | nindent 4 -}} {{- end }} From 6c6f92f81a99aeaff4e068b58c96c05d5214b8b8 Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Fri, 15 Mar 2024 11:14:01 -0500 Subject: [PATCH 08/29] chore: use v1.0.0 as default for upgrade test (#2938) use v1.0.0 as default for upgrade test Signed-off-by: Guy Daich Co-authored-by: zirain --- test/e2e/tests/eg_upgrade.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/tests/eg_upgrade.go b/test/e2e/tests/eg_upgrade.go index ffa61d1139e..48f07faad6f 100644 --- a/test/e2e/tests/eg_upgrade.go +++ b/test/e2e/tests/eg_upgrade.go @@ -34,7 +34,7 @@ var EGUpgradeTest = suite.ConformanceTest{ depNS := "envoy-gateway-system" lastVersionTag := os.Getenv("last_version_tag") if lastVersionTag == "" { - lastVersionTag = "v0.6.0" // Default version tag if not specified + lastVersionTag = "v1.0.0" // Default version tag if not specified } ns := "gateway-upgrade-infra" From d145921a855c5df13e66414f2ec5ba029963080c Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Fri, 15 Mar 2024 12:06:47 -0500 Subject: [PATCH 09/29] api: connection limits (#2709) * api: connection limit Signed-off-by: Guy Daich * Apply suggestions from code review Co-authored-by: Arko Dasgupta Signed-off-by: Guy Daich * fix gen Signed-off-by: Guy Daich --------- Signed-off-by: Guy Daich Co-authored-by: Arko Dasgupta --- api/v1alpha1/clienttrafficpolicy_types.go | 4 + api/v1alpha1/connection_types.go | 33 ++++++ api/v1alpha1/zz_generated.deepcopy.go | 100 +++++++++++++----- ...y.envoyproxy.io_clienttrafficpolicies.yaml | 21 ++++ site/content/en/latest/api/extension_types.md | 30 ++++++ 5 files changed, 163 insertions(+), 25 deletions(-) create mode 100644 api/v1alpha1/connection_types.go diff --git a/api/v1alpha1/clienttrafficpolicy_types.go b/api/v1alpha1/clienttrafficpolicy_types.go index 236a9b8d30b..58412c73723 100644 --- a/api/v1alpha1/clienttrafficpolicy_types.go +++ b/api/v1alpha1/clienttrafficpolicy_types.go @@ -87,6 +87,10 @@ type ClientTrafficPolicySpec struct { // // +optional Timeout *ClientTimeout `json:"timeout,omitempty"` + // Connection includes client connection settings. + // + // +optional + Connection *Connection `json:"connection,omitempty"` } // HeaderSettings providess configuration options for headers on the listener. diff --git a/api/v1alpha1/connection_types.go b/api/v1alpha1/connection_types.go new file mode 100644 index 00000000000..13132ddd8e1 --- /dev/null +++ b/api/v1alpha1/connection_types.go @@ -0,0 +1,33 @@ +// 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 v1alpha1 + +import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" + +// Connection allows users to configure connection-level settings +type Connection struct { + // Limit defines limits related to connections + // + // +optional + Limit *ConnectionLimit `json:"limit,omitempty"` +} + +type ConnectionLimit struct { + // Value of the maximum concurrent connections limit. + // When the limit is reached, incoming connections will be closed after the CloseDelay duration. + // Default: unlimited. + // + // +optional + // +kubebuilder:validation:Minimum=0 + Value *int64 `json:"value,omitempty"` + + // CloseDelay defines the delay to use before closing connections that are rejected + // once the limit value is reached. + // Default: none. + // + // +optional + CloseDelay *gwapiv1.Duration `json:"closeDelay,omitempty"` +} diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 1bd56138b65..314cd3a653e 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -14,9 +14,9 @@ import ( "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" - apisv1 "sigs.k8s.io/gateway-api/apis/v1" + "sigs.k8s.io/gateway-api/apis/v1" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -24,12 +24,12 @@ func (in *ActiveHealthCheck) DeepCopyInto(out *ActiveHealthCheck) { *out = *in if in.Timeout != nil { in, out := &in.Timeout, &out.Timeout - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } if in.Interval != nil { in, out := &in.Interval, &out.Interval - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } if in.UnhealthyThreshold != nil { @@ -94,12 +94,12 @@ func (in *BackOffPolicy) DeepCopyInto(out *BackOffPolicy) { *out = *in if in.BaseInterval != nil { in, out := &in.BaseInterval, &out.BaseInterval - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } if in.MaxInterval != nil { in, out := &in.MaxInterval, &out.MaxInterval - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } } @@ -286,7 +286,7 @@ func (in *CORS) DeepCopyInto(out *CORS) { } if in.MaxAge != nil { in, out := &in.MaxAge, &out.MaxAge - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } if in.AllowCredentials != nil { @@ -514,6 +514,11 @@ func (in *ClientTrafficPolicySpec) DeepCopyInto(out *ClientTrafficPolicySpec) { *out = new(ClientTimeout) (*in).DeepCopyInto(*out) } + if in.Connection != nil { + in, out := &in.Connection, &out.Connection + *out = new(Connection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientTrafficPolicySpec. @@ -531,7 +536,7 @@ func (in *ClientValidationContext) DeepCopyInto(out *ClientValidationContext) { *out = *in if in.CACertificateRefs != nil { in, out := &in.CACertificateRefs, &out.CACertificateRefs - *out = make([]apisv1.SecretObjectReference, len(*in)) + *out = make([]v1.SecretObjectReference, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -568,6 +573,51 @@ func (in *Compression) DeepCopy() *Compression { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Connection) DeepCopyInto(out *Connection) { + *out = *in + if in.Limit != nil { + in, out := &in.Limit, &out.Limit + *out = new(ConnectionLimit) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Connection. +func (in *Connection) DeepCopy() *Connection { + if in == nil { + return nil + } + out := new(Connection) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConnectionLimit) DeepCopyInto(out *ConnectionLimit) { + *out = *in + if in.Value != nil { + in, out := &in.Value, &out.Value + *out = new(int64) + **out = **in + } + if in.CloseDelay != nil { + in, out := &in.CloseDelay, &out.CloseDelay + *out = new(v1.Duration) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionLimit. +func (in *ConnectionLimit) DeepCopy() *ConnectionLimit { + if in == nil { + return nil + } + out := new(ConnectionLimit) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConsistentHash) DeepCopyInto(out *ConsistentHash) { *out = *in @@ -1503,7 +1553,7 @@ func (in *FaultInjectionDelay) DeepCopyInto(out *FaultInjectionDelay) { *out = *in if in.FixedDelay != nil { in, out := &in.FixedDelay, &out.FixedDelay - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } if in.Percentage != nil { @@ -1721,7 +1771,7 @@ func (in *HTTPClientTimeout) DeepCopyInto(out *HTTPClientTimeout) { *out = *in if in.RequestReceivedTimeout != nil { in, out := &in.RequestReceivedTimeout, &out.RequestReceivedTimeout - *out = new(apisv1.Duration) + *out = new(v1.Duration) **out = **in } } @@ -1767,12 +1817,12 @@ func (in *HTTPTimeout) DeepCopyInto(out *HTTPTimeout) { *out = *in if in.ConnectionIdleTimeout != nil { in, out := &in.ConnectionIdleTimeout, &out.ConnectionIdleTimeout - *out = new(apisv1.Duration) + *out = new(v1.Duration) **out = **in } if in.MaxConnectionDuration != nil { in, out := &in.MaxConnectionDuration, &out.MaxConnectionDuration - *out = new(apisv1.Duration) + *out = new(v1.Duration) **out = **in } } @@ -2290,7 +2340,7 @@ func (in *KubernetesWatchMode) DeepCopyInto(out *KubernetesWatchMode) { } if in.NamespaceSelector != nil { in, out := &in.NamespaceSelector, &out.NamespaceSelector - *out = new(v1.LabelSelector) + *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } } @@ -2456,7 +2506,7 @@ func (in *PassiveHealthCheck) DeepCopyInto(out *PassiveHealthCheck) { } if in.Interval != nil { in, out := &in.Interval, &out.Interval - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } if in.ConsecutiveLocalOriginFailures != nil { @@ -2476,7 +2526,7 @@ func (in *PassiveHealthCheck) DeepCopyInto(out *PassiveHealthCheck) { } if in.BaseEjectionTime != nil { in, out := &in.BaseEjectionTime, &out.BaseEjectionTime - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } if in.MaxEjectionPercent != nil { @@ -2526,7 +2576,7 @@ func (in *PerRetryPolicy) DeepCopyInto(out *PerRetryPolicy) { *out = *in if in.Timeout != nil { in, out := &in.Timeout, &out.Timeout - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } if in.BackOff != nil { @@ -2848,7 +2898,7 @@ func (in *RateLimit) DeepCopyInto(out *RateLimit) { in.Backend.DeepCopyInto(&out.Backend) if in.Timeout != nil { in, out := &in.Timeout, &out.Timeout - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } if in.Telemetry != nil { @@ -3058,7 +3108,7 @@ func (in *RedisTLSSettings) DeepCopyInto(out *RedisTLSSettings) { *out = *in if in.CertificateRef != nil { in, out := &in.CertificateRef, &out.CertificateRef - *out = new(apisv1.SecretObjectReference) + *out = new(v1.SecretObjectReference) (*in).DeepCopyInto(*out) } } @@ -3268,7 +3318,7 @@ func (in *SecurityPolicyStatus) DeepCopyInto(out *SecurityPolicyStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) + *out = make([]metav1.Condition, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -3290,12 +3340,12 @@ func (in *ShutdownConfig) DeepCopyInto(out *ShutdownConfig) { *out = *in if in.DrainTimeout != nil { in, out := &in.DrainTimeout, &out.DrainTimeout - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } if in.MinDrainDuration != nil { in, out := &in.MinDrainDuration, &out.MinDrainDuration - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } } @@ -3315,7 +3365,7 @@ func (in *SlowStart) DeepCopyInto(out *SlowStart) { *out = *in if in.Window != nil { in, out := &in.Window, &out.Window - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } } @@ -3405,12 +3455,12 @@ func (in *TCPKeepalive) DeepCopyInto(out *TCPKeepalive) { } if in.IdleTime != nil { in, out := &in.IdleTime, &out.IdleTime - *out = new(apisv1.Duration) + *out = new(v1.Duration) **out = **in } if in.Interval != nil { in, out := &in.Interval, &out.Interval - *out = new(apisv1.Duration) + *out = new(v1.Duration) **out = **in } } @@ -3430,7 +3480,7 @@ func (in *TCPTimeout) DeepCopyInto(out *TCPTimeout) { *out = *in if in.ConnectTimeout != nil { in, out := &in.ConnectTimeout, &out.ConnectTimeout - *out = new(apisv1.Duration) + *out = new(v1.Duration) **out = **in } } diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml index de677482ee6..bc5bd0c18f5 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -91,6 +91,27 @@ spec: x-kubernetes-validations: - message: customHeader cannot be used in conjunction with xForwardedFor rule: '!(has(self.xForwardedFor) && has(self.customHeader))' + connection: + description: Connection includes client connection settings. + properties: + limit: + description: Limit defines limits related to connections + properties: + closeDelay: + description: 'CloseDelay defines the delay to use before closing + connections that are rejected once the limit value is reached. + Default: none.' + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + value: + description: 'Value of the maximum concurrent connections + limit. When the limit is reached, incoming connections will + be closed after the CloseDelay duration. Default: unlimited.' + format: int64 + minimum: 0 + type: integer + type: object + type: object enableProxyProtocol: description: EnableProxyProtocol interprets the ProxyProtocol header and adds the Client Address into the X-Forwarded-For header. Note diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 12334c0bf2d..c0d2fde3281 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -329,6 +329,7 @@ _Appears in:_ | `http1` | _[HTTP1Settings](#http1settings)_ | false | HTTP1 provides HTTP/1 configuration on the listener. | | `headers` | _[HeaderSettings](#headersettings)_ | false | HeaderSettings provides configuration for header management. | | `timeout` | _[ClientTimeout](#clienttimeout)_ | false | Timeout settings for the client connections. | +| `connection` | _[Connection](#connection)_ | false | Connection includes client connection settings. | #### ClientValidationContext @@ -371,6 +372,35 @@ _Appears in:_ +#### Connection + + + +Connection allows users to configure connection-level settings + +_Appears in:_ +- [ClientTrafficPolicySpec](#clienttrafficpolicyspec) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `limit` | _[ConnectionLimit](#connectionlimit)_ | false | Limit defines limits related to connections | + + +#### ConnectionLimit + + + + + +_Appears in:_ +- [Connection](#connection) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `value` | _integer_ | false | Value of the maximum concurrent connections limit. When the limit is reached, incoming connections will be closed after the CloseDelay duration. Default: unlimited. | +| `closeDelay` | _[Duration](#duration)_ | false | CloseDelay defines the delay to use before closing connections that are rejected once the limit value is reached. Default: none. | + + #### ConsistentHash From 23fa358fa8738b03df96210bd7c9b823a462726f Mon Sep 17 00:00:00 2001 From: Marco De Benedictis Date: Fri, 15 Mar 2024 18:27:24 +0100 Subject: [PATCH 10/29] docs: fix name spelling in threat model (#2936) Signed-off-by: Marco De Benedictis Co-authored-by: zirain --- site/content/en/latest/user/security/threat-model.md | 2 +- site/content/en/v1.0.0/user/security/threat-model.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/site/content/en/latest/user/security/threat-model.md b/site/content/en/latest/user/security/threat-model.md index 76ae562c7c0..59323551f9e 100644 --- a/site/content/en/latest/user/security/threat-model.md +++ b/site/content/en/latest/user/security/threat-model.md @@ -14,7 +14,7 @@ James Callaghan, Torin van den Bulk, Eduardo Olarte ## Reviewers -Arko Dasgupta, Matt Turner, Zack Butcher, Marco De Benedectis +Arko Dasgupta, Matt Turner, Zack Butcher, Marco De Benedictis ## Introduction diff --git a/site/content/en/v1.0.0/user/security/threat-model.md b/site/content/en/v1.0.0/user/security/threat-model.md index 76ae562c7c0..59323551f9e 100644 --- a/site/content/en/v1.0.0/user/security/threat-model.md +++ b/site/content/en/v1.0.0/user/security/threat-model.md @@ -14,7 +14,7 @@ James Callaghan, Torin van den Bulk, Eduardo Olarte ## Reviewers -Arko Dasgupta, Matt Turner, Zack Butcher, Marco De Benedectis +Arko Dasgupta, Matt Turner, Zack Butcher, Marco De Benedictis ## Introduction From 0f4a9dd920c00075dbf9607db36703357549327b Mon Sep 17 00:00:00 2001 From: Dennis Zhou Date: Sat, 16 Mar 2024 07:42:24 +0800 Subject: [PATCH 11/29] api: support failOpen in ext auth (#2908) * api:support failOpen in ext auth Signed-off-by: Dennis Zhou * update api Signed-off-by: Dennis Zhou --------- Signed-off-by: Dennis Zhou --- api/v1alpha1/ext_auth_types.go | 10 ++++++++++ api/v1alpha1/zz_generated.deepcopy.go | 5 +++++ .../gateway.envoyproxy.io_securitypolicies.yaml | 11 +++++++++++ site/content/en/latest/api/extension_types.md | 1 + 4 files changed, 27 insertions(+) diff --git a/api/v1alpha1/ext_auth_types.go b/api/v1alpha1/ext_auth_types.go index 25d28a91003..6e455aa42d1 100644 --- a/api/v1alpha1/ext_auth_types.go +++ b/api/v1alpha1/ext_auth_types.go @@ -40,6 +40,16 @@ type ExtAuth struct { // in HeadersToExtAuth or not. // +optional HeadersToExtAuth []string `json:"headersToExtAuth,omitempty"` + + // FailOpen is a switch used to control the behavior when a response from the External Authorization service cannot be obtained. + // If FailOpen is set to true, the system allows the traffic to pass through. + // Otherwise, if it is set to false or not set (defaulting to false), + // the system blocks the traffic and returns a HTTP 5xx error, reflecting a fail-closed approach. + // This setting determines whether to prioritize accessibility over strict security in case of authorization service failure. + // + // +optional + // +kubebuilder:default=false + FailOpen *bool `json:"failOpen,omitempty"` } // GRPCExtAuthService defines the gRPC External Authorization service diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 314cd3a653e..5421cf01a9a 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1380,6 +1380,11 @@ func (in *ExtAuth) DeepCopyInto(out *ExtAuth) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.FailOpen != nil { + in, out := &in.FailOpen, &out.FailOpen + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtAuth. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml index 43b648987db..65df396eb7b 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -154,6 +154,17 @@ spec: extAuth: description: ExtAuth defines the configuration for External Authorization. properties: + failOpen: + default: false + description: FailOpen is a switch used to control the behavior + when a response from the External Authorization service cannot + be obtained. If FailOpen is set to true, the system allows the + traffic to pass through. Otherwise, if it is set to false or + not set (defaulting to false), the system blocks the traffic + and returns a HTTP 5xx error, reflecting a fail-closed approach. + This setting determines whether to prioritize accessibility + over strict security in case of authorization service failure. + type: boolean grpc: description: GRPC defines the gRPC External Authorization service. Either GRPCService or HTTPService must be specified, and only diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index c0d2fde3281..39b596350db 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -936,6 +936,7 @@ _Appears in:_ | `grpc` | _[GRPCExtAuthService](#grpcextauthservice)_ | true | GRPC defines the gRPC External Authorization service. Either GRPCService or HTTPService must be specified, and only one of them can be provided. | | `http` | _[HTTPExtAuthService](#httpextauthservice)_ | true | HTTP defines the HTTP External Authorization service. Either GRPCService or HTTPService must be specified, and only one of them can be provided. | | `headersToExtAuth` | _string array_ | false | HeadersToExtAuth defines the client request headers that will be included in the request to the external authorization service. Note: If not specified, the default behavior for gRPC and HTTP external authorization services is different due to backward compatibility reasons. All headers will be included in the check request to a gRPC authorization server. Only the following headers will be included in the check request to an HTTP authorization server: Host, Method, Path, Content-Length, and Authorization. And these headers will always be included to the check request to an HTTP authorization server by default, no matter whether they are specified in HeadersToExtAuth or not. | +| `failOpen` | _boolean_ | false | FailOpen is a switch used to control the behavior when a response from the External Authorization service cannot be obtained. If FailOpen is set to true, the system allows the traffic to pass through. Otherwise, if it is set to false or not set (defaulting to false), the system blocks the traffic and returns a HTTP 5xx error, reflecting a fail-closed approach. This setting determines whether to prioritize accessibility over strict security in case of authorization service failure. | #### ExtensionAPISettings From df051faa8c010d7c1cd1a2de965917cb5dad1cdd Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Fri, 15 Mar 2024 19:11:34 -0500 Subject: [PATCH 12/29] API: EnvoyExtensionPolicy (#2570) * api: EnvoyExtensionPolicy Signed-off-by: Guy Daich * review fixes Signed-off-by: Guy Daich * fix lint Signed-off-by: Guy Daich * remove ext-proc, ordering Signed-off-by: Guy Daich * fix gen Signed-off-by: Guy Daich * remove ordering, add CEL, fix api and design doc Signed-off-by: Guy Daich * fix CEL names Signed-off-by: Guy Daich --------- Signed-off-by: Guy Daich --- api/v1alpha1/envoyextensionypolicy_types.go | 71 ++++ api/v1alpha1/envoygateway_types.go | 4 + api/v1alpha1/zz_generated.deepcopy.go | 75 ++++ ....envoyproxy.io_envoyextensionpolicies.yaml | 398 ++++++++++++++++++ site/content/en/latest/api/extension_types.md | 51 +++ .../design/envoy-extension-policy.md | 165 ++++++++ .../envoyextensionpolicy_test.go | 186 ++++++++ 7 files changed, 950 insertions(+) create mode 100644 api/v1alpha1/envoyextensionypolicy_types.go create mode 100644 charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml create mode 100644 site/content/en/latest/contributions/design/envoy-extension-policy.md create mode 100644 test/cel-validation/envoyextensionpolicy_test.go diff --git a/api/v1alpha1/envoyextensionypolicy_types.go b/api/v1alpha1/envoyextensionypolicy_types.go new file mode 100644 index 00000000000..4b14955be42 --- /dev/null +++ b/api/v1alpha1/envoyextensionypolicy_types.go @@ -0,0 +1,71 @@ +// 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" +) + +const ( + // KindEnvoyExtensionPolicy is the name of the EnvoyExtensionPolicy kind. + KindEnvoyExtensionPolicy = "EnvoyExtensionPolicy" +) + +// +kubebuilder:object:root=true +// +kubebuilder:resource:shortName=eep +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[?(@.type=="Accepted")].reason` +// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` + +// EnvoyExtensionPolicy allows the user to configure various envoy extensibility options for the Gateway. +type EnvoyExtensionPolicy struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of EnvoyExtensionPolicy. + Spec EnvoyExtensionPolicySpec `json:"spec"` + + // Status defines the current status of EnvoyExtensionPolicy. + Status gwapiv1a2.PolicyStatus `json:"status,omitempty"` +} + +// EnvoyExtensionPolicySpec defines the desired state of EnvoyExtensionPolicy. +type EnvoyExtensionPolicySpec struct { + // +kubebuilder:validation:XValidation:rule="self.group == 'gateway.networking.k8s.io'", message="this policy can only have a targetRef.group of gateway.networking.k8s.io" + // +kubebuilder:validation:XValidation:rule="self.kind in ['Gateway', 'HTTPRoute', 'GRPCRoute', 'UDPRoute', 'TCPRoute', 'TLSRoute']", message="this policy can only have a targetRef.kind of Gateway/HTTPRoute/GRPCRoute/TCPRoute/UDPRoute/TLSRoute" + // +kubebuilder:validation:XValidation:rule="!has(self.sectionName)",message="this policy does not yet support the sectionName field" + // + // TargetRef is the name of the Gateway resource this policy + // is being attached to. + // This Policy and the TargetRef MUST be in the same namespace + // for this Policy to have effect and be applied to the Gateway. + // TargetRef + TargetRef gwapiv1a2.PolicyTargetReferenceWithSectionName `json:"targetRef"` + + // Priority of the EnvoyExtensionPolicy. + // If multiple EnvoyExtensionPolices are applied to the same + // TargetRef, extensions will execute in the ascending order of + // the priority i.e. int32.min has the highest priority and + // int32.max has the lowest priority. + // Defaults to 0. + // + // +optional + Priority int32 `json:"priority,omitempty"` +} + +//+kubebuilder:object:root=true + +// EnvoyExtensionPolicyList contains a list of EnvoyExtensionPolicy resources. +type EnvoyExtensionPolicyList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []EnvoyExtensionPolicy `json:"items"` +} + +func init() { + SchemeBuilder.Register(&EnvoyExtensionPolicy{}, &EnvoyExtensionPolicyList{}) +} diff --git a/api/v1alpha1/envoygateway_types.go b/api/v1alpha1/envoygateway_types.go index 145fc9b5fca..74f1edafe85 100644 --- a/api/v1alpha1/envoygateway_types.go +++ b/api/v1alpha1/envoygateway_types.go @@ -151,6 +151,10 @@ type ExtensionAPISettings struct { // EnableEnvoyPatchPolicy enables Envoy Gateway to // reconcile and implement the EnvoyPatchPolicy resources. EnableEnvoyPatchPolicy bool `json:"enableEnvoyPatchPolicy"` + + // EnableEnvoyExtensionPolicy enables Envoy Gateway to + // reconcile and implement the EnvoyExtensionPolicy resources. + EnableEnvoyExtensionPolicy bool `json:"enableEnvoyExtensionPolicy"` } // EnvoyGatewayProvider defines the desired configuration of a provider. diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 5421cf01a9a..b474db20c74 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -703,6 +703,81 @@ func (in *EnvironmentCustomTag) DeepCopy() *EnvironmentCustomTag { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EnvoyExtensionPolicy) DeepCopyInto(out *EnvoyExtensionPolicy) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyExtensionPolicy. +func (in *EnvoyExtensionPolicy) DeepCopy() *EnvoyExtensionPolicy { + if in == nil { + return nil + } + out := new(EnvoyExtensionPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *EnvoyExtensionPolicy) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EnvoyExtensionPolicyList) DeepCopyInto(out *EnvoyExtensionPolicyList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]EnvoyExtensionPolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyExtensionPolicyList. +func (in *EnvoyExtensionPolicyList) DeepCopy() *EnvoyExtensionPolicyList { + if in == nil { + return nil + } + out := new(EnvoyExtensionPolicyList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *EnvoyExtensionPolicyList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EnvoyExtensionPolicySpec) DeepCopyInto(out *EnvoyExtensionPolicySpec) { + *out = *in + in.TargetRef.DeepCopyInto(&out.TargetRef) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyExtensionPolicySpec. +func (in *EnvoyExtensionPolicySpec) DeepCopy() *EnvoyExtensionPolicySpec { + if in == nil { + return nil + } + out := new(EnvoyExtensionPolicySpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *EnvoyGateway) DeepCopyInto(out *EnvoyGateway) { *out = *in diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml new file mode 100644 index 00000000000..842dd9ce336 --- /dev/null +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -0,0 +1,398 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: envoyextensionpolicies.gateway.envoyproxy.io +spec: + group: gateway.envoyproxy.io + names: + kind: EnvoyExtensionPolicy + listKind: EnvoyExtensionPolicyList + plural: envoyextensionpolicies + shortNames: + - eep + singular: envoyextensionpolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Accepted")].reason + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: EnvoyExtensionPolicy allows the user to configure various envoy + extensibility options for the Gateway. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of EnvoyExtensionPolicy. + properties: + priority: + description: Priority of the EnvoyExtensionPolicy. If multiple EnvoyExtensionPolices + are applied to the same TargetRef, extensions will execute in the + ascending order of the priority i.e. int32.min has the highest priority + and int32.max has the lowest priority. Defaults to 0. + format: int32 + type: integer + targetRef: + description: TargetRef is the name of the Gateway resource this policy + is being attached to. This Policy and the TargetRef MUST be in the + same namespace for this Policy to have effect and be applied to + the Gateway. TargetRef + properties: + group: + description: Group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: Namespace is the namespace of the referent. When + unspecified, the local namespace is inferred. Even when policy + targets a resource in a different namespace, it MUST only apply + to traffic originating from the same namespace as the policy. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + sectionName: + description: "SectionName is the name of a section within the + target resource. When unspecified, this targetRef targets the + entire resource. In the following resources, SectionName is + interpreted as the following: \n * Gateway: Listener Name * + Service: Port Name \n If a SectionName is specified, but does + not exist on the targeted object, the Policy must fail to attach, + and the policy implementation should record a `ResolvedRefs` + or similar Condition in the Policy's status." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - group + - kind + - name + type: object + x-kubernetes-validations: + - message: this policy can only have a targetRef.group of gateway.networking.k8s.io + rule: self.group == 'gateway.networking.k8s.io' + - message: this policy can only have a targetRef.kind of Gateway/HTTPRoute/GRPCRoute/TCPRoute/UDPRoute/TLSRoute + rule: self.kind in ['Gateway', 'HTTPRoute', 'GRPCRoute', 'UDPRoute', + 'TCPRoute', 'TLSRoute'] + - message: this policy does not yet support the sectionName field + rule: '!has(self.sectionName)' + required: + - targetRef + type: object + status: + description: Status defines the current status of EnvoyExtensionPolicy. + properties: + ancestors: + description: "Ancestors is a list of ancestor resources (usually Gateways) + that are associated with the policy, and the status of the policy + with respect to each ancestor. When this policy attaches to a parent, + the controller that manages the parent and the ancestors MUST add + an entry to this list when the controller first sees the policy + and SHOULD update the entry as appropriate when the relevant ancestor + is modified. \n Note that choosing the relevant ancestor is left + to the Policy designers; an important part of Policy design is designing + the right object level at which to namespace this status. \n Note + also that implementations MUST ONLY populate ancestor status for + the Ancestor resources they are responsible for. Implementations + MUST use the ControllerName field to uniquely identify the entries + in this list that they are responsible for. \n Note that to achieve + this, the list of PolicyAncestorStatus structs MUST be treated as + a map with a composite key, made up of the AncestorRef and ControllerName + fields combined. \n A maximum of 16 ancestors will be represented + in this list. An empty list means the Policy is not relevant for + any ancestors. \n If this slice is full, implementations MUST NOT + add further entries. Instead they MUST consider the policy unimplementable + and signal that on any related resources such as the ancestor that + would be referenced here. For example, if this list was full on + BackendTLSPolicy, no additional Gateways would be able to reference + the Service targeted by the BackendTLSPolicy." + items: + description: "PolicyAncestorStatus describes the status of a route + with respect to an associated Ancestor. \n Ancestors refer to + objects that are either the Target of a policy or above it in + terms of object hierarchy. For example, if a policy targets a + Service, the Policy's Ancestors are, in order, the Service, the + HTTPRoute, the Gateway, and the GatewayClass. Almost always, in + this hierarchy, the Gateway will be the most useful object to + place Policy status on, so we recommend that implementations SHOULD + use Gateway as the PolicyAncestorStatus object unless the designers + have a _very_ good reason otherwise. \n In the context of policy + attachment, the Ancestor is used to distinguish which resource + results in a distinct application of this policy. For example, + if a policy targets a Service, it may have a distinct result per + attached Gateway. \n Policies targeting the same resource may + have different effects depending on the ancestors of those resources. + For example, different Gateways targeting the same Service may + have different capabilities, especially if they have different + underlying implementations. \n For example, in BackendTLSPolicy, + the Policy attaches to a Service that is used as a backend in + a HTTPRoute that is itself attached to a Gateway. In this case, + the relevant object for status is the Gateway, and that is the + ancestor object referred to in this status. \n Note that a parent + is also an ancestor, so for objects where the parent is the relevant + object for status, this struct SHOULD still be used. \n This struct + is intended to be used in a slice that's effectively a map, with + a composite key made up of the AncestorRef and the ControllerName." + properties: + ancestorRef: + description: AncestorRef corresponds with a ParentRef in the + spec that this PolicyAncestorStatus struct describes the status + of. + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. When unspecified, + \"gateway.networking.k8s.io\" is inferred. To set the + core API group (such as for a \"Service\" kind referent), + Group must be explicitly set to \"\" (empty string). \n + Support: Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n There are + two kinds of parent resources with \"Core\" support: \n + * Gateway (Gateway conformance profile) * Service (Mesh + conformance profile, experimental, ClusterIP Services + only) \n Support for other resources is Implementation-Specific." + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. + When unspecified, this refers to the local namespace of + the Route. \n Note that there are specific rules for ParentRefs + which cross namespace boundaries. Cross-namespace references + are only valid if they are explicitly allowed by something + in the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides + a generic way to enable any other kind of cross-namespace + reference. \n ParentRefs + from a Route to a Service in the same namespace are \"producer\" + routes, which apply default routing rules to inbound connections + from any namespace to the Service. \n ParentRefs from + a Route to a Service in a different namespace are \"consumer\" + routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the + Route, for which the intended destination of the connections + are a Service targeted as a ParentRef of the Route. + \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "Port is the network port this Route targets. + It can be interpreted differently based on the type of + parent resource. \n When the parent resource is a Gateway, + this targets all listeners listening on the specified + port that also support this kind of Route(and select this + Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to + a specific port as opposed to a listener(s) whose port(s) + may be changed. When both Port and SectionName are specified, + the name and port of the selected listener must match + both specified values. \n + When the parent resource is a Service, this targets a + specific port in the Service spec. When both Port (experimental) + and SectionName are specified, the name and port of the + selected port must match both specified values. + \n Implementations MAY choose to support other parent + resources. Implementations supporting other types of parent + resources MUST clearly document how/if Port is interpreted. + \n For the purpose of status, an attachment is considered + successful as long as the parent resource accepts it partially. + For example, Gateway listeners can restrict which Routes + can attach to them by Route kind, namespace, or hostname. + If 1 of 2 Gateway listeners accept attachment from the + referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from + this Route, the Route MUST be considered detached from + the Gateway. \n Support: Extended \n " + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: "SectionName is the name of a section within + the target resource. In the following resources, SectionName + is interpreted as the following: \n * Gateway: Listener + Name. When both Port (experimental) and SectionName are + specified, the name and port of the selected listener + must match both specified values. * Service: Port Name. + When both Port (experimental) and SectionName are specified, + the name and port of the selected listener must match + both specified values. Note that attaching Routes to Services + as Parents is part of experimental Mesh support and is + not supported for any other purpose. \n Implementations + MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName + is interpreted. \n When unspecified (empty string), this + will reference the entire resource. For the purpose of + status, an attachment is considered successful if at least + one section in the parent resource accepts it. For example, + Gateway listeners can restrict which Routes can attach + to them by Route kind, namespace, or hostname. If 1 of + 2 Gateway listeners accept attachment from the referencing + Route, the Route MUST be considered successfully attached. + If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + conditions: + description: Conditions describes the status of the Policy with + respect to the given Ancestor. + items: + description: "Condition contains details for one aspect of + the current state of this API Resource. --- This struct + is intended for direct use as an array at the field path + .status.conditions. For example, \n type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: \"Available\", \"Progressing\", + and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields + }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should + be when the underlying condition changed. If that is + not known, then using the time when the API field changed + is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, + if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the + current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier + indicating the reason for the condition's last transition. + Producers of specific condition types may define expected + values and meanings for this field, and whether the + values are considered a guaranteed API. The value should + be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across + resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability + to deconflict is important. The regex it matches is + (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: "ControllerName is a domain/path string that indicates + the name of the controller that wrote this status. This corresponds + with the controllerName field on GatewayClass. \n Example: + \"example.net/gateway-controller\". \n The format of this + field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid + Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + \n Controllers MUST populate this field when writing status. + Controllers should ensure that entries to status populated + with their ControllerName are cleaned up when they are no + longer necessary." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + required: + - ancestorRef + - controllerName + type: object + maxItems: 16 + type: array + required: + - ancestors + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 39b596350db..8f115810b47 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -18,6 +18,8 @@ API group. - [BackendTrafficPolicyList](#backendtrafficpolicylist) - [ClientTrafficPolicy](#clienttrafficpolicy) - [ClientTrafficPolicyList](#clienttrafficpolicylist) +- [EnvoyExtensionPolicy](#envoyextensionpolicy) +- [EnvoyExtensionPolicyList](#envoyextensionpolicylist) - [EnvoyGateway](#envoygateway) - [EnvoyPatchPolicy](#envoypatchpolicy) - [EnvoyPatchPolicyList](#envoypatchpolicylist) @@ -484,6 +486,54 @@ _Appears in:_ | `defaultValue` | _string_ | false | DefaultValue defines the default value to use if the environment variable is not set. | +#### EnvoyExtensionPolicy + + + +EnvoyExtensionPolicy allows the user to configure various envoy extensibility options for the Gateway. + +_Appears in:_ +- [EnvoyExtensionPolicyList](#envoyextensionpolicylist) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1` +| `kind` | _string_ | |`EnvoyExtensionPolicy` +| `metadata` | _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#objectmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. | +| `spec` | _[EnvoyExtensionPolicySpec](#envoyextensionpolicyspec)_ | true | Spec defines the desired state of EnvoyExtensionPolicy. | + + +#### EnvoyExtensionPolicyList + + + +EnvoyExtensionPolicyList contains a list of EnvoyExtensionPolicy resources. + + + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1` +| `kind` | _string_ | |`EnvoyExtensionPolicyList` +| `metadata` | _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#listmeta-v1-meta)_ | true | Refer to Kubernetes API documentation for fields of `metadata`. | +| `items` | _[EnvoyExtensionPolicy](#envoyextensionpolicy) array_ | true | | + + +#### EnvoyExtensionPolicySpec + + + +EnvoyExtensionPolicySpec defines the desired state of EnvoyExtensionPolicy. + +_Appears in:_ +- [EnvoyExtensionPolicy](#envoyextensionpolicy) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `targetRef` | _[PolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the Gateway resource this policy is being attached to. This Policy and the TargetRef MUST be in the same namespace for this Policy to have effect and be applied to the Gateway. TargetRef | +| `priority` | _integer_ | false | Priority of the EnvoyExtensionPolicy. If multiple EnvoyExtensionPolices are applied to the same TargetRef, extensions will execute in the ascending order of the priority i.e. int32.min has the highest priority and int32.max has the lowest priority. Defaults to 0. | + + #### EnvoyGateway @@ -952,6 +1002,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | | `enableEnvoyPatchPolicy` | _boolean_ | true | EnableEnvoyPatchPolicy enables Envoy Gateway to reconcile and implement the EnvoyPatchPolicy resources. | +| `enableEnvoyExtensionPolicy` | _boolean_ | true | EnableEnvoyExtensionPolicy enables Envoy Gateway to reconcile and implement the EnvoyExtensionPolicy resources. | #### ExtensionHooks diff --git a/site/content/en/latest/contributions/design/envoy-extension-policy.md b/site/content/en/latest/contributions/design/envoy-extension-policy.md new file mode 100644 index 00000000000..b02f9f3beb5 --- /dev/null +++ b/site/content/en/latest/contributions/design/envoy-extension-policy.md @@ -0,0 +1,165 @@ +--- +title: "EnvoyExtensionPolicy " +--- + +## Overview + +This design document introduces the `EnvoyExtensionPolicy` API allowing system administrators to configure traffic +processing extensibility policies, based on existing Network and HTTP Envoy proxy [extension points][]. + +Envoy Gateway already provides two methods of control plane extensibility that can be used to achieve this functionality: +* [Envoy Patch Policy][] can be used to patch Listener filters and HTTP Connection Manager filters. +* [Envoy Extension Manager][] can be used to programmatically mutate Listener filters and HTTP Connection Manager filters. + +These approaches require a high level of Envoy and Envoy Gateway expertise and may create a significant operational +burden for users (see [Alternatives][] for more details). For this reason, this document proposes to support Envoy +data plane extensibility options as first class citizens of Envoy Gateway. + +## Goals +* Add an API definition to hold settings for configuring extensibility rules on the traffic entering the gateway. + +## Non Goals +* Define the API configuration fields in this API. +* Define the API for the following extension options: + * Native Envoy extensions: custom C++ extensions that must be compiled into the Envoy binary. + * Non-filter extensions: services, matchers, tracers, private key providers, resource monitors, etc. + +## Implementation +`EnvoyExtensionPolicy` is a [Policy Attachment][] type API that can be used to extend [Gateway API][] +to define traffic extension rules. + +`BackendTrafficPolicy` is enhanced to allow users to provide per-route config for Extensions. + +### Example +Here is an example highlighting how a user can configure this API for the External Processing extension. + +```yaml +apiVersion: gateway.networking.k8s.io/v1 +kind: GatewayClass +metadata: + name: eg +spec: + controllerName: gateway.envoyproxy.io/gatewayclass-controller +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: eg + namespace: default +spec: + gatewayClassName: eg + listeners: + - name: https + protocol: HTTPS + port: 443 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: backend + namespace: default +spec: + parentRefs: + - name: eg + hostnames: + - "www.example.com" + rules: + - backendRefs: + - group: "" + kind: Service + name: backend + port: 3000 + weight: 1 + matches: + - path: + type: PathPrefix + value: / +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: EnvoyExtensionPolicy +metadata: + name: ext-proc-policy + namespace: default +spec: + priority: 10 + extProc: + - service: + backendRef: + group: "" + kind: Service + name: myExtProc + port: 3000 + processingMode: + request: + headers: SEND + body: BUFFERED + response: + headers: SKIP + body: STREAMED + attributes: + request: + - xds.route_metadata + - connection.requested_server_name + response: + - request.path + messageTimeout: 5s + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: eg + namespace: default +``` + +## Features / API Fields +Here is a list of features that can be included in this API +* Network Filters: + * WASM + * Golang +* HTTP Filters: + * External Processing + * Lua + * WASM + * Golang + +## Design Decisions +* This API will only support a single `targetRef` and can bind to a `Gateway` resource or a `HTTPRoute` or `GRPCRoute` or `TCPRoute`. +* Extensions that support both Network and HTTP filter variants (e.g. WASM, Golang) will be translated to the appropriate filter type according to the sort of route that they attach to. +* Extensions that only support HTTP extensibility (Ext-Proc, LUA) can only be attached to HTTP/GRPC Routes. +* A user-defined extension that is added to the request processing flow can have a significant impact on security, + resilience and performance of the proxy. Gateway Operators can restrict access to the extensibility policy using K8s RBAC. +* Extensibility will be disabled by default, and can be enabled using [Envoy Gateway][] API. +* Users may need to customize the order of extension and built-in filters. This will be addressed in a separate issue. +* Gateway operators may need to include multiple extensions (e.g. WASM modules developed by different teams and distributed separately). + This API will support attachment of multiple policies. Extension will execute in an order defined by the priority field. +* This API resource MUST be part of same namespace as the targetRef resource +* If the policy targets a resource but cannot attach to it, this information should be reflected + in the Policy Status field using the `Conflicted=True` condition. +* If Policy A has a `targetRef` that includes a `sectionName` i.e. + it targets a specific Listener within a `Gateway` and Policy B has a `targetRef` that targets the same + entire Gateway then + * Policy A will be applied/attached to the specific Listener defined in the `targetRef.SectionName` + * Policy B will be applied to the remaining Listeners within the Gateway. Policy B will have an additional + status condition `Overridden=True`. +* A Policy targeting the most specific scope wins over a policy targeting a lesser specific scope. + i.e. A Policy targeting a `Listener` overrides a Policy targeting the `Gateway` the listener/section is a part of. + + +## Alternatives +* The project can indefinitely wait for these configuration parameters to be part of the [Gateway API][]. +* The project can implement support for HTTP traffic extensions using vendor-specific [Gateway API Route Filters][] + instead of policies. However, this option will is less convenient for definition of gateway-level extensions. +* Users can leverage the existing [Envoy Patch Policy][] to inject extension filters. However, Envoy Gateway strives + to provide a simple abstraction for common use cases and easy operations. Envoy patches require a high level of + end-user Envoy expertise, and knowledge of how Envoy Gateway generates XDS. Such patches may be too difficult + and fragile for some users to maintain. +* Users can leverage the existing [Envoy Extension Manager][] to inject extension filters. However, this requires a + significant investment by users to build and operate an extension manager alongside Envoy Gateway. + +[extension points]: https://www.envoyproxy.io/docs/envoy/latest/extending/extending +[Policy Attachment]: https://gateway-api.sigs.k8s.io/references/policy-attachment +[Gateway API]: https://gateway-api.sigs.k8s.io/ +[Gateway API Route Filters]: https://gateway-api.sigs.k8s.io/api-types/httproute/#filters-optional +[Envoy Gateway]: ../../api/extension_types/#envoygateway +[Envoy Patch Policy]: ../../api/extension_types/#envoypatchpolicy +[Envoy Extension Manager]: ../extending-envoy-gateway.md +[Alternatives]: #Alternatives diff --git a/test/cel-validation/envoyextensionpolicy_test.go b/test/cel-validation/envoyextensionpolicy_test.go new file mode 100644 index 00000000000..4a179c84ec3 --- /dev/null +++ b/test/cel-validation/envoyextensionpolicy_test.go @@ -0,0 +1,186 @@ +// 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. + +//go:build celvalidation +// +build celvalidation + +package celvalidation + +import ( + "context" + "fmt" + "strings" + "testing" + "time" + + egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" +) + +func TestEnvoyExtensionPolicyTarget(t *testing.T) { + ctx := context.Background() + baseeep := egv1a1.EnvoyExtensionPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "eep", + Namespace: metav1.NamespaceDefault, + }, + Spec: egv1a1.EnvoyExtensionPolicySpec{}, + } + + sectionName := gwapiv1a2.SectionName("foo") + + cases := []struct { + desc string + mutate func(eep *egv1a1.EnvoyExtensionPolicy) + mutateStatus func(eep *egv1a1.EnvoyExtensionPolicy) + wantErrors []string + }{ + { + desc: "valid gateway targetRef", + mutate: func(eep *egv1a1.EnvoyExtensionPolicy) { + eep.Spec = egv1a1.EnvoyExtensionPolicySpec{ + TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ + PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + Group: gwapiv1a2.Group("gateway.networking.k8s.io"), + Kind: gwapiv1a2.Kind("Gateway"), + Name: gwapiv1a2.ObjectName("eg"), + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "valid httproute targetRef", + mutate: func(eep *egv1a1.EnvoyExtensionPolicy) { + eep.Spec = egv1a1.EnvoyExtensionPolicySpec{ + TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ + PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + Group: gwapiv1a2.Group("gateway.networking.k8s.io"), + Kind: gwapiv1a2.Kind("HTTPRoute"), + Name: gwapiv1a2.ObjectName("httpbin-route"), + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "no targetRef", + mutate: func(eep *egv1a1.EnvoyExtensionPolicy) { + eep.Spec = egv1a1.EnvoyExtensionPolicySpec{} + }, + wantErrors: []string{ + "spec.targetRef.kind: Invalid value: \"\": spec.targetRef.kind in body should be at least 1 chars long", + "spec.targetRef.name: Invalid value: \"\": spec.targetRef.name in body should be at least 1 chars long", + "spec.targetRef: Invalid value: \"object\": this policy can only have a targetRef.group of gateway.networking.k8s.io", + "spec.targetRef: Invalid value: \"object\": this policy can only have a targetRef.kind of Gateway/HTTPRoute/GRPCRoute/TCPRoute/UDPRoute/TLSRoute", + }, + }, + { + desc: "targetRef unsupported kind", + mutate: func(eep *egv1a1.EnvoyExtensionPolicy) { + eep.Spec = egv1a1.EnvoyExtensionPolicySpec{ + TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ + PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + Group: gwapiv1a2.Group("gateway.networking.k8s.io"), + Kind: gwapiv1a2.Kind("foo"), + Name: gwapiv1a2.ObjectName("eg"), + }, + }, + } + }, + wantErrors: []string{ + "spec.targetRef: Invalid value: \"object\": this policy can only have a targetRef.kind of Gateway/HTTPRoute/GRPCRoute/TCPRoute/UDPRoute/TLSRoute", + }, + }, + { + desc: "targetRef unsupported group", + mutate: func(eep *egv1a1.EnvoyExtensionPolicy) { + eep.Spec = egv1a1.EnvoyExtensionPolicySpec{ + TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ + PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + Group: gwapiv1a2.Group("foo"), + Kind: gwapiv1a2.Kind("Gateway"), + Name: gwapiv1a2.ObjectName("eg"), + }, + }, + } + }, + wantErrors: []string{ + "spec.targetRef: Invalid value: \"object\": this policy can only have a targetRef.group of gateway.networking.k8s.io", + }, + }, + { + desc: "targetRef unsupported group and kind", + mutate: func(eep *egv1a1.EnvoyExtensionPolicy) { + eep.Spec = egv1a1.EnvoyExtensionPolicySpec{ + TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ + PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + Group: gwapiv1a2.Group("foo"), + Kind: gwapiv1a2.Kind("bar"), + Name: gwapiv1a2.ObjectName("eg"), + }, + }, + } + }, + wantErrors: []string{ + "spec.targetRef: Invalid value: \"object\": this policy can only have a targetRef.group of gateway.networking.k8s.io", + "spec.targetRef: Invalid value: \"object\": this policy can only have a targetRef.kind of Gateway/HTTPRoute/GRPCRoute/TCPRoute/UDPRoute/TLSRoute", + }, + }, + { + desc: "sectionName disabled until supported", + mutate: func(eep *egv1a1.EnvoyExtensionPolicy) { + eep.Spec = egv1a1.EnvoyExtensionPolicySpec{ + TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ + PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + Group: gwapiv1a2.Group("gateway.networking.k8s.io"), + Kind: gwapiv1a2.Kind("Gateway"), + Name: gwapiv1a2.ObjectName("eg"), + }, + SectionName: §ionName, + }, + } + }, + wantErrors: []string{ + "spec.targetRef: Invalid value: \"object\": this policy does not yet support the sectionName field", + }, + }, + } + + for _, tc := range cases { + t.Run(tc.desc, func(t *testing.T) { + eep := baseeep.DeepCopy() + eep.Name = fmt.Sprintf("eep-%v", time.Now().UnixNano()) + + if tc.mutate != nil { + tc.mutate(eep) + } + err := c.Create(ctx, eep) + + if tc.mutateStatus != nil { + tc.mutateStatus(eep) + err = c.Status().Update(ctx, eep) + } + + if (len(tc.wantErrors) != 0) != (err != nil) { + t.Fatalf("Unexpected response while creating EnvoyExtensionPolicy; got err=\n%v\n;want error=%v", err, tc.wantErrors) + } + + var missingErrorStrings []string + for _, wantError := range tc.wantErrors { + if !strings.Contains(strings.ToLower(err.Error()), strings.ToLower(wantError)) { + missingErrorStrings = append(missingErrorStrings, wantError) + } + } + if len(missingErrorStrings) != 0 { + t.Errorf("Unexpected response while creating EnvoyExtensionPolicy; got err=\n%v\n;missing strings within error=%q", err, missingErrorStrings) + } + }) + } +} From 46e6cebaf5482503690a2e22d68daab471b8dffe Mon Sep 17 00:00:00 2001 From: zirain Date: Sat, 16 Mar 2024 08:22:29 +0800 Subject: [PATCH 13/29] chore: add helm template test (#2935) * add helm template test Signed-off-by: zirain * use tag latest Signed-off-by: zirain --------- Signed-off-by: zirain --- test/helm/default.yaml | 546 +++++++++++++++++++++++++++++++++++++++++ tools/make/common.mk | 2 +- tools/make/helm.mk | 4 + 3 files changed, 551 insertions(+), 1 deletion(-) create mode 100644 test/helm/default.yaml diff --git a/test/helm/default.yaml b/test/helm/default.yaml new file mode 100644 index 00000000000..f88b64a1ede --- /dev/null +++ b/test/helm/default.yaml @@ -0,0 +1,546 @@ +--- +# Source: gateway-helm/templates/envoy-gateway-deployment.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: envoy-gateway + namespace: 'default' + labels: + helm.sh/chart: gateway-helm-v0.0.0-latest + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + app.kubernetes.io/version: "latest" + app.kubernetes.io/managed-by: Helm +--- +# Source: gateway-helm/templates/envoy-gateway-config.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: envoy-gateway-config + namespace: 'default' + labels: + helm.sh/chart: gateway-helm-v0.0.0-latest + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + app.kubernetes.io/version: "latest" + app.kubernetes.io/managed-by: Helm +data: + envoy-gateway.yaml: | + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyGateway + gateway: + controllerName: gateway.envoyproxy.io/gatewayclass-controller + logging: + level: + default: info + provider: + type: Kubernetes +--- +# Source: gateway-helm/templates/envoy-gateway-rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: eg-gateway-helm-envoy-gateway-role +rules: +- apiGroups: + - "" + resources: + - nodes + - namespaces + verbs: + - get + - list + - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - gatewayclasses + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - gatewayclasses/status + verbs: + - update +- apiGroups: + - multicluster.x-k8s.io + resources: + - serviceimports + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - configmaps + - secrets + - services + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch +- apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - get + - list + - watch +- apiGroups: + - gateway.envoyproxy.io + resources: + - envoyproxies + - envoypatchpolicies + - clienttrafficpolicies + - backendtrafficpolicies + - securitypolicies + verbs: + - get + - list + - watch +- apiGroups: + - gateway.envoyproxy.io + resources: + - envoypatchpolicies/status + - clienttrafficpolicies/status + - backendtrafficpolicies/status + - securitypolicies/status + verbs: + - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - gateways + - grpcroutes + - httproutes + - referencegrants + - tcproutes + - tlsroutes + - udproutes + - backendtlspolicies + verbs: + - get + - list + - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - gateways/status + - grpcroutes/status + - httproutes/status + - tcproutes/status + - tlsroutes/status + - udproutes/status + - backendtlspolicies/status + verbs: + - update +--- +# Source: gateway-helm/templates/envoy-gateway-rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: eg-gateway-helm-envoy-gateway-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: eg-gateway-helm-envoy-gateway-role +subjects: +- kind: ServiceAccount + name: 'envoy-gateway' + namespace: 'default' +--- +# Source: gateway-helm/templates/infra-manager-rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: eg-gateway-helm-infra-manager + namespace: 'default' + labels: + helm.sh/chart: gateway-helm-v0.0.0-latest + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + app.kubernetes.io/version: "latest" + app.kubernetes.io/managed-by: Helm +rules: +- apiGroups: + - "" + resources: + - serviceaccounts + - services + verbs: + - create + - get + - update + - delete +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - get + - update + - delete +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - create + - get + - update + - delete +--- +# Source: gateway-helm/templates/leader-election-rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: eg-gateway-helm-leader-election-role + namespace: 'default' + labels: + helm.sh/chart: gateway-helm-v0.0.0-latest + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + app.kubernetes.io/version: "latest" + app.kubernetes.io/managed-by: Helm +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +# Source: gateway-helm/templates/infra-manager-rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: eg-gateway-helm-infra-manager + namespace: 'default' + labels: + helm.sh/chart: gateway-helm-v0.0.0-latest + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + app.kubernetes.io/version: "latest" + app.kubernetes.io/managed-by: Helm +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: 'eg-gateway-helm-infra-manager' +subjects: +- kind: ServiceAccount + name: 'envoy-gateway' + namespace: 'default' +--- +# Source: gateway-helm/templates/leader-election-rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: eg-gateway-helm-leader-election-rolebinding + namespace: 'default' + labels: + helm.sh/chart: gateway-helm-v0.0.0-latest + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + app.kubernetes.io/version: "latest" + app.kubernetes.io/managed-by: Helm +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: 'eg-gateway-helm-leader-election-role' +subjects: +- kind: ServiceAccount + name: 'envoy-gateway' + namespace: 'default' +--- +# Source: gateway-helm/templates/envoy-gateway-metrics-service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + prometheus.io/scrape: 'true' + prometheus.io/port: '19001' + name: envoy-gateway-metrics-service + namespace: 'default' + labels: + control-plane: envoy-gateway + helm.sh/chart: gateway-helm-v0.0.0-latest + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + app.kubernetes.io/version: "latest" + app.kubernetes.io/managed-by: Helm +spec: + selector: + control-plane: envoy-gateway + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + ports: + - name: http + port: 19001 + protocol: TCP + targetPort: http-metrics +--- +# Source: gateway-helm/templates/envoy-gateway-service.yaml +apiVersion: v1 +kind: Service +metadata: + name: envoy-gateway + namespace: 'default' + labels: + control-plane: envoy-gateway + helm.sh/chart: gateway-helm-v0.0.0-latest + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + app.kubernetes.io/version: "latest" + app.kubernetes.io/managed-by: Helm +spec: + selector: + control-plane: envoy-gateway + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + ports: + - name: grpc + port: 18000 + targetPort: 18000 + - name: ratelimit + port: 18001 + targetPort: 18001 +--- +# Source: gateway-helm/templates/envoy-gateway-deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: envoy-gateway + namespace: 'default' + labels: + control-plane: envoy-gateway + helm.sh/chart: gateway-helm-v0.0.0-latest + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + app.kubernetes.io/version: "latest" + app.kubernetes.io/managed-by: Helm +spec: + replicas: 1 + selector: + matchLabels: + control-plane: envoy-gateway + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + template: + metadata: + labels: + control-plane: envoy-gateway + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + spec: + containers: + - args: + - server + - --config-path=/config/envoy-gateway.yaml + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: KUBERNETES_CLUSTER_DOMAIN + value: cluster.local + image: docker.io/envoyproxy/gateway-dev:latest + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: envoy-gateway + ports: + - containerPort: 18000 + name: grpc + - containerPort: 18001 + name: ratelimit + - containerPort: 19001 + name: http-metrics + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 1024Mi + requests: + cpu: 100m + memory: 256Mi + securityContext: + allowPrivilegeEscalation: false + volumeMounts: + - mountPath: /config + name: envoy-gateway-config + readOnly: true + - mountPath: /certs + name: certs + readOnly: true + securityContext: + runAsNonRoot: true + serviceAccountName: envoy-gateway + terminationGracePeriodSeconds: 10 + volumes: + - configMap: + defaultMode: 420 + name: envoy-gateway-config + name: envoy-gateway-config + - name: certs + secret: + secretName: envoy-gateway +--- +# Source: gateway-helm/templates/certgen-rbac.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: eg-gateway-helm-certgen + namespace: 'default' + labels: + helm.sh/chart: gateway-helm-v0.0.0-latest + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + app.kubernetes.io/version: "latest" + app.kubernetes.io/managed-by: Helm + annotations: + "helm.sh/hook": pre-install +--- +# Source: gateway-helm/templates/certgen-rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: eg-gateway-helm-certgen + namespace: 'default' + labels: + helm.sh/chart: gateway-helm-v0.0.0-latest + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + app.kubernetes.io/version: "latest" + app.kubernetes.io/managed-by: Helm + annotations: + "helm.sh/hook": pre-install +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - create + - update +--- +# Source: gateway-helm/templates/certgen-rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: eg-gateway-helm-certgen + namespace: 'default' + labels: + helm.sh/chart: gateway-helm-v0.0.0-latest + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + app.kubernetes.io/version: "latest" + app.kubernetes.io/managed-by: Helm + annotations: + "helm.sh/hook": pre-install +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: 'eg-gateway-helm-certgen' +subjects: +- kind: ServiceAccount + name: 'eg-gateway-helm-certgen' + namespace: 'default' +--- +# Source: gateway-helm/templates/certgen.yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: eg-gateway-helm-certgen + namespace: 'default' + labels: + helm.sh/chart: gateway-helm-v0.0.0-latest + app.kubernetes.io/name: gateway-helm + app.kubernetes.io/instance: eg + app.kubernetes.io/version: "latest" + app.kubernetes.io/managed-by: Helm + annotations: + "helm.sh/hook": pre-install +spec: + backoffLimit: 1 + completions: 1 + parallelism: 1 + template: + metadata: + labels: + app: certgen + spec: + containers: + - command: + - envoy-gateway + - certgen + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: KUBERNETES_CLUSTER_DOMAIN + value: cluster.local + image: docker.io/envoyproxy/gateway-dev:latest + imagePullPolicy: Always + name: envoy-gateway-certgen + restartPolicy: Never + securityContext: + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + serviceAccountName: eg-gateway-helm-certgen + ttlSecondsAfterFinished: 0 diff --git a/tools/make/common.mk b/tools/make/common.mk index 4bda0b272d7..7c5ffa85cda 100644 --- a/tools/make/common.mk +++ b/tools/make/common.mk @@ -119,7 +119,7 @@ export USAGE_OPTIONS .PHONY: generate generate: ## Generate go code from templates and tags -generate: kube-generate helm-generate go.generate docs-api +generate: kube-generate helm-generate helm-template go.generate docs-api ## help: Show this help info. .PHONY: help diff --git a/tools/make/helm.mk b/tools/make/helm.mk index 86b943fe4e9..cabe4cbd82d 100644 --- a/tools/make/helm.mk +++ b/tools/make/helm.mk @@ -28,3 +28,7 @@ helm-install: helm-generate ## Install envoy gateway helm chart from OCI registr helm-generate: ImageRepository=${IMAGE} ImageTag=${TAG} envsubst < charts/gateway-helm/values.tmpl.yaml > ./charts/gateway-helm/values.yaml helm lint charts/gateway-helm + +helm-template: ## Template envoy gateway helm chart. + @$(LOG_TARGET) + helm template eg charts/gateway-helm --set deployment.envoyGateway.image.tag=latest > ./test/helm/default.yaml \ No newline at end of file From dafbed42bfb53fe825b4518d64c42fbfb38b4cf7 Mon Sep 17 00:00:00 2001 From: Dennis Zhou Date: Sat, 16 Mar 2024 08:28:37 +0800 Subject: [PATCH 14/29] fix: install-egctl doc dead link (#2916) * fix: install-egctl doc dead link Signed-off-by: Dennis Zhou * update url Signed-off-by: Dennis Zhou * fix lint Signed-off-by: Dennis Zhou --------- Signed-off-by: Dennis Zhou Co-authored-by: zirain --- site/content/en/latest/install/install-egctl.md | 2 +- site/content/en/v0.6.0/install/install-egctl.md | 2 +- site/content/en/v1.0.0/install/install-egctl.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/site/content/en/latest/install/install-egctl.md b/site/content/en/latest/install/install-egctl.md index 18a593c445c..d4634de8784 100644 --- a/site/content/en/latest/install/install-egctl.md +++ b/site/content/en/latest/install/install-egctl.md @@ -52,6 +52,6 @@ curl -fsSL https://gateway.envoyproxy.io/get-egctl.sh | VERSION=latest bash {{% alert title="Next Steps" color="warning" %}} -You can refer to [User Guides](/latest/user/egctl) to more details about egctl. +You can refer to [User Guides](../user/operations/egctl) to more details about egctl. {{% /alert %}} diff --git a/site/content/en/v0.6.0/install/install-egctl.md b/site/content/en/v0.6.0/install/install-egctl.md index 18a593c445c..ca8377c01c4 100644 --- a/site/content/en/v0.6.0/install/install-egctl.md +++ b/site/content/en/v0.6.0/install/install-egctl.md @@ -52,6 +52,6 @@ curl -fsSL https://gateway.envoyproxy.io/get-egctl.sh | VERSION=latest bash {{% alert title="Next Steps" color="warning" %}} -You can refer to [User Guides](/latest/user/egctl) to more details about egctl. +You can refer to [User Guides](../user/egctl) to more details about egctl. {{% /alert %}} diff --git a/site/content/en/v1.0.0/install/install-egctl.md b/site/content/en/v1.0.0/install/install-egctl.md index 18a593c445c..d4634de8784 100644 --- a/site/content/en/v1.0.0/install/install-egctl.md +++ b/site/content/en/v1.0.0/install/install-egctl.md @@ -52,6 +52,6 @@ curl -fsSL https://gateway.envoyproxy.io/get-egctl.sh | VERSION=latest bash {{% alert title="Next Steps" color="warning" %}} -You can refer to [User Guides](/latest/user/egctl) to more details about egctl. +You can refer to [User Guides](../user/operations/egctl) to more details about egctl. {{% /alert %}} From 96f71734c2c708ef2a64ab678bfe3ef063678d62 Mon Sep 17 00:00:00 2001 From: zirain Date: Sat, 16 Mar 2024 08:51:27 +0800 Subject: [PATCH 15/29] chore: fix helm-template (#2943) Signed-off-by: zirain --- test/helm/default.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helm/default.yaml b/test/helm/default.yaml index f88b64a1ede..028ec088db0 100644 --- a/test/helm/default.yaml +++ b/test/helm/default.yaml @@ -512,7 +512,7 @@ metadata: app.kubernetes.io/version: "latest" app.kubernetes.io/managed-by: Helm annotations: - "helm.sh/hook": pre-install + "helm.sh/hook": pre-install, pre-upgrade spec: backoffLimit: 1 completions: 1 From 791cdf53ad82ba90941f095481153def47476103 Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Sat, 16 Mar 2024 19:02:06 -0500 Subject: [PATCH 16/29] e2e: use default shutdown mgr settings in upgrade test suite (#2946) use shutdown mgr settings in upgrade test suite Signed-off-by: Guy Daich --- test/config/gatewayclass.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/config/gatewayclass.yaml b/test/config/gatewayclass.yaml index 162a3821f92..2700448c7d5 100644 --- a/test/config/gatewayclass.yaml +++ b/test/config/gatewayclass.yaml @@ -81,8 +81,6 @@ metadata: name: upgrade-config namespace: envoy-gateway-system spec: - shutdown: - drainTimeout: 15s provider: type: Kubernetes kubernetes: From 366e99095a6b58cba16374017238347238f04c7f Mon Sep 17 00:00:00 2001 From: Shyunn <1147212064@qq.com> Date: Sun, 17 Mar 2024 08:03:42 +0800 Subject: [PATCH 17/29] refactor: collapse eg-metrics-svc into eg-svc (#2932) * refactor: collapse eg-metrics-svc into eg-svc Signed-off-by: ShyunnY <1147212064@qq.com> * fix: fix install/api.md Signed-off-by: ShyunnY <1147212064@qq.com> * fix: update helm default.yaml Signed-off-by: ShyunnY <1147212064@qq.com> * fix: migrate prom annotations to pod Signed-off-by: ShyunnY <1147212064@qq.com> --------- Signed-off-by: ShyunnY <1147212064@qq.com> Co-authored-by: zirain --- .../templates/envoy-gateway-deployment.yaml | 2 -- .../envoy-gateway-metrics-service.yaml | 20 ----------- charts/gateway-helm/values.tmpl.yaml | 10 +++--- site/content/en/latest/install/api.md | 7 ++-- test/helm/default.yaml | 35 ++++--------------- 5 files changed, 18 insertions(+), 56 deletions(-) delete mode 100644 charts/gateway-helm/templates/envoy-gateway-metrics-service.yaml diff --git a/charts/gateway-helm/templates/envoy-gateway-deployment.yaml b/charts/gateway-helm/templates/envoy-gateway-deployment.yaml index 1ee5c7f7d86..7ca6f2b64d1 100644 --- a/charts/gateway-helm/templates/envoy-gateway-deployment.yaml +++ b/charts/gateway-helm/templates/envoy-gateway-deployment.yaml @@ -63,8 +63,6 @@ spec: - containerPort: {{ .port }} name: {{ .name }} {{- end}} - - containerPort: 19001 - name: http-metrics readinessProbe: httpGet: path: /readyz diff --git a/charts/gateway-helm/templates/envoy-gateway-metrics-service.yaml b/charts/gateway-helm/templates/envoy-gateway-metrics-service.yaml deleted file mode 100644 index da17559f0ea..00000000000 --- a/charts/gateway-helm/templates/envoy-gateway-metrics-service.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - prometheus.io/scrape: 'true' - prometheus.io/port: '19001' - name: envoy-gateway-metrics-service - namespace: '{{ .Release.Namespace }}' - labels: - control-plane: envoy-gateway - {{- include "eg.labels" . | nindent 4 }} -spec: - selector: - control-plane: envoy-gateway - {{- include "eg.selectorLabels" . | nindent 4 }} - ports: - - name: http - port: {{ .Values.envoyGatewayMetricsService.port }} - protocol: TCP - targetPort: http-metrics diff --git a/charts/gateway-helm/values.tmpl.yaml b/charts/gateway-helm/values.tmpl.yaml index 269344cd978..ce6359dabc6 100644 --- a/charts/gateway-helm/values.tmpl.yaml +++ b/charts/gateway-helm/values.tmpl.yaml @@ -19,10 +19,15 @@ deployment: - name: ratelimit port: 18001 targetPort: 18001 + - name: metrics + port: 19001 + targetPort: 19001 replicas: 1 pod: affinity: {} - annotations: {} + annotations: + prometheus.io/scrape: 'true' + prometheus.io/port: '19001' labels: {} config: @@ -35,9 +40,6 @@ config: level: default: info -envoyGatewayMetricsService: - port: 19001 - createNamespace: false kubernetesClusterDomain: cluster.local diff --git a/site/content/en/latest/install/api.md b/site/content/en/latest/install/api.md index 165a91d01e6..47351ba771b 100644 --- a/site/content/en/latest/install/api.md +++ b/site/content/en/latest/install/api.md @@ -42,7 +42,8 @@ The Helm chart for Envoy Gateway | deployment.envoyGateway.resources.requests.cpu | string | `"100m"` | | | deployment.envoyGateway.resources.requests.memory | string | `"256Mi"` | | | deployment.pod.affinity | object | `{}` | | -| deployment.pod.annotations | object | `{}` | | +| deployment.pod.annotations."prometheus.io/port" | string | `"19001"` | | +| deployment.pod.annotations."prometheus.io/scrape" | string | `"true"` | | | deployment.pod.labels | object | `{}` | | | deployment.ports[0].name | string | `"grpc"` | | | deployment.ports[0].port | int | `18000` | | @@ -50,7 +51,9 @@ The Helm chart for Envoy Gateway | deployment.ports[1].name | string | `"ratelimit"` | | | deployment.ports[1].port | int | `18001` | | | deployment.ports[1].targetPort | int | `18001` | | +| deployment.ports[2].name | string | `"metrics"` | | +| deployment.ports[2].port | int | `19001` | | +| deployment.ports[2].targetPort | int | `19001` | | | deployment.replicas | int | `1` | | -| envoyGatewayMetricsService.port | int | `19001` | | | kubernetesClusterDomain | string | `"cluster.local"` | | diff --git a/test/helm/default.yaml b/test/helm/default.yaml index 028ec088db0..4e9c147f265 100644 --- a/test/helm/default.yaml +++ b/test/helm/default.yaml @@ -294,33 +294,6 @@ subjects: name: 'envoy-gateway' namespace: 'default' --- -# Source: gateway-helm/templates/envoy-gateway-metrics-service.yaml -apiVersion: v1 -kind: Service -metadata: - annotations: - prometheus.io/scrape: 'true' - prometheus.io/port: '19001' - name: envoy-gateway-metrics-service - namespace: 'default' - labels: - control-plane: envoy-gateway - helm.sh/chart: gateway-helm-v0.0.0-latest - app.kubernetes.io/name: gateway-helm - app.kubernetes.io/instance: eg - app.kubernetes.io/version: "latest" - app.kubernetes.io/managed-by: Helm -spec: - selector: - control-plane: envoy-gateway - app.kubernetes.io/name: gateway-helm - app.kubernetes.io/instance: eg - ports: - - name: http - port: 19001 - protocol: TCP - targetPort: http-metrics ---- # Source: gateway-helm/templates/envoy-gateway-service.yaml apiVersion: v1 kind: Service @@ -346,6 +319,9 @@ spec: - name: ratelimit port: 18001 targetPort: 18001 + - name: metrics + port: 19001 + targetPort: 19001 --- # Source: gateway-helm/templates/envoy-gateway-deployment.yaml apiVersion: apps/v1 @@ -369,6 +345,9 @@ spec: app.kubernetes.io/instance: eg template: metadata: + annotations: + prometheus.io/port: "19001" + prometheus.io/scrape: "true" labels: control-plane: envoy-gateway app.kubernetes.io/name: gateway-helm @@ -401,7 +380,7 @@ spec: - containerPort: 18001 name: ratelimit - containerPort: 19001 - name: http-metrics + name: metrics readinessProbe: httpGet: path: /readyz From f9a750bbb760ee30e683f3c4df2ce975bff94e63 Mon Sep 17 00:00:00 2001 From: zirain Date: Mon, 18 Mar 2024 13:24:42 +0800 Subject: [PATCH 18/29] chore: make clean should clean tools/bin (#2945) * chore: make clean should clean tools/bin Signed-off-by: zirain * update Signed-off-by: zirain --------- Signed-off-by: zirain --- tools/make/tools.mk | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/make/tools.mk b/tools/make/tools.mk index 2edfbcee22a..4943764a972 100644 --- a/tools/make/tools.mk +++ b/tools/make/tools.mk @@ -63,3 +63,11 @@ tools/bin/$(notdir $(SHELLCHECK_TXZ)): mkdir -p $(@D) tar -C $(@D) -Jxmf $< --strip-components=1 shellcheck-v$(SHELLCHECK_VERSION)/shellcheck endif + +tools.clean: # Remove all tools + @$(LOG_TARGET) + rm -rf $(tools.bindir) + +.PHONY: clean +clean: ## Remove all files that are created during builds. +clean: tools.clean From 002459cf491edf6bd7dc298e8088ca60b55f1036 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 13:28:51 +0800 Subject: [PATCH 19/29] build(deps): bump softprops/action-gh-release from 2.0.2 to 2.0.4 (#2960) Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.0.2 to 2.0.4. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/d99959edae48b5ffffd7b00da66dcdb0a33a52ee...9d7c94cfd0a1f3ed45544c887983e9fa900f0564) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/latest_release.yaml | 2 +- .github/workflows/release.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/latest_release.yaml b/.github/workflows/latest_release.yaml index 71ad19836f7..ff8613519da 100644 --- a/.github/workflows/latest_release.yaml +++ b/.github/workflows/latest_release.yaml @@ -61,7 +61,7 @@ jobs: GITHUB_REPOSITORY: ${{ github.repository_owner }}/${{ github.event.repository.name }} - name: Recreate the Latest Release and Tag - uses: softprops/action-gh-release@d99959edae48b5ffffd7b00da66dcdb0a33a52ee # v0.1.15 + uses: softprops/action-gh-release@9d7c94cfd0a1f3ed45544c887983e9fa900f0564 # v0.1.15 with: draft: false prerelease: true diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a07e5aed4d2..ed4c9847f80 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -40,7 +40,7 @@ jobs: run: OCI_REGISTRY=oci://docker.io/envoyproxy CHART_VERSION=${{ env.release_tag }} IMAGE=docker.io/envoyproxy/gateway TAG=${{ env.release_tag }} make helm-package helm-push - name: Upload Release Manifests - uses: softprops/action-gh-release@d99959edae48b5ffffd7b00da66dcdb0a33a52ee # v0.1.15 + uses: softprops/action-gh-release@9d7c94cfd0a1f3ed45544c887983e9fa900f0564 # v0.1.15 with: files: | release-artifacts/install.yaml From 4f6378bac138248cc4e00f0d127376ea4e22634a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 17 Mar 2024 23:38:18 -0700 Subject: [PATCH 20/29] build(deps): bump distroless/static from `49af061` to `55c6361` in /tools/docker/envoy-gateway (#2956) build(deps): bump distroless/static in /tools/docker/envoy-gateway Bumps distroless/static from `49af061` to `55c6361`. --- updated-dependencies: - dependency-name: distroless/static dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- tools/docker/envoy-gateway/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/docker/envoy-gateway/Dockerfile b/tools/docker/envoy-gateway/Dockerfile index 8cdd94af859..f5502f925f2 100644 --- a/tools/docker/envoy-gateway/Dockerfile +++ b/tools/docker/envoy-gateway/Dockerfile @@ -1,6 +1,6 @@ # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details -FROM gcr.io/distroless/static:nonroot@sha256:49af06135e8bbe8ddc46c1d28b0bd00961aae9c9ed090bbc0237f58e1462dd4b +FROM gcr.io/distroless/static:nonroot@sha256:55c636171053dbc8ae07a280023bd787d2921f10e569f3e319f1539076dbba11 ARG TARGETPLATFORM COPY $TARGETPLATFORM/envoy-gateway /usr/local/bin/ From 75796afebaaf8643b11f7485406b21439cda7511 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 17 Mar 2024 23:39:02 -0700 Subject: [PATCH 21/29] build(deps): bump actions/checkout from 4.1.1 to 4.1.2 (#2959) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 to 4.1.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/b4ffde65f46336ab88eb53be808477a3936bae11...9bb56186c3b09b4f86b1c65136769dd318469633) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build_and_test.yaml | 16 ++++++++-------- .github/workflows/cherrypick.yaml | 2 +- .github/workflows/codeql.yml | 2 +- .github/workflows/docs.yaml | 4 ++-- .github/workflows/experimental_conformance.yaml | 2 +- .github/workflows/latest_release.yaml | 2 +- .github/workflows/release.yaml | 2 +- .github/workflows/scorecard.yml | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index b21817968f9..a0fa9877845 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -20,7 +20,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - uses: ./tools/github-actions/setup-deps # Generate the install manifests first so it can checked # for errors while running `make -k lint` @@ -31,21 +31,21 @@ jobs: gen-check: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - uses: ./tools/github-actions/setup-deps - run: make -k gen-check license-check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - uses: ./tools/github-actions/setup-deps - run: make -k licensecheck coverage-test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - uses: ./tools/github-actions/setup-deps # test @@ -63,7 +63,7 @@ jobs: runs-on: ubuntu-latest needs: [lint, gen-check, license-check, coverage-test] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - uses: ./tools/github-actions/setup-deps - name: Build EG Multiarch Binaries @@ -82,7 +82,7 @@ jobs: matrix: version: [ v1.26.14, v1.27.11, v1.28.7, v1.29.2 ] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - uses: ./tools/github-actions/setup-deps - name: Download EG Binaries @@ -110,7 +110,7 @@ jobs: matrix: version: [ v1.26.14, v1.27.11, v1.28.7, v1.29.2 ] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - uses: ./tools/github-actions/setup-deps - name: Download EG Binaries @@ -135,7 +135,7 @@ jobs: runs-on: ubuntu-latest needs: [conformance-test, e2e-test] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - uses: ./tools/github-actions/setup-deps - name: Download EG Binaries diff --git a/.github/workflows/cherrypick.yaml b/.github/workflows/cherrypick.yaml index b12a56af8f3..9c210a92fac 100644 --- a/.github/workflows/cherrypick.yaml +++ b/.github/workflows/cherrypick.yaml @@ -15,7 +15,7 @@ jobs: if: ${{ contains(github.event.pull_request.labels.*.name, 'cherrypick/release-v1.0') && github.event.pull_request.merged == true }} steps: - name: Checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: fetch-depth: 0 - name: Cherry pick into release/v1.0 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ea16d2440db..c38888d2632 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - uses: ./tools/github-actions/setup-deps - name: Initialize CodeQL diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index a1b89d5ce97..4d79a7496c6 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Check out code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: ref: ${{ github.event.pull_request.head.sha }} @@ -38,7 +38,7 @@ jobs: contents: write steps: - name: Git checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: submodules: true ref: ${{ github.event.pull_request.head.sha }} diff --git a/.github/workflows/experimental_conformance.yaml b/.github/workflows/experimental_conformance.yaml index a803684f08b..87dd94ae081 100644 --- a/.github/workflows/experimental_conformance.yaml +++ b/.github/workflows/experimental_conformance.yaml @@ -20,7 +20,7 @@ jobs: matrix: version: [ v1.26.14, v1.27.11, v1.28.7, v1.29.2 ] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - uses: ./tools/github-actions/setup-deps # gateway api experimental conformance diff --git a/.github/workflows/latest_release.yaml b/.github/workflows/latest_release.yaml index ff8613519da..55a14ebb106 100644 --- a/.github/workflows/latest_release.yaml +++ b/.github/workflows/latest_release.yaml @@ -22,7 +22,7 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - uses: ./tools/github-actions/setup-deps - name: Generate Release Manifests diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ed4c9847f80..ca0c8239803 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -15,7 +15,7 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Extract Release Tag and Commit SHA id: vars diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 3ccb44d4bf0..d2f6013768f 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -21,7 +21,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: persist-credentials: false From 8a8369f66d3a0ed8f980154f685e63872e479342 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 17 Mar 2024 23:39:41 -0700 Subject: [PATCH 22/29] build(deps): bump github/codeql-action from 3.24.6 to 3.24.7 (#2957) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.6 to 3.24.7. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/8a470fddafa5cbb6266ee11b37ef4d8aae19c571...3ab4101902695724f9365a384f86c1074d94e18c) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/scorecard.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c38888d2632..b9f6ae3ad7b 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -36,14 +36,14 @@ jobs: - uses: ./tools/github-actions/setup-deps - name: Initialize CodeQL - uses: github/codeql-action/init@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6 + uses: github/codeql-action/init@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6 + uses: github/codeql-action/autobuild@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6 + uses: github/codeql-action/analyze@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index d2f6013768f..b8043b01625 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -40,6 +40,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6 + uses: github/codeql-action/upload-sarif@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 with: sarif_file: results.sarif From a4e33c2caebc47b17743af0d2ad031b71241e56f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 17 Mar 2024 23:40:32 -0700 Subject: [PATCH 23/29] build(deps): bump docker/login-action from 3.0.0 to 3.1.0 (#2958) Bumps [docker/login-action](https://github.com/docker/login-action) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/343f7c4344506bcbf9b4de18042ae17996df046d...e92390c5fb421da1463c202d546fed0ec5c39f20) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build_and_test.yaml | 2 +- .github/workflows/release.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index a0fa9877845..dd01beb6a98 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -152,7 +152,7 @@ jobs: # build and push image - name: Login to DockerHub if: github.event_name == 'push' - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ca0c8239803..75d3111c32a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -25,7 +25,7 @@ jobs: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - name: Login to DockerHub - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} From 36717d70babda09dfa2955b64db71d5b5602e3e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 17 Mar 2024 23:40:54 -0700 Subject: [PATCH 24/29] build(deps): bump helm.sh/helm/v3 from 3.14.2 to 3.14.3 (#2962) Bumps [helm.sh/helm/v3](https://github.com/helm/helm) from 3.14.2 to 3.14.3. - [Release notes](https://github.com/helm/helm/releases) - [Commits](https://github.com/helm/helm/compare/v3.14.2...v3.14.3) --- updated-dependencies: - dependency-name: helm.sh/helm/v3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index aa02f1003db..23c05a8560b 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require ( google.golang.org/grpc v1.62.1 google.golang.org/protobuf v1.33.0 gopkg.in/yaml.v3 v3.0.1 - helm.sh/helm/v3 v3.14.2 + helm.sh/helm/v3 v3.14.3 k8s.io/api v0.29.2 k8s.io/apiextensions-apiserver v0.29.2 k8s.io/apimachinery v0.29.2 @@ -65,7 +65,7 @@ require ( github.com/Masterminds/squirrel v1.5.4 // indirect github.com/Microsoft/hcsshim v0.11.4 // indirect github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect - github.com/containerd/containerd v1.7.11 // indirect + github.com/containerd/containerd v1.7.12 // indirect github.com/containerd/log v0.1.0 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/docker/cli v24.0.6+incompatible // indirect diff --git a/go.sum b/go.sum index 5a287732762..7f47edfd434 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= +github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -101,8 +101,8 @@ github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= -github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw= -github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE= +github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0= +github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk= github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= @@ -931,8 +931,8 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= -helm.sh/helm/v3 v3.14.2 h1:V71fv+NGZv0icBlr+in1MJXuUIHCiPG1hW9gEBISTIA= -helm.sh/helm/v3 v3.14.2/go.mod h1:2itvvDv2WSZXTllknfQo6j7u3VVgMAvm8POCDgYH424= +helm.sh/helm/v3 v3.14.3 h1:HmvRJlwyyt9HjgmAuxHbHv3PhMz9ir/XNWHyXfmnOP4= +helm.sh/helm/v3 v3.14.3/go.mod h1:v6myVbyseSBJTzhmeE39UcPLNv6cQK6qss3dvgAySaE= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 2161064f52169764e1e84fb8d1c2900683b5d470 Mon Sep 17 00:00:00 2001 From: Dennis Zhou Date: Mon, 18 Mar 2024 16:38:54 +0800 Subject: [PATCH 25/29] feat: support failOpen in ext auth (#2948) * feat: support failOpen in ext auth Signed-off-by: Dennis Zhou * fix test Signed-off-by: Dennis Zhou --------- Signed-off-by: Dennis Zhou --- internal/gatewayapi/securitypolicy.go | 1 + ...typolicy-with-extauth-invalid-no-matching-port.in.yaml | 1 + ...ypolicy-with-extauth-invalid-no-matching-port.out.yaml | 1 + .../securitypolicy-with-extauth-invalid-no-port.in.yaml | 1 + .../securitypolicy-with-extauth-invalid-no-port.out.yaml | 1 + ...policy-with-extauth-invalid-no-reference-grant.in.yaml | 1 + ...olicy-with-extauth-invalid-no-reference-grant.out.yaml | 1 + ...securitypolicy-with-extauth-invalid-no-service.in.yaml | 1 + ...ecuritypolicy-with-extauth-invalid-no-service.out.yaml | 1 + ...uritypolicy-with-extauth-with-backendtlspolicy.in.yaml | 2 ++ ...ritypolicy-with-extauth-with-backendtlspolicy.out.yaml | 4 ++++ .../testdata/securitypolicy-with-extauth.in.yaml | 2 ++ .../testdata/securitypolicy-with-extauth.out.yaml | 5 +++++ internal/ir/xds.go | 8 ++++++++ internal/ir/zz_generated.deepcopy.go | 5 +++++ internal/xds/translator/extauth.go | 5 ++++- internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml | 3 +++ .../testdata/out/xds-ir/ext-auth.listeners.yaml | 1 + 18 files changed, 43 insertions(+), 1 deletion(-) diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index 4a85f726a7f..24604b4b4e7 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -854,6 +854,7 @@ func (t *Translator) buildExtAuth( extAuth := &ir.ExtAuth{ Name: name, HeadersToExtAuth: policy.Spec.ExtAuth.HeadersToExtAuth, + FailOpen: policy.Spec.ExtAuth.FailOpen, } if http != nil { diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.in.yaml index 91b51dbf237..4a6ba7412f4 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.in.yaml @@ -63,3 +63,4 @@ securityPolicies: headersToBackend: - header1 - header2 + failOpen: false diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.out.yaml index 0868f2ae76d..20a44008251 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.out.yaml @@ -103,6 +103,7 @@ securityPolicies: namespace: default spec: extAuth: + failOpen: false http: backendRef: name: http-backend diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.in.yaml index 1f38853fbe1..cec6e9ce285 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.in.yaml @@ -62,3 +62,4 @@ securityPolicies: headersToBackend: - header1 - header2 + failOpen: false diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.out.yaml index 115a3ba7436..4ade06fec09 100755 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.out.yaml @@ -103,6 +103,7 @@ securityPolicies: namespace: default spec: extAuth: + failOpen: false http: backendRef: name: http-backend diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.in.yaml index 64b15b558b4..f713a1dc730 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.in.yaml @@ -63,3 +63,4 @@ securityPolicies: headersToBackend: - header1 - header2 + failOpen: false diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.out.yaml index 1e547408f25..82fc12d534c 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.out.yaml @@ -103,6 +103,7 @@ securityPolicies: namespace: default spec: extAuth: + failOpen: false http: backendRef: name: http-backend diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.in.yaml index 2ab00957c3f..eb02ed446ac 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.in.yaml @@ -54,3 +54,4 @@ securityPolicies: headersToBackend: - header1 - header2 + failOpen: false diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.out.yaml index 47720b9bbb0..980d29cce01 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.out.yaml @@ -103,6 +103,7 @@ securityPolicies: namespace: default spec: extAuth: + failOpen: false http: backendRef: name: http-backend diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml index a088e08d16d..b7769b524bd 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml @@ -210,6 +210,7 @@ securityPolicies: headersToBackend: - header1 - header2 + failOpen: false - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: SecurityPolicy metadata: @@ -229,3 +230,4 @@ securityPolicies: backendRef: name: grpc-backend port: 9000 + failOpen: true diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml index b3dc1299f34..5e557abb08c 100755 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml @@ -207,6 +207,7 @@ securityPolicies: namespace: default spec: extAuth: + failOpen: true grpc: backendRef: name: grpc-backend @@ -242,6 +243,7 @@ securityPolicies: namespace: default spec: extAuth: + failOpen: false http: backendRef: name: http-backend @@ -305,6 +307,7 @@ xdsIR: protocol: HTTP weight: 1 extAuth: + failOpen: true grpc: authority: grpc-backend.default:9000 destination: @@ -345,6 +348,7 @@ xdsIR: protocol: HTTP weight: 1 extAuth: + failOpen: false http: authority: http-backend.envoy-gateway:80 destination: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml index a451b576774..3d9382a95ea 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml @@ -150,6 +150,7 @@ securityPolicies: headersToBackend: - header1 - header2 + failOpen: false - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: SecurityPolicy metadata: @@ -169,3 +170,4 @@ securityPolicies: backendRef: name: grpc-backend port: 9000 + failOpen: true diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml index 25a291a8ca3..066e9ad2f9f 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml @@ -147,6 +147,7 @@ securityPolicies: namespace: default spec: extAuth: + failOpen: true grpc: backendRef: name: grpc-backend @@ -182,6 +183,7 @@ securityPolicies: namespace: default spec: extAuth: + failOpen: false http: backendRef: name: http-backend @@ -245,6 +247,7 @@ xdsIR: protocol: HTTP weight: 1 extAuth: + failOpen: true grpc: authority: grpc-backend.default:9000 destination: @@ -280,6 +283,7 @@ xdsIR: protocol: HTTP weight: 1 extAuth: + failOpen: true grpc: authority: grpc-backend.default:9000 destination: @@ -315,6 +319,7 @@ xdsIR: protocol: HTTP weight: 1 extAuth: + failOpen: false http: authority: http-backend.envoy-gateway:80 destination: diff --git a/internal/ir/xds.go b/internal/ir/xds.go index d2194fb95e8..4f6ed8ac00d 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -599,6 +599,14 @@ type ExtAuth struct { // in HeadersToExtAuth or not. // +optional HeadersToExtAuth []string `json:"headersToExtAuth,omitempty"` + + // FailOpen is a switch used to control the behavior when a response from the External Authorization service cannot be obtained. + // If FailOpen is set to true, the system allows the traffic to pass through. + // Otherwise, if it is set to false or not set (defaulting to false), + // the system blocks the traffic and returns a HTTP 5xx error, reflecting a fail-closed approach. + // This setting determines whether to prioritize accessibility over strict security in case of authorization service failure. + // +optional + FailOpen *bool `json:"failOpen,omitempty"` } // HTTPExtAuthService defines the HTTP External Authorization service diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index ec9a1ca2bad..e11220e3222 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -461,6 +461,11 @@ func (in *ExtAuth) DeepCopyInto(out *ExtAuth) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.FailOpen != nil { + in, out := &in.FailOpen, &out.FailOpen + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtAuth. diff --git a/internal/xds/translator/extauth.go b/internal/xds/translator/extauth.go index 28e509253aa..102497633e0 100644 --- a/internal/xds/translator/extauth.go +++ b/internal/xds/translator/extauth.go @@ -102,7 +102,10 @@ func extAuthFilterName(extAuth *ir.ExtAuth) string { func extAuthConfig(extAuth *ir.ExtAuth) *extauthv3.ExtAuthz { config := &extauthv3.ExtAuthz{ TransportApiVersion: corev3.ApiVersion_V3, - FailureModeAllow: false, + } + + if extAuth.FailOpen != nil { + config.FailureModeAllow = *extAuth.FailOpen } var headersToExtAuth []*matcherv3.StringMatcher diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml index e8dd3181425..3ed7a397f0c 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml @@ -35,6 +35,7 @@ http: port: 80 protocol: HTTP weight: 1 + failOpen: false - name: httproute/default/httproute-1/rule/1/match/0/www_example_com hostname: "*" pathMatch: @@ -62,6 +63,7 @@ http: port: 80 protocol: HTTP weight: 1 + failOpen: false - name: httproute/default/httproute-2/rule/0/match/0/www_example_com hostname: "*" pathMatch: @@ -88,3 +90,4 @@ http: headersToExtAuth: - header1 - header2 + failOpen: true diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml index 1fa830a1f83..35a8b7f7ab5 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml @@ -37,6 +37,7 @@ patterns: - exact: header1 - exact: header2 + failureModeAllow: true grpcService: envoyGrpc: authority: grpc-backend.default:9000 From 3163eeb147795a3215bb3c20d1b817cb84323062 Mon Sep 17 00:00:00 2001 From: Huabing Zhao Date: Tue, 19 Mar 2024 13:09:41 +0800 Subject: [PATCH 26/29] fix: redirect user doc (#2977) backendRef is not needed here Signed-off-by: huabing zhao --- site/content/en/latest/user/traffic/http-redirect.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/site/content/en/latest/user/traffic/http-redirect.md b/site/content/en/latest/user/traffic/http-redirect.md index ac6a3aceb18..1e67e4e6fd3 100644 --- a/site/content/en/latest/user/traffic/http-redirect.md +++ b/site/content/en/latest/user/traffic/http-redirect.md @@ -38,9 +38,6 @@ spec: statusCode: 301 hostname: www.example.com port: 443 - backendRefs: - - name: backend - port: 3000 EOF ``` From 6a57cd140f33429934a02afe8a73d5f0fa65cf40 Mon Sep 17 00:00:00 2001 From: Huabing Zhao Date: Tue, 19 Mar 2024 13:22:05 +0800 Subject: [PATCH 27/29] Remove duplicated http filters (#2944) * remove duplicated http filters Signed-off-by: huabing zhao * fix lint Signed-off-by: huabing zhao * fix lint Signed-off-by: huabing zhao --------- Signed-off-by: huabing zhao --- internal/gatewayapi/securitypolicy.go | 54 +++-- .../securitypolicy-with-basic-auth.in.yaml | 152 ++++++++----- .../securitypolicy-with-basic-auth.out.yaml | 162 ++++++++++++-- ...ith-extauth-with-backendtlspolicy.out.yaml | 8 +- .../securitypolicy-with-extauth.in.yaml | 44 ++-- .../securitypolicy-with-extauth.out.yaml | 16 +- .../testdata/securitypolicy-with-oidc.in.yaml | 2 +- .../securitypolicy-with-oidc.out.yaml | 4 +- internal/ir/xds.go | 8 + internal/xds/translator/basicauth.go | 25 ++- internal/xds/translator/oidc.go | 79 +++---- .../testdata/in/xds-ir/basic-auth.yaml | 81 +++++-- .../testdata/in/xds-ir/ext-auth.yaml | 199 ++++++++++-------- .../translator/testdata/in/xds-ir/oidc.yaml | 2 + .../out/xds-ir/basic-auth.clusters.yaml | 38 +++- .../out/xds-ir/basic-auth.endpoints.yaml | 32 ++- .../out/xds-ir/basic-auth.listeners.yaml | 12 +- .../out/xds-ir/basic-auth.routes.yaml | 40 +++- .../out/xds-ir/ext-auth.clusters.yaml | 29 ++- .../out/xds-ir/ext-auth.endpoints.yaml | 34 ++- .../out/xds-ir/ext-auth.listeners.yaml | 38 ++-- .../testdata/out/xds-ir/ext-auth.routes.yaml | 30 +-- .../testdata/out/xds-ir/oidc.listeners.yaml | 12 +- .../testdata/out/xds-ir/oidc.routes.yaml | 4 +- 24 files changed, 765 insertions(+), 340 deletions(-) diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index 24604b4b4e7..434d9ce839a 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -366,20 +366,24 @@ func (t *Translator) translateSecurityPolicyForRoute( } if policy.Spec.OIDC != nil { - if oidc, err = t.buildOIDC(policy, resources); err != nil { + if oidc, err = t.buildOIDC( + irConfigName(policy), + policy, + resources); err != nil { errs = errors.Join(errs, err) } } if policy.Spec.BasicAuth != nil { - if basicAuth, err = t.buildBasicAuth(policy, resources); err != nil { + if basicAuth, err = t.buildBasicAuth( + policy, + resources); err != nil { errs = errors.Join(errs, err) } } if policy.Spec.ExtAuth != nil { if extAuth, err = t.buildExtAuth( - utils.NamespacedName(route).String(), policy, resources); err != nil { errs = errors.Join(errs, err) @@ -449,20 +453,24 @@ func (t *Translator) translateSecurityPolicyForGateway( } if policy.Spec.OIDC != nil { - if oidc, err = t.buildOIDC(policy, resources); err != nil { + if oidc, err = t.buildOIDC( + irConfigName(policy), + policy, + resources); err != nil { errs = errors.Join(errs, err) } } if policy.Spec.BasicAuth != nil { - if basicAuth, err = t.buildBasicAuth(policy, resources); err != nil { + if basicAuth, err = t.buildBasicAuth( + policy, + resources); err != nil { errs = errors.Join(errs, err) } } if policy.Spec.ExtAuth != nil { if extAuth, err = t.buildExtAuth( - utils.NamespacedName(gateway).String(), policy, resources); err != nil { errs = errors.Join(errs, err) @@ -580,6 +588,7 @@ func (t *Translator) buildJWT(jwt *egv1a1.JWT) *ir.JWT { } func (t *Translator) buildOIDC( + name string, policy *egv1a1.SecurityPolicy, resources *Resources) (*ir.OIDC, error) { var ( @@ -653,6 +662,7 @@ func (t *Translator) buildOIDC( } return &ir.OIDC{ + Name: name, Provider: *provider, ClientID: oidc.ClientID, ClientSecret: clientSecretBytes, @@ -795,11 +805,13 @@ func (t *Translator) buildBasicAuth( usersSecret.Namespace, usersSecret.Name) } - return &ir.BasicAuth{Users: usersSecretBytes}, nil + return &ir.BasicAuth{ + Name: irConfigName(policy), + Users: usersSecretBytes, + }, nil } func (t *Translator) buildExtAuth( - name string, policy *egv1a1.SecurityPolicy, resources *Resources) (*ir.ExtAuth, error) { var ( @@ -847,12 +859,12 @@ func (t *Translator) buildExtAuth( return nil, err } rd := ir.RouteDestination{ - Name: irExtServiceDestinationName(policy, string(backendRef.Name)), + Name: irExtServiceDestinationName(policy, backendRef), Settings: []*ir.DestinationSetting{ds}, } extAuth := &ir.ExtAuth{ - Name: name, + Name: irConfigName(policy), HeadersToExtAuth: policy.Spec.ExtAuth.HeadersToExtAuth, FailOpen: policy.Spec.ExtAuth.FailOpen, } @@ -944,11 +956,21 @@ func (t *Translator) processExtServiceDestination( }, nil } -func irExtServiceDestinationName(policy *egv1a1.SecurityPolicy, service string) string { +func irExtServiceDestinationName(policy *egv1a1.SecurityPolicy, backendRef *gwapiv1.BackendObjectReference) string { + nn := types.NamespacedName{ + Name: string(backendRef.Name), + Namespace: NamespaceDerefOr(backendRef.Namespace, policy.Namespace), + } + return strings.ToLower(fmt.Sprintf( - "%s/%s/%s/%s", - KindSecurityPolicy, - policy.GetNamespace(), - policy.GetName(), - service)) + "%s/%s", + irConfigName(policy), + nn.String())) +} + +func irConfigName(policy *egv1a1.SecurityPolicy) string { + return fmt.Sprintf( + "%s/%s", + strings.ToLower(KindSecurityPolicy), + utils.NamespacedName(policy).String()) } diff --git a/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.in.yaml index 619425c9bdb..3a696360dbc 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.in.yaml @@ -1,58 +1,104 @@ secrets: -- apiVersion: v1 - kind: Secret - metadata: - namespace: default - name: users-secret - data: - .htpasswd: "dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo=" + - apiVersion: v1 + kind: Secret + metadata: + namespace: default + name: users-secret1 + data: + .htpasswd: "dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo=" + - apiVersion: v1 + kind: Secret + metadata: + namespace: default + name: users-secret2 + data: + .htpasswd: "Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo=" gateways: -- apiVersion: gateway.networking.k8s.io/v1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-1 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All -httpRoutes: -- apiVersion: gateway.networking.k8s.io/v1 - kind: HTTPRoute - metadata: - namespace: default - name: httproute-1 - spec: - hostnames: - - gateway.envoyproxy.io - parentRefs: - - namespace: envoy-gateway + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: default name: gateway-1 - sectionName: http - rules: - - matches: - - path: - value: "/foo" - backendRefs: - - name: service-1 - port: 8080 -securityPolicies: -- apiVersion: gateway.envoyproxy.io/v1alpha1 - kind: SecurityPolicy - metadata: - namespace: default - name: policy-for-http-route - spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default name: httproute-1 + spec: + hostnames: + - www.foo.com + parentRefs: + - namespace: default + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: /foo1 + backendRefs: + - name: service-1 + port: 8080 + - matches: + - path: + value: /foo2 + backendRefs: + - name: service-2 + port: 8080 + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-2 + spec: + hostnames: + - www.bar.com + parentRefs: + - namespace: default + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: /bar + backendRefs: + - name: service-3 + port: 8080 +securityPolicies: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + namespace: default + name: policy-for-http-route-1 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + namespace: default + basicAuth: + users: + name: "users-secret1" + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: namespace: default - basicAuth: - users: - name: "users-secret" + name: policy-for-gateway-1 # This will only apply to the httproute-2 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: default + basicAuth: + users: + name: "users-secret2" diff --git a/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml index d862fd9d11e..3681d60e018 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml @@ -4,7 +4,7 @@ gateways: metadata: creationTimestamp: null name: gateway-1 - namespace: envoy-gateway + namespace: default spec: gatewayClassName: envoy-gateway-class listeners: @@ -16,7 +16,7 @@ gateways: protocol: HTTP status: listeners: - - attachedRoutes: 1 + - attachedRoutes: 2 conditions: - lastTransitionTime: null message: Sending translated listener configuration to the data plane @@ -48,10 +48,10 @@ httpRoutes: namespace: default spec: hostnames: - - gateway.envoyproxy.io + - www.foo.com parentRefs: - name: gateway-1 - namespace: envoy-gateway + namespace: default sectionName: http rules: - backendRefs: @@ -59,7 +59,51 @@ httpRoutes: port: 8080 matches: - path: - value: /foo + value: /foo1 + - backendRefs: + - name: service-2 + port: 8080 + matches: + - path: + value: /foo2 + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: default + sectionName: http +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-2 + namespace: default + spec: + hostnames: + - www.bar.com + parentRefs: + - name: gateway-1 + namespace: default + sectionName: http + rules: + - backendRefs: + - name: service-3 + port: 8080 + matches: + - path: + value: /bar status: parents: - conditions: @@ -76,14 +120,14 @@ httpRoutes: controllerName: gateway.envoyproxy.io/gatewayclass-controller parentRef: name: gateway-1 - namespace: envoy-gateway + namespace: default sectionName: http infraIR: - envoy-gateway/gateway-1: + default/gateway-1: proxy: listeners: - address: null - name: envoy-gateway/gateway-1/http + name: default/gateway-1/http ports: - containerPort: 10080 name: http @@ -92,21 +136,21 @@ infraIR: metadata: labels: gateway.envoyproxy.io/owning-gateway-name: gateway-1 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - name: envoy-gateway/gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: default + name: default/gateway-1 securityPolicies: - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: SecurityPolicy metadata: creationTimestamp: null - name: policy-for-http-route + name: policy-for-http-route-1 namespace: default spec: basicAuth: users: group: null kind: null - name: users-secret + name: users-secret1 targetRef: group: gateway.networking.k8s.io kind: HTTPRoute @@ -118,7 +162,7 @@ securityPolicies: group: gateway.networking.k8s.io kind: Gateway name: gateway-1 - namespace: envoy-gateway + namespace: default sectionName: http conditions: - lastTransitionTime: null @@ -127,8 +171,45 @@ securityPolicies: status: "True" type: Accepted controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + creationTimestamp: null + name: policy-for-gateway-1 + namespace: default + spec: + basicAuth: + users: + group: null + kind: null + name: users-secret2 + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: default + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: default + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: 'This policy is being overridden by other securityPolicies for these + routes: [default/httproute-1]' + reason: Overridden + status: "True" + type: Overridden + controllerName: gateway.envoyproxy.io/gatewayclass-controller xdsIR: - envoy-gateway/gateway-1: + default/gateway-1: accessLog: text: - path: /dev/stdout @@ -137,7 +218,7 @@ xdsIR: hostnames: - '*' isHTTP2: false - name: envoy-gateway/gateway-1/http + name: default/gateway-1/http path: escapedSlashesAction: UnescapeAndRedirect mergeSlashes: true @@ -147,6 +228,7 @@ xdsIR: invalid: 0 valid: 0 basicAuth: + name: securitypolicy/default/policy-for-http-route-1 users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= destination: name: httproute/default/httproute-1/rule/0 @@ -157,10 +239,54 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - hostname: gateway.envoyproxy.io + hostname: www.foo.com + isHTTP2: false + name: httproute/default/httproute-1/rule/0/match/0/www_foo_com + pathMatch: + distinct: false + name: "" + prefix: /foo1 + - backendWeights: + invalid: 0 + valid: 0 + basicAuth: + name: securitypolicy/default/policy-for-http-route-1 + users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= + destination: + name: httproute/default/httproute-1/rule/1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: www.foo.com + isHTTP2: false + name: httproute/default/httproute-1/rule/1/match/0/www_foo_com + pathMatch: + distinct: false + name: "" + prefix: /foo2 + - backendWeights: + invalid: 0 + valid: 0 + basicAuth: + name: securitypolicy/default/policy-for-gateway-1 + users: Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo= + destination: + name: httproute/default/httproute-2/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: www.bar.com isHTTP2: false - name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io + name: httproute/default/httproute-2/rule/0/match/0/www_bar_com pathMatch: distinct: false name: "" - prefix: /foo + prefix: /bar diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml index 5e557abb08c..5879169de28 100755 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml @@ -311,7 +311,7 @@ xdsIR: grpc: authority: grpc-backend.default:9000 destination: - name: securitypolicy/default/policy-for-http-route/grpc-backend + name: securitypolicy/default/policy-for-http-route/default/grpc-backend settings: - addressType: IP endpoints: @@ -327,7 +327,7 @@ xdsIR: headersToExtAuth: - header1 - header2 - name: default/httproute-1 + name: securitypolicy/default/policy-for-http-route hostname: www.foo.com isHTTP2: false name: httproute/default/httproute-1/rule/0/match/0/www_foo_com @@ -352,7 +352,7 @@ xdsIR: http: authority: http-backend.envoy-gateway:80 destination: - name: securitypolicy/default/policy-for-gateway/http-backend + name: securitypolicy/default/policy-for-gateway/envoy-gateway/http-backend settings: - addressType: IP endpoints: @@ -369,7 +369,7 @@ xdsIR: - header1 - header2 path: /auth - name: default/gateway-1 + name: securitypolicy/default/policy-for-gateway hostname: www.bar.com isHTTP2: false name: httproute/default/httproute-2/rule/0/match/0/www_bar_com diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml index 3d9382a95ea..9d7f17e93d3 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth.in.yaml @@ -133,41 +133,41 @@ securityPolicies: kind: SecurityPolicy metadata: namespace: default - name: policy-for-gateway + name: policy-for-http-route-1 spec: targetRef: group: gateway.networking.k8s.io - kind: Gateway - name: gateway-1 + kind: HTTPRoute + name: httproute-1 namespace: default extAuth: - http: + failOpen: true + headersToExtAuth: + - header1 + - header2 + grpc: backendRef: - Name: http-backend - Namespace: envoy-gateway - Port: 80 - Path: /auth - headersToBackend: - - header1 - - header2 - failOpen: false + name: grpc-backend + port: 9000 - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: SecurityPolicy metadata: namespace: default - name: policy-for-http-route + name: policy-for-gateway-1 # This will only apply to the httproute-2 spec: targetRef: group: gateway.networking.k8s.io - kind: HTTPRoute - name: httproute-1 + kind: Gateway + name: gateway-1 namespace: default extAuth: - headersToExtAuth: - - header1 - - header2 - grpc: + failOpen: false + http: backendRef: - name: grpc-backend - port: 9000 - failOpen: true + Name: http-backend + Namespace: envoy-gateway + Port: 80 + Path: /auth + headersToBackend: + - header1 + - header2 diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml index 066e9ad2f9f..f9243d6f420 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml @@ -143,7 +143,7 @@ securityPolicies: kind: SecurityPolicy metadata: creationTimestamp: null - name: policy-for-http-route + name: policy-for-http-route-1 namespace: default spec: extAuth: @@ -179,7 +179,7 @@ securityPolicies: kind: SecurityPolicy metadata: creationTimestamp: null - name: policy-for-gateway + name: policy-for-gateway-1 namespace: default spec: extAuth: @@ -251,7 +251,7 @@ xdsIR: grpc: authority: grpc-backend.default:9000 destination: - name: securitypolicy/default/policy-for-http-route/grpc-backend + name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend settings: - addressType: IP endpoints: @@ -262,7 +262,7 @@ xdsIR: headersToExtAuth: - header1 - header2 - name: default/httproute-1 + name: securitypolicy/default/policy-for-http-route-1 hostname: www.foo.com isHTTP2: false name: httproute/default/httproute-1/rule/0/match/0/www_foo_com @@ -287,7 +287,7 @@ xdsIR: grpc: authority: grpc-backend.default:9000 destination: - name: securitypolicy/default/policy-for-http-route/grpc-backend + name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend settings: - addressType: IP endpoints: @@ -298,7 +298,7 @@ xdsIR: headersToExtAuth: - header1 - header2 - name: default/httproute-1 + name: securitypolicy/default/policy-for-http-route-1 hostname: www.foo.com isHTTP2: false name: httproute/default/httproute-1/rule/1/match/0/www_foo_com @@ -323,7 +323,7 @@ xdsIR: http: authority: http-backend.envoy-gateway:80 destination: - name: securitypolicy/default/policy-for-gateway/http-backend + name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend settings: - addressType: IP endpoints: @@ -335,7 +335,7 @@ xdsIR: - header1 - header2 path: /auth - name: default/gateway-1 + name: securitypolicy/default/policy-for-gateway-1 hostname: www.bar.com isHTTP2: false name: httproute/default/httproute-2/rule/0/match/0/www_bar_com diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml index 303d05191f7..31fb6ee9bb8 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml @@ -86,7 +86,7 @@ securityPolicies: kind: SecurityPolicy metadata: namespace: envoy-gateway - name: policy-for-gateway-discover-endpoints # This policy should attach httproute-2 + name: policy-for-gateway # This policy should attach httproute-2 uid: b8284d0f-de82-4c65-b204-96a0d3f258a1 spec: targetRef: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml index ad55d9bba65..dfd4a9f6073 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml @@ -181,7 +181,7 @@ securityPolicies: kind: SecurityPolicy metadata: creationTimestamp: null - name: policy-for-gateway-discover-endpoints + name: policy-for-gateway namespace: envoy-gateway uid: b8284d0f-de82-4c65-b204-96a0d3f258a1 spec: @@ -257,6 +257,7 @@ xdsIR: cookieSuffix: 5f93c2e4 hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= logoutPath: /foo/logout + name: securitypolicy/default/policy-for-http-route provider: authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth tokenEndpoint: https://oauth.foo.com/token @@ -291,6 +292,7 @@ xdsIR: cookieSuffix: b0a1b740 hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= logoutPath: /bar/logout + name: securitypolicy/envoy-gateway/policy-for-gateway provider: authorizationEndpoint: https://accounts.google.com/o/oauth2/v2/auth tokenEndpoint: https://oauth2.googleapis.com/token diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 4f6ed8ac00d..76545ab3c80 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -518,6 +518,10 @@ type JWT struct { // // +k8s:deepcopy-gen=true type OIDC struct { + // Name is a unique name for an OIDC configuration. + // The xds translator only generates one OAuth2 filter for each unique name. + Name string `json:"name" yaml:"name"` + // The OIDC Provider configuration. Provider OIDCProvider `json:"provider" yaml:"provider"` @@ -567,6 +571,10 @@ type OIDCProvider struct { // // +k8s:deepcopy-gen=true type BasicAuth struct { + // Name is a unique name for an BasicAuth configuration. + // The xds translator only generates one basic auth filter for each unique name. + Name string `json:"name" yaml:"name"` + // The username-password pairs in htpasswd format. Users []byte `json:"users,omitempty" yaml:"users,omitempty"` } diff --git a/internal/xds/translator/basicauth.go b/internal/xds/translator/basicauth.go index 85cd77fa3c3..720cd7dddd6 100644 --- a/internal/xds/translator/basicauth.go +++ b/internal/xds/translator/basicauth.go @@ -51,7 +51,14 @@ func (*basicAuth) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTP continue } - filter, err := buildHCMBasicAuthFilter(route) + // Only generates one BasicAuth Envoy filter for each unique name. + // For example, if there are two routes under the same gateway with the + // same BasicAuth config, only one BasicAuth filter will be generated. + if hcmContainsFilter(mgr, basicAuthFilterName(route.BasicAuth)) { + continue + } + + filter, err := buildHCMBasicAuthFilter(route.BasicAuth) if err != nil { errs = errors.Join(errs, err) continue @@ -64,8 +71,8 @@ func (*basicAuth) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTP } // buildHCMBasicAuthFilter returns a basic_auth HTTP filter from the provided IR HTTPRoute. -func buildHCMBasicAuthFilter(route *ir.HTTPRoute) (*hcmv3.HttpFilter, error) { - basicAuthProto := basicAuthConfig(route) +func buildHCMBasicAuthFilter(basicAuth *ir.BasicAuth) (*hcmv3.HttpFilter, error) { + basicAuthProto := basicAuthConfig(basicAuth) if err := basicAuthProto.ValidateAll(); err != nil { return nil, err @@ -77,7 +84,7 @@ func buildHCMBasicAuthFilter(route *ir.HTTPRoute) (*hcmv3.HttpFilter, error) { } return &hcmv3.HttpFilter{ - Name: basicAuthFilterName(route), + Name: basicAuthFilterName(basicAuth), Disabled: true, ConfigType: &hcmv3.HttpFilter_TypedConfig{ TypedConfig: basicAuthAny, @@ -85,15 +92,15 @@ func buildHCMBasicAuthFilter(route *ir.HTTPRoute) (*hcmv3.HttpFilter, error) { }, nil } -func basicAuthFilterName(route *ir.HTTPRoute) string { - return perRouteFilterName(basicAuthFilter, route.Name) +func basicAuthFilterName(basicAuth *ir.BasicAuth) string { + return perRouteFilterName(basicAuthFilter, basicAuth.Name) } -func basicAuthConfig(route *ir.HTTPRoute) *basicauthv3.BasicAuth { +func basicAuthConfig(basicAuth *ir.BasicAuth) *basicauthv3.BasicAuth { return &basicauthv3.BasicAuth{ Users: &corev3.DataSource{ Specifier: &corev3.DataSource_InlineBytes{ - InlineBytes: route.BasicAuth.Users, + InlineBytes: basicAuth.Users, }, }, } @@ -129,7 +136,7 @@ func (*basicAuth) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error if irRoute.BasicAuth == nil { return nil } - filterName := basicAuthFilterName(irRoute) + filterName := basicAuthFilterName(irRoute.BasicAuth) if err := enableFilterOnRoute(route, filterName); err != nil { return err } diff --git a/internal/xds/translator/oidc.go b/internal/xds/translator/oidc.go index 2a10254ec64..503d59e5f89 100644 --- a/internal/xds/translator/oidc.go +++ b/internal/xds/translator/oidc.go @@ -56,7 +56,14 @@ func (*oidc) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListe continue } - filter, err := buildHCMOAuth2Filter(route) + // Only generates one BasicAuth Envoy filter for each unique name. + // For example, if there are two routes under the same gateway with the + // same BasicAuth config, only one BasicAuth filter will be generated. + if hcmContainsFilter(mgr, oauth2FilterName(route.OIDC)) { + continue + } + + filter, err := buildHCMOAuth2Filter(route.OIDC) if err != nil { errs = errors.Join(errs, err) continue @@ -69,8 +76,8 @@ func (*oidc) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListe } // buildHCMOAuth2Filter returns an OAuth2 HTTP filter from the provided IR HTTPRoute. -func buildHCMOAuth2Filter(route *ir.HTTPRoute) (*hcmv3.HttpFilter, error) { - oauth2Proto, err := oauth2Config(route) +func buildHCMOAuth2Filter(oidc *ir.OIDC) (*hcmv3.HttpFilter, error) { + oauth2Proto, err := oauth2Config(oidc) if err != nil { return nil, err } @@ -85,7 +92,7 @@ func buildHCMOAuth2Filter(route *ir.HTTPRoute) (*hcmv3.HttpFilter, error) { } return &hcmv3.HttpFilter{ - Name: oauth2FilterName(route), + Name: oauth2FilterName(oidc), Disabled: true, ConfigType: &hcmv3.HttpFilter_TypedConfig{ TypedConfig: OAuth2Any, @@ -93,25 +100,25 @@ func buildHCMOAuth2Filter(route *ir.HTTPRoute) (*hcmv3.HttpFilter, error) { }, nil } -func oauth2FilterName(route *ir.HTTPRoute) string { - return perRouteFilterName(oauth2Filter, route.Name) +func oauth2FilterName(oidc *ir.OIDC) string { + return perRouteFilterName(oauth2Filter, oidc.Name) } -func oauth2Config(route *ir.HTTPRoute) (*oauth2v3.OAuth2, error) { - cluster, err := url2Cluster(route.OIDC.Provider.TokenEndpoint) +func oauth2Config(oidc *ir.OIDC) (*oauth2v3.OAuth2, error) { + cluster, err := url2Cluster(oidc.Provider.TokenEndpoint) if err != nil { return nil, err } if cluster.endpointType == EndpointTypeStatic { return nil, fmt.Errorf( "static IP cluster is not allowed: %s", - route.OIDC.Provider.TokenEndpoint) + oidc.Provider.TokenEndpoint) } oauth2 := &oauth2v3.OAuth2{ Config: &oauth2v3.OAuth2Config{ TokenEndpoint: &corev3.HttpUri{ - Uri: route.OIDC.Provider.TokenEndpoint, + Uri: oidc.Provider.TokenEndpoint, HttpUpstreamType: &corev3.HttpUri_Cluster{ Cluster: cluster.name, }, @@ -119,13 +126,13 @@ func oauth2Config(route *ir.HTTPRoute) (*oauth2v3.OAuth2, error) { Seconds: defaultExtServiceRequestTimeout, }, }, - AuthorizationEndpoint: route.OIDC.Provider.AuthorizationEndpoint, - RedirectUri: route.OIDC.RedirectURL, + AuthorizationEndpoint: oidc.Provider.AuthorizationEndpoint, + RedirectUri: oidc.RedirectURL, RedirectPathMatcher: &matcherv3.PathMatcher{ Rule: &matcherv3.PathMatcher_Path{ Path: &matcherv3.StringMatcher{ MatchPattern: &matcherv3.StringMatcher_Exact{ - Exact: route.OIDC.RedirectPath, + Exact: oidc.RedirectPath, }, }, }, @@ -134,35 +141,35 @@ func oauth2Config(route *ir.HTTPRoute) (*oauth2v3.OAuth2, error) { Rule: &matcherv3.PathMatcher_Path{ Path: &matcherv3.StringMatcher{ MatchPattern: &matcherv3.StringMatcher_Exact{ - Exact: route.OIDC.LogoutPath, + Exact: oidc.LogoutPath, }, }, }, }, ForwardBearerToken: true, Credentials: &oauth2v3.OAuth2Credentials{ - ClientId: route.OIDC.ClientID, + ClientId: oidc.ClientID, TokenSecret: &tlsv3.SdsSecretConfig{ - Name: oauth2ClientSecretName(route), + Name: oauth2ClientSecretName(oidc), SdsConfig: makeConfigSource(), }, TokenFormation: &oauth2v3.OAuth2Credentials_HmacSecret{ HmacSecret: &tlsv3.SdsSecretConfig{ - Name: oauth2HMACSecretName(route), + Name: oauth2HMACSecretName(oidc), SdsConfig: makeConfigSource(), }, }, CookieNames: &oauth2v3.OAuth2Credentials_CookieNames{ - BearerToken: fmt.Sprintf("BearerToken-%s", route.OIDC.CookieSuffix), - OauthHmac: fmt.Sprintf("OauthHMAC-%s", route.OIDC.CookieSuffix), - OauthExpires: fmt.Sprintf("OauthExpires-%s", route.OIDC.CookieSuffix), - IdToken: fmt.Sprintf("IdToken-%s", route.OIDC.CookieSuffix), - RefreshToken: fmt.Sprintf("RefreshToken-%s", route.OIDC.CookieSuffix), + BearerToken: fmt.Sprintf("BearerToken-%s", oidc.CookieSuffix), + OauthHmac: fmt.Sprintf("OauthHMAC-%s", oidc.CookieSuffix), + OauthExpires: fmt.Sprintf("OauthExpires-%s", oidc.CookieSuffix), + IdToken: fmt.Sprintf("IdToken-%s", oidc.CookieSuffix), + RefreshToken: fmt.Sprintf("RefreshToken-%s", oidc.CookieSuffix), }, }, // every OIDC provider supports basic auth AuthType: oauth2v3.OAuth2Config_BASIC_AUTH, - AuthScopes: route.OIDC.Scopes, + AuthScopes: oidc.Scopes, }, } return oauth2, nil @@ -273,12 +280,12 @@ func createOAuth2Secrets(tCtx *types.ResourceVersionTable, routes []*ir.HTTPRout // a separate secret is created for each route, even they share the same // oauth2 client ID and secret. - clientSecret := buildOAuth2ClientSecret(route) + clientSecret := buildOAuth2ClientSecret(route.OIDC) if err := addXdsSecret(tCtx, clientSecret); err != nil { errs = errors.Join(errs, err) } - if err := addXdsSecret(tCtx, buildOAuth2HMACSecret(route)); err != nil { + if err := addXdsSecret(tCtx, buildOAuth2HMACSecret(route.OIDC)); err != nil { errs = errors.Join(errs, err) } } @@ -286,14 +293,14 @@ func createOAuth2Secrets(tCtx *types.ResourceVersionTable, routes []*ir.HTTPRout return errs } -func buildOAuth2ClientSecret(route *ir.HTTPRoute) *tlsv3.Secret { +func buildOAuth2ClientSecret(oidc *ir.OIDC) *tlsv3.Secret { clientSecret := &tlsv3.Secret{ - Name: oauth2ClientSecretName(route), + Name: oauth2ClientSecretName(oidc), Type: &tlsv3.Secret_GenericSecret{ GenericSecret: &tlsv3.GenericSecret{ Secret: &corev3.DataSource{ Specifier: &corev3.DataSource_InlineBytes{ - InlineBytes: route.OIDC.ClientSecret, + InlineBytes: oidc.ClientSecret, }, }, }, @@ -303,14 +310,14 @@ func buildOAuth2ClientSecret(route *ir.HTTPRoute) *tlsv3.Secret { return clientSecret } -func buildOAuth2HMACSecret(route *ir.HTTPRoute) *tlsv3.Secret { +func buildOAuth2HMACSecret(oidc *ir.OIDC) *tlsv3.Secret { hmacSecret := &tlsv3.Secret{ - Name: oauth2HMACSecretName(route), + Name: oauth2HMACSecretName(oidc), Type: &tlsv3.Secret_GenericSecret{ GenericSecret: &tlsv3.GenericSecret{ Secret: &corev3.DataSource{ Specifier: &corev3.DataSource_InlineBytes{ - InlineBytes: route.OIDC.HMACSecret, + InlineBytes: oidc.HMACSecret, }, }, }, @@ -320,12 +327,12 @@ func buildOAuth2HMACSecret(route *ir.HTTPRoute) *tlsv3.Secret { return hmacSecret } -func oauth2ClientSecretName(route *ir.HTTPRoute) string { - return fmt.Sprintf("%s/oauth2/client_secret", route.Name) +func oauth2ClientSecretName(oidc *ir.OIDC) string { + return fmt.Sprintf("oauth2/client_secret/%s", oidc.Name) } -func oauth2HMACSecretName(route *ir.HTTPRoute) string { - return fmt.Sprintf("%s/oauth2/hmac_secret", route.Name) +func oauth2HMACSecretName(oidc *ir.OIDC) string { + return fmt.Sprintf("oauth2/hmac_secret/%s", oidc.Name) } // patchRoute patches the provided route with the oauth2 config if applicable. @@ -340,7 +347,7 @@ func (*oidc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { if irRoute.OIDC == nil { return nil } - filterName := oauth2FilterName(irRoute) + filterName := oauth2FilterName(irRoute.OIDC) if err := enableFilterOnRoute(route, filterName); err != nil { return err } diff --git a/internal/xds/translator/testdata/in/xds-ir/basic-auth.yaml b/internal/xds/translator/testdata/in/xds-ir/basic-auth.yaml index af6baa0b77e..36df412f728 100644 --- a/internal/xds/translator/testdata/in/xds-ir/basic-auth.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/basic-auth.yaml @@ -1,22 +1,77 @@ http: -- name: "first-listener" - address: "0.0.0.0" - port: 10080 +- address: 0.0.0.0 hostnames: - - "*" + - '*' + isHTTP2: false + name: default/gateway-1/http path: - mergeSlashes: true escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 routes: - - name: "first-route" - hostname: "*" + - name: httproute/default/httproute-1/rule/0/match/0/www_foo_com + hostname: www.foo.com + isHTTP2: false + pathMatch: + distinct: false + name: "" + prefix: /foo1 + backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + basicAuth: + name: securitypolicy/default/policy-for-http-route-1 + users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= + - name: httproute/default/httproute-1/rule/1/match/0/www_foo_com + backendWeights: + hostname: www.foo.com + isHTTP2: false + pathMatch: + distinct: false + name: "" + prefix: /foo2 + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-1/rule/1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + basicAuth: + name: securitypolicy/default/policy-for-http-route-1 + users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= + - name: httproute/default/httproute-2/rule/0/match/0/www_bar_com + hostname: www.bar.com + isHTTP2: false pathMatch: - exact: "foo/bar" + distinct: false + name: "" + prefix: /bar + backendWeights: + invalid: 0 + valid: 0 destination: - name: "first-route-dest" + name: httproute/default/httproute-2/rule/0 settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 basicAuth: - users: "dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo=" + name: securitypolicy/default/policy-for-gateway-1 + users: Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo= diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml index 3ed7a397f0c..32d5522e6df 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml @@ -1,93 +1,120 @@ http: -- name: "first-listener" - address: "0.0.0.0" - port: 10080 - hostnames: - - "www.example.com" - path: - mergeSlashes: true - escapedSlashesAction: UnescapeAndRedirect - routes: - - name: httproute/default/httproute-1/rule/0/match/0/www_example_com - hostname: "*" - pathMatch: - exact: "foo" - destination: - name: httproute/default/httproute-1/rule/0 - settings: - - endpoints: - - host: "10.0.0.1" - port: 50000 - extAuth: - name: default/httproute-1 - http: - authority: http-backend.envoy-gateway:80 - headersToBackend: - - header1 - - header2 - path: /auth + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: default/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - name: httproute/default/httproute-1/rule/0/match/0/www_foo_com + hostname: www.foo.com + isHTTP2: false + pathMatch: + distinct: false + name: "" + prefix: /foo1 + backendWeights: + invalid: 0 + valid: 0 destination: - name: securitypolicy/default/policy-for-first-route/http-backend + name: httproute/default/httproute-1/rule/0 settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 80 - protocol: HTTP - weight: 1 - failOpen: false - - name: httproute/default/httproute-1/rule/1/match/0/www_example_com - hostname: "*" - pathMatch: - exact: "foo" - destination: - name: httproute/default/httproute-1/rule/0 - settings: - - endpoints: - - host: "10.0.0.1" - port: 50000 - extAuth: - name: default/httproute-1 - http: - authority: http-backend.envoy-gateway:80 - headersToBackend: - - header1 - - header2 - path: /auth + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + extAuth: + name: securitypolicy/default/policy-for-http-route-1 + failOpen: false + grpc: + authority: grpc-backend.default:9000 + destination: + name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend + settings: + - addressType: IP + endpoints: + - host: 8.8.8.8 + port: 9000 + protocol: GRPC + weight: 1 + headersToExtAuth: + - header1 + - header2 + - name: httproute/default/httproute-1/rule/1/match/0/www_foo_com + hostname: www.foo.com + isHTTP2: false + pathMatch: + distinct: false + name: "" + prefix: /foo2 + backendWeights: + invalid: 0 + valid: 0 destination: - name: securitypolicy/default/policy-for-first-route/http-backend + name: httproute/default/httproute-1/rule/1 settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 80 - protocol: HTTP - weight: 1 - failOpen: false - - name: httproute/default/httproute-2/rule/0/match/0/www_example_com - hostname: "*" - pathMatch: - exact: "bar" - destination: - name: httproute/default/httproute-2/rule/0 - settings: - - endpoints: - - host: "10.0.0.2" - port: 60000 - extAuth: - name: default/gateway-1 - grpc: - authority: grpc-backend.default:9000 + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + extAuth: + name: securitypolicy/default/policy-for-http-route-1 + failOpen: false + grpc: + authority: grpc-backend.default:9000 + destination: + name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend + settings: + - addressType: IP + endpoints: + - host: 8.8.8.8 + port: 9000 + protocol: GRPC + weight: 1 + headersToExtAuth: + - header1 + - header2 + - name: httproute/default/httproute-2/rule/0/match/0/www_bar_com + hostname: www.bar.com + isHTTP2: false + pathMatch: + distinct: false + name: "" + prefix: /bar + backendWeights: + invalid: 0 + valid: 0 destination: - name: securitypolicy/default/policy-for-second-route/grpc-backend + name: httproute/default/httproute-2/rule/0 settings: - - addressType: IP - endpoints: - - host: 8.8.8.8 - port: 9000 - protocol: GRPC - weight: 1 - headersToExtAuth: - - header1 - - header2 - failOpen: true + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + extAuth: + name: securitypolicy/default/policy-for-gateway-1 + failOpen: true + http: + authority: http-backend.envoy-gateway:80 + destination: + name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 80 + protocol: HTTP + weight: 1 + headersToBackend: + - header1 + - header2 + path: /auth diff --git a/internal/xds/translator/testdata/in/xds-ir/oidc.yaml b/internal/xds/translator/testdata/in/xds-ir/oidc.yaml index b90a1c97f4a..59441c23d6c 100644 --- a/internal/xds/translator/testdata/in/xds-ir/oidc.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/oidc.yaml @@ -19,6 +19,7 @@ http: - host: "1.2.3.4" port: 50000 oidc: + name: securitypolicy/default/policy-for-first-route clientID: client.oauth.foo.com clientSecret: Y2xpZW50MTpzZWNyZXQK provider: @@ -43,6 +44,7 @@ http: - host: "1.2.3.4" port: 50000 oidc: + name: securitypolicy/default/policy-for-second-route clientID: client.oauth.bar.com clientSecret: Y2xpZW50MTpzZWNyZXQK provider: diff --git a/internal/xds/translator/testdata/out/xds-ir/basic-auth.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/basic-auth.clusters.yaml index d53a7a1b2ce..e4e5b8994bc 100644 --- a/internal/xds/translator/testdata/out/xds-ir/basic-auth.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/basic-auth.clusters.yaml @@ -9,9 +9,43 @@ edsConfig: ads: {} resourceApiVersion: V3 - serviceName: first-route-dest + serviceName: httproute/default/httproute-1/rule/0 lbPolicy: LEAST_REQUEST - name: first-route-dest + name: httproute/default/httproute-1/rule/0 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-1/rule/1 + lbPolicy: LEAST_REQUEST + name: httproute/default/httproute-1/rule/1 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-2/rule/0 + lbPolicy: LEAST_REQUEST + name: httproute/default/httproute-2/rule/0 outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/basic-auth.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/basic-auth.endpoints.yaml index 3b3f2d09076..bf9f0023789 100644 --- a/internal/xds/translator/testdata/out/xds-ir/basic-auth.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/basic-auth.endpoints.yaml @@ -1,12 +1,36 @@ -- clusterName: first-route-dest +- clusterName: httproute/default/httproute-1/rule/0 endpoints: - lbEndpoints: - endpoint: address: socketAddress: - address: 1.2.3.4 - portValue: 50000 + address: 7.7.7.7 + portValue: 8080 loadBalancingWeight: 1 loadBalancingWeight: 1 locality: - region: first-route-dest/backend/0 + region: httproute/default/httproute-1/rule/0/backend/0 +- clusterName: httproute/default/httproute-1/rule/1 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-1/rule/1/backend/0 +- clusterName: httproute/default/httproute-2/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-2/rule/0/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml index 36ab0dbb7ba..bdf4ec12fab 100644 --- a/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml @@ -15,11 +15,17 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.basic_auth/first-route + name: envoy.filters.http.basic_auth/securitypolicy/default/policy-for-http-route-1 typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuth users: inlineBytes: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= + - disabled: true + name: envoy.filters.http.basic_auth/securitypolicy/default/policy-for-gateway-1 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuth + users: + inlineBytes: Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo= - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router @@ -31,10 +37,10 @@ configSource: ads: {} resourceApiVersion: V3 - routeConfigName: first-listener + routeConfigName: default/gateway-1/http serverHeaderTransformation: PASS_THROUGH statPrefix: http useRemoteAddress: true drainType: MODIFY_ONLY - name: first-listener + name: default/gateway-1/http perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/basic-auth.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/basic-auth.routes.yaml index 22938d503e2..c7196e28f6f 100644 --- a/internal/xds/translator/testdata/out/xds-ir/basic-auth.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/basic-auth.routes.yaml @@ -1,18 +1,44 @@ - ignorePortInHostMatching: true - name: first-listener + name: default/gateway-1/http virtualHosts: - domains: - - '*' - name: first-listener/* + - www.foo.com + name: default/gateway-1/http/www_foo_com routes: - match: - path: foo/bar - name: first-route + pathSeparatedPrefix: /foo1 + name: httproute/default/httproute-1/rule/0/match/0/www_foo_com route: - cluster: first-route-dest + cluster: httproute/default/httproute-1/rule/0 upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.basic_auth/first-route: + envoy.filters.http.basic_auth/securitypolicy/default/policy-for-http-route-1: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + - match: + pathSeparatedPrefix: /foo2 + name: httproute/default/httproute-1/rule/1/match/0/www_foo_com + route: + cluster: httproute/default/httproute-1/rule/1 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.basic_auth/securitypolicy/default/policy-for-http-route-1: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + - domains: + - www.bar.com + name: default/gateway-1/http/www_bar_com + routes: + - match: + pathSeparatedPrefix: /bar + name: httproute/default/httproute-2/rule/0/match/0/www_bar_com + route: + cluster: httproute/default/httproute-2/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.basic_auth/securitypolicy/default/policy-for-gateway-1: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml index d02aa6b4aa8..cf4fbc9b274 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml @@ -26,9 +26,9 @@ edsConfig: ads: {} resourceApiVersion: V3 - serviceName: httproute/default/httproute-2/rule/0 + serviceName: httproute/default/httproute-1/rule/1 lbPolicy: LEAST_REQUEST - name: httproute/default/httproute-2/rule/0 + name: httproute/default/httproute-1/rule/1 outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS @@ -43,9 +43,9 @@ edsConfig: ads: {} resourceApiVersion: V3 - serviceName: securitypolicy/default/policy-for-first-route/http-backend + serviceName: httproute/default/httproute-2/rule/0 lbPolicy: LEAST_REQUEST - name: securitypolicy/default/policy-for-first-route/http-backend + name: httproute/default/httproute-2/rule/0 outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS @@ -60,9 +60,9 @@ edsConfig: ads: {} resourceApiVersion: V3 - serviceName: securitypolicy/default/policy-for-second-route/grpc-backend + serviceName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend lbPolicy: LEAST_REQUEST - name: securitypolicy/default/policy-for-second-route/grpc-backend + name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS @@ -71,3 +71,20 @@ '@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: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend + lbPolicy: LEAST_REQUEST + name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth.endpoints.yaml index ce53193cdb2..2c0f91a63f3 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-auth.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth.endpoints.yaml @@ -4,37 +4,37 @@ - endpoint: address: socketAddress: - address: 10.0.0.1 - portValue: 50000 + address: 7.7.7.7 + portValue: 8080 loadBalancingWeight: 1 loadBalancingWeight: 1 locality: region: httproute/default/httproute-1/rule/0/backend/0 -- clusterName: httproute/default/httproute-2/rule/0 +- clusterName: httproute/default/httproute-1/rule/1 endpoints: - lbEndpoints: - endpoint: address: socketAddress: - address: 10.0.0.2 - portValue: 60000 + address: 7.7.7.7 + portValue: 8080 loadBalancingWeight: 1 loadBalancingWeight: 1 locality: - region: httproute/default/httproute-2/rule/0/backend/0 -- clusterName: securitypolicy/default/policy-for-first-route/http-backend + region: httproute/default/httproute-1/rule/1/backend/0 +- clusterName: httproute/default/httproute-2/rule/0 endpoints: - lbEndpoints: - endpoint: address: socketAddress: address: 7.7.7.7 - portValue: 80 + portValue: 8080 loadBalancingWeight: 1 loadBalancingWeight: 1 locality: - region: securitypolicy/default/policy-for-first-route/http-backend/backend/0 -- clusterName: securitypolicy/default/policy-for-second-route/grpc-backend + region: httproute/default/httproute-2/rule/0/backend/0 +- clusterName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend endpoints: - lbEndpoints: - endpoint: @@ -45,4 +45,16 @@ loadBalancingWeight: 1 loadBalancingWeight: 1 locality: - region: securitypolicy/default/policy-for-second-route/grpc-backend/backend/0 + region: securitypolicy/default/policy-for-http-route-1/default/grpc-backend/backend/0 +- clusterName: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 80 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml index 35a8b7f7ab5..e85a6d3b854 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth.listeners.yaml @@ -15,9 +15,24 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.ext_authz/default/httproute-1 + name: envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1 typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz + allowedHeaders: + patterns: + - exact: header1 + - exact: header2 + grpcService: + envoyGrpc: + authority: grpc-backend.default:9000 + clusterName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend + timeout: 10s + transportApiVersion: V3 + - disabled: true + name: envoy.filters.http.ext_authz/securitypolicy/default/policy-for-gateway-1 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz + failureModeAllow: true httpService: authorizationResponse: allowedUpstreamHeaders: @@ -25,25 +40,10 @@ - exact: header1 - exact: header2 serverUri: - cluster: securitypolicy/default/policy-for-first-route/http-backend + cluster: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend timeout: 10s uri: http://http-backend.envoy-gateway:80/auth transportApiVersion: V3 - - disabled: true - name: envoy.filters.http.ext_authz/default/gateway-1 - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz - allowedHeaders: - patterns: - - exact: header1 - - exact: header2 - failureModeAllow: true - grpcService: - envoyGrpc: - authority: grpc-backend.default:9000 - clusterName: securitypolicy/default/policy-for-second-route/grpc-backend - timeout: 10s - transportApiVersion: V3 - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router @@ -55,10 +55,10 @@ configSource: ads: {} resourceApiVersion: V3 - routeConfigName: first-listener + routeConfigName: default/gateway-1/http serverHeaderTransformation: PASS_THROUGH statPrefix: http useRemoteAddress: true drainType: MODIFY_ONLY - name: first-listener + name: default/gateway-1/http perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth.routes.yaml index 7ca5275220c..08edfc3c406 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-auth.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth.routes.yaml @@ -1,40 +1,44 @@ - ignorePortInHostMatching: true - name: first-listener + name: default/gateway-1/http virtualHosts: - domains: - - '*' - name: first-listener/* + - www.foo.com + name: default/gateway-1/http/www_foo_com routes: - match: - path: foo - name: httproute/default/httproute-1/rule/0/match/0/www_example_com + pathSeparatedPrefix: /foo1 + name: httproute/default/httproute-1/rule/0/match/0/www_foo_com route: cluster: httproute/default/httproute-1/rule/0 upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_authz/default/httproute-1: + envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} - match: - path: foo - name: httproute/default/httproute-1/rule/1/match/0/www_example_com + pathSeparatedPrefix: /foo2 + name: httproute/default/httproute-1/rule/1/match/0/www_foo_com route: - cluster: httproute/default/httproute-1/rule/0 + cluster: httproute/default/httproute-1/rule/1 upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_authz/default/httproute-1: + envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} + - domains: + - www.bar.com + name: default/gateway-1/http/www_bar_com + routes: - match: - path: bar - name: httproute/default/httproute-2/rule/0/match/0/www_example_com + pathSeparatedPrefix: /bar + name: httproute/default/httproute-2/rule/0/match/0/www_bar_com route: cluster: httproute/default/httproute-2/rule/0 upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_authz/default/gateway-1: + envoy.filters.http.ext_authz/securitypolicy/default/policy-for-gateway-1: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml index 132b1d06a48..1d7cf7ba34b 100644 --- a/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml @@ -15,7 +15,7 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.oauth2/first-route + name: envoy.filters.http.oauth2/securitypolicy/default/policy-for-first-route typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2 config: @@ -34,12 +34,12 @@ oauthHmac: OauthHMAC-5F93C2E4 refreshToken: RefreshToken-5F93C2E4 hmacSecret: - name: first-route/oauth2/hmac_secret + name: oauth2/hmac_secret/securitypolicy/default/policy-for-first-route sdsConfig: ads: {} resourceApiVersion: V3 tokenSecret: - name: first-route/oauth2/client_secret + name: oauth2/client_secret/securitypolicy/default/policy-for-first-route sdsConfig: ads: {} resourceApiVersion: V3 @@ -56,7 +56,7 @@ timeout: 10s uri: https://oauth.foo.com/token - disabled: true - name: envoy.filters.http.oauth2/second-route + name: envoy.filters.http.oauth2/securitypolicy/default/policy-for-second-route typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2 config: @@ -75,12 +75,12 @@ oauthHmac: OauthHMAC-5f93c2e4 refreshToken: RefreshToken-5f93c2e4 hmacSecret: - name: second-route/oauth2/hmac_secret + name: oauth2/hmac_secret/securitypolicy/default/policy-for-second-route sdsConfig: ads: {} resourceApiVersion: V3 tokenSecret: - name: second-route/oauth2/client_secret + name: oauth2/client_secret/securitypolicy/default/policy-for-second-route sdsConfig: ads: {} resourceApiVersion: V3 diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc.routes.yaml index d597d98514e..2170a16d131 100644 --- a/internal/xds/translator/testdata/out/xds-ir/oidc.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/oidc.routes.yaml @@ -13,7 +13,7 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.oauth2/first-route: + envoy.filters.http.oauth2/securitypolicy/default/policy-for-first-route: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} - match: @@ -24,6 +24,6 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.oauth2/second-route: + envoy.filters.http.oauth2/securitypolicy/default/policy-for-second-route: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} From 6fa99be5a9a3e5d16294492162181ff64db67003 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 15:14:51 -0700 Subject: [PATCH 28/29] build(deps): bump the k8s-io group with 6 updates (#2961) Bumps the k8s-io group with 6 updates: | Package | From | To | | --- | --- | --- | | [k8s.io/api](https://github.com/kubernetes/api) | `0.29.2` | `0.29.3` | | [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.29.2` | `0.29.3` | | [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.29.2` | `0.29.3` | | [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.29.2` | `0.29.3` | | [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.29.2` | `0.29.3` | | [k8s.io/kubectl](https://github.com/kubernetes/kubectl) | `0.29.2` | `0.29.3` | Updates `k8s.io/api` from 0.29.2 to 0.29.3 - [Commits](https://github.com/kubernetes/api/compare/v0.29.2...v0.29.3) Updates `k8s.io/apiextensions-apiserver` from 0.29.2 to 0.29.3 - [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases) - [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.29.2...v0.29.3) Updates `k8s.io/apimachinery` from 0.29.2 to 0.29.3 - [Commits](https://github.com/kubernetes/apimachinery/compare/v0.29.2...v0.29.3) Updates `k8s.io/cli-runtime` from 0.29.2 to 0.29.3 - [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.29.2...v0.29.3) Updates `k8s.io/client-go` from 0.29.2 to 0.29.3 - [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/kubernetes/client-go/compare/v0.29.2...v0.29.3) Updates `k8s.io/kubectl` from 0.29.2 to 0.29.3 - [Commits](https://github.com/kubernetes/kubectl/compare/v0.29.2...v0.29.3) --- updated-dependencies: - dependency-name: k8s.io/api dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-io - dependency-name: k8s.io/apiextensions-apiserver dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-io - dependency-name: k8s.io/apimachinery dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-io - dependency-name: k8s.io/cli-runtime dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-io - dependency-name: k8s.io/client-go dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-io - dependency-name: k8s.io/kubectl dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-io ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 16 ++++++++-------- go.sum | 32 ++++++++++++++++---------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index 23c05a8560b..71a64d168bf 100644 --- a/go.mod +++ b/go.mod @@ -39,12 +39,12 @@ require ( google.golang.org/protobuf v1.33.0 gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.14.3 - k8s.io/api v0.29.2 - k8s.io/apiextensions-apiserver v0.29.2 - k8s.io/apimachinery v0.29.2 - k8s.io/cli-runtime v0.29.2 - k8s.io/client-go v0.29.2 - k8s.io/kubectl v0.29.2 + k8s.io/api v0.29.3 + k8s.io/apiextensions-apiserver v0.29.3 + k8s.io/apimachinery v0.29.3 + k8s.io/cli-runtime v0.29.3 + k8s.io/client-go v0.29.3 + k8s.io/kubectl v0.29.3 k8s.io/utils v0.0.0-20230726121419-3b25d923346b sigs.k8s.io/controller-runtime v0.17.2 sigs.k8s.io/gateway-api v1.0.0 @@ -107,7 +107,7 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect golang.org/x/crypto v0.21.0 // indirect - k8s.io/apiserver v0.29.2 // indirect + k8s.io/apiserver v0.29.3 // indirect oras.land/oras-go v1.2.4 // indirect ) @@ -183,7 +183,7 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/component-base v0.29.2 // indirect + k8s.io/component-base v0.29.3 // indirect k8s.io/klog/v2 v2.110.1 // indirect k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect diff --git a/go.sum b/go.sum index 7f47edfd434..14e8c0171db 100644 --- a/go.sum +++ b/go.sum @@ -938,32 +938,32 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= k8s.io/api v0.18.4/go.mod h1:lOIQAKYgai1+vz9J7YcDZwC26Z0zQewYOGWdyIPUUQ4= -k8s.io/api v0.29.2 h1:hBC7B9+MU+ptchxEqTNW2DkUosJpp1P+Wn6YncZ474A= -k8s.io/api v0.29.2/go.mod h1:sdIaaKuU7P44aoyyLlikSLayT6Vb7bvJNCX105xZXY0= +k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw= +k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80= k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio= -k8s.io/apiextensions-apiserver v0.29.2 h1:UK3xB5lOWSnhaCk0RFZ0LUacPZz9RY4wi/yt2Iu+btg= -k8s.io/apiextensions-apiserver v0.29.2/go.mod h1:aLfYjpA5p3OwtqNXQFkhJ56TB+spV8Gc4wfMhUA3/b8= +k8s.io/apiextensions-apiserver v0.29.3 h1:9HF+EtZaVpFjStakF4yVufnXGPRppWFEQ87qnO91YeI= +k8s.io/apiextensions-apiserver v0.29.3/go.mod h1:po0XiY5scnpJfFizNGo6puNU6Fq6D70UJY2Cb2KwAVc= k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= k8s.io/apimachinery v0.18.4/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= -k8s.io/apimachinery v0.29.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8= -k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= +k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU= +k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU= k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw= k8s.io/apiserver v0.18.4/go.mod h1:q+zoFct5ABNnYkGIaGQ3bcbUNdmPyOCoEBcg51LChY8= -k8s.io/apiserver v0.29.2 h1:+Z9S0dSNr+CjnVXQePG8TcBWHr3Q7BmAr7NraHvsMiQ= -k8s.io/apiserver v0.29.2/go.mod h1:B0LieKVoyU7ykQvPFm7XSdIHaCHSzCzQWPFa5bqbeMQ= -k8s.io/cli-runtime v0.29.2 h1:smfsOcT4QujeghsNjECKN3lwyX9AwcFU0nvJ7sFN3ro= -k8s.io/cli-runtime v0.29.2/go.mod h1:KLisYYfoqeNfO+MkTWvpqIyb1wpJmmFJhioA0xd4MW8= +k8s.io/apiserver v0.29.3 h1:xR7ELlJ/BZSr2n4CnD3lfA4gzFivh0wwfNfz9L0WZcE= +k8s.io/apiserver v0.29.3/go.mod h1:hrvXlwfRulbMbBgmWRQlFru2b/JySDpmzvQwwk4GUOs= +k8s.io/cli-runtime v0.29.3 h1:r68rephmmytoywkw2MyJ+CxjpasJDQY7AGc3XY2iv1k= +k8s.io/cli-runtime v0.29.3/go.mod h1:aqVUsk86/RhaGJwDhHXH0jcdqBrgdF3bZWk4Z9D4mkM= k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= k8s.io/client-go v0.18.4/go.mod h1:f5sXwL4yAZRkAtzOxRWUhA/N8XzGCb+nPZI8PfobZ9g= -k8s.io/client-go v0.29.2 h1:FEg85el1TeZp+/vYJM7hkDlSTFZ+c5nnK44DJ4FyoRg= -k8s.io/client-go v0.29.2/go.mod h1:knlvFZE58VpqbQpJNbCbctTVXcd35mMyAAwBdpt4jrA= +k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg= +k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0= k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= k8s.io/code-generator v0.18.4/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM= k8s.io/component-base v0.18.4/go.mod h1:7jr/Ef5PGmKwQhyAz/pjByxJbC58mhKAhiaDu0vXfPk= -k8s.io/component-base v0.29.2 h1:lpiLyuvPA9yV1aQwGLENYyK7n/8t6l3nn3zAtFTJYe8= -k8s.io/component-base v0.29.2/go.mod h1:BfB3SLrefbZXiBfbM+2H1dlat21Uewg/5qtKOl8degM= +k8s.io/component-base v0.29.3 h1:Oq9/nddUxlnrCuuR2K/jp6aflVvc0uDvxMzAWxnGzAo= +k8s.io/component-base v0.29.3/go.mod h1:Yuj33XXjuOk2BAaHsIGHhCKZQAgYKhqIxIjIr2UXYio= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= @@ -976,8 +976,8 @@ k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/kubectl v0.29.2 h1:uaDYaBhumvkwz0S2XHt36fK0v5IdNgL7HyUniwb2IUo= -k8s.io/kubectl v0.29.2/go.mod h1:BhizuYBGcKaHWyq+G7txGw2fXg576QbPrrnQdQDZgqI= +k8s.io/kubectl v0.29.3 h1:RuwyyIU42MAISRIePaa8Q7A3U74Q9P4MoJbDFz9o3us= +k8s.io/kubectl v0.29.3/go.mod h1:yCxfY1dbwgVdEt2zkJ6d5NNLOhhWgTyrqACIoFhpdd4= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= From 655ee5d74657659ef454179d1f3748bd7a7fa9ac Mon Sep 17 00:00:00 2001 From: Karol Szwaj Date: Wed, 20 Mar 2024 01:56:12 +0100 Subject: [PATCH 29/29] chore: set mergedGateways in translator runner (#2971) * chore: set mergedGateways in translator runner Signed-off-by: Karol Szwaj * fix tests Signed-off-by: Karol Szwaj --------- Signed-off-by: Karol Szwaj --- internal/gatewayapi/helpers.go | 2 +- internal/gatewayapi/runner/runner.go | 1 + internal/gatewayapi/translator.go | 3 +-- internal/gatewayapi/translator_test.go | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go index 6503d4f2f41..252056f2d7d 100644 --- a/internal/gatewayapi/helpers.go +++ b/internal/gatewayapi/helpers.go @@ -399,7 +399,7 @@ func irTLSCACertName(namespace, name string) string { return fmt.Sprintf("%s/%s/%s", namespace, name, caCertKey) } -func isMergeGatewaysEnabled(resources *Resources) bool { +func IsMergeGatewaysEnabled(resources *Resources) bool { return resources.EnvoyProxy != nil && resources.EnvoyProxy.Spec.MergeGateways != nil && *resources.EnvoyProxy.Spec.MergeGateways } diff --git a/internal/gatewayapi/runner/runner.go b/internal/gatewayapi/runner/runner.go index 4cb3d69d15f..abc1016aa83 100644 --- a/internal/gatewayapi/runner/runner.go +++ b/internal/gatewayapi/runner/runner.go @@ -84,6 +84,7 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) { GlobalRateLimitEnabled: r.EnvoyGateway.RateLimit != nil, EnvoyPatchPolicyEnabled: r.EnvoyGateway.ExtensionAPIs != nil && r.EnvoyGateway.ExtensionAPIs.EnableEnvoyPatchPolicy, Namespace: r.Namespace, + MergeGateways: gatewayapi.IsMergeGatewaysEnabled(resources), } // If an extension is loaded, pass its supported groups/kinds to the translator diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index 83a819fbd23..12a5cf81743 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -252,8 +252,7 @@ func (t *Translator) InitIRs(gateways []*GatewayContext, resources *Resources) ( annotations := infrastructureAnnotations(gateway.Gateway) gwInfraIR.Proxy.GetProxyMetadata().Annotations = annotations - if isMergeGatewaysEnabled(resources) { - t.MergeGateways = true + if t.MergeGateways { irKey = string(t.GatewayClassName) maps.Copy(labels, GatewayClassOwnerLabel(string(t.GatewayClassName))) diff --git a/internal/gatewayapi/translator_test.go b/internal/gatewayapi/translator_test.go index ffadaf8bcbf..a22b69b534f 100644 --- a/internal/gatewayapi/translator_test.go +++ b/internal/gatewayapi/translator_test.go @@ -78,6 +78,7 @@ func TestTranslate(t *testing.T) { GlobalRateLimitEnabled: true, EnvoyPatchPolicyEnabled: envoyPatchPolicyEnabled, Namespace: "envoy-gateway-system", + MergeGateways: IsMergeGatewaysEnabled(resources), } // Add common test fixtures @@ -270,6 +271,7 @@ func TestTranslateWithExtensionKinds(t *testing.T) { GatewayClassName: "envoy-gateway-class", GlobalRateLimitEnabled: true, ExtensionGroupKinds: []schema.GroupKind{{Group: "foo.example.io", Kind: "Foo"}}, + MergeGateways: IsMergeGatewaysEnabled(resources), } // Add common test fixtures