diff --git a/api/v1alpha1/validation/envoygateway_validate.go b/api/v1alpha1/validation/envoygateway_validate.go new file mode 100644 index 00000000000..1f254696ef2 --- /dev/null +++ b/api/v1alpha1/validation/envoygateway_validate.go @@ -0,0 +1,87 @@ +// 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 validation + +import ( + "errors" + "fmt" + "net/url" + + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" + + "github.com/envoyproxy/gateway/api/v1alpha1" +) + +// Validate validates the provided EnvoyGateway. +func ValidateEnvoyGateway(eg *v1alpha1.EnvoyGateway) error { + switch { + case eg == nil: + return errors.New("envoy gateway config is unspecified") + case eg.Gateway == nil: + return errors.New("gateway is unspecified") + case len(eg.Gateway.ControllerName) == 0: + return errors.New("gateway controllerName is unspecified") + case eg.Provider == nil: + return errors.New("provider is unspecified") + case eg.Provider.Type != v1alpha1.ProviderTypeKubernetes: + return fmt.Errorf("unsupported provider %v", eg.Provider.Type) + case eg.Logging != nil && len(eg.Logging.Level) != 0: + level := eg.Logging.Level + for component, logLevel := range level { + switch component { + case v1alpha1.LogComponentGatewayDefault, + v1alpha1.LogComponentProviderRunner, + v1alpha1.LogComponentGatewayAPIRunner, + v1alpha1.LogComponentXdsTranslatorRunner, + v1alpha1.LogComponentXdsServerRunner, + v1alpha1.LogComponentInfrastructureRunner, + v1alpha1.LogComponentGlobalRateLimitRunner: + switch logLevel { + case v1alpha1.LogLevelDebug, v1alpha1.LogLevelError, v1alpha1.LogLevelWarn, v1alpha1.LogLevelInfo: + default: + return errors.New("envoy gateway logging level invalid. valid options: info/debug/warn/error") + } + default: + return errors.New("envoy gateway logging components invalid. valid options: system/provider/gateway-api/xds-translator/xds-server/infrastructure") + } + } + case eg.RateLimit != nil: + if eg.RateLimit.Backend.Type != v1alpha1.RedisBackendType { + return fmt.Errorf("unsupported ratelimit backend %v", eg.RateLimit.Backend.Type) + } + if eg.RateLimit.Backend.Redis == nil || eg.RateLimit.Backend.Redis.URL == "" { + return fmt.Errorf("empty ratelimit redis settings") + } + if _, err := url.Parse(eg.RateLimit.Backend.Redis.URL); err != nil { + return fmt.Errorf("unknown ratelimit redis url format: %w", err) + } + case eg.ExtensionManager != nil: + if eg.ExtensionManager.Hooks == nil || eg.ExtensionManager.Hooks.XDSTranslator == nil { + return fmt.Errorf("registered extension has no hooks specified") + } + + if len(eg.ExtensionManager.Hooks.XDSTranslator.Pre) == 0 && len(eg.ExtensionManager.Hooks.XDSTranslator.Post) == 0 { + return fmt.Errorf("registered extension has no hooks specified") + } + + if eg.ExtensionManager.Service == nil { + return fmt.Errorf("extension service config is empty") + } + + if eg.ExtensionManager.Service.TLS != nil { + certificateRefKind := eg.ExtensionManager.Service.TLS.CertificateRef.Kind + + if certificateRefKind == nil { + return fmt.Errorf("certificateRef empty in extension service server TLS settings") + } + + if *certificateRefKind != gwapiv1.Kind("Secret") { + return fmt.Errorf("unsupported extension server TLS certificateRef %v", certificateRefKind) + } + } + } + return nil +} diff --git a/api/v1alpha1/validation/envoygateway_validate_test.go b/api/v1alpha1/validation/envoygateway_validate_test.go new file mode 100644 index 00000000000..a88caf5d517 --- /dev/null +++ b/api/v1alpha1/validation/envoygateway_validate_test.go @@ -0,0 +1,430 @@ +// 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 validation + +import ( + "testing" + + "github.com/stretchr/testify/require" + v1 "sigs.k8s.io/gateway-api/apis/v1" + + "github.com/envoyproxy/gateway/api/v1alpha1" +) + +var ( + TLSSecretKind = v1.Kind("Secret") + TLSUnrecognizedKind = v1.Kind("Unrecognized") +) + +func TestValidateEnvoyGateway(t *testing.T) { + eg := v1alpha1.DefaultEnvoyGateway() + + testCases := []struct { + name string + eg *v1alpha1.EnvoyGateway + expect bool + }{ + { + name: "default", + eg: eg, + expect: true, + }, + { + name: "unspecified envoy gateway", + eg: nil, + expect: false, + }, + { + name: "unspecified gateway", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + }, + }, + expect: false, + }, + { + name: "unspecified provider", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + }, + }, + expect: false, + }, + { + name: "empty gateway controllerName", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: &v1alpha1.Gateway{ControllerName: ""}, + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + }, + }, + expect: false, + }, + { + name: "unsupported provider", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: &v1alpha1.EnvoyGatewayProvider{Type: v1alpha1.ProviderTypeFile}, + }, + }, + expect: false, + }, + { + name: "empty ratelimit", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + RateLimit: &v1alpha1.RateLimit{}, + }, + }, + expect: false, + }, + { + name: "empty ratelimit redis setting", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + RateLimit: &v1alpha1.RateLimit{ + Backend: v1alpha1.RateLimitDatabaseBackend{ + Type: v1alpha1.RedisBackendType, + Redis: &v1alpha1.RateLimitRedisSettings{}, + }, + }, + }, + }, + expect: false, + }, + { + name: "unknown ratelimit redis url format", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + RateLimit: &v1alpha1.RateLimit{ + Backend: v1alpha1.RateLimitDatabaseBackend{ + Type: v1alpha1.RedisBackendType, + Redis: &v1alpha1.RateLimitRedisSettings{ + URL: ":foo", + }, + }, + }, + }, + }, + expect: false, + }, + { + name: "happy ratelimit redis settings", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + RateLimit: &v1alpha1.RateLimit{ + Backend: v1alpha1.RateLimitDatabaseBackend{ + Type: v1alpha1.RedisBackendType, + Redis: &v1alpha1.RateLimitRedisSettings{ + URL: "localhost:6376", + }, + }, + }, + }, + }, + expect: true, + }, + { + name: "happy extension settings", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + ExtensionManager: &v1alpha1.ExtensionManager{ + Resources: []v1alpha1.GroupVersionKind{ + { + Group: "foo.example.io", + Version: "v1alpha1", + Kind: "Foo", + }, + }, + Hooks: &v1alpha1.ExtensionHooks{ + XDSTranslator: &v1alpha1.XDSTranslatorHooks{ + Pre: []v1alpha1.XDSTranslatorHook{}, + Post: []v1alpha1.XDSTranslatorHook{ + v1alpha1.XDSHTTPListener, + v1alpha1.XDSTranslation, + v1alpha1.XDSRoute, + v1alpha1.XDSVirtualHost, + }, + }, + }, + Service: &v1alpha1.ExtensionService{ + Host: "foo.extension", + Port: 80, + }, + }, + }, + }, + expect: true, + }, + { + name: "happy extension settings tls", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + ExtensionManager: &v1alpha1.ExtensionManager{ + Resources: []v1alpha1.GroupVersionKind{ + { + Group: "foo.example.io", + Version: "v1alpha1", + Kind: "Foo", + }, + }, + Hooks: &v1alpha1.ExtensionHooks{ + XDSTranslator: &v1alpha1.XDSTranslatorHooks{ + Pre: []v1alpha1.XDSTranslatorHook{}, + Post: []v1alpha1.XDSTranslatorHook{ + v1alpha1.XDSHTTPListener, + v1alpha1.XDSTranslation, + v1alpha1.XDSRoute, + v1alpha1.XDSVirtualHost, + }, + }, + }, + Service: &v1alpha1.ExtensionService{ + Host: "foo.extension", + Port: 443, + TLS: &v1alpha1.ExtensionTLS{ + CertificateRef: v1.SecretObjectReference{ + Kind: &TLSSecretKind, + Name: v1.ObjectName("certificate"), + }, + }, + }, + }, + }, + }, + expect: true, + }, + { + name: "happy extension settings no resources", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + ExtensionManager: &v1alpha1.ExtensionManager{ + Hooks: &v1alpha1.ExtensionHooks{ + XDSTranslator: &v1alpha1.XDSTranslatorHooks{ + Pre: []v1alpha1.XDSTranslatorHook{}, + Post: []v1alpha1.XDSTranslatorHook{ + v1alpha1.XDSHTTPListener, + v1alpha1.XDSTranslation, + v1alpha1.XDSRoute, + v1alpha1.XDSVirtualHost, + }, + }, + }, + Service: &v1alpha1.ExtensionService{ + Host: "foo.extension", + Port: 443, + TLS: &v1alpha1.ExtensionTLS{ + CertificateRef: v1.SecretObjectReference{ + Kind: &TLSSecretKind, + Name: v1.ObjectName("certificate"), + }, + }, + }, + }, + }, + }, + expect: true, + }, + { + name: "unknown TLS certificateRef in extension settings", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + ExtensionManager: &v1alpha1.ExtensionManager{ + Resources: []v1alpha1.GroupVersionKind{ + { + Group: "foo.example.io", + Version: "v1alpha1", + Kind: "Foo", + }, + }, + Hooks: &v1alpha1.ExtensionHooks{ + XDSTranslator: &v1alpha1.XDSTranslatorHooks{ + Pre: []v1alpha1.XDSTranslatorHook{}, + Post: []v1alpha1.XDSTranslatorHook{ + v1alpha1.XDSHTTPListener, + v1alpha1.XDSTranslation, + v1alpha1.XDSRoute, + v1alpha1.XDSVirtualHost, + }, + }, + }, + Service: &v1alpha1.ExtensionService{ + Host: "foo.extension", + Port: 8080, + TLS: &v1alpha1.ExtensionTLS{ + CertificateRef: v1.SecretObjectReference{ + Kind: &TLSUnrecognizedKind, + Name: v1.ObjectName("certificate"), + }, + }, + }, + }, + }, + }, + expect: false, + }, + { + name: "empty service in extension settings", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + ExtensionManager: &v1alpha1.ExtensionManager{ + Resources: []v1alpha1.GroupVersionKind{ + { + Group: "foo.example.io", + Version: "v1alpha1", + Kind: "Foo", + }, + }, + Hooks: &v1alpha1.ExtensionHooks{ + XDSTranslator: &v1alpha1.XDSTranslatorHooks{ + Pre: []v1alpha1.XDSTranslatorHook{}, + Post: []v1alpha1.XDSTranslatorHook{ + v1alpha1.XDSHTTPListener, + v1alpha1.XDSTranslation, + v1alpha1.XDSRoute, + v1alpha1.XDSVirtualHost, + }, + }, + }, + }, + }, + }, + expect: false, + }, + { + name: "empty hooks in extension settings", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + ExtensionManager: &v1alpha1.ExtensionManager{ + Resources: []v1alpha1.GroupVersionKind{ + { + Group: "foo.example.io", + Version: "v1alpha1", + Kind: "Foo", + }, + }, + Service: &v1alpha1.ExtensionService{ + Host: "foo.extension", + Port: 8080, + }, + }, + }, + }, + expect: false, + }, + { + name: "valid gateway logging level info", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + Logging: &v1alpha1.EnvoyGatewayLogging{ + Level: map[v1alpha1.EnvoyGatewayLogComponent]v1alpha1.LogLevel{ + v1alpha1.LogComponentGatewayDefault: v1alpha1.LogLevelInfo, + }, + }, + }, + }, + expect: true, + }, + { + name: "valid gateway logging level warn", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + Logging: &v1alpha1.EnvoyGatewayLogging{ + Level: map[v1alpha1.EnvoyGatewayLogComponent]v1alpha1.LogLevel{ + v1alpha1.LogComponentGatewayDefault: v1alpha1.LogLevelWarn, + }, + }, + }, + }, + expect: true, + }, + { + name: "valid gateway logging level error", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + Logging: &v1alpha1.EnvoyGatewayLogging{ + Level: map[v1alpha1.EnvoyGatewayLogComponent]v1alpha1.LogLevel{ + v1alpha1.LogComponentGatewayDefault: v1alpha1.LogLevelError, + }, + }, + }, + }, + expect: true, + }, + { + name: "valid gateway logging level debug", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + Logging: &v1alpha1.EnvoyGatewayLogging{ + Level: map[v1alpha1.EnvoyGatewayLogComponent]v1alpha1.LogLevel{ + v1alpha1.LogComponentGatewayDefault: v1alpha1.LogLevelDebug, + v1alpha1.LogComponentProviderRunner: v1alpha1.LogLevelDebug, + }, + }, + }, + }, + expect: true, + }, + { + name: "invalid gateway logging level", + eg: &v1alpha1.EnvoyGateway{ + EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ + Gateway: v1alpha1.DefaultGateway(), + Provider: v1alpha1.DefaultEnvoyGatewayProvider(), + Logging: &v1alpha1.EnvoyGatewayLogging{ + Level: map[v1alpha1.EnvoyGatewayLogComponent]v1alpha1.LogLevel{ + v1alpha1.LogComponentGatewayDefault: "inffo", + }, + }, + }, + }, + expect: false, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := ValidateEnvoyGateway(tc.eg) + if !tc.expect { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/api/v1alpha1/validation/validate.go b/api/v1alpha1/validation/envoyproxy_validate.go similarity index 100% rename from api/v1alpha1/validation/validate.go rename to api/v1alpha1/validation/envoyproxy_validate.go diff --git a/api/v1alpha1/validation/validate_test.go b/api/v1alpha1/validation/envoyproxy_validate_test.go similarity index 100% rename from api/v1alpha1/validation/validate_test.go rename to api/v1alpha1/validation/envoyproxy_validate_test.go diff --git a/internal/envoygateway/config/config.go b/internal/envoygateway/config/config.go index 2b7deb2411e..4c9674a88b4 100644 --- a/internal/envoygateway/config/config.go +++ b/internal/envoygateway/config/config.go @@ -7,12 +7,9 @@ package config import ( "errors" - "fmt" - "net/url" - - gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/api/v1alpha1/validation" "github.com/envoyproxy/gateway/internal/logging" "github.com/envoyproxy/gateway/internal/utils/env" ) @@ -57,72 +54,12 @@ func (s *Server) Validate() error { switch { case s == nil: return errors.New("server config is unspecified") - case s.EnvoyGateway == nil: - return errors.New("envoy gateway config is unspecified") - case s.EnvoyGateway.Gateway == nil: - return errors.New("gateway is unspecified") - case len(s.EnvoyGateway.Gateway.ControllerName) == 0: - return errors.New("gateway controllerName is unspecified") - case s.EnvoyGateway.Provider == nil: - return errors.New("provider is unspecified") - case s.EnvoyGateway.Provider.Type != v1alpha1.ProviderTypeKubernetes: - return fmt.Errorf("unsupported provider %v", s.EnvoyGateway.Provider.Type) case len(s.Namespace) == 0: return errors.New("namespace is empty string") - case s.EnvoyGateway.Logging != nil && len(s.EnvoyGateway.Logging.Level) != 0: - level := s.EnvoyGateway.Logging.Level - for component, logLevel := range level { - switch component { - case v1alpha1.LogComponentGatewayDefault, - v1alpha1.LogComponentProviderRunner, - v1alpha1.LogComponentGatewayAPIRunner, - v1alpha1.LogComponentXdsTranslatorRunner, - v1alpha1.LogComponentXdsServerRunner, - v1alpha1.LogComponentInfrastructureRunner, - v1alpha1.LogComponentGlobalRateLimitRunner: - switch logLevel { - case v1alpha1.LogLevelDebug, v1alpha1.LogLevelError, v1alpha1.LogLevelWarn, v1alpha1.LogLevelInfo: - default: - return errors.New("envoy gateway logging level invalid. valid options: info/debug/warn/error") - } - default: - return errors.New("envoy gateway logging components invalid. valid options: system/provider/gateway-api/xds-translator/xds-server/infrastructure") - } - } - case s.EnvoyGateway.RateLimit != nil: - if s.EnvoyGateway.RateLimit.Backend.Type != v1alpha1.RedisBackendType { - return fmt.Errorf("unsupported ratelimit backend %v", s.EnvoyGateway.RateLimit.Backend.Type) - } - if s.EnvoyGateway.RateLimit.Backend.Redis == nil || s.EnvoyGateway.RateLimit.Backend.Redis.URL == "" { - return fmt.Errorf("empty ratelimit redis settings") - } - if _, err := url.Parse(s.EnvoyGateway.RateLimit.Backend.Redis.URL); err != nil { - return fmt.Errorf("unknown ratelimit redis url format: %w", err) - } - case s.EnvoyGateway.ExtensionManager != nil: - if s.EnvoyGateway.ExtensionManager.Hooks == nil || s.EnvoyGateway.ExtensionManager.Hooks.XDSTranslator == nil { - return fmt.Errorf("registered extension has no hooks specified") - } - - if len(s.EnvoyGateway.ExtensionManager.Hooks.XDSTranslator.Pre) == 0 && len(s.EnvoyGateway.ExtensionManager.Hooks.XDSTranslator.Post) == 0 { - return fmt.Errorf("registered extension has no hooks specified") - } - - if s.EnvoyGateway.ExtensionManager.Service == nil { - return fmt.Errorf("extension service config is empty") - } - - if s.EnvoyGateway.ExtensionManager.Service.TLS != nil { - certificateRefKind := s.EnvoyGateway.ExtensionManager.Service.TLS.CertificateRef.Kind - - if certificateRefKind == nil { - return fmt.Errorf("certificateRef empty in extension service server TLS settings") - } - - if *certificateRefKind != gwapiv1.Kind("Secret") { - return fmt.Errorf("unsupported extension server TLS certificateRef %v", certificateRefKind) - } - } } + if err := validation.ValidateEnvoyGateway(s.EnvoyGateway); err != nil { + return err + } + return nil } diff --git a/internal/envoygateway/config/config_test.go b/internal/envoygateway/config/config_test.go index 591d2f2e056..09f3ddfdcb2 100644 --- a/internal/envoygateway/config/config_test.go +++ b/internal/envoygateway/config/config_test.go @@ -29,6 +29,11 @@ func TestValidate(t *testing.T) { cfg *Server expect bool }{ + { + name: "nil cfg", + cfg: nil, + expect: false, + }, { name: "default", cfg: cfg, @@ -55,440 +60,6 @@ func TestValidate(t *testing.T) { }, expect: false, }, - { - name: "unspecified gateway", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - }, - }, - Namespace: "test-ns", - }, - expect: false, - }, - { - name: "unspecified provider", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - }, - }, - Namespace: "test-ns", - }, - expect: false, - }, - { - name: "empty gateway controllerName", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: &v1alpha1.Gateway{ControllerName: ""}, - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - }, - }, - Namespace: "test-ns", - }, - expect: false, - }, - { - name: "unsupported provider", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: &v1alpha1.EnvoyGatewayProvider{Type: v1alpha1.ProviderTypeFile}, - }, - }, - Namespace: "test-ns", - }, - expect: false, - }, - { - name: "empty ratelimit", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - RateLimit: &v1alpha1.RateLimit{}, - }, - }, - Namespace: "test-ns", - }, - expect: false, - }, - { - name: "empty ratelimit redis setting", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - RateLimit: &v1alpha1.RateLimit{ - Backend: v1alpha1.RateLimitDatabaseBackend{ - Type: v1alpha1.RedisBackendType, - Redis: &v1alpha1.RateLimitRedisSettings{}, - }, - }, - }, - }, - Namespace: "test-ns", - }, - expect: false, - }, - { - name: "unknown ratelimit redis url format", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - RateLimit: &v1alpha1.RateLimit{ - Backend: v1alpha1.RateLimitDatabaseBackend{ - Type: v1alpha1.RedisBackendType, - Redis: &v1alpha1.RateLimitRedisSettings{ - URL: ":foo", - }, - }, - }, - }, - }, - Namespace: "test-ns", - }, - expect: false, - }, - { - name: "happy ratelimit redis settings", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - RateLimit: &v1alpha1.RateLimit{ - Backend: v1alpha1.RateLimitDatabaseBackend{ - Type: v1alpha1.RedisBackendType, - Redis: &v1alpha1.RateLimitRedisSettings{ - URL: "localhost:6376", - }, - }, - }, - }, - }, - Namespace: "test-ns", - }, - expect: true, - }, - { - name: "happy extension settings", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - ExtensionManager: &v1alpha1.ExtensionManager{ - Resources: []v1alpha1.GroupVersionKind{ - { - Group: "foo.example.io", - Version: "v1alpha1", - Kind: "Foo", - }, - }, - Hooks: &v1alpha1.ExtensionHooks{ - XDSTranslator: &v1alpha1.XDSTranslatorHooks{ - Pre: []v1alpha1.XDSTranslatorHook{}, - Post: []v1alpha1.XDSTranslatorHook{ - v1alpha1.XDSHTTPListener, - v1alpha1.XDSTranslation, - v1alpha1.XDSRoute, - v1alpha1.XDSVirtualHost, - }, - }, - }, - Service: &v1alpha1.ExtensionService{ - Host: "foo.extension", - Port: 80, - }, - }, - }, - }, - Namespace: "test-ns", - }, - expect: true, - }, - { - name: "happy extension settings tls", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - ExtensionManager: &v1alpha1.ExtensionManager{ - Resources: []v1alpha1.GroupVersionKind{ - { - Group: "foo.example.io", - Version: "v1alpha1", - Kind: "Foo", - }, - }, - Hooks: &v1alpha1.ExtensionHooks{ - XDSTranslator: &v1alpha1.XDSTranslatorHooks{ - Pre: []v1alpha1.XDSTranslatorHook{}, - Post: []v1alpha1.XDSTranslatorHook{ - v1alpha1.XDSHTTPListener, - v1alpha1.XDSTranslation, - v1alpha1.XDSRoute, - v1alpha1.XDSVirtualHost, - }, - }, - }, - Service: &v1alpha1.ExtensionService{ - Host: "foo.extension", - Port: 443, - TLS: &v1alpha1.ExtensionTLS{ - CertificateRef: v1.SecretObjectReference{ - Kind: &TLSSecretKind, - Name: v1.ObjectName("certificate"), - }, - }, - }, - }, - }, - }, - Namespace: "test-ns", - }, - expect: true, - }, - { - name: "happy extension settings no resources", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - ExtensionManager: &v1alpha1.ExtensionManager{ - Hooks: &v1alpha1.ExtensionHooks{ - XDSTranslator: &v1alpha1.XDSTranslatorHooks{ - Pre: []v1alpha1.XDSTranslatorHook{}, - Post: []v1alpha1.XDSTranslatorHook{ - v1alpha1.XDSHTTPListener, - v1alpha1.XDSTranslation, - v1alpha1.XDSRoute, - v1alpha1.XDSVirtualHost, - }, - }, - }, - Service: &v1alpha1.ExtensionService{ - Host: "foo.extension", - Port: 443, - TLS: &v1alpha1.ExtensionTLS{ - CertificateRef: v1.SecretObjectReference{ - Kind: &TLSSecretKind, - Name: v1.ObjectName("certificate"), - }, - }, - }, - }, - }, - }, - Namespace: "test-ns", - }, - expect: true, - }, - { - name: "unknown TLS certificateRef in extension settings", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - ExtensionManager: &v1alpha1.ExtensionManager{ - Resources: []v1alpha1.GroupVersionKind{ - { - Group: "foo.example.io", - Version: "v1alpha1", - Kind: "Foo", - }, - }, - Hooks: &v1alpha1.ExtensionHooks{ - XDSTranslator: &v1alpha1.XDSTranslatorHooks{ - Pre: []v1alpha1.XDSTranslatorHook{}, - Post: []v1alpha1.XDSTranslatorHook{ - v1alpha1.XDSHTTPListener, - v1alpha1.XDSTranslation, - v1alpha1.XDSRoute, - v1alpha1.XDSVirtualHost, - }, - }, - }, - Service: &v1alpha1.ExtensionService{ - Host: "foo.extension", - Port: 8080, - TLS: &v1alpha1.ExtensionTLS{ - CertificateRef: v1.SecretObjectReference{ - Kind: &TLSUnrecognizedKind, - Name: v1.ObjectName("certificate"), - }, - }, - }, - }, - }, - }, - Namespace: "test-ns", - }, - expect: false, - }, - { - name: "empty service in extension settings", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - ExtensionManager: &v1alpha1.ExtensionManager{ - Resources: []v1alpha1.GroupVersionKind{ - { - Group: "foo.example.io", - Version: "v1alpha1", - Kind: "Foo", - }, - }, - Hooks: &v1alpha1.ExtensionHooks{ - XDSTranslator: &v1alpha1.XDSTranslatorHooks{ - Pre: []v1alpha1.XDSTranslatorHook{}, - Post: []v1alpha1.XDSTranslatorHook{ - v1alpha1.XDSHTTPListener, - v1alpha1.XDSTranslation, - v1alpha1.XDSRoute, - v1alpha1.XDSVirtualHost, - }, - }, - }, - }, - }, - }, - Namespace: "test-ns", - }, - expect: false, - }, - { - name: "empty hooks in extension settings", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - ExtensionManager: &v1alpha1.ExtensionManager{ - Resources: []v1alpha1.GroupVersionKind{ - { - Group: "foo.example.io", - Version: "v1alpha1", - Kind: "Foo", - }, - }, - Service: &v1alpha1.ExtensionService{ - Host: "foo.extension", - Port: 8080, - }, - }, - }, - }, - Namespace: "test-ns", - }, - expect: false, - }, - { - name: "valid gateway logging level info", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - Logging: &v1alpha1.EnvoyGatewayLogging{ - Level: map[v1alpha1.EnvoyGatewayLogComponent]v1alpha1.LogLevel{ - v1alpha1.LogComponentGatewayDefault: v1alpha1.LogLevelInfo, - }, - }, - }, - }, - Namespace: "test-ns", - }, - expect: true, - }, - { - name: "valid gateway logging level warn", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - Logging: &v1alpha1.EnvoyGatewayLogging{ - Level: map[v1alpha1.EnvoyGatewayLogComponent]v1alpha1.LogLevel{ - v1alpha1.LogComponentGatewayDefault: v1alpha1.LogLevelWarn, - }, - }, - }, - }, - Namespace: "test-ns", - }, - expect: true, - }, - { - name: "valid gateway logging level error", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - Logging: &v1alpha1.EnvoyGatewayLogging{ - Level: map[v1alpha1.EnvoyGatewayLogComponent]v1alpha1.LogLevel{ - v1alpha1.LogComponentGatewayDefault: v1alpha1.LogLevelError, - }, - }, - }, - }, - Namespace: "test-ns", - }, - expect: true, - }, - { - name: "valid gateway logging level debug", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - Logging: &v1alpha1.EnvoyGatewayLogging{ - Level: map[v1alpha1.EnvoyGatewayLogComponent]v1alpha1.LogLevel{ - v1alpha1.LogComponentGatewayDefault: v1alpha1.LogLevelDebug, - v1alpha1.LogComponentProviderRunner: v1alpha1.LogLevelDebug, - }, - }, - }, - }, - Namespace: "test-ns", - }, - expect: true, - }, - { - name: "invalid gateway logging level", - cfg: &Server{ - EnvoyGateway: &v1alpha1.EnvoyGateway{ - EnvoyGatewaySpec: v1alpha1.EnvoyGatewaySpec{ - Gateway: v1alpha1.DefaultGateway(), - Provider: v1alpha1.DefaultEnvoyGatewayProvider(), - Logging: &v1alpha1.EnvoyGatewayLogging{ - Level: map[v1alpha1.EnvoyGatewayLogComponent]v1alpha1.LogLevel{ - v1alpha1.LogComponentGatewayDefault: "inffo", - }, - }, - }, - }, - Namespace: "test-ns", - }, - expect: false, - }, } for _, tc := range testCases { diff --git a/test/conformance/conformance_test.go b/test/conformance/conformance_test.go index 731b4a4d1a5..6bfa06fe39b 100644 --- a/test/conformance/conformance_test.go +++ b/test/conformance/conformance_test.go @@ -16,7 +16,7 @@ import ( "k8s.io/client-go/kubernetes" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/config" - "sigs.k8s.io/gateway-api/apis/v1" + v1 "sigs.k8s.io/gateway-api/apis/v1" "sigs.k8s.io/gateway-api/apis/v1alpha2" "sigs.k8s.io/gateway-api/apis/v1beta1" "sigs.k8s.io/gateway-api/conformance/tests" diff --git a/test/conformance/experimental_conformance_test.go b/test/conformance/experimental_conformance_test.go index 7a59247ab31..9276d290ebe 100644 --- a/test/conformance/experimental_conformance_test.go +++ b/test/conformance/experimental_conformance_test.go @@ -20,7 +20,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/config" "sigs.k8s.io/yaml" - "sigs.k8s.io/gateway-api/apis/v1" + v1 "sigs.k8s.io/gateway-api/apis/v1" "sigs.k8s.io/gateway-api/apis/v1alpha2" "sigs.k8s.io/gateway-api/apis/v1beta1" confv1a1 "sigs.k8s.io/gateway-api/conformance/apis/v1alpha1"