From a24263c4983bbffd8acdf913ffc97a2a7ba114a6 Mon Sep 17 00:00:00 2001 From: Huabing Zhao Date: Thu, 11 Apr 2024 08:23:36 +0800 Subject: [PATCH 01/10] Refactor and fix early return: HTTP Listener XDS translator (#2981) * refactor Signed-off-by: huabing zhao * minor change Signed-off-by: huabing zhao --------- Signed-off-by: huabing zhao --- internal/xds/translator/listener.go | 12 +- internal/xds/translator/translator.go | 335 +++++++++++++++----------- 2 files changed, 211 insertions(+), 136 deletions(-) diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go index 9d470edbe35..821d713f613 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -194,7 +194,17 @@ func buildXdsQuicListener(name, address string, port uint32, accesslog *ir.Acces return xdsListener } -func (t *Translator) addXdsHTTPFilterChain(xdsListener *listenerv3.Listener, irListener *ir.HTTPListener, +// addHCMToXDSListener adds a HCM filter to the listener's filter chain, and adds +// all the necessary HTTP filters to that HCM. +// +// - If tls is not enabled, a HCM filter is added to the Listener's default TCP filter chain. +// All the ir HTTP Listeners on the same address + port combination share the +// same HCM + HTTP filters. +// - If tls is enabled, a new TCP filter chain is created and added to the listener. +// A HCM filter is added to the new TCP filter chain. +// The newly created TCP filter chain is configured with a filter chain match to +// match the server names(SNI) based on the listener's hostnames. +func (t *Translator) addHCMToXDSListener(xdsListener *listenerv3.Listener, irListener *ir.HTTPListener, accesslog *ir.AccessLog, tracing *ir.Tracing, http3Listener bool, connection *ir.Connection) error { al := buildXdsAccessLog(accesslog, false) diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index adc74d53fd6..d0b6289b472 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -126,36 +126,67 @@ func (t *Translator) processHTTPListenerXdsTranslation( // errors and return them at the end. var errs error for _, httpListener := range httpListeners { - addFilterChain := true - var xdsRouteCfg *routev3.RouteConfiguration - - // Search for an existing listener, if it does not exist, create one. - xdsListener := findXdsListenerByHostPort(tCtx, httpListener.Address, httpListener.Port, corev3.SocketAddress_TCP) - var quicXDSListener *listenerv3.Listener - enabledHTTP3 := httpListener.HTTP3 != nil - if xdsListener == nil { - xdsListener = buildXdsTCPListener(httpListener.Name, httpListener.Address, httpListener.Port, httpListener.TCPKeepalive, httpListener.Connection, accessLog) - if enabledHTTP3 { + var ( + http3Enabled = httpListener.HTTP3 != nil // Whether HTTP3 is enabled + tcpXDSListener *listenerv3.Listener // TCP Listener for HTTP1/HTTP2 traffic + quicXDSListener *listenerv3.Listener // UDP(QUIC) Listener for HTTP3 traffic + xdsListenerOnSameAddressPortExists bool // Whether a listener already exists on the same address + port combination + tlsEnabled bool // Whether TLS is enabled for the listener + xdsRouteCfg *routev3.RouteConfiguration // The route config is used by both the TCP and QUIC listeners + addHCM bool // Whether to add an HCM(HTTP Connection Manager filter) to the listener's TCP filter chain + err error + ) + + // Search for an existing TCP listener on the same address + port combination. + tcpXDSListener = findXdsListenerByHostPort(tCtx, httpListener.Address, httpListener.Port, corev3.SocketAddress_TCP) + xdsListenerOnSameAddressPortExists = tcpXDSListener != nil + tlsEnabled = httpListener.TLS != nil + + switch { + // If no existing listener exists, create a new one. + case !xdsListenerOnSameAddressPortExists: + // Create a new UDP(QUIC) listener for HTTP3 traffic if HTTP3 is enabled + if http3Enabled { quicXDSListener = buildXdsQuicListener(httpListener.Name, httpListener.Address, httpListener.Port, accessLog) - if err := tCtx.AddXdsResource(resourcev3.ListenerType, quicXDSListener); err != nil { - return err + if err = tCtx.AddXdsResource(resourcev3.ListenerType, quicXDSListener); err != nil { + errs = errors.Join(errs, err) + continue } } - if err := tCtx.AddXdsResource(resourcev3.ListenerType, xdsListener); err != nil { - // skip this listener if failed to add xds listener to the - // resource version table. Normally, this should not happen. + + // Create a new TCP listener for HTTP1/HTTP2 traffic. + tcpXDSListener = buildXdsTCPListener(httpListener.Name, httpListener.Address, httpListener.Port, httpListener.TCPKeepalive, httpListener.Connection, accessLog) + if err = tCtx.AddXdsResource(resourcev3.ListenerType, tcpXDSListener); err != nil { errs = errors.Join(errs, err) continue } - } else if httpListener.TLS == nil { + + // We need to add an HCM to the newly created listener. + addHCM = true + case xdsListenerOnSameAddressPortExists && !tlsEnabled: + // If a xds listener exists, and Gateway HTTP Listener does not enable TLS, + // we use the listener's default TCP filter chain because we can not + // differentiate the HTTP traffic at the TCP filter chain level using SNI. + // + // A HCM(HTTP Connection Manager filter) is added to the listener's + // default filter chain if it has not yet been added. + // + // The HCM is configured with a RouteConfiguration, which is used to + // route HTTP traffic to the correct virtual host for all the domains + // specified in the Gateway HTTP Listener's routes. + var ( + routeName string + hasHCMInDefaultFilterChain bool + ) + // Find the route config associated with this listener that // maps to the default filter chain for http traffic - routeName := findXdsHTTPRouteConfigName(xdsListener) + // Routes for this listener will be added to this route config + routeName = findXdsHTTPRouteConfigName(tcpXDSListener) + hasHCMInDefaultFilterChain = routeName != "" + addHCM = !hasHCMInDefaultFilterChain + if routeName != "" { - // If an existing listener exists, dont create a new filter chain - // for HTTP traffic, match on the Domains field within VirtualHosts - // within the same RouteConfiguration instead - addFilterChain = false xdsRouteCfg = findXdsRouteConfig(tCtx, routeName) if xdsRouteCfg == nil { // skip this listener if failed to find xds route config @@ -163,174 +194,208 @@ func (t *Translator) processHTTPListenerXdsTranslation( continue } } + case xdsListenerOnSameAddressPortExists && tlsEnabled: + // If an existing xds listener exists, and Gateway HTTP Listener enables + // TLS, we need to create an HCM. + // + // In this case, a new filter chain is created and added to the listener, + // and the HCM is added to the new filter chain. + // The newly created filter chain is configured with a filter chain + // match to match the server names(SNI) based on the listener's hostnames. + addHCM = true } - if addFilterChain { - if err := t.addXdsHTTPFilterChain(xdsListener, httpListener, accessLog, tracing, false, httpListener.Connection); err != nil { - return err + if addHCM { + if err = t.addHCMToXDSListener(tcpXDSListener, httpListener, accessLog, tracing, false, httpListener.Connection); err != nil { + errs = errors.Join(errs, err) + continue } - if enabledHTTP3 { - if err := t.addXdsHTTPFilterChain(quicXDSListener, httpListener, accessLog, tracing, true, httpListener.Connection); err != nil { - return err + if http3Enabled { + if err = t.addHCMToXDSListener(quicXDSListener, httpListener, accessLog, tracing, true, httpListener.Connection); err != nil { + errs = errors.Join(errs, err) + continue } } } else { // When the DefaultFilterChain is shared by multiple Gateway HTTP // Listeners, we need to add the HTTP filters associated with the // HTTPListener to the HCM if they have not yet been added. - if err := t.addHTTPFiltersToHCM(xdsListener.DefaultFilterChain, httpListener); err != nil { + if err = t.addHTTPFiltersToHCM(tcpXDSListener.DefaultFilterChain, httpListener); err != nil { errs = errors.Join(errs, err) continue } - if enabledHTTP3 { - if err := t.addHTTPFiltersToHCM(quicXDSListener.DefaultFilterChain, httpListener); err != nil { + if http3Enabled { + if err = t.addHTTPFiltersToHCM(quicXDSListener.DefaultFilterChain, httpListener); err != nil { errs = errors.Join(errs, err) continue } } } - // Create a route config if we have not found one yet - if xdsRouteCfg == nil { - xdsRouteCfg = &routev3.RouteConfiguration{ - IgnorePortInHostMatching: true, - Name: httpListener.Name, - } - - if err := tCtx.AddXdsResource(resourcev3.RouteType, xdsRouteCfg); err != nil { - errs = errors.Join(errs, err) - } - } - + // Add the secrets referenced by the listener's TLS configuration to the + // resource version table. // 1:1 between IR TLSListenerConfig and xDS Secret if httpListener.TLS != nil { - for t := range httpListener.TLS.Certificates { - secret := buildXdsTLSCertSecret(httpListener.TLS.Certificates[t]) - if err := tCtx.AddXdsResource(resourcev3.SecretType, secret); err != nil { + for c := range httpListener.TLS.Certificates { + secret := buildXdsTLSCertSecret(httpListener.TLS.Certificates[c]) + if err = tCtx.AddXdsResource(resourcev3.SecretType, secret); err != nil { errs = errors.Join(errs, err) } } if httpListener.TLS.CACertificate != nil { caSecret := buildXdsTLSCaCertSecret(httpListener.TLS.CACertificate) - if err := tCtx.AddXdsResource(resourcev3.SecretType, caSecret); err != nil { + if err = tCtx.AddXdsResource(resourcev3.SecretType, caSecret); err != nil { errs = errors.Join(errs, err) } } } - // store virtual hosts by domain - vHosts := map[string]*routev3.VirtualHost{} - // keep track of order by using a list as well as the map - var vHostsList []*routev3.VirtualHost - - // Check if an extension is loaded that wants to modify xDS Routes after they have been generated - for _, httpRoute := range httpListener.Routes { - // 1:1 between IR HTTPRoute Hostname and xDS VirtualHost. - vHost := vHosts[httpRoute.Hostname] - if vHost == nil { - // Remove dots from the hostname before appending it to the virtualHost name - // since dots are special chars used in stats tag extraction in Envoy - underscoredHostname := strings.ReplaceAll(httpRoute.Hostname, ".", "_") - // Allocate virtual host for this httpRoute. - vHost = &routev3.VirtualHost{ - Name: fmt.Sprintf("%s/%s", httpListener.Name, underscoredHostname), - Domains: []string{httpRoute.Hostname}, - } - if metrics != nil && metrics.EnableVirtualHostStats { - vHost.VirtualClusters = []*routev3.VirtualCluster{ - { - Name: underscoredHostname, - Headers: []*routev3.HeaderMatcher{ - { - Name: AuthorityHeaderKey, - HeaderMatchSpecifier: &routev3.HeaderMatcher_StringMatch{ - StringMatch: &matcherv3.StringMatcher{ - MatchPattern: &matcherv3.StringMatcher_Prefix{ - Prefix: httpRoute.Hostname, - }, - }, - }, - }, - }, - }, - } - } - vHosts[httpRoute.Hostname] = vHost - vHostsList = append(vHostsList, vHost) - } - - // 1:1 between IR HTTPRoute and xDS config.route.v3.Route - xdsRoute, err := buildXdsRoute(httpRoute) - if err != nil { - // skip this route if failed to build xds route - errs = errors.Join(errs, err) - continue + // Create a route config if we have not found one yet + if xdsRouteCfg == nil { + xdsRouteCfg = &routev3.RouteConfiguration{ + IgnorePortInHostMatching: true, + Name: httpListener.Name, } - // Check if an extension want to modify the route we just generated - // If no extension exists (or it doesn't subscribe to this hook) then this is a quick no-op. - if err = processExtensionPostRouteHook(xdsRoute, vHost, httpRoute, t.ExtensionManager); err != nil { + if err = tCtx.AddXdsResource(resourcev3.RouteType, xdsRouteCfg); err != nil { errs = errors.Join(errs, err) } - - if enabledHTTP3 { - http3AltSvcHeader := buildHTTP3AltSvcHeader(int(httpListener.HTTP3.QUICPort)) - if xdsRoute.ResponseHeadersToAdd == nil { - xdsRoute.ResponseHeadersToAdd = make([]*corev3.HeaderValueOption, 0) - } - xdsRoute.ResponseHeadersToAdd = append(xdsRoute.ResponseHeadersToAdd, http3AltSvcHeader) - } - vHost.Routes = append(vHost.Routes, xdsRoute) - - if httpRoute.Destination != nil { - if err = processXdsCluster(tCtx, httpRoute, httpListener.HTTP1); err != nil { - errs = errors.Join(errs, err) - } - } - - if httpRoute.Mirrors != nil { - for _, mirrorDest := range httpRoute.Mirrors { - if err := addXdsCluster(tCtx, &xdsClusterArgs{ - name: mirrorDest.Name, - settings: mirrorDest.Settings, - tSocket: nil, - endpointType: EndpointTypeStatic, - }); err != nil && !errors.Is(err, ErrXdsClusterExists) { - errs = errors.Join(errs, err) - } - } - } } - for _, vHost := range vHostsList { - // Check if an extension want to modify the Virtual Host we just generated - // If no extension exists (or it doesn't subscribe to this hook) then this is a quick no-op. - if err := processExtensionPostVHostHook(vHost, t.ExtensionManager); err != nil { - errs = errors.Join(errs, err) - } + // Generate xDS virtual hosts and routes for the given HTTPListener, + // and add them to the xDS route config. + if err = t.addRouteToRouteConfig(tCtx, xdsRouteCfg, httpListener, metrics, http3Enabled); err != nil { + errs = errors.Join(errs, err) } - xdsRouteCfg.VirtualHosts = append(xdsRouteCfg.VirtualHosts, vHostsList...) // Add all the other needed resources referenced by this filter to the // resource version table. - if err := patchResources(tCtx, httpListener.Routes); err != nil { - return err + if err = patchResources(tCtx, httpListener.Routes); err != nil { + errs = errors.Join(errs, err) } // RateLimit filter is handled separately because it relies on the global // rate limit server configuration. // Check if a ratelimit cluster exists, if not, add it, if it's needed. - if err := t.createRateLimitServiceCluster(tCtx, httpListener); err != nil { + if err = t.createRateLimitServiceCluster(tCtx, httpListener); err != nil { errs = errors.Join(errs, err) } // Check if an extension want to modify the listener that was just configured/created // If no extension exists (or it doesn't subscribe to this hook) then this is a quick no-op - if err := processExtensionPostListenerHook(tCtx, xdsListener, t.ExtensionManager); err != nil { + // TODO zhaohuabing should we also process the quicXDSListener? + if err = processExtensionPostListenerHook(tCtx, tcpXDSListener, t.ExtensionManager); err != nil { + errs = errors.Join(errs, err) + } + } + + return errs +} + +// addRouteToRouteConfig generates xDS virtual hosts and routes for the given HTTPListener, +// and adds them to the provided xDS route config. +func (t *Translator) addRouteToRouteConfig( + tCtx *types.ResourceVersionTable, + xdsRouteCfg *routev3.RouteConfiguration, + httpListener *ir.HTTPListener, + metrics *ir.Metrics, + http3Enabled bool) error { + var ( + vHosts = map[string]*routev3.VirtualHost{} // store virtual hosts by domain + vHostList []*routev3.VirtualHost // keep track of order by using a list as well as the map + errs error // the accumulated errors + err error + ) + + // Check if an extension is loaded that wants to modify xDS Routes after they have been generated + for _, httpRoute := range httpListener.Routes { + // 1:1 between IR HTTPRoute Hostname and xDS VirtualHost. + vHost := vHosts[httpRoute.Hostname] + if vHost == nil { + // Remove dots from the hostname before appending it to the virtualHost name + // since dots are special chars used in stats tag extraction in Envoy + underscoredHostname := strings.ReplaceAll(httpRoute.Hostname, ".", "_") + // Allocate virtual host for this httpRoute. + vHost = &routev3.VirtualHost{ + Name: fmt.Sprintf("%s/%s", httpListener.Name, underscoredHostname), + Domains: []string{httpRoute.Hostname}, + } + if metrics != nil && metrics.EnableVirtualHostStats { + vHost.VirtualClusters = []*routev3.VirtualCluster{ + { + Name: underscoredHostname, + Headers: []*routev3.HeaderMatcher{ + { + Name: AuthorityHeaderKey, + HeaderMatchSpecifier: &routev3.HeaderMatcher_StringMatch{ + StringMatch: &matcherv3.StringMatcher{ + MatchPattern: &matcherv3.StringMatcher_Prefix{ + Prefix: httpRoute.Hostname, + }, + }, + }, + }, + }, + }, + } + } + vHosts[httpRoute.Hostname] = vHost + vHostList = append(vHostList, vHost) + } + + var xdsRoute *routev3.Route + // 1:1 between IR HTTPRoute and xDS config.route.v3.Route + xdsRoute, err = buildXdsRoute(httpRoute) + if err != nil { + // skip this route if failed to build xds route + errs = errors.Join(errs, err) + continue + } + + // Check if an extension want to modify the route we just generated + // If no extension exists (or it doesn't subscribe to this hook) then this is a quick no-op. + if err = processExtensionPostRouteHook(xdsRoute, vHost, httpRoute, t.ExtensionManager); err != nil { + errs = errors.Join(errs, err) + } + + if http3Enabled { + http3AltSvcHeader := buildHTTP3AltSvcHeader(int(httpListener.HTTP3.QUICPort)) + if xdsRoute.ResponseHeadersToAdd == nil { + xdsRoute.ResponseHeadersToAdd = make([]*corev3.HeaderValueOption, 0) + } + xdsRoute.ResponseHeadersToAdd = append(xdsRoute.ResponseHeadersToAdd, http3AltSvcHeader) + } + vHost.Routes = append(vHost.Routes, xdsRoute) + + if httpRoute.Destination != nil { + if err = processXdsCluster(tCtx, httpRoute, httpListener.HTTP1); err != nil { + errs = errors.Join(errs, err) + } + } + + if httpRoute.Mirrors != nil { + for _, mirrorDest := range httpRoute.Mirrors { + if err = addXdsCluster(tCtx, &xdsClusterArgs{ + name: mirrorDest.Name, + settings: mirrorDest.Settings, + tSocket: nil, + endpointType: EndpointTypeStatic, + }); err != nil && !errors.Is(err, ErrXdsClusterExists) { + errs = errors.Join(errs, err) + } + } + } + } + + for _, vHost := range vHostList { + // Check if an extension want to modify the Virtual Host we just generated + // If no extension exists (or it doesn't subscribe to this hook) then this is a quick no-op. + if err = processExtensionPostVHostHook(vHost, t.ExtensionManager); err != nil { errs = errors.Join(errs, err) } } + xdsRouteCfg.VirtualHosts = append(xdsRouteCfg.VirtualHosts, vHostList...) return errs } From b608831849859eb054ecb74a0347289ac92e5a63 Mon Sep 17 00:00:00 2001 From: Xunzhuo Date: Thu, 11 Apr 2024 10:52:18 +0800 Subject: [PATCH 02/10] fix: remove no needed new pointer creation (#2739) fix: remove no needed new pointer Signed-off-by: bitliu --- internal/gatewayapi/runner/runner.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/internal/gatewayapi/runner/runner.go b/internal/gatewayapi/runner/runner.go index 4ef2d3d2702..12ebe509a8b 100644 --- a/internal/gatewayapi/runner/runner.go +++ b/internal/gatewayapi/runner/runner.go @@ -123,37 +123,31 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) { // Update Status for _, gateway := range result.Gateways { - gateway := gateway key := utils.NamespacedName(gateway) r.ProviderResources.GatewayStatuses.Store(key, &gateway.Status) delete(statusesToDelete.GatewayStatusKeys, key) } for _, httpRoute := range result.HTTPRoutes { - httpRoute := httpRoute key := utils.NamespacedName(httpRoute) r.ProviderResources.HTTPRouteStatuses.Store(key, &httpRoute.Status) delete(statusesToDelete.HTTPRouteStatusKeys, key) } for _, grpcRoute := range result.GRPCRoutes { - grpcRoute := grpcRoute key := utils.NamespacedName(grpcRoute) r.ProviderResources.GRPCRouteStatuses.Store(key, &grpcRoute.Status) delete(statusesToDelete.GRPCRouteStatusKeys, key) } for _, tlsRoute := range result.TLSRoutes { - tlsRoute := tlsRoute key := utils.NamespacedName(tlsRoute) r.ProviderResources.TLSRouteStatuses.Store(key, &tlsRoute.Status) delete(statusesToDelete.TLSRouteStatusKeys, key) } for _, tcpRoute := range result.TCPRoutes { - tcpRoute := tcpRoute key := utils.NamespacedName(tcpRoute) r.ProviderResources.TCPRouteStatuses.Store(key, &tcpRoute.Status) delete(statusesToDelete.TCPRouteStatusKeys, key) } for _, udpRoute := range result.UDPRoutes { - udpRoute := udpRoute key := utils.NamespacedName(udpRoute) r.ProviderResources.UDPRouteStatuses.Store(key, &udpRoute.Status) delete(statusesToDelete.UDPRouteStatusKeys, key) @@ -173,7 +167,6 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) { } for _, clientTrafficPolicy := range result.ClientTrafficPolicies { - clientTrafficPolicy := clientTrafficPolicy key := utils.NamespacedName(clientTrafficPolicy) if !(reflect.ValueOf(clientTrafficPolicy.Status).IsZero()) { r.ProviderResources.ClientTrafficPolicyStatuses.Store(key, &clientTrafficPolicy.Status) @@ -181,7 +174,6 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) { delete(statusesToDelete.ClientTrafficPolicyStatusKeys, key) } for _, backendTrafficPolicy := range result.BackendTrafficPolicies { - backendTrafficPolicy := backendTrafficPolicy key := utils.NamespacedName(backendTrafficPolicy) if !(reflect.ValueOf(backendTrafficPolicy.Status).IsZero()) { r.ProviderResources.BackendTrafficPolicyStatuses.Store(key, &backendTrafficPolicy.Status) @@ -189,7 +181,6 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) { delete(statusesToDelete.BackendTrafficPolicyStatusKeys, key) } for _, securityPolicy := range result.SecurityPolicies { - securityPolicy := securityPolicy key := utils.NamespacedName(securityPolicy) if !(reflect.ValueOf(securityPolicy.Status).IsZero()) { r.ProviderResources.SecurityPolicyStatuses.Store(key, &securityPolicy.Status) From aa4e3a0f5add9d6ccdd4b8973cc3da085f84ffff Mon Sep 17 00:00:00 2001 From: Shyunn Date: Thu, 11 Apr 2024 11:18:33 +0800 Subject: [PATCH 03/10] feat: add trace for rate-limit (#2974) * feat: support trace of ratelimit Signed-off-by: ShyunnY <1147212064@qq.com> * fix: add json tag Signed-off-by: ShyunnY <1147212064@qq.com> * fix: use OTEL_EXPORTER_OTLP_ENDPOINT env Signed-off-by: ShyunnY <1147212064@qq.com> * fix Signed-off-by: ShyunnY <1147212064@qq.com> * docs: update docs Signed-off-by: yuluo-yx --------- Signed-off-by: ShyunnY <1147212064@qq.com> Signed-off-by: yuluo-yx Co-authored-by: yuluo-yx Co-authored-by: zirain --- api/v1alpha1/envoygateway_types.go | 31 ++++ api/v1alpha1/zz_generated.deepcopy.go | 50 ++++++ .../kubernetes/ratelimit/resource.go | 96 ++++++++++- .../kubernetes/ratelimit/resource_provider.go | 3 +- .../ratelimit/resource_provider_test.go | 40 +++++ .../kubernetes/ratelimit/resource_test.go | 40 +++++ .../deployments/enable-tracing-custom.yaml | 160 ++++++++++++++++++ .../testdata/deployments/enable-tracing.yaml | 160 ++++++++++++++++++ site/content/en/latest/api/extension_types.md | 33 ++++ .../observability/rate-limit-observability.md | 70 ++++++++ 10 files changed, 679 insertions(+), 4 deletions(-) create mode 100644 internal/infrastructure/kubernetes/ratelimit/resource_test.go create mode 100644 internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml create mode 100644 internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml create mode 100644 site/content/en/latest/tasks/observability/rate-limit-observability.md diff --git a/api/v1alpha1/envoygateway_types.go b/api/v1alpha1/envoygateway_types.go index 47b9861e170..ade9e056b1e 100644 --- a/api/v1alpha1/envoygateway_types.go +++ b/api/v1alpha1/envoygateway_types.go @@ -354,6 +354,9 @@ type RateLimit struct { type RateLimitTelemetry struct { // Metrics defines metrics configuration for RateLimit. Metrics *RateLimitMetrics `json:"metrics,omitempty"` + + // Tracing defines traces configuration for RateLimit. + Tracing *RateLimitTracing `json:"tracing,omitempty"` } type RateLimitMetrics struct { @@ -366,6 +369,34 @@ type RateLimitMetricsPrometheusProvider struct { Disable bool `json:"disable,omitempty"` } +type RateLimitTracing struct { + // SamplingRate controls the rate at which traffic will be + // selected for tracing if no prior sampling decision has been made. + // Defaults to 100, valid values [0-100]. 100 indicates 100% sampling. + // +optional + SamplingRate *uint32 `json:"samplingRate,omitempty"` + + // Provider defines the rateLimit tracing provider. + // Only OpenTelemetry is supported currently. + Provider *RateLimitTracingProvider `json:"provider,omitempty"` +} + +type RateLimitTracingProviderType string + +const ( + RateLimitTracingProviderTypeOpenTelemetry TracingProviderType = "OpenTelemetry" +) + +// RateLimitTracingProvider defines the tracing provider configuration of RateLimit +type RateLimitTracingProvider struct { + // Type defines the tracing provider type. + // Since to RateLimit Exporter currently using OpenTelemetry, only OpenTelemetry is supported + Type *RateLimitTracingProviderType `json:"type,omitempty"` + + // URL is the endpoint of the trace collector that supports the OTLP protocol + URL string `json:"url"` +} + // RateLimitDatabaseBackend defines the configuration associated with // the database backend used by the rate limit service. // +union diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index e82cda7787f..b1e849077bd 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -3298,6 +3298,11 @@ func (in *RateLimitTelemetry) DeepCopyInto(out *RateLimitTelemetry) { *out = new(RateLimitMetrics) (*in).DeepCopyInto(*out) } + if in.Tracing != nil { + in, out := &in.Tracing, &out.Tracing + *out = new(RateLimitTracing) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitTelemetry. @@ -3310,6 +3315,51 @@ func (in *RateLimitTelemetry) DeepCopy() *RateLimitTelemetry { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RateLimitTracing) DeepCopyInto(out *RateLimitTracing) { + *out = *in + if in.SamplingRate != nil { + in, out := &in.SamplingRate, &out.SamplingRate + *out = new(uint32) + **out = **in + } + if in.Provider != nil { + in, out := &in.Provider, &out.Provider + *out = new(RateLimitTracingProvider) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitTracing. +func (in *RateLimitTracing) DeepCopy() *RateLimitTracing { + if in == nil { + return nil + } + out := new(RateLimitTracing) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RateLimitTracingProvider) DeepCopyInto(out *RateLimitTracingProvider) { + *out = *in + if in.Type != nil { + in, out := &in.Type, &out.Type + *out = new(RateLimitTracingProviderType) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitTracingProvider. +func (in *RateLimitTracingProvider) DeepCopy() *RateLimitTracingProvider { + if in == nil { + return nil + } + out := new(RateLimitTracingProvider) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RateLimitValue) DeepCopyInto(out *RateLimitValue) { *out = *in diff --git a/internal/infrastructure/kubernetes/ratelimit/resource.go b/internal/infrastructure/kubernetes/ratelimit/resource.go index 32dfba94c1b..7e7a9d3722d 100644 --- a/internal/infrastructure/kubernetes/ratelimit/resource.go +++ b/internal/infrastructure/kubernetes/ratelimit/resource.go @@ -79,6 +79,18 @@ const ( ConfigGrpcXdsServerURLEnvVar = "CONFIG_GRPC_XDS_SERVER_URL" // ConfigGrpcXdsNodeIDEnvVar is the id of ratelimit node. ConfigGrpcXdsNodeIDEnvVar = "CONFIG_GRPC_XDS_NODE_ID" + // TracingEnabledVar is enabled the tracing feature + TracingEnabledVar = "TRACING_ENABLED" + // TracingServiceNameVar is service name appears in tracing span + TracingServiceNameVar = "TRACING_SERVICE_NAME" + // TracingServiceNamespaceVar is service namespace appears in tracing span + TracingServiceNamespaceVar = "TRACING_SERVICE_NAMESPACE" + // TracingServiceInstanceIDVar is service instance id appears in tracing span + TracingServiceInstanceIDVar = "TRACING_SERVICE_INSTANCE_ID" + // TracingSamplingRateVar is trace sampling rate + TracingSamplingRateVar = "TRACING_SAMPLING_RATE" + // OTELExporterOTLPTraceEndpointVar is target url to which the trace exporter is going to send + OTELExporterOTLPTraceEndpointVar = "OTEL_EXPORTER_OTLP_ENDPOINT" // InfraName is the name for rate-limit resources. InfraName = "envoy-ratelimit" @@ -125,7 +137,8 @@ func rateLimitLabels() map[string]string { } // expectedRateLimitContainers returns expected rateLimit containers. -func expectedRateLimitContainers(rateLimit *egv1a1.RateLimit, rateLimitDeployment *egv1a1.KubernetesDeploymentSpec) []corev1.Container { +func expectedRateLimitContainers(rateLimit *egv1a1.RateLimit, rateLimitDeployment *egv1a1.KubernetesDeploymentSpec, + namespace string) []corev1.Container { ports := []corev1.ContainerPort{ { Name: "grpc", @@ -142,7 +155,7 @@ func expectedRateLimitContainers(rateLimit *egv1a1.RateLimit, rateLimitDeploymen Command: []string{ "/bin/ratelimit", }, - Env: expectedRateLimitContainerEnv(rateLimit, rateLimitDeployment), + Env: expectedRateLimitContainerEnv(rateLimit, rateLimitDeployment, namespace), Ports: ports, Resources: *rateLimitDeployment.Container.Resources, SecurityContext: rateLimitDeployment.Container.SecurityContext, @@ -275,7 +288,8 @@ func expectedDeploymentVolumes(rateLimit *egv1a1.RateLimit, rateLimitDeployment } // expectedRateLimitContainerEnv returns expected rateLimit container envs. -func expectedRateLimitContainerEnv(rateLimit *egv1a1.RateLimit, rateLimitDeployment *egv1a1.KubernetesDeploymentSpec) []corev1.EnvVar { +func expectedRateLimitContainerEnv(rateLimit *egv1a1.RateLimit, rateLimitDeployment *egv1a1.KubernetesDeploymentSpec, + namespace string) []corev1.EnvVar { env := []corev1.EnvVar{ { Name: RuntimeRootEnvVar, @@ -384,6 +398,54 @@ func expectedRateLimitContainerEnv(rateLimit *egv1a1.RateLimit, rateLimitDeploym } } + if enableTracing(rateLimit) { + var sampleRate = 1.0 + if rateLimit.Telemetry.Tracing.SamplingRate != nil { + sampleRate = float64(*rateLimit.Telemetry.Tracing.SamplingRate) / 100.0 + } + + traceEndpoint := checkTraceEndpointScheme(rateLimit.Telemetry.Tracing.Provider.URL) + tracingEnvs := []corev1.EnvVar{ + { + Name: TracingEnabledVar, + Value: "true", + }, + { + Name: TracingServiceNameVar, + Value: InfraName, + }, + { + Name: TracingServiceNamespaceVar, + Value: namespace, + }, + { + // By default, this is a random instanceID, + // we use the RateLimit pod name as the trace service instanceID. + Name: TracingServiceInstanceIDVar, + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "metadata.name", + }, + }, + }, + { + Name: TracingSamplingRateVar, + // The api is configured with [0,100], but sampling can only be [0,1]. + // doc: https://github.com/envoyproxy/ratelimit?tab=readme-ov-file#tracing + // You will lose precision during the conversion process, but don't worry, + // this follows the rounding rule and won't make the expected sampling rate too different + // from the actual sampling rate + Value: strconv.FormatFloat(sampleRate, 'f', 1, 64), + }, + { + Name: OTELExporterOTLPTraceEndpointVar, + Value: traceEndpoint, + }, + } + env = append(env, tracingEnvs...) + } + return resource.ExpectedContainerEnv(rateLimitDeployment.Container, env) } @@ -399,3 +461,31 @@ func Validate(ctx context.Context, client client.Client, gateway *egv1a1.EnvoyGa return nil } + +func enableTracing(rl *egv1a1.RateLimit) bool { + // Other fields can use the default values, + // but we have to make sure the user has the Provider.URL + if rl != nil && rl.Telemetry != nil && + rl.Telemetry.Tracing != nil && + rl.Telemetry.Tracing.Provider != nil && + len(rl.Telemetry.Tracing.Provider.URL) != 0 { + return true + } + + return false +} + +// checkTraceEndpointScheme Check the scheme prefix in the trace url +func checkTraceEndpointScheme(url string) string { + // Since the OTLP collector needs to configure the scheme prefix, + // we need to check if the user has configured this + // TODO: It is currently assumed to be a normal connection, + // and a TLS connection will be added later. + httpScheme := "http://" + exist := strings.HasPrefix(url, httpScheme) + if exist { + return url + } + + return fmt.Sprintf("%s%s", httpScheme, url) +} diff --git a/internal/infrastructure/kubernetes/ratelimit/resource_provider.go b/internal/infrastructure/kubernetes/ratelimit/resource_provider.go index 90f646d014f..885cb4ddca6 100644 --- a/internal/infrastructure/kubernetes/ratelimit/resource_provider.go +++ b/internal/infrastructure/kubernetes/ratelimit/resource_provider.go @@ -61,6 +61,7 @@ func (r *ResourceRender) Name() string { func enablePrometheus(rl *egv1a1.RateLimit) bool { if rl != nil && rl.Telemetry != nil && + rl.Telemetry.Metrics != nil && rl.Telemetry.Metrics.Prometheus != nil { return !rl.Telemetry.Metrics.Prometheus.Disable } @@ -183,7 +184,7 @@ func (r *ResourceRender) ServiceAccount() (*corev1.ServiceAccount, error) { // Deployment returns the expected rate limit Deployment based on the provided infra. func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) { - containers := expectedRateLimitContainers(r.rateLimit, r.rateLimitDeployment) + containers := expectedRateLimitContainers(r.rateLimit, r.rateLimitDeployment, r.Namespace) labels := rateLimitLabels() selector := resource.GetSelector(labels) diff --git a/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go b/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go index 6c56631d9cc..52aec1fabed 100644 --- a/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go +++ b/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go @@ -648,6 +648,46 @@ func TestDeployment(t *testing.T) { }, }, }, + { + caseName: "enable-tracing", + rateLimit: &egv1a1.RateLimit{ + Backend: egv1a1.RateLimitDatabaseBackend{ + Type: egv1a1.RedisBackendType, + Redis: &egv1a1.RateLimitRedisSettings{ + URL: "redis.redis.svc:6379", + }, + }, + Telemetry: &egv1a1.RateLimitTelemetry{ + Tracing: &egv1a1.RateLimitTracing{ + Provider: &egv1a1.RateLimitTracingProvider{ + URL: "http://trace-collector.envoy-gateway-system.svc.cluster.local:4318", + }, + }, + }, + }, + }, + { + caseName: "enable-tracing-custom", + rateLimit: &egv1a1.RateLimit{ + Backend: egv1a1.RateLimitDatabaseBackend{ + Type: egv1a1.RedisBackendType, + Redis: &egv1a1.RateLimitRedisSettings{ + URL: "redis.redis.svc:6379", + }, + }, + Telemetry: &egv1a1.RateLimitTelemetry{ + Tracing: &egv1a1.RateLimitTracing{ + SamplingRate: func() *uint32 { + var samplingRate uint32 = 55 + return &samplingRate + }(), + Provider: &egv1a1.RateLimitTracingProvider{ + URL: "trace-collector.envoy-gateway-system.svc.cluster.local:4317", + }, + }, + }, + }, + }, } for _, tc := range cases { t.Run(tc.caseName, func(t *testing.T) { diff --git a/internal/infrastructure/kubernetes/ratelimit/resource_test.go b/internal/infrastructure/kubernetes/ratelimit/resource_test.go new file mode 100644 index 00000000000..71179c8c7c4 --- /dev/null +++ b/internal/infrastructure/kubernetes/ratelimit/resource_test.go @@ -0,0 +1,40 @@ +// 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 ratelimit + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCheckTraceEndpointScheme(t *testing.T) { + + cases := []struct { + caseName string + actualURL string + expectedURL string + }{ + { + caseName: "normal url with http prefix", + actualURL: "http://collector.observability.svc.cluster.local:4318", + expectedURL: "http://collector.observability.svc.cluster.local:4318", + }, + { + caseName: "abnormal url without http prefix", + actualURL: "collector.observability.svc.cluster.local:4318", + expectedURL: "http://collector.observability.svc.cluster.local:4318", + }, + } + + for _, tc := range cases { + t.Run(tc.caseName, func(t *testing.T) { + actual := checkTraceEndpointScheme(tc.actualURL) + require.Equal(t, tc.expectedURL, actual) + }) + } + +} diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml new file mode 100644 index 00000000000..b4c7d9472e9 --- /dev/null +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml @@ -0,0 +1,160 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy-ratelimit + name: envoy-ratelimit + namespace: envoy-gateway-system + ownerReferences: + - apiVersion: apps/v1 + kind: Deployment + name: envoy-gateway + uid: test-owner-reference-uid-for-deployment +spec: + progressDeadlineSeconds: 600 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy-ratelimit + strategy: + type: RollingUpdate + template: + metadata: + annotations: + prometheus.io/path: /metrics + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy-ratelimit + spec: + automountServiceAccountToken: false + containers: + - command: + - /bin/ratelimit + env: + - name: RUNTIME_ROOT + value: /data + - name: RUNTIME_SUBDIRECTORY + value: ratelimit + - name: RUNTIME_IGNOREDOTFILES + value: "true" + - name: RUNTIME_WATCH_ROOT + value: "false" + - name: LOG_LEVEL + value: info + - name: USE_STATSD + value: "false" + - name: CONFIG_TYPE + value: GRPC_XDS_SOTW + - name: CONFIG_GRPC_XDS_SERVER_URL + value: envoy-gateway:18001 + - name: CONFIG_GRPC_XDS_NODE_ID + value: envoy-ratelimit + - name: GRPC_SERVER_USE_TLS + value: "true" + - name: GRPC_SERVER_TLS_CERT + value: /certs/tls.crt + - name: GRPC_SERVER_TLS_KEY + value: /certs/tls.key + - name: GRPC_SERVER_TLS_CA_CERT + value: /certs/ca.crt + - name: CONFIG_GRPC_XDS_SERVER_USE_TLS + value: "true" + - name: CONFIG_GRPC_XDS_CLIENT_TLS_CERT + value: /certs/tls.crt + - name: CONFIG_GRPC_XDS_CLIENT_TLS_KEY + value: /certs/tls.key + - name: CONFIG_GRPC_XDS_SERVER_TLS_CACERT + value: /certs/ca.crt + - name: FORCE_START_WITHOUT_INITIAL_CONFIG + value: "true" + - name: REDIS_SOCKET_TYPE + value: tcp + - name: REDIS_URL + value: redis.redis.svc:6379 + - name: TRACING_ENABLED + value: "true" + - name: TRACING_SERVICE_NAME + value: envoy-ratelimit + - name: TRACING_SERVICE_NAMESPACE + value: envoy-gateway-system + - name: TRACING_SERVICE_INSTANCE_ID + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: TRACING_SAMPLING_RATE + value: "0.6" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://trace-collector.envoy-gateway-system.svc.cluster.local:4317 + image: envoyproxy/ratelimit:master + imagePullPolicy: IfNotPresent + name: envoy-ratelimit + ports: + - containerPort: 8081 + name: grpc + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthcheck + port: 8080 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - command: + - /bin/statsd_exporter + - --web.listen-address=:19001 + - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml + image: prom/statsd-exporter:v0.18.0 + imagePullPolicy: IfNotPresent + name: prom-statsd-exporter + ports: + - containerPort: 9125 + name: statsd + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /etc/statsd-exporter + name: statsd-exporter-config + readOnly: true + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-ratelimit + terminationGracePeriodSeconds: 300 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy-rate-limit + - configMap: + defaultMode: 420 + name: statsd-exporter-config + optional: true + name: statsd-exporter-config +status: {} diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml new file mode 100644 index 00000000000..e36ff5ef87d --- /dev/null +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml @@ -0,0 +1,160 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy-ratelimit + name: envoy-ratelimit + namespace: envoy-gateway-system + ownerReferences: + - apiVersion: apps/v1 + kind: Deployment + name: envoy-gateway + uid: test-owner-reference-uid-for-deployment +spec: + progressDeadlineSeconds: 600 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy-ratelimit + strategy: + type: RollingUpdate + template: + metadata: + annotations: + prometheus.io/path: /metrics + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy-ratelimit + spec: + automountServiceAccountToken: false + containers: + - command: + - /bin/ratelimit + env: + - name: RUNTIME_ROOT + value: /data + - name: RUNTIME_SUBDIRECTORY + value: ratelimit + - name: RUNTIME_IGNOREDOTFILES + value: "true" + - name: RUNTIME_WATCH_ROOT + value: "false" + - name: LOG_LEVEL + value: info + - name: USE_STATSD + value: "false" + - name: CONFIG_TYPE + value: GRPC_XDS_SOTW + - name: CONFIG_GRPC_XDS_SERVER_URL + value: envoy-gateway:18001 + - name: CONFIG_GRPC_XDS_NODE_ID + value: envoy-ratelimit + - name: GRPC_SERVER_USE_TLS + value: "true" + - name: GRPC_SERVER_TLS_CERT + value: /certs/tls.crt + - name: GRPC_SERVER_TLS_KEY + value: /certs/tls.key + - name: GRPC_SERVER_TLS_CA_CERT + value: /certs/ca.crt + - name: CONFIG_GRPC_XDS_SERVER_USE_TLS + value: "true" + - name: CONFIG_GRPC_XDS_CLIENT_TLS_CERT + value: /certs/tls.crt + - name: CONFIG_GRPC_XDS_CLIENT_TLS_KEY + value: /certs/tls.key + - name: CONFIG_GRPC_XDS_SERVER_TLS_CACERT + value: /certs/ca.crt + - name: FORCE_START_WITHOUT_INITIAL_CONFIG + value: "true" + - name: REDIS_SOCKET_TYPE + value: tcp + - name: REDIS_URL + value: redis.redis.svc:6379 + - name: TRACING_ENABLED + value: "true" + - name: TRACING_SERVICE_NAME + value: envoy-ratelimit + - name: TRACING_SERVICE_NAMESPACE + value: envoy-gateway-system + - name: TRACING_SERVICE_INSTANCE_ID + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: TRACING_SAMPLING_RATE + value: "1.0" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://trace-collector.envoy-gateway-system.svc.cluster.local:4318 + image: envoyproxy/ratelimit:master + imagePullPolicy: IfNotPresent + name: envoy-ratelimit + ports: + - containerPort: 8081 + name: grpc + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthcheck + port: 8080 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - command: + - /bin/statsd_exporter + - --web.listen-address=:19001 + - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml + image: prom/statsd-exporter:v0.18.0 + imagePullPolicy: IfNotPresent + name: prom-statsd-exporter + ports: + - containerPort: 9125 + name: statsd + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /etc/statsd-exporter + name: statsd-exporter-config + readOnly: true + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-ratelimit + terminationGracePeriodSeconds: 300 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy-rate-limit + - configMap: + defaultMode: 420 + name: statsd-exporter-config + optional: true + name: statsd-exporter-config +status: {} diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index c3316f67026..7234b805d8f 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -2354,6 +2354,39 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | | `metrics` | _[RateLimitMetrics](#ratelimitmetrics)_ | true | Metrics defines metrics configuration for RateLimit. | +| `tracing` | _[RateLimitTracing](#ratelimittracing)_ | true | Tracing defines traces configuration for RateLimit. | + + +#### RateLimitTracing + + + + + +_Appears in:_ +- [RateLimitTelemetry](#ratelimittelemetry) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `samplingRate` | _integer_ | false | SamplingRate controls the rate at which traffic will be
selected for tracing if no prior sampling decision has been made.
Defaults to 100, valid values [0-100]. 100 indicates 100% sampling. | +| `provider` | _[RateLimitTracingProvider](#ratelimittracingprovider)_ | true | Provider defines the rateLimit tracing provider.
Only OpenTelemetry is supported currently. | + + +#### RateLimitTracingProvider + + + +RateLimitTracingProvider defines the tracing provider configuration of RateLimit + +_Appears in:_ +- [RateLimitTracing](#ratelimittracing) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `type` | _[RateLimitTracingProviderType](#ratelimittracingprovidertype)_ | true | Type defines the tracing provider type.
Since to RateLimit Exporter currently using OpenTelemetry, only OpenTelemetry is supported | +| `url` | _string_ | true | URL is the endpoint of the trace collector that supports the OTLP protocol | + + #### RateLimitType diff --git a/site/content/en/latest/tasks/observability/rate-limit-observability.md b/site/content/en/latest/tasks/observability/rate-limit-observability.md new file mode 100644 index 00000000000..350be4dc4b1 --- /dev/null +++ b/site/content/en/latest/tasks/observability/rate-limit-observability.md @@ -0,0 +1,70 @@ +--- +title: "RateLimit Observability" +--- + +Envoy Gateway provides observability for the RateLimit instances. +This guide show you how to config RateLimit observability, includes traces. + +## Prerequisites + +Follow the steps from the [Quickstart Guide](../quickstart) to install Envoy Gateway and the HTTPRoute example manifest. +Before proceeding, you should be able to query the example backend using HTTP. Follow the steps from the [Global Rate Limit](../traffic/global-rate-limit) to install RateLimit. + +[OpenTelemetry Collector](https://opentelemetry.io/docs/collector/) offers a vendor-agnostic implementation of how to receive, process and export telemetry data. + +Install OTel-Collector: + +```shell +helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts +helm repo update +helm upgrade --install otel-collector open-telemetry/opentelemetry-collector -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/otel-collector/helm-values.yaml -n monitoring --create-namespace --version 0.60.0 +``` + +## Traces + +By default, the Envoy Gateway does not configure RateLimit to send traces to the OpenTelemetry Sink. +You can configure the collector in the `rateLimit.telemetry.tracing` of the `EnvoyGateway`CRD. + +RateLimit uses the OpenTelemetry Exporter to export traces to the collector. +You can configure a collector that supports the OTLP protocol, which includes but is not limited to: OpenTelemetry Collector, Jaeger, Zipkin, and so on. + +***Note:*** + +* By default, the Envoy Gateway configures a `100%` sampling rate for RateLimit, which may lead to performance issues. + +Assuming the OpenTelemetry Collector is running in the `observability` namespace, and it has a service named `otel-svc`, +we only want to sample `50%` of the trace data. We would configure it as follows: + +```shell +cat < Date: Thu, 11 Apr 2024 11:58:07 +0800 Subject: [PATCH 04/10] docs: fix typo in release process (#3175) Signed-off-by: Wilson Wu --- site/content/en/latest/contributions/RELEASING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/en/latest/contributions/RELEASING.md b/site/content/en/latest/contributions/RELEASING.md index 3ee8b970c5f..76211b61e1a 100644 --- a/site/content/en/latest/contributions/RELEASING.md +++ b/site/content/en/latest/contributions/RELEASING.md @@ -148,7 +148,7 @@ export GITHUB_REMOTE=origin ``` - 6. Uodate the `Documentation` referred link on the menu in `site/hugo.toml`: + 6. Update the `Documentation` referred link on the menu in `site/hugo.toml`: ```shell [[menu.main]] From 0cb3299a0efc5b330f319c3be9d2bf659851b313 Mon Sep 17 00:00:00 2001 From: zirain Date: Thu, 11 Apr 2024 12:45:38 +0800 Subject: [PATCH 05/10] feat: implment BackendRefs in EnvoyProxy (#3080) * implment BackendRef in EnvoyProxy Signed-off-by: zirain --- api/v1alpha1/accesslogging_types.go | 14 +- api/v1alpha1/envoyproxy_metric_types.go | 14 +- api/v1alpha1/shared_types.go | 8 + api/v1alpha1/tracing_types.go | 14 +- .../validation/envoyproxy_validate_test.go | 2 +- api/v1alpha1/zz_generated.deepcopy.go | 61 ++- .../gateway.envoyproxy.io_envoyproxies.yaml | 425 +++++++++--------- internal/gatewayapi/listener.go | 32 +- internal/gatewayapi/listener_test.go | 103 ++++- .../envoyproxy-accesslog-backend.in.yaml | 89 ++++ .../envoyproxy-accesslog-backend.out.yaml | 158 +++++++ internal/ir/xds.go | 8 +- internal/ir/zz_generated.deepcopy.go | 8 +- internal/utils/net/backendref.go | 25 ++ internal/xds/bootstrap/bootstrap.go | 17 +- internal/xds/bootstrap/bootstrap_test.go | 31 +- .../render/otel-metrics-backendref.yaml | 133 ++++++ .../testdata/in/xds-ir/tracing.yaml | 5 +- internal/xds/translator/tracing.go | 12 +- site/content/en/latest/api/extension_types.md | 32 +- test/cel-validation/envoyproxy_test.go | 275 ++++++++++-- test/config/gatewayclass.yaml | 19 +- tools/make/golang.mk | 2 +- 23 files changed, 1181 insertions(+), 306 deletions(-) create mode 100644 internal/gatewayapi/testdata/envoyproxy-accesslog-backend.in.yaml create mode 100755 internal/gatewayapi/testdata/envoyproxy-accesslog-backend.out.yaml create mode 100644 internal/utils/net/backendref.go create mode 100644 internal/xds/bootstrap/testdata/render/otel-metrics-backendref.yaml diff --git a/api/v1alpha1/accesslogging_types.go b/api/v1alpha1/accesslogging_types.go index 48694edb2a7..4c62d230b45 100644 --- a/api/v1alpha1/accesslogging_types.go +++ b/api/v1alpha1/accesslogging_types.go @@ -5,8 +5,6 @@ package v1alpha1 -import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" - type ProxyAccessLog struct { // Disable disables access logging for managed proxies if set to true. Disable bool `json:"disable,omitempty"` @@ -96,11 +94,13 @@ type FileEnvoyProxyAccessLog struct { // OpenTelemetryEnvoyProxyAccessLog defines the OpenTelemetry access log sink. // -// +kubebuilder:validation:XValidation:message="BackendRef only support Service Kind.",rule="!has(self.backendRef) || !has(self.backendRef.kind) || self.backendRef.kind == 'Service'" +// +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0" type OpenTelemetryEnvoyProxyAccessLog struct { // Host define the extension service hostname. // Deprecated: Use BackendRef instead. - Host string `json:"host"` + // + // +optional + Host *string `json:"host,omitempty"` // Port defines the port the extension service is exposed on. // Deprecated: Use BackendRef instead. // @@ -108,12 +108,14 @@ type OpenTelemetryEnvoyProxyAccessLog struct { // +kubebuilder:validation:Minimum=0 // +kubebuilder:default=4317 Port int32 `json:"port,omitempty"` - // BackendRef references a Kubernetes object that represents the + // BackendRefs references a Kubernetes object that represents the // backend server to which the accesslog will be sent. // Only service Kind is supported for now. // // +optional - BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"` + // +kubebuilder:validation:MaxItems=1 + // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')" + BackendRefs []BackendRef `json:"backendRefs,omitempty"` // Resources is a set of labels that describe the source of a log entry, including envoy node info. // It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). // +optional diff --git a/api/v1alpha1/envoyproxy_metric_types.go b/api/v1alpha1/envoyproxy_metric_types.go index 4c45df39e36..59c6a6f2dd9 100644 --- a/api/v1alpha1/envoyproxy_metric_types.go +++ b/api/v1alpha1/envoyproxy_metric_types.go @@ -5,8 +5,6 @@ package v1alpha1 -import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" - type MetricSinkType string const ( @@ -51,11 +49,13 @@ type ProxyMetricSink struct { // ProxyOpenTelemetrySink defines the configuration for OpenTelemetry sink. // -// +kubebuilder:validation:XValidation:message="BackendRef only support Service Kind.",rule="!has(self.backendRef) || !has(self.backendRef.kind) || self.backendRef.kind == 'Service'" +// +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0" type ProxyOpenTelemetrySink struct { // Host define the service hostname. // Deprecated: Use BackendRef instead. - Host string `json:"host"` + // + // +optional + Host *string `json:"host,omitempty"` // Port defines the port the service is exposed on. // Deprecated: Use BackendRef instead. // @@ -64,12 +64,14 @@ type ProxyOpenTelemetrySink struct { // +kubebuilder:validation:Maximum=65535 // +kubebuilder:default=4317 Port int32 `json:"port,omitempty"` - // BackendRef references a Kubernetes object that represents the + // BackendRefs references a Kubernetes object that represents the // backend server to which the metric will be sent. // Only service Kind is supported for now. // // +optional - BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"` + // +kubebuilder:validation:MaxItems=1 + // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')" + BackendRefs []BackendRef `json:"backendRefs,omitempty"` // TODO: add support for customizing OpenTelemetry sink in https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/stat_sinks/open_telemetry/v3/open_telemetry.proto#envoy-v3-api-msg-extensions-stat-sinks-open-telemetry-v3-sinkconfig } diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go index a634995e1b5..7d8128df3c6 100644 --- a/api/v1alpha1/shared_types.go +++ b/api/v1alpha1/shared_types.go @@ -10,6 +10,7 @@ import ( autoscalingv2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" ) const ( @@ -407,3 +408,10 @@ type KubernetesPatchSpec struct { // Object contains the raw configuration for merged object Value apiextensionsv1.JSON `json:"value"` } + +// BackendRef defines how an ObjectReference that is specific to BackendRef. +type BackendRef struct { + // BackendObjectReference references a Kubernetes object that represents the backend. + // Only service Kind is supported for now. + gwapiv1.BackendObjectReference `json:",inline"` +} diff --git a/api/v1alpha1/tracing_types.go b/api/v1alpha1/tracing_types.go index 7c86ba7c846..d3a18673f60 100644 --- a/api/v1alpha1/tracing_types.go +++ b/api/v1alpha1/tracing_types.go @@ -5,8 +5,6 @@ package v1alpha1 -import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" - type ProxyTracing struct { // SamplingRate controls the rate at which traffic will be // selected for tracing if no prior sampling decision has been made. @@ -32,7 +30,7 @@ const ( // TracingProvider defines the tracing provider configuration. // -// +kubebuilder:validation:XValidation:message="BackendRef only support Service Kind.",rule="!has(self.backendRef) || !has(self.backendRef.kind) || self.backendRef.kind == 'Service'" +// +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0" type TracingProvider struct { // Type defines the tracing provider type. // EG currently only supports OpenTelemetry. @@ -41,7 +39,9 @@ type TracingProvider struct { Type TracingProviderType `json:"type"` // Host define the provider service hostname. // Deprecated: Use BackendRef instead. - Host string `json:"host"` + // + // +optional + Host *string `json:"host,omitempty"` // Port defines the port the provider service is exposed on. // Deprecated: Use BackendRef instead. // @@ -49,12 +49,14 @@ type TracingProvider struct { // +kubebuilder:validation:Minimum=0 // +kubebuilder:default=4317 Port int32 `json:"port,omitempty"` - // BackendRef references a Kubernetes object that represents the + // BackendRefs references a Kubernetes object that represents the // backend server to which the accesslog will be sent. // Only service Kind is supported for now. // // +optional - BackendRef *gwapiv1.BackendObjectReference `json:"backendRef"` + // +kubebuilder:validation:MaxItems=1 + // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')" + BackendRefs []BackendRef `json:"backendRefs,omitempty"` } type CustomTagType string diff --git a/api/v1alpha1/validation/envoyproxy_validate_test.go b/api/v1alpha1/validation/envoyproxy_validate_test.go index 93381bd527a..54342d73579 100644 --- a/api/v1alpha1/validation/envoyproxy_validate_test.go +++ b/api/v1alpha1/validation/envoyproxy_validate_test.go @@ -438,7 +438,7 @@ func TestValidateEnvoyProxy(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - Host: "0.0.0.0", + Host: ptr.To("0.0.0.0"), Port: 3217, }, }, diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index b1e849077bd..71dcff84f36 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -114,6 +114,22 @@ func (in *BackOffPolicy) DeepCopy() *BackOffPolicy { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackendRef) DeepCopyInto(out *BackendRef) { + *out = *in + in.BackendObjectReference.DeepCopyInto(&out.BackendObjectReference) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendRef. +func (in *BackendRef) DeepCopy() *BackendRef { + if in == nil { + return nil + } + out := new(BackendRef) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BackendTrafficPolicy) DeepCopyInto(out *BackendTrafficPolicy) { *out = *in @@ -2689,10 +2705,17 @@ func (in *OIDCProvider) DeepCopy() *OIDCProvider { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OpenTelemetryEnvoyProxyAccessLog) DeepCopyInto(out *OpenTelemetryEnvoyProxyAccessLog) { *out = *in - if in.BackendRef != nil { - in, out := &in.BackendRef, &out.BackendRef - *out = new(v1.BackendObjectReference) - (*in).DeepCopyInto(*out) + if in.Host != nil { + in, out := &in.Host, &out.Host + *out = new(string) + **out = **in + } + if in.BackendRefs != nil { + in, out := &in.BackendRefs, &out.BackendRefs + *out = make([]BackendRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.Resources != nil { in, out := &in.Resources, &out.Resources @@ -3009,10 +3032,17 @@ func (in *ProxyMetrics) DeepCopy() *ProxyMetrics { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProxyOpenTelemetrySink) DeepCopyInto(out *ProxyOpenTelemetrySink) { *out = *in - if in.BackendRef != nil { - in, out := &in.BackendRef, &out.BackendRef - *out = new(v1.BackendObjectReference) - (*in).DeepCopyInto(*out) + if in.Host != nil { + in, out := &in.Host, &out.Host + *out = new(string) + **out = **in + } + if in.BackendRefs != nil { + in, out := &in.BackendRefs, &out.BackendRefs + *out = make([]BackendRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } } @@ -3845,10 +3875,17 @@ func (in *Timeout) DeepCopy() *Timeout { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TracingProvider) DeepCopyInto(out *TracingProvider) { *out = *in - if in.BackendRef != nil { - in, out := &in.BackendRef, &out.BackendRef - *out = new(v1.BackendObjectReference) - (*in).DeepCopyInto(*out) + if in.Host != nil { + in, out := &in.Host, &out.Host + *out = new(string) + **out = **in + } + if in.BackendRefs != nil { + in, out := &in.BackendRefs, &out.BackendRefs + *out = make([]BackendRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } } diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml index 4232d906453..0f5cf8f6bf5 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml @@ -5899,85 +5899,94 @@ spec: description: OpenTelemetry defines the OpenTelemetry accesslog sink. properties: - backendRef: + backendRefs: description: |- - BackendRef references a Kubernetes object that represents the + BackendRefs references a Kubernetes object that represents the backend server to which the accesslog will be sent. Only service Kind is supported for now. - properties: - group: - default: "" - description: |- - Group is the group of the referent. For example, "gateway.networking.k8s.io". - When unspecified or empty string, core API group is inferred. - 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: Service - description: |- - Kind is the Kubernetes resource kind of the referent. For example - "Service". + items: + description: BackendRef defines how an ObjectReference + that is specific to BackendRef. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + 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: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". - Defaults to "Service" when not specified. + Defaults to "Service" when not specified. - ExternalName services can refer to CNAME DNS records that may live - outside of the cluster and as such are difficult to reason about in - terms of conformance. They also may not be safe to forward to (see - CVE-2021-25740 for more information). Implementations SHOULD NOT - support ExternalName Services. + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. - Support: Core (Services with a type other than ExternalName) + Support: Core (Services with a type other than ExternalName) - Support: Implementation-specific (Services with type ExternalName) - 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. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: |- - Namespace is the namespace of the backend. When unspecified, the local - namespace is inferred. + Support: Implementation-specific (Services with type ExternalName) + 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. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. - Note that when a namespace different than the local namespace is specified, - a ReferenceGrant object is required in the referent namespace to allow that - namespace's owner to accept the reference. See the ReferenceGrant - documentation for details. + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. - Support: Core - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: |- - Port specifies the destination port number to use for this resource. - Port is required when the referent is a Kubernetes Service. In this - case, the port number is the service port number, not the target port. - For other resources, destination port might be derived from the referent - resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - required: - - name - type: object + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind + == ''Service'') ? has(self.port) : true' + maxItems: 1 + type: array x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind - == ''Service'') ? has(self.port) : true' + - message: only support Service kind. + rule: self.all(f, f.kind == 'Service') host: description: |- Host define the extension service hostname. @@ -5998,13 +6007,11 @@ spec: Resources is a set of labels that describe the source of a log entry, including envoy node info. It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). type: object - required: - - host type: object x-kubernetes-validations: - - message: BackendRef only support Service Kind. - rule: '!has(self.backendRef) || !has(self.backendRef.kind) - || self.backendRef.kind == ''Service''' + - message: host or backendRefs needs to be set + rule: has(self.host) || self.backendRefs.size() + > 0 type: description: Type defines the type of accesslog sink. @@ -6092,85 +6099,93 @@ spec: OpenTelemetry defines the configuration for OpenTelemetry sink. It's required if the sink type is OpenTelemetry. properties: - backendRef: + backendRefs: description: |- - BackendRef references a Kubernetes object that represents the + BackendRefs references a Kubernetes object that represents the backend server to which the metric will be sent. Only service Kind is supported for now. - properties: - group: - default: "" - description: |- - Group is the group of the referent. For example, "gateway.networking.k8s.io". - When unspecified or empty string, core API group is inferred. - 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: Service - description: |- - Kind is the Kubernetes resource kind of the referent. For example - "Service". + items: + description: BackendRef defines how an ObjectReference + that is specific to BackendRef. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + 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: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". - Defaults to "Service" when not specified. + Defaults to "Service" when not specified. - ExternalName services can refer to CNAME DNS records that may live - outside of the cluster and as such are difficult to reason about in - terms of conformance. They also may not be safe to forward to (see - CVE-2021-25740 for more information). Implementations SHOULD NOT - support ExternalName Services. + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. - Support: Core (Services with a type other than ExternalName) + Support: Core (Services with a type other than ExternalName) - Support: Implementation-specific (Services with type ExternalName) - 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. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: |- - Namespace is the namespace of the backend. When unspecified, the local - namespace is inferred. + Support: Implementation-specific (Services with type ExternalName) + 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. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. - Note that when a namespace different than the local namespace is specified, - a ReferenceGrant object is required in the referent namespace to allow that - namespace's owner to accept the reference. See the ReferenceGrant - documentation for details. + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. - Support: Core - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: |- - Port specifies the destination port number to use for this resource. - Port is required when the referent is a Kubernetes Service. In this - case, the port number is the service port number, not the target port. - For other resources, destination port might be derived from the referent - resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - required: - - name - type: object + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == + ''Service'') ? has(self.port) : true' + maxItems: 1 + type: array x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == - ''Service'') ? has(self.port) : true' + - message: only support Service kind. + rule: self.all(f, f.kind == 'Service') host: description: |- Host define the service hostname. @@ -6185,13 +6200,11 @@ spec: maximum: 65535 minimum: 0 type: integer - required: - - host type: object x-kubernetes-validations: - - message: BackendRef only support Service Kind. - rule: '!has(self.backendRef) || !has(self.backendRef.kind) - || self.backendRef.kind == ''Service''' + - message: host or backendRefs needs to be set + rule: has(self.host) || self.backendRefs.size() > + 0 type: default: OpenTelemetry description: |- @@ -6282,85 +6295,93 @@ spec: Provider defines the tracing provider. Only OpenTelemetry is supported currently. properties: - backendRef: + backendRefs: description: |- - BackendRef references a Kubernetes object that represents the + BackendRefs references a Kubernetes object that represents the backend server to which the accesslog will be sent. Only service Kind is supported for now. - properties: - group: - default: "" - description: |- - Group is the group of the referent. For example, "gateway.networking.k8s.io". - When unspecified or empty string, core API group is inferred. - 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: Service - description: |- - Kind is the Kubernetes resource kind of the referent. For example - "Service". + items: + description: BackendRef defines how an ObjectReference + that is specific to BackendRef. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + 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: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". - Defaults to "Service" when not specified. + Defaults to "Service" when not specified. - ExternalName services can refer to CNAME DNS records that may live - outside of the cluster and as such are difficult to reason about in - terms of conformance. They also may not be safe to forward to (see - CVE-2021-25740 for more information). Implementations SHOULD NOT - support ExternalName Services. + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. - Support: Core (Services with a type other than ExternalName) + Support: Core (Services with a type other than ExternalName) - Support: Implementation-specific (Services with type ExternalName) - 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. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: |- - Namespace is the namespace of the backend. When unspecified, the local - namespace is inferred. + Support: Implementation-specific (Services with type ExternalName) + 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. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. - Note that when a namespace different than the local namespace is specified, - a ReferenceGrant object is required in the referent namespace to allow that - namespace's owner to accept the reference. See the ReferenceGrant - documentation for details. + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. - Support: Core - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: |- - Port specifies the destination port number to use for this resource. - Port is required when the referent is a Kubernetes Service. In this - case, the port number is the service port number, not the target port. - For other resources, destination port might be derived from the referent - resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - required: - - name - type: object + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == ''Service'') + ? has(self.port) : true' + maxItems: 1 + type: array x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') - ? has(self.port) : true' + - message: only support Service kind. + rule: self.all(f, f.kind == 'Service') host: description: |- Host define the provider service hostname. @@ -6383,13 +6404,11 @@ spec: - OpenTelemetry type: string required: - - host - type type: object x-kubernetes-validations: - - message: BackendRef only support Service Kind. - rule: '!has(self.backendRef) || !has(self.backendRef.kind) - || self.backendRef.kind == ''Service''' + - message: host or backendRefs needs to be set + rule: has(self.host) || self.backendRefs.size() > 0 samplingRate: default: 100 description: |- diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go index de94aaf27e9..37f83c49cc1 100644 --- a/internal/gatewayapi/listener.go +++ b/internal/gatewayapi/listener.go @@ -15,6 +15,7 @@ import ( "github.com/envoyproxy/gateway/internal/ir" "github.com/envoyproxy/gateway/internal/utils" "github.com/envoyproxy/gateway/internal/utils/naming" + "github.com/envoyproxy/gateway/internal/utils/net" ) var _ ListenersTranslator = (*Translator)(nil) @@ -216,12 +217,20 @@ func processAccessLog(envoyproxy *egv1a1.EnvoyProxy) *ir.AccessLog { continue } + // TODO: remove support for Host/Port in v1.2 al := &ir.OpenTelemetryAccessLog{ Port: uint32(sink.OpenTelemetry.Port), - Host: sink.OpenTelemetry.Host, Resources: sink.OpenTelemetry.Resources, } + if sink.OpenTelemetry.Host != nil { + al.Host = *sink.OpenTelemetry.Host + } + + if len(sink.OpenTelemetry.BackendRefs) > 0 { + al.Host, al.Port = net.BackendHostAndPort(sink.OpenTelemetry.BackendRefs[0].BackendObjectReference, envoyproxy.Namespace) + } + switch accessLog.Format.Type { case egv1a1.ProxyAccessLogFormatTypeJSON: al.Attributes = accessLog.Format.JSON @@ -243,10 +252,29 @@ func processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.EnvoyProxy) *ir.Trac envoyproxy.Spec.Telemetry.Tracing == nil { return nil } + tracing := envoyproxy.Spec.Telemetry.Tracing + + // TODO: remove support for Host/Port in v1.2 + var host string + var port uint32 + if tracing.Provider.Host != nil { + host, port = *tracing.Provider.Host, uint32(tracing.Provider.Port) + } + if len(tracing.Provider.BackendRefs) > 0 { + host, port = net.BackendHostAndPort(tracing.Provider.BackendRefs[0].BackendObjectReference, gw.Namespace) + } + + samplingRate := 100.0 + if tracing.SamplingRate != nil { + samplingRate = float64(*tracing.SamplingRate) + } return &ir.Tracing{ ServiceName: naming.ServiceName(utils.NamespacedName(gw)), - ProxyTracing: *envoyproxy.Spec.Telemetry.Tracing, + Host: host, + Port: port, + SamplingRate: samplingRate, + CustomTags: tracing.CustomTags, } } diff --git a/internal/gatewayapi/listener_test.go b/internal/gatewayapi/listener_test.go index ddecda17ada..6cdd4a69659 100644 --- a/internal/gatewayapi/listener_test.go +++ b/internal/gatewayapi/listener_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" egcfgv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" @@ -40,7 +41,107 @@ func TestProcessTracing(t *testing.T) { }, expected: &ir.Tracing{ ServiceName: "fake-gw.fake-ns", - ProxyTracing: egcfgv1a1.ProxyTracing{}, + SamplingRate: 100.0, + }, + }, + { + gw: gwapiv1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-gw", + Namespace: "fake-ns", + }, + }, + proxy: &egcfgv1a1.EnvoyProxy{ + Spec: egcfgv1a1.EnvoyProxySpec{ + Telemetry: &egcfgv1a1.ProxyTelemetry{ + Tracing: &egcfgv1a1.ProxyTracing{ + Provider: egcfgv1a1.TracingProvider{ + Host: ptr.To("fake-host"), + Port: 4317, + }, + }, + }, + }, + }, + expected: &ir.Tracing{ + ServiceName: "fake-gw.fake-ns", + SamplingRate: 100.0, + Host: "fake-host", + Port: 4317, + }, + }, + { + gw: gwapiv1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-gw", + Namespace: "fake-ns", + }, + }, + proxy: &egcfgv1a1.EnvoyProxy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-eproxy", + Namespace: "fake-ns", + }, + Spec: egcfgv1a1.EnvoyProxySpec{ + Telemetry: &egcfgv1a1.ProxyTelemetry{ + Tracing: &egcfgv1a1.ProxyTracing{ + Provider: egcfgv1a1.TracingProvider{ + Host: ptr.To("fake-host"), + Port: 4317, + BackendRefs: []egcfgv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-name", + Port: PortNumPtr(4317), + }, + }, + }, + }, + }, + }, + }, + }, + expected: &ir.Tracing{ + ServiceName: "fake-gw.fake-ns", + SamplingRate: 100.0, + Host: "fake-name.fake-ns.svc", + Port: 4317, + }, + }, + { + gw: gwapiv1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-gw", + Namespace: "fake-ns", + }, + }, + proxy: &egcfgv1a1.EnvoyProxy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-eproxy", + Namespace: "fake-ns", + }, + Spec: egcfgv1a1.EnvoyProxySpec{ + Telemetry: &egcfgv1a1.ProxyTelemetry{ + Tracing: &egcfgv1a1.ProxyTracing{ + Provider: egcfgv1a1.TracingProvider{ + BackendRefs: []egcfgv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-name", + Port: PortNumPtr(4317), + }, + }, + }, + }, + }, + }, + }, + }, + expected: &ir.Tracing{ + ServiceName: "fake-gw.fake-ns", + SamplingRate: 100.0, + Host: "fake-name.fake-ns.svc", + Port: 4317, }, }, } diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.in.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.in.yaml new file mode 100644 index 00000000000..4dccf1a36d3 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.in.yaml @@ -0,0 +1,89 @@ +envoyproxy: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + namespace: envoy-gateway-system + name: test + spec: + telemetry: + accessLog: + settings: + - format: + type: Text + text: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + sinks: + - type: File + file: + path: /dev/stdout + - type: OpenTelemetry + openTelemetry: + backendRefs: + - name: otel-collector + namespace: monitoring + port: 4317 + resources: + k8s.cluster.name: "cluster-1" + provider: + type: Kubernetes + kubernetes: + envoyService: + type: LoadBalancer + envoyDeployment: + replicas: 2 + container: + env: + - name: env_a + value: env_a_value + - name: env_b + value: env_b_name + image: "envoyproxy/envoy:distroless-dev" + resources: + requests: + cpu: 100m + memory: 512Mi + securityContext: + runAsUser: 2000 + allowPrivilegeEscalation: false + pod: + annotations: + key1: val1 + key2: val2 + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-nodepool + operator: In + values: + - router-node + tolerations: + - effect: NoSchedule + key: node-type + operator: Exists + value: "router" + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + fsGroup: 2000 + fsGroupChangePolicy: "OnRootMismatch" + volumes: + - name: certs + secret: + secretName: envoy-cert +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: Same diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.out.yaml new file mode 100755 index 00000000000..e527eea3e63 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.out.yaml @@ -0,0 +1,158 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +infraIR: + envoy-gateway/gateway-1: + proxy: + config: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + creationTimestamp: null + name: test + namespace: envoy-gateway-system + spec: + logging: {} + provider: + kubernetes: + envoyDeployment: + container: + env: + - name: env_a + value: env_a_value + - name: env_b + value: env_b_name + image: envoyproxy/envoy:distroless-dev + resources: + requests: + cpu: 100m + memory: 512Mi + securityContext: + allowPrivilegeEscalation: false + runAsUser: 2000 + pod: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-nodepool + operator: In + values: + - router-node + annotations: + key1: val1 + key2: val2 + securityContext: + fsGroup: 2000 + fsGroupChangePolicy: OnRootMismatch + runAsGroup: 3000 + runAsUser: 1000 + tolerations: + - effect: NoSchedule + key: node-type + operator: Exists + value: router + volumes: + - name: certs + secret: + secretName: envoy-cert + replicas: 2 + envoyService: + type: LoadBalancer + type: Kubernetes + telemetry: + accessLog: + settings: + - format: + text: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + type: Text + sinks: + - file: + path: /dev/stdout + type: File + - openTelemetry: + backendRefs: + - name: otel-collector + namespace: monitoring + port: 4317 + resources: + k8s.cluster.name: cluster-1 + type: OpenTelemetry + status: {} + listeners: + - address: null + name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 +xdsIR: + envoy-gateway/gateway-1: + accessLog: + openTelemetry: + - host: otel-collector.monitoring.svc + port: 4317 + resources: + k8s.cluster.name: cluster-1 + text: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + text: + - format: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 diff --git a/internal/ir/xds.go b/internal/ir/xds.go index abe5d59b6b9..c2d444ef8a8 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -1380,9 +1380,11 @@ type JSONPatchOperation struct { // Tracing defines the configuration for tracing a Envoy xDS Resource // +k8s:deepcopy-gen=true type Tracing struct { - ServiceName string `json:"serviceName"` - - egv1a1.ProxyTracing + ServiceName string `json:"serviceName"` + Host string `json:"host"` + Port uint32 `json:"port"` + SamplingRate float64 `json:"samplingRate,omitempty"` + CustomTags map[string]egv1a1.CustomTag `json:"customTags,omitempty"` } // Metrics defines the configuration for metrics generated by Envoy diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 34d00d3eb48..e633075feaf 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -2281,7 +2281,13 @@ func (in *Timeout) DeepCopy() *Timeout { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Tracing) DeepCopyInto(out *Tracing) { *out = *in - in.ProxyTracing.DeepCopyInto(&out.ProxyTracing) + if in.CustomTags != nil { + in, out := &in.CustomTags, &out.CustomTags + *out = make(map[string]v1alpha1.CustomTag, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Tracing. diff --git a/internal/utils/net/backendref.go b/internal/utils/net/backendref.go new file mode 100644 index 00000000000..d5cb27ecaab --- /dev/null +++ b/internal/utils/net/backendref.go @@ -0,0 +1,25 @@ +// 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 net + +import ( + "fmt" + + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" +) + +func BackendHostAndPort(backendRef gwapiv1.BackendObjectReference, defaultNamespace string) (string, uint32) { + ns := defaultNamespace + if backendRef.Namespace != nil { + ns = string(*backendRef.Namespace) + } + + if ns == "" { + return string(backendRef.Name), uint32(*backendRef.Port) + } + + return fmt.Sprintf("%s.%s.svc", backendRef.Name, ns), uint32(*backendRef.Port) +} diff --git a/internal/xds/bootstrap/bootstrap.go b/internal/xds/bootstrap/bootstrap.go index 4794c7374cc..115494fd350 100644 --- a/internal/xds/bootstrap/bootstrap.go +++ b/internal/xds/bootstrap/bootstrap.go @@ -15,6 +15,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/utils/net" "github.com/envoyproxy/gateway/internal/utils/regex" ) @@ -84,7 +85,7 @@ type metricSink struct { // Address is the address of the XDS Server that Envoy is managed by. Address string // Port is the port of the XDS Server that Envoy is managed by. - Port int32 + Port uint32 } type adminServerParameters struct { @@ -154,15 +155,23 @@ func GetRenderedBootstrapConfig(opts *RenderBootsrapConfigOptions) (string, erro } // skip duplicate sinks - addr := fmt.Sprintf("%s:%d", sink.OpenTelemetry.Host, sink.OpenTelemetry.Port) + var host string + var port uint32 + if sink.OpenTelemetry.Host != nil { + host, port = *sink.OpenTelemetry.Host, uint32(sink.OpenTelemetry.Port) + } + if len(sink.OpenTelemetry.BackendRefs) > 0 { + host, port = net.BackendHostAndPort(sink.OpenTelemetry.BackendRefs[0].BackendObjectReference, "") + } + addr := fmt.Sprintf("%s:%d", host, port) if addresses.Has(addr) { continue } addresses.Insert(addr) metricSinks = append(metricSinks, metricSink{ - Address: sink.OpenTelemetry.Host, - Port: sink.OpenTelemetry.Port, + Address: host, + Port: port, }) } diff --git a/internal/xds/bootstrap/bootstrap_test.go b/internal/xds/bootstrap/bootstrap_test.go index 2bfa874d653..87c5ecb7958 100644 --- a/internal/xds/bootstrap/bootstrap_test.go +++ b/internal/xds/bootstrap/bootstrap_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "k8s.io/utils/ptr" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" ) @@ -52,7 +53,7 @@ func TestGetRenderedBootstrapConfig(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - Host: "otel-collector.monitoring.svc", + Host: ptr.To("otel-collector.monitoring.svc"), Port: 4317, }, }, @@ -60,6 +61,34 @@ func TestGetRenderedBootstrapConfig(t *testing.T) { }, }, }, + { + name: "otel-metrics-backendref", + opts: &RenderBootsrapConfigOptions{ + ProxyMetrics: &egv1a1.ProxyMetrics{ + Prometheus: &egv1a1.ProxyPrometheusProvider{ + Disable: true, + }, + Sinks: []egv1a1.ProxyMetricSink{ + { + Type: egv1a1.MetricSinkTypeOpenTelemetry, + OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ + Host: ptr.To("otel-collector.monitoring.svc"), + Port: 4317, + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "otel-collector", + Namespace: ptr.To(gwapiv1.Namespace("monitoring")), + Port: ptr.To(gwapiv1.PortNumber(4317)), + }, + }, + }, + }, + }, + }, + }, + }, + }, { name: "custom-stats-matcher", opts: &RenderBootsrapConfigOptions{ diff --git a/internal/xds/bootstrap/testdata/render/otel-metrics-backendref.yaml b/internal/xds/bootstrap/testdata/render/otel-metrics-backendref.yaml new file mode 100644 index 00000000000..db865b4cb8b --- /dev/null +++ b/internal/xds/bootstrap/testdata/render/otel-metrics-backendref.yaml @@ -0,0 +1,133 @@ +admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 +layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 +dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 +stats_sinks: +- name: "envoy.stat_sinks.open_telemetry" + typed_config: + "@type": type.googleapis.com/envoy.extensions.stat_sinks.open_telemetry.v3.SinkConfig + grpc_service: + envoy_grpc: + cluster_name: otel_metric_sink_0 +static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: otel_metric_sink_0 + connect_timeout: 0.250s + type: STRICT_DNS + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: {} + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: otel_metric_sink_0 + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: otel-collector.monitoring.svc + port_value: 4317 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 +overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing.yaml index d67ab2d015f..674eb66acef 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tracing.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tracing.yaml @@ -17,9 +17,8 @@ tracing: requestHeader: name: "X-Request-Id" defaultValue: "-" - provider: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + host: otel-collector.monitoring.svc.cluster.local + port: 4317 http: - name: "first-listener" address: "0.0.0.0" diff --git a/internal/xds/translator/tracing.go b/internal/xds/translator/tracing.go index e0ace0d49cc..8e948fe710e 100644 --- a/internal/xds/translator/tracing.go +++ b/internal/xds/translator/tracing.go @@ -33,8 +33,8 @@ func buildHCMTracing(tracing *ir.Tracing) (*hcm.HttpConnectionManager_Tracing, e GrpcService: &corev3.GrpcService{ TargetSpecifier: &corev3.GrpcService_EnvoyGrpc_{ EnvoyGrpc: &corev3.GrpcService_EnvoyGrpc{ - ClusterName: buildClusterName("tracing", tracing.Provider.Host, uint32(tracing.Provider.Port)), - Authority: tracing.Provider.Host, + ClusterName: buildClusterName("tracing", tracing.Host, tracing.Port), + Authority: tracing.Host, }, }, }, @@ -46,7 +46,7 @@ func buildHCMTracing(tracing *ir.Tracing) (*hcm.HttpConnectionManager_Tracing, e return nil, fmt.Errorf("failed to marshal OpenTelemetryConfig: %w", err) } - tags := []*tracingtype.CustomTag{} + tags := make([]*tracingtype.CustomTag, 0, len(tracing.CustomTags)) // TODO: consider add some default tags for better UX for k, v := range tracing.CustomTags { switch v.Type { @@ -106,7 +106,7 @@ func buildHCMTracing(tracing *ir.Tracing) (*hcm.HttpConnectionManager_Tracing, e Value: 100.0, }, RandomSampling: &xdstype.Percent{ - Value: float64(*tracing.SamplingRate), + Value: tracing.SamplingRate, }, Provider: &tracecfg.Tracing_Http{ Name: "envoy.tracers.opentelemetry", @@ -124,12 +124,12 @@ func processClusterForTracing(tCtx *types.ResourceVersionTable, tracing *ir.Trac return nil } - clusterName := buildClusterName("tracing", tracing.Provider.Host, uint32(tracing.Provider.Port)) + clusterName := buildClusterName("tracing", tracing.Host, tracing.Port) ds := &ir.DestinationSetting{ Weight: ptr.To[uint32](1), Protocol: ir.GRPC, - Endpoints: []*ir.DestinationEndpoint{ir.NewDestEndpoint(tracing.Provider.Host, uint32(tracing.Provider.Port))}, + Endpoints: []*ir.DestinationEndpoint{ir.NewDestEndpoint(tracing.Host, tracing.Port)}, } if err := addXdsCluster(tCtx, &xdsClusterArgs{ name: clusterName, diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 7234b805d8f..21f5bab7250 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -115,6 +115,26 @@ _Appears in:_ | `maxInterval` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | false | MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval | +#### BackendRef + + + +BackendRef defines how an ObjectReference that is specific to BackendRef. + +_Appears in:_ +- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog) +- [ProxyOpenTelemetrySink](#proxyopentelemetrysink) +- [TracingProvider](#tracingprovider) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `group` | _[Group](#group)_ | false | Group is the group of the referent. For example, "gateway.networking.k8s.io".
When unspecified or empty string, core API group is inferred. | +| `kind` | _[Kind](#kind)_ | false | Kind is the Kubernetes resource kind of the referent. For example
"Service".

Defaults to "Service" when not specified.

ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.

Support: Core (Services with a type other than ExternalName)

Support: Implementation-specific (Services with type ExternalName) | +| `name` | _[ObjectName](#objectname)_ | true | Name is the name of the referent. | +| `namespace` | _[Namespace](#namespace)_ | false | Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.

Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.

Support: Core | +| `port` | _[PortNumber](#portnumber)_ | false | Port specifies the destination port number to use for this resource.
Port is required when the referent is a Kubernetes Service. In this
case, the port number is the service port number, not the target port.
For other resources, destination port might be derived from the referent
resource or this field. | + + #### BackendTrafficPolicy @@ -1851,9 +1871,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `host` | _string_ | true | Host define the extension service hostname.
Deprecated: Use BackendRef instead. | +| `host` | _string_ | false | Host define the extension service hostname.
Deprecated: Use BackendRef instead. | | `port` | _integer_ | false | Port defines the port the extension service is exposed on.
Deprecated: Use BackendRef instead. | -| `backendRef` | _[BackendObjectReference](#backendobjectreference)_ | false | BackendRef references a Kubernetes object that represents the
backend server to which the accesslog will be sent.
Only service Kind is supported for now. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the accesslog will be sent.
Only service Kind is supported for now. | | `resources` | _object (keys:string, values:string)_ | false | Resources is a set of labels that describe the source of a log entry, including envoy node info.
It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). | @@ -2125,9 +2145,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `host` | _string_ | true | Host define the service hostname.
Deprecated: Use BackendRef instead. | +| `host` | _string_ | false | Host define the service hostname.
Deprecated: Use BackendRef instead. | | `port` | _integer_ | false | Port defines the port the service is exposed on.
Deprecated: Use BackendRef instead. | -| `backendRef` | _[BackendObjectReference](#backendobjectreference)_ | false | BackendRef references a Kubernetes object that represents the
backend server to which the metric will be sent.
Only service Kind is supported for now. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the metric will be sent.
Only service Kind is supported for now. | #### ProxyPrometheusProvider @@ -2767,9 +2787,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | | `type` | _[TracingProviderType](#tracingprovidertype)_ | true | Type defines the tracing provider type.
EG currently only supports OpenTelemetry. | -| `host` | _string_ | true | Host define the provider service hostname.
Deprecated: Use BackendRef instead. | +| `host` | _string_ | false | Host define the provider service hostname.
Deprecated: Use BackendRef instead. | | `port` | _integer_ | false | Port defines the port the provider service is exposed on.
Deprecated: Use BackendRef instead. | -| `backendRef` | _[BackendObjectReference](#backendobjectreference)_ | false | BackendRef references a Kubernetes object that represents the
backend server to which the accesslog will be sent.
Only service Kind is supported for now. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the accesslog will be sent.
Only service Kind is supported for now. | #### TracingProviderType diff --git a/test/cel-validation/envoyproxy_test.go b/test/cel-validation/envoyproxy_test.go index b7850a084ad..344acdb69f9 100644 --- a/test/cel-validation/envoyproxy_test.go +++ b/test/cel-validation/envoyproxy_test.go @@ -415,7 +415,7 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ - Host: "0.0.0.0", + Host: ptr.To("0.0.0.0"), Port: 8080, }, }, @@ -443,9 +443,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("foo")), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("foo")), + }, + }, }, }, }, @@ -456,7 +460,7 @@ func TestEnvoyProxyProvider(t *testing.T) { }, } }, - wantErrors: []string{"BackendRef only support Service Kind."}, + wantErrors: []string{"only support Service Kind."}, }, { desc: "accesslog-backendref", @@ -474,10 +478,56 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("Service")), - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + }, + }, + { + desc: "multi-accesslog-backendref", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + AccessLog: &egv1a1.ProxyAccessLog{ + Settings: []egv1a1.ProxyAccessLogSetting{ + { + Format: egv1a1.ProxyAccessLogFormat{ + Type: "Text", + Text: ptr.To("[%START_TIME%]"), + }, + Sinks: []egv1a1.ProxyAccessLogSink{ + { + Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, + OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, }, }, }, @@ -488,6 +538,7 @@ func TestEnvoyProxyProvider(t *testing.T) { }, } }, + wantErrors: []string{"must have at most 1 items"}, }, { desc: "accesslog-backendref-empty-kind", @@ -505,9 +556,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, }, }, }, @@ -519,6 +574,32 @@ func TestEnvoyProxyProvider(t *testing.T) { } }, }, + { + desc: "accesslog-backend-empty", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + AccessLog: &egv1a1.ProxyAccessLog{ + Settings: []egv1a1.ProxyAccessLogSetting{ + { + Format: egv1a1.ProxyAccessLogFormat{ + Type: "Text", + Text: ptr.To("[%START_TIME%]"), + }, + Sinks: []egv1a1.ProxyAccessLogSink{ + { + Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, + OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{}, + }, + }, + }, + }, + }, + }, + } + }, + wantErrors: []string{"host or backendRefs needs to be set"}, + }, { desc: "ProxyMetricSink-with-TypeOpenTelemetry-but-no-openTelemetry", mutate: func(envoy *egv1a1.EnvoyProxy) { @@ -546,7 +627,7 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - Host: "0.0.0.0", + Host: ptr.To("0.0.0.0"), Port: 3217, }, }, @@ -557,6 +638,24 @@ func TestEnvoyProxyProvider(t *testing.T) { }, wantErrors: []string{}, }, + { + desc: "ProxyMetrics-sinks-backend-empty", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + Metrics: &egv1a1.ProxyMetrics{ + Sinks: []egv1a1.ProxyMetricSink{ + { + Type: egv1a1.MetricSinkTypeOpenTelemetry, + OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{}, + }, + }, + }, + }, + } + }, + wantErrors: []string{"host or backendRefs needs to be set"}, + }, { desc: "ProxyMetrics-sinks-backendref", mutate: func(envoy *egv1a1.EnvoyProxy) { @@ -567,10 +666,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("Service")), - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, }, }, }, @@ -581,6 +683,39 @@ func TestEnvoyProxyProvider(t *testing.T) { }, wantErrors: []string{}, }, + { + desc: "ProxyMetrics-sinks-multi-backendref", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + Metrics: &egv1a1.ProxyMetrics{ + Sinks: []egv1a1.ProxyMetricSink{ + { + Type: egv1a1.MetricSinkTypeOpenTelemetry, + OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, + }, + }, + }, + }, + }, + }, + } + }, + wantErrors: []string{"must have at most 1 items"}, + }, { desc: "ProxyMetrics-sinks-backendref-empty-kind", mutate: func(envoy *egv1a1.EnvoyProxy) { @@ -591,9 +726,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, }, }, }, @@ -614,10 +753,14 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("foo")), - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("foo")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, }, }, }, @@ -626,26 +769,30 @@ func TestEnvoyProxyProvider(t *testing.T) { }, } }, - wantErrors: []string{"BackendRef only support Service Kind."}, + wantErrors: []string{"only support Service Kind."}, }, { - desc: "invalid-tracing-backendref", + desc: "invalid-tracing-backendref-invalid-kind", mutate: func(envoy *egv1a1.EnvoyProxy) { envoy.Spec = egv1a1.EnvoyProxySpec{ Telemetry: &egv1a1.ProxyTelemetry{ Tracing: &egv1a1.ProxyTracing{ Provider: egv1a1.TracingProvider{ Type: egv1a1.TracingProviderTypeOpenTelemetry, - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("foo")), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("foo")), + }, + }, }, }, }, }, } }, - wantErrors: []string{"BackendRef only support Service Kind."}, + wantErrors: []string{"only support Service Kind."}, }, { desc: "tracing-backendref-empty-kind", @@ -655,9 +802,13 @@ func TestEnvoyProxyProvider(t *testing.T) { Tracing: &egv1a1.ProxyTracing{ Provider: egv1a1.TracingProvider{ Type: egv1a1.TracingProviderTypeOpenTelemetry, - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, }, }, }, @@ -673,16 +824,66 @@ func TestEnvoyProxyProvider(t *testing.T) { Tracing: &egv1a1.ProxyTracing{ Provider: egv1a1.TracingProvider{ Type: egv1a1.TracingProviderTypeOpenTelemetry, - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("Service")), - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, + }, + }, + }, + }, + } + }, + }, + { + desc: "tracing-multi-backendref", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + Tracing: &egv1a1.ProxyTracing{ + Provider: egv1a1.TracingProvider{ + Type: egv1a1.TracingProviderTypeOpenTelemetry, + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, }, }, }, }, } }, + wantErrors: []string{"must have at most 1 items"}, + }, + { + desc: "tracing-empty-backend", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + Tracing: &egv1a1.ProxyTracing{ + Provider: egv1a1.TracingProvider{ + Type: egv1a1.TracingProviderTypeOpenTelemetry, + }, + }, + }, + } + }, + wantErrors: []string{"host or backendRefs needs to be set"}, }, { desc: "ProxyHpa-maxReplicas-is-required", diff --git a/test/config/gatewayclass.yaml b/test/config/gatewayclass.yaml index 2700448c7d5..b90646a7770 100644 --- a/test/config/gatewayclass.yaml +++ b/test/config/gatewayclass.yaml @@ -22,8 +22,10 @@ spec: sinks: - type: OpenTelemetry openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + backendRefs: + - name: otel-collector + namespace: monitoring + port: 4317 accessLog: settings: - format: @@ -36,14 +38,18 @@ spec: path: /dev/stdout - type: OpenTelemetry openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + backendRefs: + - name: otel-collector + namespace: monitoring + port: 4317 resources: k8s.cluster.name: "envoy-gateway" tracing: provider: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + backendRefs: + - name: otel-collector + namespace: monitoring + port: 4317 customTags: "k8s.cluster.name": type: Literal @@ -86,4 +92,3 @@ spec: kubernetes: envoyDeployment: replicas: 2 - diff --git a/tools/make/golang.mk b/tools/make/golang.mk index 4ea47019f0f..9e4937b3df3 100644 --- a/tools/make/golang.mk +++ b/tools/make/golang.mk @@ -59,7 +59,7 @@ go.testdata.complete: ## Override test ouputdata go.test.coverage: go.test.cel ## Run go unit and integration tests in GitHub Actions @$(LOG_TARGET) KUBEBUILDER_ASSETS="$(shell $(tools/setup-envtest) use $(ENVTEST_K8S_VERSION) -p path)" \ - go test ./... --tags=integration,celvalidation -race -coverprofile=coverage.xml -covermode=atomic + go test ./... --tags=integration -race -coverprofile=coverage.xml -covermode=atomic .PHONY: go.test.cel go.test.cel: manifests $(tools/setup-envtest) # Run the CEL validation tests From 0b761df11a17ffdb801fcefec634cc6ddac9dae1 Mon Sep 17 00:00:00 2001 From: yigang01 <58393296+yigang01@users.noreply.github.com> Date: Thu, 11 Apr 2024 17:31:54 +0800 Subject: [PATCH 06/10] fix: delete tab character (#3169) Signed-off-by: yigang01 <1769703801@qq.com> Co-authored-by: zirain --- charts/gateway-helm/templates/envoy-gateway-service.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/gateway-helm/templates/envoy-gateway-service.yaml b/charts/gateway-helm/templates/envoy-gateway-service.yaml index b9dd4cd5f22..099129477f7 100644 --- a/charts/gateway-helm/templates/envoy-gateway-service.yaml +++ b/charts/gateway-helm/templates/envoy-gateway-service.yaml @@ -11,4 +11,4 @@ spec: control-plane: envoy-gateway {{- include "eg.selectorLabels" . | nindent 4 }} ports: - {{- .Values.deployment.ports | toYaml | nindent 2 -}} + {{- .Values.deployment.ports | toYaml | nindent 2 -}} From cdab7d53b3dc3d0396b1873e425dd287277d8d82 Mon Sep 17 00:00:00 2001 From: zirain Date: Fri, 12 Apr 2024 12:26:16 +0800 Subject: [PATCH 07/10] docs: move contribution out of version (#3176) * move contirbutions out of versions Signed-off-by: zirain * remove pre Signed-off-by: zirain * fix site links Signed-off-by: zirain * fix README Signed-off-by: zirain * nit Signed-off-by: zirain --------- Signed-off-by: zirain --- README.md | 10 +- site/content/en/_index.md | 4 +- site/content/en/announcements/_index.md | 2 +- .../en/blog/news/1.0-release/1.0-release.md | 4 +- .../{latest => }/contributions/CODEOWNERS.md | 0 .../contributions/CODE_OF_CONDUCT.md | 0 .../contributions/CONTRIBUTING.md | 4 +- .../en/{latest => }/contributions/DEVELOP.md | 2 +- .../en/{latest => }/contributions/DOCS.md | 0 .../{latest => }/contributions/RELEASING.md | 0 site/content/en/contributions/_index.md | 8 + .../contributions/design/_index.md | 0 .../contributions/design/accesslog.md | 0 .../design/backend-traffic-policy.md | 0 .../contributions/design/bootstrap.md | 2 +- .../design/client-traffic-policy.md | 0 .../contributions/design/config-api.md | 0 .../contributions/design/eg-metrics.md | 0 .../contributions/design/egctl.md | 0 .../design/envoy-extension-policy.md | 2 +- .../design/envoy-patch-policy.md | 8 +- .../design/extending-envoy-gateway.md | 4 +- .../design/gatewayapi-translator.md | 0 .../contributions/design/goals.md | 0 .../design/local-envoy-gateway.md | 0 .../contributions/design/metrics.md | 0 .../contributions/design/pprof.md | 0 .../contributions/design/rate-limit.md | 0 .../contributions/design/security-policy.md | 0 .../contributions/design/system-design.md | 0 .../contributions/design/tcp-udp-design.md | 0 .../contributions/design/tracing.md | 0 .../contributions/design/watching.md | 0 .../en/{latest => }/contributions/roadmap.md | 0 site/content/en/latest/_index.md | 2 +- .../content/en/latest/contributions/_index.md | 5 - .../latest/contributions/design/bootstrap.md | 381 --------------- .../design/envoy-patch-policy.md | 176 ------- .../content/en/latest/install/install-helm.md | 2 +- .../content/en/latest/install/install-yaml.md | 2 +- site/content/en/latest/tasks/quickstart.md | 2 +- .../en/latest/tasks/security/basic-auth.md | 4 +- site/content/en/latest/tasks/security/cors.md | 4 +- .../en/latest/tasks/security/ext-auth.md | 4 +- .../tasks/security/jwt-authentication.md | 4 +- site/content/en/latest/tasks/security/oidc.md | 4 +- .../latest/tasks/security/secure-gateways.md | 2 +- .../en/latest/tasks/security/threat-model.md | 54 +-- .../latest/tasks/security/tls-passthrough.md | 2 +- .../tasks/traffic/gatewayapi-support.md | 4 +- .../en/latest/tasks/traffic/udp-routing.md | 2 +- .../content/en/v0.5.0/install/install-helm.md | 2 +- .../content/en/v0.6.0/install/install-helm.md | 2 +- .../content/en/v0.6.0/install/install-yaml.md | 2 +- site/content/en/v1.0.1/_index.md | 2 +- .../en/v1.0.1/contributions/CODEOWNERS.md | 21 - .../v1.0.1/contributions/CODE_OF_CONDUCT.md | 6 - .../en/v1.0.1/contributions/CONTRIBUTING.md | 190 -------- .../en/v1.0.1/contributions/DEVELOP.md | 163 ------- site/content/en/v1.0.1/contributions/DOCS.md | 69 --- .../en/v1.0.1/contributions/RELEASING.md | 255 ---------- .../content/en/v1.0.1/contributions/_index.md | 5 - .../en/v1.0.1/contributions/design/_index.md | 5 - .../v1.0.1/contributions/design/accesslog.md | 243 ---------- .../design/backend-traffic-policy.md | 156 ------ .../design/client-traffic-policy.md | 114 ----- .../v1.0.1/contributions/design/config-api.md | 353 -------------- .../v1.0.1/contributions/design/eg-metrics.md | 233 --------- .../en/v1.0.1/contributions/design/egctl.md | 59 --- .../design/extending-envoy-gateway.md | 327 ------------- .../design/gatewayapi-translator.md | 253 ---------- .../en/v1.0.1/contributions/design/goals.md | 91 ---- .../design/local-envoy-gateway.md | 52 -- .../en/v1.0.1/contributions/design/metrics.md | 117 ----- .../en/v1.0.1/contributions/design/pprof.md | 70 --- .../v1.0.1/contributions/design/rate-limit.md | 447 ------------------ .../contributions/design/security-policy.md | 115 ----- .../contributions/design/system-design.md | 173 ------- .../contributions/design/tcp-udp-design.md | 52 -- .../en/v1.0.1/contributions/design/tracing.md | 166 ------- .../v1.0.1/contributions/design/watching.md | 120 ----- .../en/v1.0.1/contributions/roadmap.md | 96 ---- .../content/en/v1.0.1/install/install-helm.md | 2 +- .../content/en/v1.0.1/install/install-yaml.md | 2 +- site/content/en/v1.0.1/tasks/quickstart.md | 2 +- .../en/v1.0.1/tasks/security/basic-auth.md | 4 +- site/content/en/v1.0.1/tasks/security/cors.md | 4 +- .../en/v1.0.1/tasks/security/ext-auth.md | 4 +- .../tasks/security/jwt-authentication.md | 4 +- site/content/en/v1.0.1/tasks/security/oidc.md | 4 +- .../v1.0.1/tasks/security/secure-gateways.md | 2 +- .../en/v1.0.1/tasks/security/threat-model.md | 54 +-- .../v1.0.1/tasks/security/tls-passthrough.md | 2 +- .../tasks/traffic/gatewayapi-support.md | 4 +- .../en/v1.0.1/tasks/traffic/udp-routing.md | 2 +- site/content/zh/_index.md | 5 +- site/hugo.toml | 12 +- 97 files changed, 130 insertions(+), 4640 deletions(-) rename site/content/en/{latest => }/contributions/CODEOWNERS.md (100%) rename site/content/en/{latest => }/contributions/CODE_OF_CONDUCT.md (100%) rename site/content/en/{latest => }/contributions/CONTRIBUTING.md (98%) rename site/content/en/{latest => }/contributions/DEVELOP.md (99%) rename site/content/en/{latest => }/contributions/DOCS.md (100%) rename site/content/en/{latest => }/contributions/RELEASING.md (100%) create mode 100644 site/content/en/contributions/_index.md rename site/content/en/{latest => }/contributions/design/_index.md (100%) rename site/content/en/{latest => }/contributions/design/accesslog.md (100%) rename site/content/en/{latest => }/contributions/design/backend-traffic-policy.md (100%) rename site/content/en/{v1.0.1 => }/contributions/design/bootstrap.md (99%) rename site/content/en/{latest => }/contributions/design/client-traffic-policy.md (100%) rename site/content/en/{latest => }/contributions/design/config-api.md (100%) rename site/content/en/{latest => }/contributions/design/eg-metrics.md (100%) rename site/content/en/{latest => }/contributions/design/egctl.md (100%) rename site/content/en/{latest => }/contributions/design/envoy-extension-policy.md (98%) rename site/content/en/{v1.0.1 => }/contributions/design/envoy-patch-policy.md (95%) rename site/content/en/{latest => }/contributions/design/extending-envoy-gateway.md (99%) rename site/content/en/{latest => }/contributions/design/gatewayapi-translator.md (100%) rename site/content/en/{latest => }/contributions/design/goals.md (100%) rename site/content/en/{latest => }/contributions/design/local-envoy-gateway.md (100%) rename site/content/en/{latest => }/contributions/design/metrics.md (100%) rename site/content/en/{latest => }/contributions/design/pprof.md (100%) rename site/content/en/{latest => }/contributions/design/rate-limit.md (100%) rename site/content/en/{latest => }/contributions/design/security-policy.md (100%) rename site/content/en/{latest => }/contributions/design/system-design.md (100%) rename site/content/en/{latest => }/contributions/design/tcp-udp-design.md (100%) rename site/content/en/{latest => }/contributions/design/tracing.md (100%) rename site/content/en/{latest => }/contributions/design/watching.md (100%) rename site/content/en/{latest => }/contributions/roadmap.md (100%) delete mode 100644 site/content/en/latest/contributions/_index.md delete mode 100644 site/content/en/latest/contributions/design/bootstrap.md delete mode 100644 site/content/en/latest/contributions/design/envoy-patch-policy.md delete mode 100644 site/content/en/v1.0.1/contributions/CODEOWNERS.md delete mode 100644 site/content/en/v1.0.1/contributions/CODE_OF_CONDUCT.md delete mode 100644 site/content/en/v1.0.1/contributions/CONTRIBUTING.md delete mode 100644 site/content/en/v1.0.1/contributions/DEVELOP.md delete mode 100644 site/content/en/v1.0.1/contributions/DOCS.md delete mode 100644 site/content/en/v1.0.1/contributions/RELEASING.md delete mode 100644 site/content/en/v1.0.1/contributions/_index.md delete mode 100644 site/content/en/v1.0.1/contributions/design/_index.md delete mode 100644 site/content/en/v1.0.1/contributions/design/accesslog.md delete mode 100644 site/content/en/v1.0.1/contributions/design/backend-traffic-policy.md delete mode 100644 site/content/en/v1.0.1/contributions/design/client-traffic-policy.md delete mode 100644 site/content/en/v1.0.1/contributions/design/config-api.md delete mode 100644 site/content/en/v1.0.1/contributions/design/eg-metrics.md delete mode 100644 site/content/en/v1.0.1/contributions/design/egctl.md delete mode 100644 site/content/en/v1.0.1/contributions/design/extending-envoy-gateway.md delete mode 100644 site/content/en/v1.0.1/contributions/design/gatewayapi-translator.md delete mode 100644 site/content/en/v1.0.1/contributions/design/goals.md delete mode 100644 site/content/en/v1.0.1/contributions/design/local-envoy-gateway.md delete mode 100644 site/content/en/v1.0.1/contributions/design/metrics.md delete mode 100644 site/content/en/v1.0.1/contributions/design/pprof.md delete mode 100644 site/content/en/v1.0.1/contributions/design/rate-limit.md delete mode 100644 site/content/en/v1.0.1/contributions/design/security-policy.md delete mode 100644 site/content/en/v1.0.1/contributions/design/system-design.md delete mode 100644 site/content/en/v1.0.1/contributions/design/tcp-udp-design.md delete mode 100644 site/content/en/v1.0.1/contributions/design/tracing.md delete mode 100644 site/content/en/v1.0.1/contributions/design/watching.md delete mode 100644 site/content/en/v1.0.1/contributions/roadmap.md diff --git a/README.md b/README.md index babe462ad38..8529e20b15f 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ Kubernetes-based application gateway. * [Blog][blog] introducing Envoy Gateway. * [Goals](GOALS.md) -* [Quickstart](https://gateway.envoyproxy.io/latest/user/quickstart/) to use Envoy Gateway in a few simple steps. -* [Roadmap](https://gateway.envoyproxy.io/latest/contributions/roadmap/) +* [Quickstart](https://gateway.envoyproxy.io/latest/tasks/quickstart/) to use Envoy Gateway in a few simple steps. +* [Roadmap](https://gateway.envoyproxy.io/contributions/roadmap/) ## Contact @@ -22,9 +22,9 @@ Kubernetes-based application gateway. ## Contributing -* [Code of conduct](https://gateway.envoyproxy.io/latest/contributions/code_of_conduct/) -* [Contributing guide](https://gateway.envoyproxy.io/latest/contributions/contributing/) -* [Developer guide](https://gateway.envoyproxy.io/latest/contributions/develop/) +* [Code of conduct](/CODE_OF_CONDUCT) +* [Contributing guide](https://gateway.envoyproxy.io/contributions/contributing/) +* [Developer guide](https://gateway.envoyproxy.io/contributions/develop/) ## Community Meeting diff --git a/site/content/en/_index.md b/site/content/en/_index.md index e453eec5789..dd4456c47ac 100644 --- a/site/content/en/_index.md +++ b/site/content/en/_index.md @@ -6,7 +6,7 @@ title: Envoy Gateway GET STARTED - + CONTRIBUTING

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

@@ -66,7 +66,7 @@ Try Envoy Gateway in GitHub Releases {{% /blocks/feature %}} {{% blocks/feature icon="fab fa-github" title="Contributions Welcome!" - url="/latest/contributions/" %}} + url="/contributions/" %}} We do a [Pull Request](https://github.com/envoyproxy/gateway/pulls) contributions workflow on **GitHub**. {{% /blocks/feature %}} diff --git a/site/content/en/announcements/_index.md b/site/content/en/announcements/_index.md index 89da20bbadc..3c4fe9a2f7d 100644 --- a/site/content/en/announcements/_index.md +++ b/site/content/en/announcements/_index.md @@ -51,5 +51,5 @@ In order to align with the Envoy Proxy [release schedule][], Envoy Gateway relea | 0.6.0 | 2023/10/22 | 2023/11/02 | +10 days | 2024/05/02 | [v2.0.0 spec]: https://semver.org/spec/v2.0.0.html -[release guide]: ../latest/contributions/releasing +[release guide]: ../contributions/releasing [release schedule]: https://github.com/envoyproxy/envoy/blob/main/RELEASES.md#major-release-schedule 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 c0546812d43..5711ee83b91 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 @@ -58,8 +58,8 @@ Following the 1.0 release, we’ll be focusing on: * **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](/v1.0.1/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 +* **Outside of Kubernetes**: Running Envoy Gateway in non-k8s environments - this has been an [explicit goal](/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](/v1.0.1/tasks/operations/egctl/) ## Get Started -If you’ve been looking to use Envoy as a Gateway, check out our [quickstart guide](/v1.0.1/tasks/quickstart) and give it a try! If you’re interested in contributing, check out our [guide for getting involved](/v1.0.1/contributions/)! +If you’ve been looking to use Envoy as a Gateway, check out our [quickstart guide](/v1.0.1/tasks/quickstart) and give it a try! If you’re interested in contributing, check out our [guide for getting involved](/contributions/)! diff --git a/site/content/en/latest/contributions/CODEOWNERS.md b/site/content/en/contributions/CODEOWNERS.md similarity index 100% rename from site/content/en/latest/contributions/CODEOWNERS.md rename to site/content/en/contributions/CODEOWNERS.md diff --git a/site/content/en/latest/contributions/CODE_OF_CONDUCT.md b/site/content/en/contributions/CODE_OF_CONDUCT.md similarity index 100% rename from site/content/en/latest/contributions/CODE_OF_CONDUCT.md rename to site/content/en/contributions/CODE_OF_CONDUCT.md diff --git a/site/content/en/latest/contributions/CONTRIBUTING.md b/site/content/en/contributions/CONTRIBUTING.md similarity index 98% rename from site/content/en/latest/contributions/CONTRIBUTING.md rename to site/content/en/contributions/CONTRIBUTING.md index 975a86c85be..6598efb6d47 100644 --- a/site/content/en/latest/contributions/CONTRIBUTING.md +++ b/site/content/en/contributions/CONTRIBUTING.md @@ -49,7 +49,7 @@ to the following guidelines for all code, APIs, and documentation: build. If your PR cannot have 100% coverage for some reason please clearly explain why when you open it. * Any PR that changes user-facing behavior **must** have associated documentation in the [docs](https://github.com/envoyproxy/gateway/tree/main/site) folder of the repo as - well as the [changelog](../releases). + well as the [changelog](./RELEASING). * All code comments and documentation are expected to have proper English grammar and punctuation. If you are not a fluent English speaker (or a bad writer ;-)) please let us know and we will try to find some help but there are no guarantees. @@ -81,7 +81,7 @@ to the following guidelines for all code, APIs, and documentation: ## Maintainer PR Review Policy -* See [CODEOWNERS.md](../codeowners) for the current list of maintainers. +* See [CODEOWNERS.md](./codeowners) for the current list of maintainers. * A maintainer representing a different affiliation from the PR owner is required to review and approve the PR. * When the project matures, it is expected that a "domain expert" for the code the PR touches should diff --git a/site/content/en/latest/contributions/DEVELOP.md b/site/content/en/contributions/DEVELOP.md similarity index 99% rename from site/content/en/latest/contributions/DEVELOP.md rename to site/content/en/contributions/DEVELOP.md index 83702cd81d6..5006f04d995 100644 --- a/site/content/en/latest/contributions/DEVELOP.md +++ b/site/content/en/contributions/DEVELOP.md @@ -158,6 +158,6 @@ and is hosted in the repo. [Envoy admin interface]: https://www.envoyproxy.io/docs/envoy/latest/operations/admin#operations-admin-interface [jwt]: https://tools.ietf.org/html/rfc7519 [jwks]: https://tools.ietf.org/html/rfc7517 -[request authentication]: ../tasks/security/jwt-authentication +[request authentication]: ../latest/tasks/security/jwt-authentication [JWT Debugger]: https://jwt.io/ [JWK Creator]: https://russelldavies.github.io/jwk-creator/ diff --git a/site/content/en/latest/contributions/DOCS.md b/site/content/en/contributions/DOCS.md similarity index 100% rename from site/content/en/latest/contributions/DOCS.md rename to site/content/en/contributions/DOCS.md diff --git a/site/content/en/latest/contributions/RELEASING.md b/site/content/en/contributions/RELEASING.md similarity index 100% rename from site/content/en/latest/contributions/RELEASING.md rename to site/content/en/contributions/RELEASING.md diff --git a/site/content/en/contributions/_index.md b/site/content/en/contributions/_index.md new file mode 100644 index 00000000000..fc9a0518c9b --- /dev/null +++ b/site/content/en/contributions/_index.md @@ -0,0 +1,8 @@ ++++ +title = "Get Involved" +description = "This section includes contents related to Contributions" +linktitle = "Get Involved" + +[[cascade]] +type = "docs" ++++ \ No newline at end of file diff --git a/site/content/en/latest/contributions/design/_index.md b/site/content/en/contributions/design/_index.md similarity index 100% rename from site/content/en/latest/contributions/design/_index.md rename to site/content/en/contributions/design/_index.md diff --git a/site/content/en/latest/contributions/design/accesslog.md b/site/content/en/contributions/design/accesslog.md similarity index 100% rename from site/content/en/latest/contributions/design/accesslog.md rename to site/content/en/contributions/design/accesslog.md diff --git a/site/content/en/latest/contributions/design/backend-traffic-policy.md b/site/content/en/contributions/design/backend-traffic-policy.md similarity index 100% rename from site/content/en/latest/contributions/design/backend-traffic-policy.md rename to site/content/en/contributions/design/backend-traffic-policy.md diff --git a/site/content/en/v1.0.1/contributions/design/bootstrap.md b/site/content/en/contributions/design/bootstrap.md similarity index 99% rename from site/content/en/v1.0.1/contributions/design/bootstrap.md rename to site/content/en/contributions/design/bootstrap.md index c0581347a24..55f31d2440e 100644 --- a/site/content/en/v1.0.1/contributions/design/bootstrap.md +++ b/site/content/en/contributions/design/bootstrap.md @@ -376,6 +376,6 @@ spec: ``` [Issue 31]: https://github.com/envoyproxy/gateway/issues/31 -[EnvoyProxy]: ../../api/extension_types#envoyproxy +[EnvoyProxy]: ../../latest/api/extension_types#envoyproxy [GatewayClass]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass [parametersRef]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.ParametersReference diff --git a/site/content/en/latest/contributions/design/client-traffic-policy.md b/site/content/en/contributions/design/client-traffic-policy.md similarity index 100% rename from site/content/en/latest/contributions/design/client-traffic-policy.md rename to site/content/en/contributions/design/client-traffic-policy.md diff --git a/site/content/en/latest/contributions/design/config-api.md b/site/content/en/contributions/design/config-api.md similarity index 100% rename from site/content/en/latest/contributions/design/config-api.md rename to site/content/en/contributions/design/config-api.md diff --git a/site/content/en/latest/contributions/design/eg-metrics.md b/site/content/en/contributions/design/eg-metrics.md similarity index 100% rename from site/content/en/latest/contributions/design/eg-metrics.md rename to site/content/en/contributions/design/eg-metrics.md diff --git a/site/content/en/latest/contributions/design/egctl.md b/site/content/en/contributions/design/egctl.md similarity index 100% rename from site/content/en/latest/contributions/design/egctl.md rename to site/content/en/contributions/design/egctl.md diff --git a/site/content/en/latest/contributions/design/envoy-extension-policy.md b/site/content/en/contributions/design/envoy-extension-policy.md similarity index 98% rename from site/content/en/latest/contributions/design/envoy-extension-policy.md rename to site/content/en/contributions/design/envoy-extension-policy.md index ffd5c2751bb..4bda1eb85ab 100644 --- a/site/content/en/latest/contributions/design/envoy-extension-policy.md +++ b/site/content/en/contributions/design/envoy-extension-policy.md @@ -158,6 +158,6 @@ Here is a list of features that can be included in this API [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 Patch Policy]: ../../api/extension_types#envoypatchpolicy +[Envoy Patch Policy]: ../../latest/api/extension_types#envoypatchpolicy [Envoy Extension Manager]: ./extending-envoy-gateway [Alternatives]: #Alternatives diff --git a/site/content/en/v1.0.1/contributions/design/envoy-patch-policy.md b/site/content/en/contributions/design/envoy-patch-policy.md similarity index 95% rename from site/content/en/v1.0.1/contributions/design/envoy-patch-policy.md rename to site/content/en/contributions/design/envoy-patch-policy.md index 343e6bab1e4..2fb2bcba17d 100644 --- a/site/content/en/v1.0.1/contributions/design/envoy-patch-policy.md +++ b/site/content/en/contributions/design/envoy-patch-policy.md @@ -167,10 +167,10 @@ patches will work. [Gateway API]: https://gateway-api.sigs.k8s.io/ [Kubernetes]: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/ [Kustomize]: https://github.com/kubernetes-sigs/kustomize/blob/master/examples/jsonpatch.md -[Extension APIs]: ../../api/extension_types/ +[Extension APIs]: ../../latest/api/extension_types [RateLimit]: ./rate-limit -[EnvoyGateway]: ../../api/extension_types#envoygateway +[EnvoyGateway]: ../../latest/api/extension_types#envoygateway [Extending the Control Plane]: ./extending-envoy-gateway [EnvoyFilter]: https://istio.io/latest/docs/reference/config/networking/envoy-filter -[egctl x translate]: ../../tasks/operations/egctl#egctl-experimental-translate -[Bootstrap configuration using EnvoyProxy API]: ../../tasks/operations/customize-envoyproxy#customize-envoyproxy-bootstrap-config +[egctl x translate]: ../../latest/tasks/operations/egctl#egctl-experimental-translate +[Bootstrap configuration using EnvoyProxy API]: ../../latest/tasks/operations/customize-envoyproxy#customize-envoyproxy-bootstrap-config diff --git a/site/content/en/latest/contributions/design/extending-envoy-gateway.md b/site/content/en/contributions/design/extending-envoy-gateway.md similarity index 99% rename from site/content/en/latest/contributions/design/extending-envoy-gateway.md rename to site/content/en/contributions/design/extending-envoy-gateway.md index 0b549460b65..84c9755b179 100644 --- a/site/content/en/latest/contributions/design/extending-envoy-gateway.md +++ b/site/content/en/contributions/design/extending-envoy-gateway.md @@ -316,10 +316,10 @@ Extending Envoy Gateway by using an external extension server which makes use of [Envoy specific configuration (xDS)]: https://www.envoyproxy.io/docs/envoy/v1.25.1/configuration/configuration [v1]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1 [rate limiting]: ./rate-limit -[authentication]: ../../tasks/security/jwt-authentication +[authentication]: ../../latest/tasks/security/jwt-authentication [HTTPRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRoute [GRPCRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRoute -[EnvoyGateway config]: ../../api/extension_types/#envoygateway +[EnvoyGateway config]: ../../latest/api/extension_types#envoygateway [controller-runtime]: https://github.com/kubernetes-sigs/controller-runtime [Unstructured]: https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured [Listener]: https://www.envoyproxy.io/docs/envoy/v1.23.0/api-v3/config/listener/v3/listener.proto#config-listener-v3-listener diff --git a/site/content/en/latest/contributions/design/gatewayapi-translator.md b/site/content/en/contributions/design/gatewayapi-translator.md similarity index 100% rename from site/content/en/latest/contributions/design/gatewayapi-translator.md rename to site/content/en/contributions/design/gatewayapi-translator.md diff --git a/site/content/en/latest/contributions/design/goals.md b/site/content/en/contributions/design/goals.md similarity index 100% rename from site/content/en/latest/contributions/design/goals.md rename to site/content/en/contributions/design/goals.md diff --git a/site/content/en/latest/contributions/design/local-envoy-gateway.md b/site/content/en/contributions/design/local-envoy-gateway.md similarity index 100% rename from site/content/en/latest/contributions/design/local-envoy-gateway.md rename to site/content/en/contributions/design/local-envoy-gateway.md diff --git a/site/content/en/latest/contributions/design/metrics.md b/site/content/en/contributions/design/metrics.md similarity index 100% rename from site/content/en/latest/contributions/design/metrics.md rename to site/content/en/contributions/design/metrics.md diff --git a/site/content/en/latest/contributions/design/pprof.md b/site/content/en/contributions/design/pprof.md similarity index 100% rename from site/content/en/latest/contributions/design/pprof.md rename to site/content/en/contributions/design/pprof.md diff --git a/site/content/en/latest/contributions/design/rate-limit.md b/site/content/en/contributions/design/rate-limit.md similarity index 100% rename from site/content/en/latest/contributions/design/rate-limit.md rename to site/content/en/contributions/design/rate-limit.md diff --git a/site/content/en/latest/contributions/design/security-policy.md b/site/content/en/contributions/design/security-policy.md similarity index 100% rename from site/content/en/latest/contributions/design/security-policy.md rename to site/content/en/contributions/design/security-policy.md diff --git a/site/content/en/latest/contributions/design/system-design.md b/site/content/en/contributions/design/system-design.md similarity index 100% rename from site/content/en/latest/contributions/design/system-design.md rename to site/content/en/contributions/design/system-design.md diff --git a/site/content/en/latest/contributions/design/tcp-udp-design.md b/site/content/en/contributions/design/tcp-udp-design.md similarity index 100% rename from site/content/en/latest/contributions/design/tcp-udp-design.md rename to site/content/en/contributions/design/tcp-udp-design.md diff --git a/site/content/en/latest/contributions/design/tracing.md b/site/content/en/contributions/design/tracing.md similarity index 100% rename from site/content/en/latest/contributions/design/tracing.md rename to site/content/en/contributions/design/tracing.md diff --git a/site/content/en/latest/contributions/design/watching.md b/site/content/en/contributions/design/watching.md similarity index 100% rename from site/content/en/latest/contributions/design/watching.md rename to site/content/en/contributions/design/watching.md diff --git a/site/content/en/latest/contributions/roadmap.md b/site/content/en/contributions/roadmap.md similarity index 100% rename from site/content/en/latest/contributions/roadmap.md rename to site/content/en/contributions/roadmap.md diff --git a/site/content/en/latest/_index.md b/site/content/en/latest/_index.md index 567b43bfe36..ea08d244d31 100644 --- a/site/content/en/latest/_index.md +++ b/site/content/en/latest/_index.md @@ -9,7 +9,7 @@ type = "docs" {{% alert title="Note" color="primary" %}} -This project is under **active** development. Many features are not complete. We would love for you to [Get Involved](contributions/)! +This project is under **active** development. Many features are not complete. We would love for you to [Get Involved](/contributions)! {{% /alert %}} diff --git a/site/content/en/latest/contributions/_index.md b/site/content/en/latest/contributions/_index.md deleted file mode 100644 index 1d3037e609e..00000000000 --- a/site/content/en/latest/contributions/_index.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Get Involved -description: "This section includes contents related to Contributions" -weight: 100 ---- diff --git a/site/content/en/latest/contributions/design/bootstrap.md b/site/content/en/latest/contributions/design/bootstrap.md deleted file mode 100644 index c0581347a24..00000000000 --- a/site/content/en/latest/contributions/design/bootstrap.md +++ /dev/null @@ -1,381 +0,0 @@ ---- -title: "Bootstrap Design" ---- - -## Overview - -[Issue 31][] specifies the need for allowing advanced users to specify their custom -Envoy Bootstrap configuration rather than using the default Bootstrap configuration -defined in Envoy Gateway. This allows advanced users to extend Envoy Gateway and -support their custom use cases such setting up tracing and stats configuration -that is not supported by Envoy Gateway. - -## Goals - -* Define an API field to allow a user to specify a custom Bootstrap -* Provide tooling to allow the user to generate the default Bootstrap configuration - as well as validate their custom Bootstrap. - -## Non Goals - -* Allow user to configure only a section of the Bootstrap - -## API - -Leverage the existing [EnvoyProxy][] resource which can be attached to the [GatewayClass][] using -the [parametersRef][] field, and define a `Bootstrap` field within the resource. If this field is set, -the value is used as the Bootstrap configuration for all managed Envoy Proxies created by Envoy Gateway. - -```go -// EnvoyProxySpec defines the desired state of EnvoyProxy. -type EnvoyProxySpec struct { - ...... - // Bootstrap defines the Envoy Bootstrap as a YAML string. - // Visit https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-msg-config-bootstrap-v3-bootstrap - // to learn more about the syntax. - // If set, this is the Bootstrap configuration used for the managed Envoy Proxy fleet instead of the default Bootstrap configuration - // set by Envoy Gateway. - // Some fields within the Bootstrap that are required to communicate with the xDS Server (Envoy Gateway) and receive xDS resources - // from it are not configurable and will result in the `EnvoyProxy` resource being rejected. - // Backward compatibility across minor versions is not guaranteed. - // We strongly recommend using `egctl x translate` to generate a `EnvoyProxy` resource with the `Bootstrap` field set to the default - // Bootstrap configuration used. You can edit this configuration, and rerun `egctl x translate` to ensure there are no validation errors. - // - // +optional - Bootstrap *string `json:"bootstrap,omitempty"` -} -``` - -## Tooling - -A CLI tool `egctl x translate` will be provided to the user to help generate a working Bootstrap configuration. -Here is an example where a user inputs a `GatewayClass` and the CLI generates the `EnvoyProxy` resource with the `Bootstrap` field populated. - -``` -cat <// - name: default/eg/http - operation: - op: add - path: "/default_filter_chain/filters/0/typed_config/http_filters/0" - value: - name: "envoy.filters.http.ratelimit" - typed_config: - "@type": "type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit" - domain: "eag-ratelimit" - failure_mode_deny: true - timeout: 1s - rate_limit_service: - grpc_service: - envoy_grpc: - cluster_name: rate-limit-cluster - transport_api_version: V3 - - type: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration" - # The route name is of the form // - name: default/eg/http - operation: - op: add - path: "/virtual_hosts/0/rate_limits" - value: - - actions: - - remote_address: {} - - type: "type.googleapis.com/envoy.config.cluster.v3.Cluster" - name: rate-limit-cluster - operation: - op: add - path: "" - value: - name: rate-limit-cluster - type: STRICT_DNS - connect_timeout: 10s - lb_policy: ROUND_ROBIN - http2_protocol_options: {} - load_assignment: - cluster_name: rate-limit-cluster - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: ratelimit.svc.cluster.local - port_value: 8081 -``` - - -## Verification -* Offline - Leverage [egctl x translate][] to ensure that the `EnvoyPatchPolicy` can be successfully applied and the desired -output xDS is created. -* Runtime - Use the `Status` field within `EnvoyPatchPolicy` to highlight whether the patch was applied successfully or not. - -## State of the World -* Istio - Supports the [EnvoyFilter][] API which allows users to customize the output xDS using patches and proto based merge -semantics. - -## Design Decisions -* This API will only support a single `targetRef` and can bind to only a `Gateway` or `GatewayClass` resource. This simplifies reasoning of how -patches will work. -* This API will always be an experimental API and cannot be graduated into a stable API because Envoy Gateway cannot garuntee - * that the naming scheme for the generated resources names will not change across releases - * that the underlying Envoy Proxy API will not change across releases -* This API needs to be explicitly enabled using the [EnvoyGateway][] API - -## Open Questions -* Should the value only support JSON or YAML as well (which is a JSON superset) ? - -## Alternatives -* Users can customize the Envoy [Bootstrap configuration using EnvoyProxy API][] and provide static xDS configuration. -* Users can extend functionality by [Extending the Control Plane][] and adding gRPC hooks to modify the generated xDS configuration. - - - -[Direct Policy Attachment]: https://gateway-api.sigs.k8s.io/references/policy-attachment/#direct-policy-attachment -[RFC 6902]: https://datatracker.ietf.org/doc/html/rfc6902 -[Gateway API]: https://gateway-api.sigs.k8s.io/ -[Kubernetes]: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/ -[Kustomize]: https://github.com/kubernetes-sigs/kustomize/blob/master/examples/jsonpatch.md -[Extension APIs]: ../../api/extension_types/ -[RateLimit]: ./rate-limit -[EnvoyGateway]: ../../api/extension_types#envoygateway -[Extending the Control Plane]: ./extending-envoy-gateway -[EnvoyFilter]: https://istio.io/latest/docs/reference/config/networking/envoy-filter -[egctl x translate]: ../../tasks/operations/egctl#egctl-experimental-translate -[Bootstrap configuration using EnvoyProxy API]: ../../tasks/operations/customize-envoyproxy#customize-envoyproxy-bootstrap-config diff --git a/site/content/en/latest/install/install-helm.md b/site/content/en/latest/install/install-helm.md index 50c372d3e2a..69efd45390c 100644 --- a/site/content/en/latest/install/install-helm.md +++ b/site/content/en/latest/install/install-helm.md @@ -28,7 +28,7 @@ You can visit [Envoy Gateway Helm Chart](https://hub.docker.com/r/envoyproxy/gat Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one. {{% alert title="Developer Guide" color="primary" %}} -Refer to the [Developer Guide](/latest/contributions/develop) to learn more. +Refer to the [Developer Guide](../../contributions/develop) to learn more. {{% /alert %}} Install the Gateway API CRDs and Envoy Gateway: diff --git a/site/content/en/latest/install/install-yaml.md b/site/content/en/latest/install/install-yaml.md index 4fc9b38b0dd..b8b02582b2d 100644 --- a/site/content/en/latest/install/install-yaml.md +++ b/site/content/en/latest/install/install-yaml.md @@ -25,7 +25,7 @@ Refer to the [Version Compatibility Matrix](./matrix) to learn more. Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one. {{% alert title="Developer Guide" color="primary" %}} -Refer to the [Developer Guide](/latest/contributions/develop) to learn more. +Refer to the [Developer Guide](../../contributions/develop) to learn more. {{% /alert %}} 1. In your terminal, run the following command: diff --git a/site/content/en/latest/tasks/quickstart.md b/site/content/en/latest/tasks/quickstart.md index 980190b2bbf..4fe91fb3405 100644 --- a/site/content/en/latest/tasks/quickstart.md +++ b/site/content/en/latest/tasks/quickstart.md @@ -101,4 +101,4 @@ helm uninstall eg -n envoy-gateway-system ## Next Steps -Checkout the [Developer Guide](../contributions/develop) to get involved in the project. +Checkout the [Developer Guide](../../contributions/develop) to get involved in the project. diff --git a/site/content/en/latest/tasks/security/basic-auth.md b/site/content/en/latest/tasks/security/basic-auth.md index 28c3ca53d5c..aa475de189e 100644 --- a/site/content/en/latest/tasks/security/basic-auth.md +++ b/site/content/en/latest/tasks/security/basic-auth.md @@ -188,9 +188,9 @@ kubectl delete secret/example-cert ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [http Basic authentication]: https://tools.ietf.org/html/rfc2617 [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/latest/tasks/security/cors.md b/site/content/en/latest/tasks/security/cors.md index 1abbe77a737..aa2994200a5 100644 --- a/site/content/en/latest/tasks/security/cors.md +++ b/site/content/en/latest/tasks/security/cors.md @@ -132,9 +132,9 @@ kubectl delete securitypolicy/cors-example ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [cors]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/latest/tasks/security/ext-auth.md b/site/content/en/latest/tasks/security/ext-auth.md index b3eafd7e0be..223d3b53c4b 100644 --- a/site/content/en/latest/tasks/security/ext-auth.md +++ b/site/content/en/latest/tasks/security/ext-auth.md @@ -304,8 +304,8 @@ kubectl delete backendtlspolicy/grpc-ext-auth-btls ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/latest/tasks/security/jwt-authentication.md b/site/content/en/latest/tasks/security/jwt-authentication.md index 2e129b387f1..8b160403882 100644 --- a/site/content/en/latest/tasks/security/jwt-authentication.md +++ b/site/content/en/latest/tasks/security/jwt-authentication.md @@ -160,9 +160,9 @@ kubectl delete securitypolicy/jwt-example ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [jwt]: https://tools.ietf.org/html/rfc7519 [jwks]: https://tools.ietf.org/html/rfc7517 [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway diff --git a/site/content/en/latest/tasks/security/oidc.md b/site/content/en/latest/tasks/security/oidc.md index 9b168822796..7fce6f9257e 100644 --- a/site/content/en/latest/tasks/security/oidc.md +++ b/site/content/en/latest/tasks/security/oidc.md @@ -155,10 +155,10 @@ kubectl delete httproute/myapp ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. [oidc]: https://openid.net/connect/ [google-oidc]: https://developers.google.com/identity/protocols/oauth2/openid-connect -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/latest/tasks/security/secure-gateways.md b/site/content/en/latest/tasks/security/secure-gateways.md index f1f1f525526..1568cbf3017 100644 --- a/site/content/en/latest/tasks/security/secure-gateways.md +++ b/site/content/en/latest/tasks/security/secure-gateways.md @@ -450,6 +450,6 @@ Refer to the steps mentioned earlier under [Testing in clusters with External Lo ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. [ReferenceGrant]: https://gateway-api.sigs.k8s.io/api-types/referencegrant/ diff --git a/site/content/en/latest/tasks/security/threat-model.md b/site/content/en/latest/tasks/security/threat-model.md index 7fd334e6143..fcf8643e184 100644 --- a/site/content/en/latest/tasks/security/threat-model.md +++ b/site/content/en/latest/tasks/security/threat-model.md @@ -528,7 +528,7 @@ When considering internal threat actors, we chose to follow the [security model] **Threat**: Threat actors establish persistence and move laterally through the cluster unnoticed. - **Recommendation**: Configure [access logging](https://gateway.envoyproxy.io/latest/contributions/design/accesslog/) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout. + **Recommendation**: Configure [access logging](../../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout. Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR). @@ -589,33 +589,33 @@ Set runAsUser and runAsGroup security context options to specific UIDs (e.g., ru ### Identified Threats by Priority -|ID|UID|Category|Risk|Threat|Priority| Recommendation | -|-|-|-|-|-|-|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -|EGTM-001|EGTM-GW-001|Gateway API| Self-signed certificates (which do not comply with PKI best practices) could lead to unauthorised access to the private key associated with the certificate used for inbound TLS termination at Envoy Proxy, compromising the confidentiality and integrity of proxied traffic.

| Compromise of the private key associated with the certificate used for inbound TLS terminating at Envoy Proxy.

|High| The Envoy Gateway quickstart demonstrates how to set up a Secure Gateway using an example where a self-signed root certificate is created using openssl. As stated in the Envoy Gateway documentation, this is not a suitable configuration for Production usage. It is recommended that PKI best practices are followed, whereby certificates are signed by an Intermediary CA which sits underneath an organisational \'offline\' Root CA.

PKI best practices should also apply to the management of client certificates when using mTLS. The Envoy Gateway [mTLS](../security/mutual-tls) task shows how to set up client certificates using self-signed certificates. In the same way as gateway certificates and, as mentioned in the documentation, this configuration should not be used in production environments. | -|EGTM-002|EGTM-CS-001|Container Security| There is a risk that a threat actor could compromise the Kubernetes secret containing the Envoy private key, allowing the attacker to decrypt Envoy Proxy traffic, compromising the confidentiality of proxied traffic.

| Kubernetes secret containing the Envoy private key is compromised and used to decrypt proxied traffic.

|High| Certificate management best practices mandate short-lived key material where practical, meaning that a mechanism for rotation of private keys and certificates is required, along with a way for certificates to be mounted into Envoy containers. If Kubernetes secrets are used, when a certificate expires, the associated secret must be updated, and Envoy containers must be redeployed. Instead of a manual configuration, it is recommended that [cert-manager](https://github.com/cert-manager/cert-manager) is used. | -|EGTM-004|EGTM-K8-002|Container Security| There is a risk that a threat actor could abuse misconfigured RBAC to access the Envoy Gateway ClusterRole (envoy-gateway-role) and use it to expose all secrets across the cluster, thus compromising the confidentiality and integrity of tenant data.

| Compromised Envoy Gateway or misconfigured ClusterRoleBinding (envoy-gateway-rolebinding) to Envoy Gateway ClusterRole (envoy-gateway-role), provides access to resources and secrets in different namespaces.

|High| Users should be aware that Envoy Gateway uses a ClusterRole (envoy-gateway-role) when deployed via the Helm chart, to allow management of Envoy Proxies across different namespaces. This ClusterRole is powerful and includes the ability to read secrets in namespaces which may not be within the purview of Envoy Gateway.

Kubernetes best-practices involve restriction of ClusterRoleBindings, with the use of RoleBindings where possible to limit access per namespace by specifying the namespace in metadata. Namespace isolation reduces the impact of compromise from cluster-scoped roles. Ideally, fine-grained K8s roles should be created per the principle of least privilege to ensure they have the minimum access necessary for role functions.

The pull request \#[1656](https://github.com/envoyproxy/gateway/pull/1656) introduced the use of Roles and RoleBindings in [namespaced mode](https://gateway.envoyproxy.io/latest/api/extension_types/#kuberneteswatchmode). This feature can be leveraged to reduce the amount of permissions required by the Envoy Gateway. | -|EGTM-007|EGTM-EG-002|Envoy Gateway| There is a risk that a threat actor could exploit misconfigured Kubernetes RBAC to create or modify Gateway API resources with no business need, potentially leading to the compromise of the confidentiality, integrity, and availability of resources and traffic within the cluster.

| Unauthorised creation or misconfiguration of Gateway API resources by a threat actor with cluster-scoped access.

|High| Configure the apiGroup and resource fields in RBAC policies to restrict access to [Gateway](https://gateway-api.sigs.k8s.io/) and [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/) resources. Enable namespace isolation by using the namespace field, preventing unauthorised access to gateways in other namespaces. | -|EGTM-009|EGTM-GW-002|Gateway API| There is a risk that a co-tenant misconfigures Gateway or Route resources, compromising the confidentiality, integrity, and availability of routed traffic through Envoy Gateway.

| Malicious or accidental co-tenant misconfiguration of Gateways and Routes associated with other application teams.

|High| Dedicated Envoy Gateways should be provided to each tenant within their respective namespace. A one-to-one relationship should be established between GatewayClass and Gateway resources, meaning that each tenant namespace should have their own GatewayClass watched by a unique Envoy Gateway Controller as defined here in the [Deployment Mode](../operations/deployment-mode) documentation.

Application Admins should have write permissions on the Gateway resource, but only in their specific namespaces, and Application Developers should only hold write permissions on Route resources. To enact this access control schema, follow the [Write Permissions for Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model) described in the Kubernetes Gateway API security model. Examples of secured gateway-route topologies can be found [here](https://gateway-api.sigs.k8s.io/concepts/api-overview/#attaching-routes-to-gateways) within the Kubernetes Gateway API docs.

Optionally, consider a GitOps model, where only the GitOps operator has the permission to deploy or modify custom resources in production. | -|EGTM-014|EGTM-CS-006|Container Security| There is a risk that a supply chain attack on Envoy Gateway results in an arbitrary compromise of the confidentiality, integrity or availability of tenant data.

| Supply chain threat actor introduces malicious code into Envoy Gateway or Proxy.

|High| The Envoy Gateway project should continue to work towards conformance with supply-chain security best practices throughout the project lifecycle (for example, as set out in the [CNCF Software Supply Chain Best Practices Whitepaper](https://github.com/cncf/tag-security/blob/main/supply-chain-security/supply-chain-security-paper/CNCF_SSCP_v1.pdf). Adherence to [Supply-chain Levels for Software Artefacts](https://slsa.dev/) (SLSA) standards is crucial for maintaining the security of the system. Employ version control systems to monitor the source and build platforms and assign responsibility to a specific stakeholder.

Integrate a supply chain security tool such as Sigstore, which provides native capabilities for signing and verifying container images and software artefacts. [Software Bill of Materials](https://www.cisa.gov/sbom) (SBOM), [Vulnerability Exploitability eXchange](https://www.ntia.gov/files/ntia/publications/vex_one-page_summary.pdf) (VEX), and signed artefacts should also be incorporated into the security protocol. | -|EGTM-020|EGTM-CS-009|Container Security| There is a risk that a threat actor exploits an Envoy Proxy vulnerability to remote code execution (RCE) due to out of date or misconfigured Envoy Proxy pod deployment, compromising the confidentiality and integrity of Envoy Proxy along with the availability of the proxy service.

| Deployment of an Envoy Proxy or Gateway image containing exploitable CVEs.

|High| Always use the latest version of the Envoy Proxy image. Regularly check for updates and patch the system as soon as updates become available. Implement a CI/CD pipeline that includes security checks for images and prevents deployment of insecure configurations. A tool such as Snyk can be used to provide container vulnerability scanning to mitigate the risk of known vulnerabilities.

Utilise the [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) controller to enforce [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) and configure the [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) to limit its capabilities per the principle of least privilege. | -|EGTM-022|EGTM-CS-010|Container Security| There is a risk that the OIDC client secret (for OIDC authentication) and user password hashes (for basic authentication) get leaked due to misconfigured RBAC permissions.

| Unauthorised access to the application due to credential leakage.

|High| Ensure that only authorised users and service accounts are able to access secrets. This is especially important in namespaces where SecurityPolicy objects are configured, since those namespaces are the ones to store secrets containing the client secret (in OIDC scenarios) and user password hashes (in basic authentication scenarios).

To do so, minimise the use of ClusterRoles and Roles allowing listing and getting secrets. Perform periodic audits of RBAC permissions. | -|EGTM-023|EGTM-EG-007|Envoy Gateway| There is a risk of unauthorised access due to the use of basic authentication, which does not enforce any password restriction in terms of complexity and length. In addition, password hashes are stored in SHA1 format, which is a deprecated hashing function.

| Unauthorised access to the application due to weak authentication mechanisms.

|High| It is recommended to make use of stronger authentication mechanisms (i.e. JWT authentication and OIDC authentication) instead of basic authentication. These authentication mechanisms have many advantages, such as the use of short-lived credentials and a central management of security policies through the identity provider. | -|EGTM-008|EGTM-EG-003|Envoy Gateway| There is a risk of a threat actor misconfiguring static config and compromising the integrity of Envoy Gateway, ultimately leading to the compromised confidentiality, integrity, or availability of tenant data and cluster resources.

| Accidental or deliberate misconfiguration of static configuration leads to a misconfigured deployment of Envoy Gateway, for example logging parameters could be modified or global rate limiting configuration misconfigured.

|Medium| Implement a GitOps model, utilising Kubernetes\' Role-Based Access Control (RBAC) and adhering to the principle of least privilege to minimise human intervention on the cluster. For instance, tools like [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) can be used for declarative GitOps deployments, ensuring all changes are tracked and reviewed. Additionally, configure your source control management (SCM) system to include mandatory pull request (PR) reviews, commit signing, and protected branches to ensure only authorised changes can be committed to the start-up configuration. | -|EGTM-010|EGTM-CS-005|Container Security| There is a risk that a threat actor exploits a weak pod security context, compromising the CIA of a node and the resources / services which run on it.

| Threat Actor who has compromised a pod exploits weak security context to escape to a node, potentially leading to the compromise of Envoy Proxy or Gateway running on the same node.

|Medium| To mitigate this risk, apply [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) at a minimum of [Baseline](https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline) level to all namespaces, especially those containing Envoy Gateway and Proxy Pods. Pod security standards are implemented through K8s [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) to provide [admission control modes](https://kubernetes.io/docs/concepts/security/pod-security-admission/#pod-security-admission-labels-for-namespaces) (enforce, audit, and warn) for namespaces. Pod security standards can be enforced by namespace labels as shown [here](https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/), to enforce a baseline level of pod security to specific namespaces.

Further enhance the security by implementing a sandboxing solution such as [gVisor](https://gvisor.dev/) for Envoy Gateway and Proxy Pods to isolate the application from the host kernel. This can be set within the runtimeClassName of the Pod specification. | -|EGTM-012|EGTM-GW-004|Gateway API| There is a risk that a threat actor could abuse excessive RBAC privileges to create ReferenceGrant resources. These resources could then be used to create cross-namespace communication, leading to unauthorised access to the application. This could compromise the confidentiality and integrity of resources and configuration in the affected namespaces and potentially disrupt the availability of services that rely on these object references.

| A ReferenceGrant is created, which validates traffic to cross namespace trust boundaries without a valid business reason, such as a route in one tenant\'s namespace referencing a backend in another.

|Medium| Ensure that the ability to create ReferenceGrant resources is restricted to the minimum number of people. Pay special attention to ClusterRoles that allow that action. | +|ID|UID|Category|Risk|Threat|Priority| Recommendation | +|-|-|-|-|-|-|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|EGTM-001|EGTM-GW-001|Gateway API| Self-signed certificates (which do not comply with PKI best practices) could lead to unauthorised access to the private key associated with the certificate used for inbound TLS termination at Envoy Proxy, compromising the confidentiality and integrity of proxied traffic.

| Compromise of the private key associated with the certificate used for inbound TLS terminating at Envoy Proxy.

|High| The Envoy Gateway quickstart demonstrates how to set up a Secure Gateway using an example where a self-signed root certificate is created using openssl. As stated in the Envoy Gateway documentation, this is not a suitable configuration for Production usage. It is recommended that PKI best practices are followed, whereby certificates are signed by an Intermediary CA which sits underneath an organisational \'offline\' Root CA.

PKI best practices should also apply to the management of client certificates when using mTLS. The Envoy Gateway [mTLS](../security/mutual-tls) task shows how to set up client certificates using self-signed certificates. In the same way as gateway certificates and, as mentioned in the documentation, this configuration should not be used in production environments. | +|EGTM-002|EGTM-CS-001|Container Security| There is a risk that a threat actor could compromise the Kubernetes secret containing the Envoy private key, allowing the attacker to decrypt Envoy Proxy traffic, compromising the confidentiality of proxied traffic.

| Kubernetes secret containing the Envoy private key is compromised and used to decrypt proxied traffic.

|High| Certificate management best practices mandate short-lived key material where practical, meaning that a mechanism for rotation of private keys and certificates is required, along with a way for certificates to be mounted into Envoy containers. If Kubernetes secrets are used, when a certificate expires, the associated secret must be updated, and Envoy containers must be redeployed. Instead of a manual configuration, it is recommended that [cert-manager](https://github.com/cert-manager/cert-manager) is used. | +|EGTM-004|EGTM-K8-002|Container Security| There is a risk that a threat actor could abuse misconfigured RBAC to access the Envoy Gateway ClusterRole (envoy-gateway-role) and use it to expose all secrets across the cluster, thus compromising the confidentiality and integrity of tenant data.

| Compromised Envoy Gateway or misconfigured ClusterRoleBinding (envoy-gateway-rolebinding) to Envoy Gateway ClusterRole (envoy-gateway-role), provides access to resources and secrets in different namespaces.

|High| Users should be aware that Envoy Gateway uses a ClusterRole (envoy-gateway-role) when deployed via the Helm chart, to allow management of Envoy Proxies across different namespaces. This ClusterRole is powerful and includes the ability to read secrets in namespaces which may not be within the purview of Envoy Gateway.

Kubernetes best-practices involve restriction of ClusterRoleBindings, with the use of RoleBindings where possible to limit access per namespace by specifying the namespace in metadata. Namespace isolation reduces the impact of compromise from cluster-scoped roles. Ideally, fine-grained K8s roles should be created per the principle of least privilege to ensure they have the minimum access necessary for role functions.

The pull request \#[1656](https://github.com/envoyproxy/gateway/pull/1656) introduced the use of Roles and RoleBindings in [namespaced mode](https://gateway.envoyproxy.io/latest/api/extension_types/#kuberneteswatchmode). This feature can be leveraged to reduce the amount of permissions required by the Envoy Gateway. | +|EGTM-007|EGTM-EG-002|Envoy Gateway| There is a risk that a threat actor could exploit misconfigured Kubernetes RBAC to create or modify Gateway API resources with no business need, potentially leading to the compromise of the confidentiality, integrity, and availability of resources and traffic within the cluster.

| Unauthorised creation or misconfiguration of Gateway API resources by a threat actor with cluster-scoped access.

|High| Configure the apiGroup and resource fields in RBAC policies to restrict access to [Gateway](https://gateway-api.sigs.k8s.io/) and [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/) resources. Enable namespace isolation by using the namespace field, preventing unauthorised access to gateways in other namespaces. | +|EGTM-009|EGTM-GW-002|Gateway API| There is a risk that a co-tenant misconfigures Gateway or Route resources, compromising the confidentiality, integrity, and availability of routed traffic through Envoy Gateway.

| Malicious or accidental co-tenant misconfiguration of Gateways and Routes associated with other application teams.

|High| Dedicated Envoy Gateways should be provided to each tenant within their respective namespace. A one-to-one relationship should be established between GatewayClass and Gateway resources, meaning that each tenant namespace should have their own GatewayClass watched by a unique Envoy Gateway Controller as defined here in the [Deployment Mode](../operations/deployment-mode) documentation.

Application Admins should have write permissions on the Gateway resource, but only in their specific namespaces, and Application Developers should only hold write permissions on Route resources. To enact this access control schema, follow the [Write Permissions for Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model) described in the Kubernetes Gateway API security model. Examples of secured gateway-route topologies can be found [here](https://gateway-api.sigs.k8s.io/concepts/api-overview/#attaching-routes-to-gateways) within the Kubernetes Gateway API docs.

Optionally, consider a GitOps model, where only the GitOps operator has the permission to deploy or modify custom resources in production. | +|EGTM-014|EGTM-CS-006|Container Security| There is a risk that a supply chain attack on Envoy Gateway results in an arbitrary compromise of the confidentiality, integrity or availability of tenant data.

| Supply chain threat actor introduces malicious code into Envoy Gateway or Proxy.

|High| The Envoy Gateway project should continue to work towards conformance with supply-chain security best practices throughout the project lifecycle (for example, as set out in the [CNCF Software Supply Chain Best Practices Whitepaper](https://github.com/cncf/tag-security/blob/main/supply-chain-security/supply-chain-security-paper/CNCF_SSCP_v1.pdf). Adherence to [Supply-chain Levels for Software Artefacts](https://slsa.dev/) (SLSA) standards is crucial for maintaining the security of the system. Employ version control systems to monitor the source and build platforms and assign responsibility to a specific stakeholder.

Integrate a supply chain security tool such as Sigstore, which provides native capabilities for signing and verifying container images and software artefacts. [Software Bill of Materials](https://www.cisa.gov/sbom) (SBOM), [Vulnerability Exploitability eXchange](https://www.ntia.gov/files/ntia/publications/vex_one-page_summary.pdf) (VEX), and signed artefacts should also be incorporated into the security protocol. | +|EGTM-020|EGTM-CS-009|Container Security| There is a risk that a threat actor exploits an Envoy Proxy vulnerability to remote code execution (RCE) due to out of date or misconfigured Envoy Proxy pod deployment, compromising the confidentiality and integrity of Envoy Proxy along with the availability of the proxy service.

| Deployment of an Envoy Proxy or Gateway image containing exploitable CVEs.

|High| Always use the latest version of the Envoy Proxy image. Regularly check for updates and patch the system as soon as updates become available. Implement a CI/CD pipeline that includes security checks for images and prevents deployment of insecure configurations. A tool such as Snyk can be used to provide container vulnerability scanning to mitigate the risk of known vulnerabilities.

Utilise the [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) controller to enforce [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) and configure the [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) to limit its capabilities per the principle of least privilege. | +|EGTM-022|EGTM-CS-010|Container Security| There is a risk that the OIDC client secret (for OIDC authentication) and user password hashes (for basic authentication) get leaked due to misconfigured RBAC permissions.

| Unauthorised access to the application due to credential leakage.

|High| Ensure that only authorised users and service accounts are able to access secrets. This is especially important in namespaces where SecurityPolicy objects are configured, since those namespaces are the ones to store secrets containing the client secret (in OIDC scenarios) and user password hashes (in basic authentication scenarios).

To do so, minimise the use of ClusterRoles and Roles allowing listing and getting secrets. Perform periodic audits of RBAC permissions. | +|EGTM-023|EGTM-EG-007|Envoy Gateway| There is a risk of unauthorised access due to the use of basic authentication, which does not enforce any password restriction in terms of complexity and length. In addition, password hashes are stored in SHA1 format, which is a deprecated hashing function.

| Unauthorised access to the application due to weak authentication mechanisms.

|High| It is recommended to make use of stronger authentication mechanisms (i.e. JWT authentication and OIDC authentication) instead of basic authentication. These authentication mechanisms have many advantages, such as the use of short-lived credentials and a central management of security policies through the identity provider. | +|EGTM-008|EGTM-EG-003|Envoy Gateway| There is a risk of a threat actor misconfiguring static config and compromising the integrity of Envoy Gateway, ultimately leading to the compromised confidentiality, integrity, or availability of tenant data and cluster resources.

| Accidental or deliberate misconfiguration of static configuration leads to a misconfigured deployment of Envoy Gateway, for example logging parameters could be modified or global rate limiting configuration misconfigured.

|Medium| Implement a GitOps model, utilising Kubernetes\' Role-Based Access Control (RBAC) and adhering to the principle of least privilege to minimise human intervention on the cluster. For instance, tools like [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) can be used for declarative GitOps deployments, ensuring all changes are tracked and reviewed. Additionally, configure your source control management (SCM) system to include mandatory pull request (PR) reviews, commit signing, and protected branches to ensure only authorised changes can be committed to the start-up configuration. | +|EGTM-010|EGTM-CS-005|Container Security| There is a risk that a threat actor exploits a weak pod security context, compromising the CIA of a node and the resources / services which run on it.

| Threat Actor who has compromised a pod exploits weak security context to escape to a node, potentially leading to the compromise of Envoy Proxy or Gateway running on the same node.

|Medium| To mitigate this risk, apply [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) at a minimum of [Baseline](https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline) level to all namespaces, especially those containing Envoy Gateway and Proxy Pods. Pod security standards are implemented through K8s [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) to provide [admission control modes](https://kubernetes.io/docs/concepts/security/pod-security-admission/#pod-security-admission-labels-for-namespaces) (enforce, audit, and warn) for namespaces. Pod security standards can be enforced by namespace labels as shown [here](https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/), to enforce a baseline level of pod security to specific namespaces.

Further enhance the security by implementing a sandboxing solution such as [gVisor](https://gvisor.dev/) for Envoy Gateway and Proxy Pods to isolate the application from the host kernel. This can be set within the runtimeClassName of the Pod specification. | +|EGTM-012|EGTM-GW-004|Gateway API| There is a risk that a threat actor could abuse excessive RBAC privileges to create ReferenceGrant resources. These resources could then be used to create cross-namespace communication, leading to unauthorised access to the application. This could compromise the confidentiality and integrity of resources and configuration in the affected namespaces and potentially disrupt the availability of services that rely on these object references.

| A ReferenceGrant is created, which validates traffic to cross namespace trust boundaries without a valid business reason, such as a route in one tenant\'s namespace referencing a backend in another.

|Medium| Ensure that the ability to create ReferenceGrant resources is restricted to the minimum number of people. Pay special attention to ClusterRoles that allow that action. | |EGTM-018|EGTM-GW-006|Gateway API| There is a risk that malicious requests could lead to a Denial of Service (DoS) attack, thereby reducing API gateway availability due to misconfigurations in rate-limiting or load balancing controls, or a lack of route timeout enforcement.

| Reduced API gateway availability due to an attacker\'s maliciously crafted request (e.g., QoD) potentially inducing a Denial of Service (DoS) attack.

|Medium| To ensure high availability and to mitigate potential security threats, adhere to the Envoy Gateway documentation for the configuration of a [rate-limiting](https://gateway.envoyproxy.io/v0.6.0/user/rate-limit/) filter and load balancing.

Further, adhere to best practices for configuring Envoy Proxy as an edge proxy documented [here](https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/edge#configuring-envoy-as-an-edge-proxy) within the EnvoyProxy docs. This involves configuring TCP and HTTP proxies with specific settings, including restricting access to the admin endpoint, setting the [overload manager](https://www.envoyproxy.io/docs/envoy/latest/configuration/operations/overload_manager/overload_manager#config-overload-manager) and [listener](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto#envoy-v3-api-field-config-listener-v3-listener-per-connection-buffer-limit-bytes) / [cluster](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#envoy-v3-api-field-config-cluster-v3-cluster-per-connection-buffer-limit-bytes) buffer limits, enabling [use_remote_address](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-use-remote-address), setting [connection and stream timeouts](https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/timeouts#faq-configuration-timeouts), limiting [maximum concurrent streams](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-max-concurrent-streams), setting [initial stream window size limit](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size), and configuring action on [headers_with_underscores](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-headers-with-underscores-action).

[Path normalisation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-normalize-path) should be enabled to minimise path confusion vulnerabilities. These measures help protect against volumetric threats such as Denial of Service (DoS)nattacks. Utilise custom resources to implement policy attachment, thereby exposing request limit configuration for route types. | -|EGTM-019|EGTM-DP-004|Container Security| There is a risk that replay attacks using stolen or reused JSON Web Tokens (JWTs) can compromise transmission integrity, thereby undermining the confidentiality and integrity of the data plane.

| Transmission integrity is compromised due to replay attacks using stolen or reused JSON Web Tokens (JWTs).

|Medium| Comply with JWT best practices for enhanced security, paying special attention to the use of short-lived tokens, which reduce the window of opportunity for a replay attack. The [exp](https://datatracker.ietf.org/doc/html/rfc7519#page-9) claim can be used to set token expiration times. | -|EGTM-024|EGTM-EG-008|Envoy Gateway| There is a risk of developers getting more privileges than required due to the use of SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy and BackendTrafficPolicy. These resources can be attached to a Gateway resource. Therefore, a developer with permission to deploy them would be able to modify a Gateway configuration by targeting the gateway in the policy manifest. This conflicts with the [Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model), where developers do not have write permissions on Gateways.

| Excessive developer permissions lead to a misconfiguration and/or unauthorised access.

|Medium| Considering the Tenant C scenario (represented in the Architecture Diagram), if a developer can create SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy or BackendTrafficPolicy objects in namespace C, they would be able to modify a Gateway configuration by attaching the policy to the gateway. In such scenarios, it is recommended to either:

a. Create a separate namespace, where developers have no permissions, > to host tenant C\'s gateway. Note that, due to design decisions, > the > SecurityPolicy/EnvoyPatchPolicy/ClientTrafficPolicy/BackendTrafficPolicy > object can only target resources deployed in the same namespace. > Therefore, having a separate namespace for the gateway would > prevent developers from attaching the policy to the gateway.

b. Forbid the creation of these policies for developers in namespace C.

On the other hand, in scenarios similar to tenants A and B, where a shared gateway namespace is in place, this issue is more limited. Note that in this scenario, developers don\'t have access to the shared gateway namespace.

In addition, it is important to mention that EnvoyPatchPolicy resources can also be attached to GatewayClass resources. This means that, in order to comply with the Advanced 4 Tier model, individuals with the Application Administrator role should not have access to this resource either. | -|EGTM-003|EGTM-EG-001|Envoy Gateway| There is a risk that a threat actor could downgrade the security of proxied connections by configuring a weak set of cipher suites, compromising the confidentiality and integrity of proxied traffic.

| Exploit weak cipher suite configuration to downgrade security of proxied connections.

|Low| Users operating in highly regulated environments may need to tightly control the TLS protocol and associated cipher suites, blocking non-conforming incoming connections to the gateway.

EnvoyProxy bootstrap config can be customised as per the [customise EnvoyProxy](../operations/customize-envoyproxy) documentation. In addition, from v.1.0.0, it is possible to configure common TLS properties for a Gateway or XRoute through the [ClientTrafficPolicy](https://gateway.envoyproxy.io/latest/api/extension_types/#clienttrafficpolicy) object. | -|EGTM-005|EGTM-CP-002|Container Security| Threat actor who has obtained access to Envoy Gateway pod could exploit the lack of AppArmor and Seccomp profiles in the Envoy Gateway deployment to attempt a container breakout, given the presence of an exploitable vulnerability, potentially impacting the confidentiality and integrity of namespace resources.

| Unauthorised syscalls and malicious code running in the Envoy Gateway pod.

|Low| Implement [AppArmor](https://kubernetes.io/docs/tutorials/security/apparmor/) policies by setting \: \ within container.apparmor.security.beta.kubernetes.io (note, this config is set *per container*). Well-defined AppArmor policies may provide greater protection from unknown threats.

Enforce [Seccomp](https://kubernetes.io/docs/tutorials/security/seccomp/) profiles by setting the seccompProfile under securityContext. Ideally, a [fine-grained](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-with-a-seccomp-profile-that-only-allows-necessary-syscalls) profile should be used to restrict access to only necessary syscalls, however the \--seccomp-default flag can be set to resort to [RuntimeDefault](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-that-uses-the-container-runtime-default-seccomp-profile) which provides a container runtime specific. Example seccomp profiles can be found [here](https://kubernetes.io/docs/tutorials/security/seccomp/#download-profiles).

To further enhance pod security, consider implementing [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) via seLinuxOptions for additional syscall attack surface reduction. Setting readOnlyRootFilesystem == true enforces an immutable root filesystem, preventing the addition of malicious binaries to the PATH and increasing the attack cost. Together, these configuration items improve the pods [Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). | -|EGTM-006|EGTM-CS-004|Container Security| There is a risk that a threat actor exploits a vulnerability in Envoy Proxy to expose a reverse shell, enabling them to compromise the confidentiality, integrity and availability of tenant data via a secondary attack.

| If an external attacker managed to exploit a vulnerability in Envoy, the presence of a shell would be greatly helpful for the attacker in terms of potentially pivoting, escalating, or establishing some form of persistence.

|Low| By default, Envoy uses a [distroless](https://github.com/GoogleContainerTools/distroless) image since v.0.6.0, which does not ship a shell. Therefore, ensure EnvoyProxy image is up-to-date and patched with the latest stable version.

If using private EnvoyProxy images, use a lightweight EnvoyProxy image without a shell or debugging tool(s) which may be useful for an attacker.

An [AuditPolicy](https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/#audit-policy) (audit.k8s.io/v1beta1) can be configured to record API calls made within your cluster, allowing for identification of malicious traffic and enabling incident response. Requests are recorded based on stages which delineate between the lifecycle stage of the request made (e.g., RequestReceived, ResponseStarted, & ResponseComplete). | -|EGTM-011|EGTM-GW-003|Gateway API| There is a risk that a gateway owner (or someone with the ability to set namespace labels) maliciously or accidentally binds routes across namespace boundaries, potentially compromising the confidentiality and integrity of traffic in a multitenant scenario.

| If a Route Binding within a Gateway Listener is configured based on a custom label, it could allow a malicious internal actor with the ability to label namespaces to change the set of namespaces supported by the Gateway

|Low| Consider the use of custom admission control to restrict what labels can be set on namespaces through tooling such as [Kubewarden](https://kyverno.io/policies/pod-security/), [Kyverno](https://github.com/kubewarden), and [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Route binding should follow the Kubernetes Gateway API security model, as shown [here](https://gateway-api.sigs.k8s.io/concepts/security-model/#1-route-binding), to connect gateways in different namespaces. | -|EGTM-013|EGTM-GW-005|Gateway API| There is a risk that an unauthorised actor deploys an unauthorised GatewayClass due to GatewayClass namespace validation not being configured, leading to non-compliance with business and security requirements.

| Unauthorised deployment of Gateway resource via GatewayClass template which crosses namespace trust boundaries.

|Low| Leverage GatewayClass namespace validation to limit the namespaces where GatewayClasses can be run through a tool such as using [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Reference pull request \#[24](https://github.com/open-policy-agent/gatekeeper-library/pull/24) within gatekeeper-library which outlines how to add GatewayClass namespace validation through a GatewayClassNamespaces API resource kind within the constraints.gatekeeper.sh/v1beta1 apiGroup. | -|EGTM-015|EGTM-CS-007|Container Security| There is a risk that threat actors could exploit ServiceAccount tokens for illegitimate authentication, thereby leading to privilege escalation and the undermining of gateway API resources\' integrity, confidentiality, and availability.

| The threat arises from threat actors impersonating the envoy-gateway ServiceAccount through the replay of ServiceAccount tokens, thereby achieving escalated privileges and gaining unauthorised access to Kubernetes resources.

|Low| Limit the creation of ServiceAccounts to only when necessary, specifically refraining from using default service account tokens, especially for high-privilege service accounts. For legacy clusters running Kubernetes version 1.21 or earlier, note that ServiceAccount tokens are long-lived by default. To disable the automatic mounting of the service account token, set automountServiceAccountToken: false in the PodSpec. | -|EGTM-016|EGTM-EG-004|Envoy Gateway| There is a risk that threat actors establish persistence and move laterally through the cluster unnoticed due to limited visibility into access and application-level activity.

| Threat actors establish persistence and move laterally through the cluster unnoticed.

|Low| Configure [access logging](../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.

Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR). | -|EGTM-017|EGTM-EG-005|Envoy Gateway| There is a risk that an insider misconfigures an envoy gateway component and goes unnoticed due to a low-touch logging configuration (via default) which responsible stakeholders are not aptly aware of or have immediate access to.

| The threat emerges from an insider misconfiguring an Envoy Gateway component without detection.

|Low| Configure the logging level of the Envoy Gateway using the \'level\' field in [EnvoyGatewayLogging](https://gateway.envoyproxy.io/latest/api/extension_types/#envoygatewaylogging). Ensure the appropriate logging levels are set for relevant components such as \'gateway-api\', \'xds-translator\', or \'global-ratelimit\'. If left unspecified, the logging level defaults to \"info\", which may not provide sufficient detail for security monitoring.

Employ a centralised logging mechanism, like [Fluentd](https://github.com/fluent/fluentd), to enhance visibility into application-level activity and to enable efficient incident response. | -|EGTM-021|EGTM-EG-006|Envoy Gateway| There is a risk that the admin interface is exposed without valid business reason, increasing the attack surface.

| Exposed admin interfaces give internal attackers the option to affect production traffic in unauthorised ways, and the option to exploit any vulnerabilities which may be present in the admin interface (e.g. by orchestrating malicious GET requests to the admin interface through CSRF, compromising Envoy Proxy global configuration or shutting off the service entirely (e.g., /quitquitquit).

|Low| The Envoy Proxy admin interface is only exposed to localhost, meaning that it is secure by default. However, due to the risk of misconfiguration, this recommendation is included.

Due to the importance of the admin interface, it is recommended to ensure that Envoy Proxies have not been accidentally misconfigured to expose the admin interface to untrusted networks. | -|EGTM-025 | EGTM-CS-011 | Container Security | The presence of a vulnerability, be it in the kernel or another system component, when coupled with containers running as root, could enable a threat actor to escape the container, thereby compromising the confidentiality, integrity, or availability of cluster resources. | The Envoy Proxy container's root-user configuration can be leveraged by an attacker to escalate privileges, execute a container breakout, and traverse across trust boundaries. | Low | By default, Envoy Gateway deployments do not use root users. Nonetheless, in case a custom image or deployment manifest is to be used, make sure Envoy Proxy pods run as a non-root user with a high UID within the container. Set runAsUser and runAsGroup security context options to specific UIDs (e.g., runAsUser: 1000 & runAsGroup: 3000) to ensure the container operates with the stipulated non-root user and group ID. If using helm chart deployment, define the user and group ID in the values.yaml file or via the command line during helm install / upgrade. | +|EGTM-019|EGTM-DP-004|Container Security| There is a risk that replay attacks using stolen or reused JSON Web Tokens (JWTs) can compromise transmission integrity, thereby undermining the confidentiality and integrity of the data plane.

| Transmission integrity is compromised due to replay attacks using stolen or reused JSON Web Tokens (JWTs).

|Medium| Comply with JWT best practices for enhanced security, paying special attention to the use of short-lived tokens, which reduce the window of opportunity for a replay attack. The [exp](https://datatracker.ietf.org/doc/html/rfc7519#page-9) claim can be used to set token expiration times. | +|EGTM-024|EGTM-EG-008|Envoy Gateway| There is a risk of developers getting more privileges than required due to the use of SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy and BackendTrafficPolicy. These resources can be attached to a Gateway resource. Therefore, a developer with permission to deploy them would be able to modify a Gateway configuration by targeting the gateway in the policy manifest. This conflicts with the [Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model), where developers do not have write permissions on Gateways.

| Excessive developer permissions lead to a misconfiguration and/or unauthorised access.

|Medium| Considering the Tenant C scenario (represented in the Architecture Diagram), if a developer can create SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy or BackendTrafficPolicy objects in namespace C, they would be able to modify a Gateway configuration by attaching the policy to the gateway. In such scenarios, it is recommended to either:

a. Create a separate namespace, where developers have no permissions, > to host tenant C\'s gateway. Note that, due to design decisions, > the > SecurityPolicy/EnvoyPatchPolicy/ClientTrafficPolicy/BackendTrafficPolicy > object can only target resources deployed in the same namespace. > Therefore, having a separate namespace for the gateway would > prevent developers from attaching the policy to the gateway.

b. Forbid the creation of these policies for developers in namespace C.

On the other hand, in scenarios similar to tenants A and B, where a shared gateway namespace is in place, this issue is more limited. Note that in this scenario, developers don\'t have access to the shared gateway namespace.

In addition, it is important to mention that EnvoyPatchPolicy resources can also be attached to GatewayClass resources. This means that, in order to comply with the Advanced 4 Tier model, individuals with the Application Administrator role should not have access to this resource either. | +|EGTM-003|EGTM-EG-001|Envoy Gateway| There is a risk that a threat actor could downgrade the security of proxied connections by configuring a weak set of cipher suites, compromising the confidentiality and integrity of proxied traffic.

| Exploit weak cipher suite configuration to downgrade security of proxied connections.

|Low| Users operating in highly regulated environments may need to tightly control the TLS protocol and associated cipher suites, blocking non-conforming incoming connections to the gateway.

EnvoyProxy bootstrap config can be customised as per the [customise EnvoyProxy](../operations/customize-envoyproxy) documentation. In addition, from v.1.0.0, it is possible to configure common TLS properties for a Gateway or XRoute through the [ClientTrafficPolicy](https://gateway.envoyproxy.io/latest/api/extension_types/#clienttrafficpolicy) object. | +|EGTM-005|EGTM-CP-002|Container Security| Threat actor who has obtained access to Envoy Gateway pod could exploit the lack of AppArmor and Seccomp profiles in the Envoy Gateway deployment to attempt a container breakout, given the presence of an exploitable vulnerability, potentially impacting the confidentiality and integrity of namespace resources.

| Unauthorised syscalls and malicious code running in the Envoy Gateway pod.

|Low| Implement [AppArmor](https://kubernetes.io/docs/tutorials/security/apparmor/) policies by setting \: \ within container.apparmor.security.beta.kubernetes.io (note, this config is set *per container*). Well-defined AppArmor policies may provide greater protection from unknown threats.

Enforce [Seccomp](https://kubernetes.io/docs/tutorials/security/seccomp/) profiles by setting the seccompProfile under securityContext. Ideally, a [fine-grained](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-with-a-seccomp-profile-that-only-allows-necessary-syscalls) profile should be used to restrict access to only necessary syscalls, however the \--seccomp-default flag can be set to resort to [RuntimeDefault](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-that-uses-the-container-runtime-default-seccomp-profile) which provides a container runtime specific. Example seccomp profiles can be found [here](https://kubernetes.io/docs/tutorials/security/seccomp/#download-profiles).

To further enhance pod security, consider implementing [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) via seLinuxOptions for additional syscall attack surface reduction. Setting readOnlyRootFilesystem == true enforces an immutable root filesystem, preventing the addition of malicious binaries to the PATH and increasing the attack cost. Together, these configuration items improve the pods [Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). | +|EGTM-006|EGTM-CS-004|Container Security| There is a risk that a threat actor exploits a vulnerability in Envoy Proxy to expose a reverse shell, enabling them to compromise the confidentiality, integrity and availability of tenant data via a secondary attack.

| If an external attacker managed to exploit a vulnerability in Envoy, the presence of a shell would be greatly helpful for the attacker in terms of potentially pivoting, escalating, or establishing some form of persistence.

|Low| By default, Envoy uses a [distroless](https://github.com/GoogleContainerTools/distroless) image since v.0.6.0, which does not ship a shell. Therefore, ensure EnvoyProxy image is up-to-date and patched with the latest stable version.

If using private EnvoyProxy images, use a lightweight EnvoyProxy image without a shell or debugging tool(s) which may be useful for an attacker.

An [AuditPolicy](https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/#audit-policy) (audit.k8s.io/v1beta1) can be configured to record API calls made within your cluster, allowing for identification of malicious traffic and enabling incident response. Requests are recorded based on stages which delineate between the lifecycle stage of the request made (e.g., RequestReceived, ResponseStarted, & ResponseComplete). | +|EGTM-011|EGTM-GW-003|Gateway API| There is a risk that a gateway owner (or someone with the ability to set namespace labels) maliciously or accidentally binds routes across namespace boundaries, potentially compromising the confidentiality and integrity of traffic in a multitenant scenario.

| If a Route Binding within a Gateway Listener is configured based on a custom label, it could allow a malicious internal actor with the ability to label namespaces to change the set of namespaces supported by the Gateway

|Low| Consider the use of custom admission control to restrict what labels can be set on namespaces through tooling such as [Kubewarden](https://kyverno.io/policies/pod-security/), [Kyverno](https://github.com/kubewarden), and [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Route binding should follow the Kubernetes Gateway API security model, as shown [here](https://gateway-api.sigs.k8s.io/concepts/security-model/#1-route-binding), to connect gateways in different namespaces. | +|EGTM-013|EGTM-GW-005|Gateway API| There is a risk that an unauthorised actor deploys an unauthorised GatewayClass due to GatewayClass namespace validation not being configured, leading to non-compliance with business and security requirements.

| Unauthorised deployment of Gateway resource via GatewayClass template which crosses namespace trust boundaries.

|Low| Leverage GatewayClass namespace validation to limit the namespaces where GatewayClasses can be run through a tool such as using [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Reference pull request \#[24](https://github.com/open-policy-agent/gatekeeper-library/pull/24) within gatekeeper-library which outlines how to add GatewayClass namespace validation through a GatewayClassNamespaces API resource kind within the constraints.gatekeeper.sh/v1beta1 apiGroup. | +|EGTM-015|EGTM-CS-007|Container Security| There is a risk that threat actors could exploit ServiceAccount tokens for illegitimate authentication, thereby leading to privilege escalation and the undermining of gateway API resources\' integrity, confidentiality, and availability.

| The threat arises from threat actors impersonating the envoy-gateway ServiceAccount through the replay of ServiceAccount tokens, thereby achieving escalated privileges and gaining unauthorised access to Kubernetes resources.

|Low| Limit the creation of ServiceAccounts to only when necessary, specifically refraining from using default service account tokens, especially for high-privilege service accounts. For legacy clusters running Kubernetes version 1.21 or earlier, note that ServiceAccount tokens are long-lived by default. To disable the automatic mounting of the service account token, set automountServiceAccountToken: false in the PodSpec. | +|EGTM-016|EGTM-EG-004|Envoy Gateway| There is a risk that threat actors establish persistence and move laterally through the cluster unnoticed due to limited visibility into access and application-level activity.

| Threat actors establish persistence and move laterally through the cluster unnoticed.

|Low| Configure [access logging](../../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.

Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR). | +|EGTM-017|EGTM-EG-005|Envoy Gateway| There is a risk that an insider misconfigures an envoy gateway component and goes unnoticed due to a low-touch logging configuration (via default) which responsible stakeholders are not aptly aware of or have immediate access to.

| The threat emerges from an insider misconfiguring an Envoy Gateway component without detection.

|Low| Configure the logging level of the Envoy Gateway using the \'level\' field in [EnvoyGatewayLogging](https://gateway.envoyproxy.io/latest/api/extension_types/#envoygatewaylogging). Ensure the appropriate logging levels are set for relevant components such as \'gateway-api\', \'xds-translator\', or \'global-ratelimit\'. If left unspecified, the logging level defaults to \"info\", which may not provide sufficient detail for security monitoring.

Employ a centralised logging mechanism, like [Fluentd](https://github.com/fluent/fluentd), to enhance visibility into application-level activity and to enable efficient incident response. | +|EGTM-021|EGTM-EG-006|Envoy Gateway| There is a risk that the admin interface is exposed without valid business reason, increasing the attack surface.

| Exposed admin interfaces give internal attackers the option to affect production traffic in unauthorised ways, and the option to exploit any vulnerabilities which may be present in the admin interface (e.g. by orchestrating malicious GET requests to the admin interface through CSRF, compromising Envoy Proxy global configuration or shutting off the service entirely (e.g., /quitquitquit).

|Low| The Envoy Proxy admin interface is only exposed to localhost, meaning that it is secure by default. However, due to the risk of misconfiguration, this recommendation is included.

Due to the importance of the admin interface, it is recommended to ensure that Envoy Proxies have not been accidentally misconfigured to expose the admin interface to untrusted networks. | +|EGTM-025 | EGTM-CS-011 | Container Security | The presence of a vulnerability, be it in the kernel or another system component, when coupled with containers running as root, could enable a threat actor to escape the container, thereby compromising the confidentiality, integrity, or availability of cluster resources. | The Envoy Proxy container's root-user configuration can be leveraged by an attacker to escalate privileges, execute a container breakout, and traverse across trust boundaries. | Low | By default, Envoy Gateway deployments do not use root users. Nonetheless, in case a custom image or deployment manifest is to be used, make sure Envoy Proxy pods run as a non-root user with a high UID within the container. Set runAsUser and runAsGroup security context options to specific UIDs (e.g., runAsUser: 1000 & runAsGroup: 3000) to ensure the container operates with the stipulated non-root user and group ID. If using helm chart deployment, define the user and group ID in the values.yaml file or via the command line during helm install / upgrade. | ## Attack Trees diff --git a/site/content/en/latest/tasks/security/tls-passthrough.md b/site/content/en/latest/tasks/security/tls-passthrough.md index 874ec2aac4e..5942a68f4db 100644 --- a/site/content/en/latest/tasks/security/tls-passthrough.md +++ b/site/content/en/latest/tasks/security/tls-passthrough.md @@ -116,4 +116,4 @@ kubectl delete secret/server-certs ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. diff --git a/site/content/en/latest/tasks/traffic/gatewayapi-support.md b/site/content/en/latest/tasks/traffic/gatewayapi-support.md index 778a9972d62..7ea0e91e54b 100644 --- a/site/content/en/latest/tasks/traffic/gatewayapi-support.md +++ b/site/content/en/latest/tasks/traffic/gatewayapi-support.md @@ -94,7 +94,7 @@ these types of cross-namespace references. Envoy Gateway supports the following namespace. - Allowing a Gateway's [SecretObjectReference][] to reference a secret in a different namespace. -[system design]: ../../contributions/design/system-design/ +[system design]: ../../../contributions/design/system-design [Gateway API]: https://gateway-api.sigs.k8s.io/ [GatewayClass]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass [parameters reference]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.ParametersReference @@ -110,7 +110,7 @@ these types of cross-namespace references. Envoy Gateway supports the following [TLSRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TLSRoute [ReferenceGrant]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.ReferenceGrant [SecretObjectReference]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.SecretObjectReference -[rate limiting]: ../../contributions/design/rate-limit +[rate limiting]: ../../../contributions/design/rate-limit [request authentication]: ../security/jwt-authentication [EnvoyProxy]: ../../../api/extension_types#envoyproxy [resolving conflicts]: https://gateway-api.sigs.k8s.io/concepts/guidelines/?h=conflict#conflicts diff --git a/site/content/en/latest/tasks/traffic/udp-routing.md b/site/content/en/latest/tasks/traffic/udp-routing.md index c703abe804f..51f3b1f8dd6 100644 --- a/site/content/en/latest/tasks/traffic/udp-routing.md +++ b/site/content/en/latest/tasks/traffic/udp-routing.md @@ -141,7 +141,7 @@ kubectl delete udproute/coredns ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. [UDPRoute]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.UDPRoute [UDP proxy documentation]: https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/udp_filters/udp_proxy diff --git a/site/content/en/v0.5.0/install/install-helm.md b/site/content/en/v0.5.0/install/install-helm.md index ad6f945bddb..44e84aaa9df 100644 --- a/site/content/en/v0.5.0/install/install-helm.md +++ b/site/content/en/v0.5.0/install/install-helm.md @@ -28,7 +28,7 @@ You can visit [Envoy Gateway Helm Chart](https://hub.docker.com/r/envoyproxy/gat Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one. {{% alert title="Developer Guide" color="primary" %}} -Refer to the [Developer Guide](/latest/contributions/develop) to learn more. +Refer to the [Developer Guide](/contributions/develop) to learn more. {{% /alert %}} Install the Gateway API CRDs and Envoy Gateway: diff --git a/site/content/en/v0.6.0/install/install-helm.md b/site/content/en/v0.6.0/install/install-helm.md index 3f3c57e1db9..7bb4b63952b 100644 --- a/site/content/en/v0.6.0/install/install-helm.md +++ b/site/content/en/v0.6.0/install/install-helm.md @@ -28,7 +28,7 @@ You can visit [Envoy Gateway Helm Chart](https://hub.docker.com/r/envoyproxy/gat Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one. {{% alert title="Developer Guide" color="primary" %}} -Refer to the [Developer Guide](/latest/contributions/develop) to learn more. +Refer to the [Developer Guide](/contributions/develop) to learn more. {{% /alert %}} Install the Gateway API CRDs and Envoy Gateway: diff --git a/site/content/en/v0.6.0/install/install-yaml.md b/site/content/en/v0.6.0/install/install-yaml.md index 4b13529f000..0b617d34be6 100644 --- a/site/content/en/v0.6.0/install/install-yaml.md +++ b/site/content/en/v0.6.0/install/install-yaml.md @@ -25,7 +25,7 @@ Refer to the [Version Compatibility Matrix](/blog/2022/10/01/versions/) to learn Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one. {{% alert title="Developer Guide" color="primary" %}} -Refer to the [Developer Guide](/latest/contributions/develop) to learn more. +Refer to the [Developer Guide](/contributions/develop) to learn more. {{% /alert %}} 1. In your terminal, run the following command: diff --git a/site/content/en/v1.0.1/_index.md b/site/content/en/v1.0.1/_index.md index 567b43bfe36..ea08d244d31 100644 --- a/site/content/en/v1.0.1/_index.md +++ b/site/content/en/v1.0.1/_index.md @@ -9,7 +9,7 @@ type = "docs" {{% alert title="Note" color="primary" %}} -This project is under **active** development. Many features are not complete. We would love for you to [Get Involved](contributions/)! +This project is under **active** development. Many features are not complete. We would love for you to [Get Involved](/contributions)! {{% /alert %}} diff --git a/site/content/en/v1.0.1/contributions/CODEOWNERS.md b/site/content/en/v1.0.1/contributions/CODEOWNERS.md deleted file mode 100644 index aeec0b7439b..00000000000 --- a/site/content/en/v1.0.1/contributions/CODEOWNERS.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: "Maintainers" -description: "This section includes Maintainers of Envoy Gateway." ---- - -## The following maintainers, listed in alphabetical order, own everything - -- @AliceProxy -- @arkodg -- @qicz -- @Xunzhuo -- @zirain -- @zhaohuabing - -## Emeritus Maintainers - -- @alexgervais -- @danehans -- @LukeShu -- @skriss -- @youngnick diff --git a/site/content/en/v1.0.1/contributions/CODE_OF_CONDUCT.md b/site/content/en/v1.0.1/contributions/CODE_OF_CONDUCT.md deleted file mode 100644 index e19da050dff..00000000000 --- a/site/content/en/v1.0.1/contributions/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "Code of Conduct" -description: "This section includes Code of Conduct of Envoy Gateway." ---- - -Envoy Gateway follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). diff --git a/site/content/en/v1.0.1/contributions/CONTRIBUTING.md b/site/content/en/v1.0.1/contributions/CONTRIBUTING.md deleted file mode 100644 index 6964a31e9fe..00000000000 --- a/site/content/en/v1.0.1/contributions/CONTRIBUTING.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -title: "Contributing" -description: "This section tells how to contribute to Envoy Gateway." -weight: 3 ---- - -We welcome contributions from the community. Please carefully review the [project goals](/about) -and following guidelines to streamline your contributions. - -## Communication - -* Before starting work on a major feature, please contact us via GitHub or Slack. We will ensure no - one else is working on it and ask you to open a GitHub issue. -* A "major feature" is defined as any change that is > 100 LOC altered (not including tests), or - changes any user-facing behavior. We will use the GitHub issue to discuss the feature and come to - agreement. This is to prevent your time being wasted, as well as ours. The GitHub review process - for major features is also important so that [affiliations with commit access](./codeowners) can - come to agreement on the design. If it's appropriate to write a design document, the document must - be hosted either in the GitHub issue, or linked to from the issue and hosted in a world-readable - location. -* Small patches and bug fixes don't need prior communication. - -## Inclusivity - -The Envoy Gateway community has an explicit goal to be inclusive to all. As such, all PRs must adhere -to the following guidelines for all code, APIs, and documentation: - -* The following words and phrases are not allowed: - * *Whitelist*: use allowlist instead. - * *Blacklist*: use denylist or blocklist instead. - * *Master*: use primary instead. - * *Slave*: use secondary or replica instead. -* Documentation should be written in an inclusive style. The [Google developer - documentation](https://developers.google.com/style/inclusive-documentation) contains an excellent - reference on this topic. -* The above policy is not considered definitive and may be amended in the future as industry best - practices evolve. Additional comments on this topic may be provided by maintainers during code - review. - -## Submitting a PR - -* Fork the repo. -* Hack -* DCO sign-off each commit. This can be done with `git commit -s`. -* Submit your PR. -* Tests will automatically run for you. -* We will **not** merge any PR that is not passing tests. -* PRs are expected to have 100% test coverage for added code. This can be verified with a coverage - build. If your PR cannot have 100% coverage for some reason please clearly explain why when you - open it. -* Any PR that changes user-facing behavior **must** have associated documentation in the [docs](https://github.com/envoyproxy/gateway/tree/main/site) folder of the repo as - well as the [changelog](../releases). -* All code comments and documentation are expected to have proper English grammar and punctuation. - If you are not a fluent English speaker (or a bad writer ;-)) please let us know and we will try - to find some help but there are no guarantees. -* Your PR title should be descriptive, and generally start with type that contains a subsystem name with `()` if necessary - and summary followed by a colon. format `chore/docs/feat/fix/refactor/style/test: summary`. - Examples: - * "docs: fix grammar error" - * "feat(translator): add new feature" - * "fix: fix xx bug" - * "chore: change ci & build tools etc" -* Your PR commit message will be used as the commit message when your PR is merged. You should - update this field if your PR diverges during review. -* Your PR description should have details on what the PR does. If it fixes an existing issue it - should end with "Fixes #XXX". -* If your PR is co-authored or based on an earlier PR from another contributor, - please attribute them with `Co-authored-by: name `. See - GitHub's [multiple author - guidance](https://help.github.com/en/github/committing-changes-to-your-project/creating-a-commit-with-multiple-authors) - for further details. -* When all tests are passing and all other conditions described herein are satisfied, a maintainer - will be assigned to review and merge the PR. -* Once you submit a PR, *please do not rebase it*. It's much easier to review if subsequent commits - are new commits and/or merges. We squash and merge so the number of commits you have in the PR - doesn't matter. -* We expect that once a PR is opened, it will be actively worked on until it is merged or closed. - We reserve the right to close PRs that are not making progress. This is generally defined as no - changes for 7 days. Obviously PRs that are closed due to lack of activity can be reopened later. - Closing stale PRs helps us to keep on top of all the work currently in flight. - -## Maintainer PR Review Policy - -* See [CODEOWNERS.md](../codeowners) for the current list of maintainers. -* A maintainer representing a different affiliation from the PR owner is required to review and - approve the PR. -* When the project matures, it is expected that a "domain expert" for the code the PR touches should - review the PR. This person does not require commit access, just domain knowledge. -* The above rules may be waived for PRs which only update docs or comments, or trivial changes to - tests and tools (where trivial is decided by the maintainer in question). -* If there is a question on who should review a PR please discuss in Slack. -* Anyone is welcome to review any PR that they want, whether they are a maintainer or not. -* Please make sure that the PR title, commit message, and description are updated if the PR changes - significantly during review. -* Please **clean up the title and body** before merging. By default, GitHub fills the squash merge - title with the original title, and the commit body with every individual commit from the PR. - The maintainer doing the merge should make sure the title follows the guidelines above and should - overwrite the body with the original commit message from the PR (cleaning it up if necessary) - while preserving the PR author's final DCO sign-off. - -## Decision making - -This is a new and complex project, and we need to make a lot of decisions very quickly. -To this end, we've settled on this process for making (possibly contentious) decisions: - -* For decisions that need a record, we create an issue. -* In that issue, we discuss opinions, then a maintainer can call for a vote in a comment. -* Maintainers can cast binding votes on that comment by reacting or replying in another comment. -* Non-maintainer community members are welcome to cast non-binding votes by either of these methods. -* Voting will be resolved by simple majority. -* In the event of deadlocks, the question will be put to steering instead. - -## DCO: Sign your work - -The sign-off is a simple line at the end of the explanation for the -patch, which certifies that you wrote it or otherwise have the right to -pass it on as an open-source patch. The rules are pretty simple: if you -can certify the below (from -[developercertificate.org](https://developercertificate.org/)): - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -660 York Street, Suite 102, -San Francisco, CA 94110 USA - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -then you just add a line to every git commit message: - - Signed-off-by: Joe Smith - -using your real name (sorry, no pseudonyms or anonymous contributions.) - -You can add the sign-off when creating the git commit via `git commit -s`. - -If you want this to be automatic you can set up some aliases: - -```bash -git config --add alias.amend "commit -s --amend" -git config --add alias.c "commit -s" -``` - -## Fixing DCO - -If your PR fails the DCO check, it's necessary to fix the entire commit history in the PR. Best -practice is to [squash](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits) -the commit history to a single commit, append the DCO sign-off as described above, and [force -push](https://git-scm.com/docs/git-push#git-push---force). For example, if you have 2 commits in -your history: - -```bash -git rebase -i HEAD^^ -(interactive squash + DCO append) -git push origin -f -``` - -Note, that in general rewriting history in this way is a hindrance to the review process and this -should only be done to correct a DCO mistake. diff --git a/site/content/en/v1.0.1/contributions/DEVELOP.md b/site/content/en/v1.0.1/contributions/DEVELOP.md deleted file mode 100644 index a73fae4e7ba..00000000000 --- a/site/content/en/v1.0.1/contributions/DEVELOP.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -title: "Developer Guide" -description: "This section tells how to develop Envoy Gateway." -weight: 2 ---- - -Envoy Gateway is built using a [make][]-based build system. Our CI is based on [Github Actions][] using [workflows][]. - -## Prerequisites - -### go - -* Version: 1.20 -* Installation Guide: https://go.dev/doc/install - -### make - -* Recommended Version: 4.0 or later -* Installation Guide: https://www.gnu.org/software/make - -### docker - -* Optional when you want to build a Docker image or run `make` inside Docker. -* Recommended Version: 20.10.16 -* Installation Guide: https://docs.docker.com/engine/install - -### python3 - -* Need a `python3` program -* Must have a functioning `venv` module; this is part of the standard - library, but some distributions (such as Debian and Ubuntu) replace - it with a stub and require you to install a `python3-venv` package - separately. - -## Quickstart - -* Run `make help` to see all the available targets to build, test and run Envoy Gateway. - -### Building - -* Run `make build` to build all the binaries. -* Run `make build BINS="envoy-gateway"` to build the Envoy Gateway binary. -* Run `make build BINS="egctl"` to build the egctl binary. - -__Note:__ The binaries get generated in the `bin/$OS/$ARCH` directory, for example, `bin/linux/amd64/`. - -### Testing - -* Run `make test` to run the golang tests. - -* Run `make testdata` to generate the golden YAML testdata files. - -### Running Linters - -* Run `make lint` to make sure your code passes all the linter checks. -__Note:__ The `golangci-lint` configuration resides [here](https://github.com/envoyproxy/gateway/blob/main/tools/linter/golangci-lint/.golangci.yml). - -### Building and Pushing the Image - -* Run `IMAGE=docker.io/you/gateway-dev make image` to build the docker image. -* Run `IMAGE=docker.io/you/gateway-dev make push-multiarch` to build and push the multi-arch docker image. - -__Note:__ Replace `IMAGE` with your registry's image name. - -### Deploying Envoy Gateway for Test/Dev - -* Run `make create-cluster` to create a [Kind][] cluster. - -#### Option 1: Use the Latest [gateway-dev][] Image - -* Run `TAG=latest make kube-deploy` to deploy Envoy Gateway in the Kind cluster using the latest image. Replace `latest` - to use a different image tag. - -#### Option 2: Use a Custom Image - -* Run `make kube-install-image` to build an image from the tip of your current branch and load it in the Kind cluster. -* Run `IMAGE_PULL_POLICY=IfNotPresent make kube-deploy` to install Envoy Gateway into the Kind cluster using your custom image. - -### Deploying Envoy Gateway in Kubernetes - -* Run `TAG=latest make kube-deploy` to deploy Envoy Gateway using the latest image into a Kubernetes cluster (linked to - the current kube context). Preface the command with `IMAGE` or replace `TAG` to use a different Envoy Gateway image or - tag. -* Run `make kube-undeploy` to uninstall Envoy Gateway from the cluster. - -__Note:__ Envoy Gateway is tested against Kubernetes v1.24.0. - -### Demo Setup - -* Run `make kube-demo` to deploy a demo backend service, gatewayclass, gateway and httproute resource -(similar to steps outlined in the [Quickstart][] docs) and test the configuration. -* Run `make kube-demo-undeploy` to delete the resources created by the `make kube-demo` command. - -### Run Gateway API Conformance Tests - -The commands below deploy Envoy Gateway to a Kubernetes cluster and run the Gateway API conformance tests. Refer to the -Gateway API [conformance homepage][] to learn more about the tests. If Envoy Gateway is already installed, run -`TAG=latest make run-conformance` to run the conformance tests. - -#### On a Linux Host - -* Run `TAG=latest make conformance` to create a Kind cluster, install Envoy Gateway using the latest [gateway-dev][] - image, and run Gateway API conformance tests. - -#### On a Mac Host - -Since Mac doesn't support [directly exposing][] the Docker network to the Mac host, use one of the following -workarounds to run conformance tests: - -* Deploy your own Kubernetes cluster or use Docker Desktop with [Kubernetes support][] and then run - `TAG=latest make kube-deploy run-conformance`. This will install Envoy Gateway using the latest [gateway-dev][] image - to the Kubernetes cluster using the current kubectl context and run the conformance tests. Use `make kube-undeploy` to - uninstall Envoy Gateway. -* Install and run [Docker Mac Net Connect][mac_connect] and then run `TAG=latest make conformance`. - -__Note:__ Preface commands with `IMAGE` or replace `TAG` to use a different Envoy Gateway image or tag. If `TAG` -is unspecified, the short SHA of your current branch is used. - -### Debugging the Envoy Config - -An easy way to view the envoy config that Envoy Gateway is using is to port-forward to the admin interface port -(currently `19000`) on the Envoy deployment that corresponds to a Gateway so that it can be accessed locally. - -Get the name of the Envoy deployment. The following example is for Gateway `eg` in the `default` namespace: - -```shell -export ENVOY_DEPLOYMENT=$(kubectl get deploy -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}') -``` - -Port forward the admin interface port: - -```shell -kubectl port-forward deploy/${ENVOY_DEPLOYMENT} -n envoy-gateway-system 19000:19000 -``` - -Now you are able to view the running Envoy configuration by navigating to `127.0.0.1:19000/config_dump`. - -There are many other endpoints on the [Envoy admin interface][] that may be helpful when debugging. - -### JWT Testing - -An example [JSON Web Token (JWT)][jwt] and [JSON Web Key Set (JWKS)][jwks] are used for the [request authentication][] -user guide. The JWT was created by the [JWT Debugger][], using the `RS256` algorithm. The public key from the JWTs -verify signature was copied to [JWK Creator][] for generating the JWK. The JWK Creator was configured with matching -settings, i.e. `Signing` public key use and the `RS256` algorithm. The generated JWK was wrapped in a JWKS structure -and is hosted in the repo. - -[Quickstart]: https://github.com/envoyproxy/gateway/blob/main/docs/latest/user/quickstart.md -[make]: https://www.gnu.org/software/make/ -[Github Actions]: https://docs.github.com/en/actions -[workflows]: https://github.com/envoyproxy/gateway/tree/main/.github/workflows -[Kind]: https://kind.sigs.k8s.io/ -[conformance homepage]: https://gateway-api.sigs.k8s.io/concepts/conformance/ -[directly exposing]: https://kind.sigs.k8s.io/docs/user/loadbalancer/ -[Kubernetes support]: https://docs.docker.com/desktop/kubernetes/ -[gateway-dev]: https://hub.docker.com/r/envoyproxy/gateway-dev/tags -[mac_connect]: https://github.com/chipmk/docker-mac-net-connect -[Envoy admin interface]: https://www.envoyproxy.io/docs/envoy/latest/operations/admin#operations-admin-interface -[jwt]: https://tools.ietf.org/html/rfc7519 -[jwks]: https://tools.ietf.org/html/rfc7517 -[request authentication]: ../tasks/security/jwt-authentication -[JWT Debugger]: https://jwt.io/ -[JWK Creator]: https://russelldavies.github.io/jwk-creator/ diff --git a/site/content/en/v1.0.1/contributions/DOCS.md b/site/content/en/v1.0.1/contributions/DOCS.md deleted file mode 100644 index ae19953a8b5..00000000000 --- a/site/content/en/v1.0.1/contributions/DOCS.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: "Working on Envoy Gateway Docs" -description: "This section tells the development of - Envoy Gateway Documents." ---- - -{{% alert title="Note" color="warning" %}} -We migrated from ***Sphinx*** to ***Hugo*** for Envoy Gateway Documents. - -Read blog: [Welcome to new website!](/blog/2023/10/08/welcome-to-new-website/) -{{% /alert %}} - -The documentation for the Envoy Gateway lives in the `site/content/en` directory. Any -individual document can be written using [Markdown]. - -## Documentation Structure - -We supported the versioned Docs now, the directory name under docs represents -the version of docs. The root of the latest site is in `site/content/en/latest`. -This is probably where to start if you're trying to understand how things fit together. - -Note that the new contents should be added to `site/content/en/latest` and will be cut off at -the next release. The contents under `site/content/en/v0.5.0` are auto-generated, -and usually do not need to make changes to them, unless if you find the current release pages have -some incorrect contents. If so, you should send a PR to update contents both of `site/content/en/latest` -and `site/content/en/v0.5.0`. - -You can access the website which represents the current release in default, -and you can access the website which contains the latest version changes in -[Here][latest-website] or at the footer of the pages. - -## Documentation Workflow - -To work with the docs, just edit Markdown files in `site/content/en/latest`, -then run - -```bash -make docs -``` - -This will create `site/public` with the built HTML pages. You can preview it -by running: - -``` shell -make docs-serve -``` - -If you want to generate a new release version of the docs, like `v0.6.0`, then run - -```bash -make docs-release TAG=v0.6.0 -``` - -This will update the VERSION file at the project root, which records current release version, -and it will be used in the pages version context and binary version output. Also, this will generate -new dir `site/content/en/v0.6.0`, which contains docs at v0.6.0 and updates artifact links to `v0.6.0` -in all files under `site/content/en/v0.6.0/user`, like `quickstart.md`, `http-routing.md` and etc. - -## Publishing Docs - -Whenever docs are pushed to `main`, CI will publish the built docs to GitHub -Pages. For more details, see `.github/workflows/docs.yaml`. - -## Reference - -Go to [Hugo](https://gohugo.io) and [Docsy](https://www.docsy.dev/docs) to learn more. - -[Markdown]: https://daringfireball.net/projects/markdown/syntax -[latest-website]: /latest diff --git a/site/content/en/v1.0.1/contributions/RELEASING.md b/site/content/en/v1.0.1/contributions/RELEASING.md deleted file mode 100644 index 3ee8b970c5f..00000000000 --- a/site/content/en/v1.0.1/contributions/RELEASING.md +++ /dev/null @@ -1,255 +0,0 @@ ---- -title: "Release Process" -description: "This section tells the release process of Envoy Gateway." ---- - -This document guides maintainers through the process of creating an Envoy Gateway release. - -- [Release Candidate](#release-candidate) - - [Prerequisites](#prerequisites) - - [Setup cherry picker action](#setup-cherry-picker-action) -- [Minor Release](#minor-release) - - [Prerequisites](#prerequisites-1) -- [Announce the Release](#announce-the-release) - -## Release Candidate - -The following steps should be used for creating a release candidate. - -### Prerequisites - -- Permissions to push to the Envoy Gateway repository. - -Set environment variables for use in subsequent steps: - -```shell -export MAJOR_VERSION=0 -export MINOR_VERSION=3 -export RELEASE_CANDIDATE_NUMBER=1 -export GITHUB_REMOTE=origin -``` - -1. Clone the repo, checkout the `main` branch, ensure it’s up-to-date, and your local branch is clean. -2. Create a topic branch for adding the release notes and updating the [VERSION][] file with the release version. Refer to previous [release notes][] and [VERSION][] for additional details. -3. Sign, commit, and push your changes to your fork. -4. Submit a [Pull Request][] to merge the changes into the `main` branch. Do not proceed until your PR has merged and - the [Build and Test][] has successfully completed. -5. Create a new release branch from `main`. The release branch should be named - `release/v${MAJOR_VERSION}.${MINOR_VERSION}`, e.g. `release/v0.3`. - - ```shell - git checkout -b release/v${MAJOR_VERSION}.${MINOR_VERSION} - ``` - -6. Push the branch to the Envoy Gateway repo. - - ```shell - git push ${GITHUB_REMOTE} release/v${MAJOR_VERSION}.${MINOR_VERSION} - ``` - -7. Create a topic branch for updating the Envoy proxy image and Envoy Ratelimit image to the tag supported by the release. Reference [PR #2098][] - for additional details on updating the image tag. -8. Sign, commit, and push your changes to your fork. -9. Submit a [Pull Request][] to merge the changes into the `release/v${MAJOR_VERSION}.${MINOR_VERSION}` branch. Do not - proceed until your PR has merged into the release branch and the [Build and Test][] has completed for your PR. -10. Ensure your release branch is up-to-date and tag the head of your release branch with the release candidate number. - - ```shell - git tag -a v${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER} -m 'Envoy Gateway v${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER} Release Candidate' - ``` - -11. Push the tag to the Envoy Gateway repository. - - ```shell - git push ${GITHUB_REMOTE} v${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER} - ``` - -12. This will trigger the [release GitHub action][] that generates the release, release artifacts, etc. -13. Confirm that the [release workflow][] completed successfully. -14. Confirm that the Envoy Gateway [image][] with the correct release tag was published to Docker Hub. -15. Confirm that the [release][] was created. -16. Note that the [Quickstart][] references are __not__ updated for release candidates. However, test - the quickstart steps using the release candidate by manually updating the links. -17. [Generate][] the GitHub changelog. -18. Ensure you check the "This is a pre-release" checkbox when editing the GitHub release. -19. If you find any bugs in this process, please create an issue. - -### Setup cherry picker action - -After release branch cut, RM (Release Manager) should add job [cherrypick action](https://github.com/envoyproxy/gateway/blob/main/.github/workflows/cherrypick.yaml) for target release. - -Configuration looks like following: - -```yaml - cherry_pick_release_v0_4: - runs-on: ubuntu-latest - name: Cherry pick into release-v0.4 - if: ${{ contains(github.event.pull_request.labels.*.name, 'cherrypick/release-v0.4') && github.event.pull_request.merged == true }} - steps: - - name: Checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - with: - fetch-depth: 0 - - name: Cherry pick into release/v0.4 - uses: carloscastrojumo/github-cherry-pick-action@a145da1b8142e752d3cbc11aaaa46a535690f0c5 # v1.0.9 - with: - branch: release/v0.4 - title: "[release/v0.4] {old_title}" - body: "Cherry picking #{old_pull_request_id} onto release/v0.4" - labels: | - cherrypick/release-v0.4 - # put release manager here - reviewers: | - AliceProxy -``` - -Replace `v0.4` with real branch name, and `AliceProxy` with the real name of RM. - -## Minor Release - -The following steps should be used for creating a minor release. - -### Prerequisites - -- Permissions to push to the Envoy Gateway repository. -- A release branch that has been cut from the corresponding release candidate. Refer to the - [Release Candidate](#release-candidate) section for additional details on cutting a release candidate. - -Set environment variables for use in subsequent steps: - -```shell -export MAJOR_VERSION=0 -export MINOR_VERSION=3 -export GITHUB_REMOTE=origin -``` - -1. Clone the repo, checkout the `main` branch, ensure it’s up-to-date, and your local branch is clean. -2. Create a topic branch for adding the release notes, release announcement, and versioned release docs. - - 1. Create the release notes. Reference previous [release notes][] for additional details. __Note:__ The release - notes should be an accumulation of the release candidate release notes and any changes since the release - candidate. - 2. Create a release announcement. Refer to [PR #635] as an example release announcement. - 3. Include the release in the compatibility matrix. Refer to [PR #1002] as an example. - 4. Generate the versioned release docs: - - ``` shell - make docs-release TAG=v${MAJOR_VERSION}.${MINOR_VERSION}.0 - ``` - - 5. Update the `Get Started` and `Contributing` button referred link in `site/content/en/_index.md`: - - ```shell - - Get Started - - - Contributing - - ``` - - 6. Uodate the `Documentation` referred link on the menu in `site/hugo.toml`: - - ```shell - [[menu.main]] - name = "Documentation" - weight = -101 - pre = "" - url = "/v0.5.0" - ``` - -3. Sign, commit, and push your changes to your fork. -4. Submit a [Pull Request][] to merge the changes into the `main` branch. Do not proceed until all your PRs have merged - and the [Build and Test][] has completed for your final PR. - -5. Checkout the release branch. - - ```shell - git checkout -b release/v${MAJOR_VERSION}.${MINOR_VERSION} $GITHUB_REMOTE/release/v${MAJOR_VERSION}.${MINOR_VERSION} - ``` - -6. If the tip of the release branch does not match the tip of `main`, perform the following: - - 1. Create a topic branch from the release branch. - 2. Cherry-pick the commits from `main` that differ from the release branch. - 3. Run tests locally, e.g. `make lint`. - 4. Sign, commit, and push your topic branch to your Envoy Gateway fork. - 5. Submit a PR to merge the topic from of your fork into the Envoy Gateway release branch. - 6. Do not proceed until the PR has merged and CI passes for the merged PR. - 7. If you are still on your topic branch, change to the release branch: - - ```shell - git checkout release/v${MAJOR_VERSION}.${MINOR_VERSION} - ``` - - 8. Ensure your local release branch is up-to-date: - - ```shell - git pull $GITHUB_REMOTE release/v${MAJOR_VERSION}.${MINOR_VERSION} - ``` - -7. Tag the head of your release branch with the release tag. For example: - - ```shell - git tag -a v${MAJOR_VERSION}.${MINOR_VERSION}.0 -m 'Envoy Gateway v${MAJOR_VERSION}.${MINOR_VERSION}.0 Release' - ``` - - __Note:__ The tag version differs from the release branch by including the `.0` patch version. - -8. Push the tag to the Envoy Gateway repository. - - ```shell - git push origin v${MAJOR_VERSION}.${MINOR_VERSION}.0 - ``` - -9. This will trigger the [release GitHub action][] that generates the release, release artifacts, etc. -10. Confirm that the [release workflow][] completed successfully. -11. Confirm that the Envoy Gateway [image][] with the correct release tag was published to Docker Hub. -12. Confirm that the [release][] was created. -13. Confirm that the steps in the [Quickstart][] work as expected. -14. [Generate][] the GitHub changelog and include the following text at the beginning of the release page: - - ```console - # Release Announcement - - Check out the [v${MAJOR_VERSION}.${MINOR_VERSION} release announcement] - (https://gateway.envoyproxy.io/releases/v${MAJOR_VERSION}.${MINOR_VERSION}.html) to learn more about the release. - ``` - -If you find any bugs in this process, please create an issue. - -## Announce the Release - -It's important that the world knows about the release. Use the following steps to announce the release. - -1. Set the release information in the Envoy Gateway Slack channel. For example: - - ```shell - Envoy Gateway v${MAJOR_VERSION}.${MINOR_VERSION} has been released: https://github.com/envoyproxy/gateway/releases/tag/v${MAJOR_VERSION}.${MINOR_VERSION}.0 - ``` - -2. Send a message to the Envoy Gateway Slack channel. For example: - - ```shell - On behalf of the entire Envoy Gateway community, I am pleased to announce the release of Envoy Gateway - v${MAJOR_VERSION}.${MINOR_VERSION}. A big thank you to all the contributors that made this release possible. - Refer to the official v${MAJOR_VERSION}.${MINOR_VERSION} announcement for release details and the project docs - to start using Envoy Gateway. - ... - ``` - - Link to the GitHub release and release announcement page that highlights the release. - -[release notes]: https://github.com/envoyproxy/gateway/tree/main/release-notes -[Pull Request]: https://github.com/envoyproxy/gateway/pulls -[Quickstart]: https://github.com/envoyproxy/gateway/blob/main/docs/user/quickstart.md -[Build and Test]: https://github.com/envoyproxy/gateway/blob/main/.github/workflows/build_and_test.yaml -[release GitHub action]: https://github.com/envoyproxy/gateway/blob/main/.github/workflows/release.yaml -[release workflow]: https://github.com/envoyproxy/gateway/actions/workflows/release.yaml -[image]: https://hub.docker.com/r/envoyproxy/gateway/tags -[release]: https://github.com/envoyproxy/gateway/releases -[Generate]: https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes -[PR #635]: https://github.com/envoyproxy/gateway/pull/635 -[PR #2098]: https://github.com/envoyproxy/gateway/pull/2098 -[PR #1002]: https://github.com/envoyproxy/gateway/pull/1002 -[VERSION]: https://github.com/envoyproxy/gateway/blob/main/VERSION diff --git a/site/content/en/v1.0.1/contributions/_index.md b/site/content/en/v1.0.1/contributions/_index.md deleted file mode 100644 index 1d3037e609e..00000000000 --- a/site/content/en/v1.0.1/contributions/_index.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Get Involved -description: "This section includes contents related to Contributions" -weight: 100 ---- diff --git a/site/content/en/v1.0.1/contributions/design/_index.md b/site/content/en/v1.0.1/contributions/design/_index.md deleted file mode 100644 index 5cacb86df70..00000000000 --- a/site/content/en/v1.0.1/contributions/design/_index.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "Design" -weight: -100 -description: This section includes Designs of Envoy Gateway. ---- diff --git a/site/content/en/v1.0.1/contributions/design/accesslog.md b/site/content/en/v1.0.1/contributions/design/accesslog.md deleted file mode 100644 index a229d5f6eff..00000000000 --- a/site/content/en/v1.0.1/contributions/design/accesslog.md +++ /dev/null @@ -1,243 +0,0 @@ ---- -title: "Observability: Accesslog" ---- - -## Overview - -Envoy supports extensible accesslog to different sinks, File, gRPC etc. Envoy supports customizable access log formats using predefined fields as well as arbitrary HTTP request and response headers. Envoy supports several built-in access log filters and extension filters that are registered at runtime. - -Envoy Gateway leverages [Gateway API][] for configuring managed Envoy proxies. Gateway API defines core, extended, and implementation-specific API [support levels][] for implementers such as Envoy Gateway to expose features. Since accesslog is not covered by `Core` or `Extended` APIs, EG should provide an easy to config access log formats and sinks per `EnvoyProxy`. - -## Goals - -- Support send accesslog to `File` or `OpenTelemetry` backend -- TODO: Support access log filters base on [CEL][] expression - -## Non-Goals - -- Support non-CEL filters, e.g. `status_code_filter`, `response_flag_filter` -- Support [HttpGrpcAccessLogConfig][] or [TcpGrpcAccessLogConfig][] - -## Use-Cases - -- Configure accesslog for a `EnvoyProxy` to `File` -- Configure accesslog for a `EnvoyProxy` to `OpenTelemetry` backend -- Configure multi accesslog providers for a `EnvoyProxy` - -### ProxyAccessLog API Type - -```golang mdox-exec="sed '1,7d' api/config/v1alpha1/accesslogging_types.go" -type ProxyAccessLog struct { - // Disable disables access logging for managed proxies if set to true. - Disable bool `json:"disable,omitempty"` - // Settings defines accesslog settings for managed proxies. - // If unspecified, will send default format to stdout. - // +optional - Settings []ProxyAccessLogSetting `json:"settings,omitempty"` -} - -type ProxyAccessLogSetting struct { - // Format defines the format of accesslog. - Format ProxyAccessLogFormat `json:"format"` - // Sinks defines the sinks of accesslog. - // +kubebuilder:validation:MinItems=1 - Sinks []ProxyAccessLogSink `json:"sinks"` -} - -type ProxyAccessLogFormatType string - -const ( - // ProxyAccessLogFormatTypeText defines the text accesslog format. - ProxyAccessLogFormatTypeText ProxyAccessLogFormatType = "Text" - // ProxyAccessLogFormatTypeJSON defines the JSON accesslog format. - ProxyAccessLogFormatTypeJSON ProxyAccessLogFormatType = "JSON" - // TODO: support format type "mix" in the future. -) - -// ProxyAccessLogFormat defines the format of accesslog. -// +union -type ProxyAccessLogFormat struct { - // Type defines the type of accesslog format. - // +kubebuilder:validation:Enum=Text;JSON - // +unionDiscriminator - Type ProxyAccessLogFormatType `json:"type,omitempty"` - // Text defines the text accesslog format, following Envoy accesslog formatting, - // empty value results in proxy's default access log format. - // It's required when the format type is "Text". - // Envoy [command operators](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators) may be used in the format. - // The [format string documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#config-access-log-format-strings) provides more information. - // +optional - Text *string `json:"text,omitempty"` - // JSON is additional attributes that describe the specific event occurrence. - // Structured format for the envoy access logs. Envoy [command operators](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators) - // can be used as values for fields within the Struct. - // It's required when the format type is "JSON". - // +optional - JSON map[string]string `json:"json,omitempty"` -} - -type ProxyAccessLogSinkType string - -const ( - // ProxyAccessLogSinkTypeFile defines the file accesslog sink. - ProxyAccessLogSinkTypeFile ProxyAccessLogSinkType = "File" - // ProxyAccessLogSinkTypeOpenTelemetry defines the OpenTelemetry accesslog sink. - ProxyAccessLogSinkTypeOpenTelemetry ProxyAccessLogSinkType = "OpenTelemetry" -) - -type ProxyAccessLogSink struct { - // Type defines the type of accesslog sink. - // +kubebuilder:validation:Enum=File;OpenTelemetry - Type ProxyAccessLogSinkType `json:"type,omitempty"` - // File defines the file accesslog sink. - // +optional - File *FileEnvoyProxyAccessLog `json:"file,omitempty"` - // OpenTelemetry defines the OpenTelemetry accesslog sink. - // +optional - OpenTelemetry *OpenTelemetryEnvoyProxyAccessLog `json:"openTelemetry,omitempty"` -} - -type FileEnvoyProxyAccessLog struct { - // Path defines the file path used to expose envoy access log(e.g. /dev/stdout). - // Empty value disables accesslog. - Path string `json:"path,omitempty"` -} - -// TODO: consider reuse ExtensionService? -type OpenTelemetryEnvoyProxyAccessLog struct { - // Host define the extension service hostname. - Host string `json:"host"` - // Port defines the port the extension service is exposed on. - // - // +optional - // +kubebuilder:validation:Minimum=0 - // +kubebuilder:default=4317 - Port int32 `json:"port,omitempty"` - // Resources is a set of labels that describe the source of a log entry, including envoy node info. - // It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). - // +optional - Resources map[string]string `json:"resources,omitempty"` - - // TODO: support more OpenTelemetry accesslog options(e.g. TLS, auth etc.) in the future. -} -``` - -### Example - -- The following is an example to disable access log. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/accesslog/disable-accesslog.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: disable-accesslog - namespace: envoy-gateway-system -spec: - telemetry: - accessLog: - disable: true -``` - -- The following is an example with text format access log. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/accesslog/text-accesslog.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: text-access-logging - namespace: envoy-gateway-system -spec: - telemetry: - accessLog: - settings: - - format: - type: Text - text: | - [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" - sinks: - - type: File - file: - path: /dev/stdout -``` - -- The following is an example with json format access log. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/accesslog/json-accesslog.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: json-access-logging - namespace: envoy-gateway-system -spec: - telemetry: - accessLog: - settings: - - format: - type: JSON - json: - status: "%RESPONSE_CODE%" - message: "%LOCAL_REPLY_BODY%" - sinks: - - type: File - file: - path: /dev/stdout -``` - -- The following is an example with OpenTelemetry format access log. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/accesslog/otel-accesslog.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: otel-access-logging - namespace: envoy-gateway-system -spec: - telemetry: - accessLog: - settings: - - format: - type: Text - text: | - [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" - sinks: - - type: OpenTelemetry - openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 - resources: - k8s.cluster.name: "cluster-1" -``` - -- The following is an example of sending same format to different sinks. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/accesslog/multi-sinks.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: multi-sinks - namespace: envoy-gateway-system -spec: - telemetry: - accessLog: - settings: - - format: - type: Text - text: | - [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" - sinks: - - type: File - file: - path: /dev/stdout - - type: OpenTelemetry - openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 - resources: - k8s.cluster.name: "cluster-1" -``` - -[Gateway API]: https://gateway-api.sigs.k8s.io/ -[support levels]: https://gateway-api.sigs.k8s.io/concepts/conformance/?h=extended#2-support-levels -[CEL]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/access_loggers/filters/cel/v3/cel.proto#extension-envoy-access-loggers-extension-filters-cel -[HttpGrpcAccessLogConfig]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/access_loggers/grpc/v3/als.proto#extensions-access-loggers-grpc-v3-httpgrpcaccesslogconfig -[TcpGrpcAccessLogConfig]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/access_loggers/grpc/v3/als.proto#extensions-access-loggers-grpc-v3-tcpgrpcaccesslogconfig diff --git a/site/content/en/v1.0.1/contributions/design/backend-traffic-policy.md b/site/content/en/v1.0.1/contributions/design/backend-traffic-policy.md deleted file mode 100644 index 9411ef20978..00000000000 --- a/site/content/en/v1.0.1/contributions/design/backend-traffic-policy.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -title: "BackendTrafficPolicy" ---- - -## Overview - -This design document introduces the `BackendTrafficPolicy` API allowing users to configure -the behavior for how the Envoy Proxy server communicates with upstream backend services/endpoints. - -## Goals - -- Add an API definition to hold settings for configuring behavior of the connection between the backend services -and Envoy Proxy listener. - -## Non Goals - -- Define the API configuration fields in this API. - -## Implementation - -`BackendTrafficPolicy` is an implied hierarchy type API that can be used to extend [Gateway API][]. -It can target either a `Gateway`, or an xRoute (`HTTPRoute`/`GRPCRoute`/etc.). When targeting a `Gateway`, -it will apply the configured settings within ght `BackendTrafficPolicy` to all children xRoute resources of that `Gateway`. -If a `BackendTrafficPolicy` targets an xRoute and a different `BackendTrafficPolicy` targets the `Gateway` that route belongs to, -then the configuration from the policy that is targeting the xRoute resource will win in a conflict. - -### Example - -Here is an example highlighting how a user can configure this API. - -```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: http - protocol: HTTP - port: 80 ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: ipv4-route - namespace: default -spec: - parentRefs: - - name: eg - hostnames: - - "www.foo.example.com" - rules: - - backendRefs: - - group: "" - kind: Service - name: ipv4-service - port: 3000 - weight: 1 - matches: - - path: - type: PathPrefix - value: / ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: ipv6-route - namespace: default -spec: - parentRefs: - - name: eg - hostnames: - - "www.bar.example.com" - rules: - - backendRefs: - - group: "" - kind: Service - name: ipv6-service - port: 3000 - weight: 1 - matches: - - path: - type: PathPrefix - value: / ---- -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: default-ipv-policy - namespace: default -spec: - protocols: - enableIPv6: false - targetRef: - group: gateway.networking.k8s.io - kind: Gateway - name: eg - namespace: default ---- -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ipv6-support-policy - namespace: default -spec: - protocols: - enableIPv6: true - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: ipv6-route - namespace: default -``` - -## Features / API Fields - -Here is a list of some features that can be included in this API. Note that this list is not exhaustive. - -- Protocol configuration -- Circuit breaking -- Retries -- Keep alive probes -- Health checking -- Load balancing -- Rate limit - -## Design Decisions - -- This API will only support a single `targetRef` and can bind to only a `Gateway` or xRoute (`HTTPRoute`/`GRPCRoute`/etc.) resource. -- This API resource MUST be part of same namespace as the resource it targets. -- There can be only be ONE policy resource attached to a specific `Listener` (section) within a `Gateway` -- 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 multiple polices target the same resource, the oldest resource (based on creation timestamp) will -attach to the Gateway Listeners, the others will not. -- 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`. - -## Alternatives - -- The project can indefintely wait for these configuration parameters to be part of the [Gateway API][]. - -[Gateway API]: https://gateway-api.sigs.k8s.io/ diff --git a/site/content/en/v1.0.1/contributions/design/client-traffic-policy.md b/site/content/en/v1.0.1/contributions/design/client-traffic-policy.md deleted file mode 100644 index 9cd72d84575..00000000000 --- a/site/content/en/v1.0.1/contributions/design/client-traffic-policy.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: "ClientTrafficPolicy " ---- - -## Overview - -This design document introduces the `ClientTrafficPolicy` API allowing system administrators to configure -the behavior for how the Envoy Proxy server behaves with downstream clients. - -## Goals - -* Add an API definition to hold settings for configuring behavior of the connection between the downstream -client and Envoy Proxy listener. - -## Non Goals - -* Define the API configuration fields in this API. - -## Implementation - -`ClientTrafficPolicy` is a [Direct Policy Attachment][] type API that can be used to extend [Gateway API][] -to define configuration that affect the connection between the downstream client and Envoy Proxy listener. - -### Example - -Here is an example highlighting how a user can configure this API. - -``` -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: http - protocol: HTTP - port: 80 ---- -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: ClientTrafficPolicy -metadata: - name: enable-proxy-protocol-policy - namespace: default -spec: - targetRef: - group: gateway.networking.k8s.io - kind: Gateway - name: eg - namespace: default - enableProxyProtocol: true -``` - -## Features / API Fields - -Here is a list of features that can be included in this API - -* Downstream ProxyProtocol -* Downstream Keep Alives -* IP Blocking -* Downstream HTTP3 - -## Design Decisions - -* This API will only support a single `targetRef` and can bind to only a `Gateway` resource. -* This API resource MUST be part of same namespace as the `Gateway` resource -* There can be only be ONE policy resource attached to a specific `Listener` (section) within a `Gateway` -* 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 multiple polices target the same resource, the oldest resource (based on creation timestamp) will -attach to the Gateway Listeners, the others will not. -* 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`. - -## Alternatives - -* The project can indefintely wait for these configuration parameters to be part of the [Gateway API]. - -[Direct Policy Attachment]: https://gateway-api.sigs.k8s.io/references/policy-attachment/#direct-policy-attachment -[Gateway API]: https://gateway-api.sigs.k8s.io/ diff --git a/site/content/en/v1.0.1/contributions/design/config-api.md b/site/content/en/v1.0.1/contributions/design/config-api.md deleted file mode 100644 index 1c6f3057848..00000000000 --- a/site/content/en/v1.0.1/contributions/design/config-api.md +++ /dev/null @@ -1,353 +0,0 @@ ---- -title: "Configuration API Design" ---- - -## Motivation - -[Issue 51][issue_51] specifies the need to design an API for configuring Envoy Gateway. The control plane is configured -statically at startup and the data plane is configured dynamically through Kubernetes resources, primarily -[Gateway API][gw_api] objects. Refer to the Envoy Gateway [design doc][design_doc] for additional details regarding -Envoy Gateway terminology and configuration. - -## Goals - -* Define an __initial__ API to configure Envoy Gateway at startup. -* Define an __initial__ API for configuring the managed data plane, e.g. Envoy proxies. - -## Non-Goals - -* Implementation of the configuration APIs. -* Define the `status` subresource of the configuration APIs. -* Define a __complete__ set of APIs for configuring Envoy Gateway. As stated in the [Goals](#goals), this document - defines the initial configuration APIs. -* Define an API for deploying/provisioning/operating Envoy Gateway. If needed, a future Envoy Gateway operator would be - responsible for designing and implementing this type of API. -* Specify tooling for managing the API, e.g. generate protos, CRDs, controller RBAC, etc. - -## Control Plane API - -The `EnvoyGateway` API defines the control plane configuration, e.g. Envoy Gateway. Key points of this API are: - -* It will define Envoy Gateway's startup configuration file. If the file does not exist, Envoy Gateway will start up - with default configuration parameters. -* EnvoyGateway inlines the `TypeMeta` API. This allows EnvoyGateway to be versioned and managed as a GroupVersionKind - scheme. -* EnvoyGateway does not contain a metadata field since it's currently represented as a static configuration file instead of - a Kubernetes resource. -* Since EnvoyGateway does not surface status, EnvoyGatewaySpec is inlined. -* If data plane static configuration is required in the future, Envoy Gateway will use a separate file for this purpose. - -The `v1alpha1` version and `gateway.envoyproxy.io` API group get generated: - -```go -// gateway/api/config/v1alpha1/doc.go - -// Package v1alpha1 contains API Schema definitions for the gateway.envoyproxy.io API group. -// -// +groupName=gateway.envoyproxy.io -package v1alpha1 -``` - -The initial `EnvoyGateway` API: - -```go -// gateway/api/config/v1alpha1/envoygateway.go - -package valpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// EnvoyGateway is the Schema for the envoygateways API -type EnvoyGateway struct { - metav1.TypeMeta `json:",inline"` - - // EnvoyGatewaySpec defines the desired state of Envoy Gateway. - EnvoyGatewaySpec `json:",inline"` -} - -// EnvoyGatewaySpec defines the desired state of Envoy Gateway configuration. -type EnvoyGatewaySpec struct { - // Gateway defines Gateway-API specific configuration. If unset, default - // configuration parameters will apply. - // - // +optional - Gateway *Gateway `json:"gateway,omitempty"` - - // Provider defines the desired provider configuration. If unspecified, - // the Kubernetes provider is used with default parameters. - // - // +optional - Provider *EnvoyGatewayProvider `json:"provider,omitempty"` -} - -// Gateway defines desired Gateway API configuration of Envoy Gateway. -type Gateway struct { - // ControllerName defines the name of the Gateway API controller. If unspecified, - // defaults to "gateway.envoyproxy.io/gatewayclass-controller". See the following - // for additional details: - // - // https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.GatewayClass - // - // +optional - ControllerName string `json:"controllerName,omitempty"` -} - -// EnvoyGatewayProvider defines the desired configuration of a provider. -// +union -type EnvoyGatewayProvider struct { - // Type is the type of provider to use. If unset, the Kubernetes provider is used. - // - // +unionDiscriminator - Type ProviderType `json:"type,omitempty"` - // Kubernetes defines the configuration of the Kubernetes provider. Kubernetes - // provides runtime configuration via the Kubernetes API. - // - // +optional - Kubernetes *EnvoyGatewayKubernetesProvider `json:"kubernetes,omitempty"` - - // File defines the configuration of the File provider. File provides runtime - // configuration defined by one or more files. - // - // +optional - File *EnvoyGatewayFileProvider `json:"file,omitempty"` -} - -// ProviderType defines the types of providers supported by Envoy Gateway. -type ProviderType string - -const ( - // KubernetesProviderType defines the "Kubernetes" provider. - KubernetesProviderType ProviderType = "Kubernetes" - - // FileProviderType defines the "File" provider. - FileProviderType ProviderType = "File" -) - -// EnvoyGatewayKubernetesProvider defines configuration for the Kubernetes provider. -type EnvoyGatewayKubernetesProvider struct { - // TODO: Add config as use cases are better understood. -} - -// EnvoyGatewayFileProvider defines configuration for the File provider. -type EnvoyGatewayFileProvider struct { - // TODO: Add config as use cases are better understood. -} -``` - -__Note:__ Provider-specific configuration is defined in the `{$PROVIDER_NAME}Provider` API. - -### Gateway - -Gateway defines desired configuration of [Gateway API][gw_api] controllers that reconcile and translate Gateway API -resources into the Intermediate Representation (IR). Refer to the Envoy Gateway [design doc][design_doc] for additional -details. - -### Provider - -Provider defines the desired configuration of an Envoy Gateway provider. A provider is an infrastructure component that -Envoy Gateway calls to establish its runtime configuration. Provider is a [union type][union]. Therefore, Envoy Gateway -can be configured with only one provider based on the `type` discriminator field. Refer to the Envoy Gateway -[design doc][design_doc] for additional details. - -### Control Plane Configuration - -The configuration file is defined by the EnvoyGateway API type. At startup, Envoy Gateway searches for the configuration -at "/etc/envoy-gateway/config.yaml". - -Start Envoy Gateway: - -```shell -$ ./envoy-gateway -``` - -Since the configuration file does not exist, Envoy Gateway will start with default configuration parameters. - -The Kubernetes provider can be configured explicitly using `provider.kubernetes`: - -```yaml -$ cat << EOF > /etc/envoy-gateway/config.yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -provider: - type: Kubernetes - kubernetes: {} -EOF -``` - -This configuration will cause Envoy Gateway to use the Kubernetes provider with default configuration parameters. - -The Kubernetes provider can be configured using the `provider` field. For example, the `foo` field can be set to "bar": - -```yaml -$ cat << EOF > /etc/envoy-gateway/config.yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -provider: - type: Kubernetes - kubernetes: - foo: bar -EOF -``` - -__Note:__ The Provider API from the Kubernetes package is currently undefined and `foo: bar` is provided for -illustration purposes only. - -The same API structure is followed for each supported provider. The following example causes Envoy Gateway to use the -File provider: - -```yaml -$ cat << EOF > /etc/envoy-gateway/config.yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -provider: - type: File - file: - foo: bar -EOF -``` - -__Note:__ The Provider API from the File package is currently undefined and `foo: bar` is provided for illustration -purposes only. - -Gateway API-related configuration is expressed through the `gateway` field. If unspecified, Envoy Gateway will use -default configuration parameters for `gateway`. The following example causes the [GatewayClass][gc] controller to -manage GatewayClasses with controllerName `foo` instead of the default `gateway.envoyproxy.io/gatewayclass-controller`: - -```yaml -$ cat << EOF > /etc/envoy-gateway/config.yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -gateway: - controllerName: foo -EOF -``` - -With any of the above configuration examples, Envoy Gateway can be started without any additional arguments: - -```shell -$ ./envoy-gateway -``` - -## Data Plane API - -The data plane is configured dynamically through Kubernetes resources, primarily [Gateway API][gw_api] objects. -Optionally, the data plane infrastructure can be configured by referencing a [custom resource (CR)][cr] through -`spec.parametersRef` of the managed GatewayClass. The `EnvoyProxy` API defines the data plane infrastructure -configuration and is represented as the CR referenced by the managed GatewayClass. Key points of this API are: - -* If unreferenced by `gatewayclass.spec.parametersRef`, default parameters will be used to configure the data plane - infrastructure, e.g. expose Envoy network endpoints using a LoadBalancer service. -* Envoy Gateway will follow Gateway API [recommendations][gc] regarding updates to the EnvoyProxy CR: - > It is recommended that this resource be used as a template for Gateways. This means that a Gateway is based on the - > state of the GatewayClass at the time it was created and changes to the GatewayClass or associated parameters are - > not propagated down to existing Gateways. - -The initial `EnvoyProxy` API: - -```go -// gateway/api/config/v1alpha1/envoyproxy.go - -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// EnvoyProxy is the Schema for the envoyproxies API. -type EnvoyProxy struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec EnvoyProxySpec `json:"spec,omitempty"` - Status EnvoyProxyStatus `json:"status,omitempty"` -} - -// EnvoyProxySpec defines the desired state of Envoy Proxy infrastructure -// configuration. -type EnvoyProxySpec struct { - // Undefined by this design spec. -} - -// EnvoyProxyStatus defines the observed state of EnvoyProxy. -type EnvoyProxyStatus struct { - // Undefined by this design spec. -} -``` - -The EnvoyProxySpec and EnvoyProxyStatus fields will be defined in the future as proxy infrastructure configuration use -cases are better understood. - -### Data Plane Configuration - -GatewayClass and Gateway resources define the data plane infrastructure. Note that all examples assume Envoy Gateway is -running with the Kubernetes provider. - -```yaml -apiVersion: gateway.networking.k8s.io/v1 -kind: GatewayClass -metadata: - name: example-class -spec: - controllerName: gateway.envoyproxy.io/gatewayclass-controller ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: Gateway -metadata: - name: example-gateway -spec: - gatewayClassName: example-class - listeners: - - name: http - protocol: HTTP - port: 80 -``` - -Since the GatewayClass does not define `spec.parametersRef`, the data plane is provisioned using default configuration -parameters. The Envoy proxies will be configured with a http listener and a Kubernetes LoadBalancer service listening -on port 80. - -The following example will configure the data plane to use a ClusterIP service instead of the default LoadBalancer -service: - -```yaml -apiVersion: gateway.networking.k8s.io/v1 -kind: GatewayClass -metadata: - name: example-class -spec: - controllerName: gateway.envoyproxy.io/gatewayclass-controller - parametersRef: - name: example-config - group: gateway.envoyproxy.io - kind: EnvoyProxy ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: Gateway -metadata: - name: example-gateway -spec: - gatewayClassName: example-class - listeners: - - name: http - protocol: HTTP - port: 80 ---- -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: example-config -spec: - networkPublishing: - type: ClusterIPService -``` - -__Note:__ The NetworkPublishing API is currently undefined and is provided here for illustration purposes only. - -[issue_51]: https://github.com/envoyproxy/gateway/issues/51 -[design_doc]: ../system-design/ -[gw_api]: https://gateway-api.sigs.k8s.io/ -[gc]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass -[cr]: https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/ -[union]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#unions diff --git a/site/content/en/v1.0.1/contributions/design/eg-metrics.md b/site/content/en/v1.0.1/contributions/design/eg-metrics.md deleted file mode 100644 index 0ca0e7229ec..00000000000 --- a/site/content/en/v1.0.1/contributions/design/eg-metrics.md +++ /dev/null @@ -1,233 +0,0 @@ ---- -date: 2023-10-10 -title: "Control Plane Observability: Metrics" ---- - -This document aims to cover all aspects of envoy gateway control plane metrics observability. - -{{% alert title="Note" color="secondary" %}} -**Data plane** observability (while important) is outside of scope for this document. For dataplane observability, refer to [here](../metrics). -{{% /alert %}} - -## Current State - -At present, the Envoy Gateway control plane provides logs and controller-runtime metrics, without traces. Logs are managed through our proprietary library (`internal/logging`, a shim to `zap`) and are written to `/dev/stdout`. - -## Goals - -Our objectives include: - -+ Supporting **PULL** mode for Prometheus metrics and exposing these metrics on the admin address. -+ Supporting **PUSH** mode for Prometheus metrics, thereby sending metrics to the Open Telemetry Stats sink via gRPC or HTTP. - -## Non-Goals - -Our non-goals include: - -+ Supporting other stats sinks. - -## Use-Cases - -The use-cases include: - -+ Exposing Prometheus metrics in the Envoy Gateway Control Plane. -+ Pushing Envoy Gateway Control Plane metrics via the Open Telemetry Sink. - -## Design - -### Standards - -Our metrics, will be built upon the [OpenTelemetry][] standards. All metrics will be configured via the [OpenTelemetry SDK][], which offers neutral libraries that can be connected to various backends. - -This approach allows the Envoy Gateway code to concentrate on the crucial aspect - generating the metrics - and delegate all other tasks to systems designed for telemetry ingestion. - -### Attributes - -OpenTelemetry defines a set of [Semantic Conventions][], including [Kubernetes specific ones][]. - -These attributes can be expressed in logs (as keys of structured logs), traces (as attributes), and metrics (as labels). - -We aim to use attributes consistently where applicable. Where possible, these should adhere to codified Semantic Conventions; when not possible, they should maintain consistency across the project. - -### Extensibility - -Envoy Gateway supports both **PULL/PUSH** mode metrics, with Metrics exported via Prometheus by default. - -Additionally, Envoy Gateway can export metrics using both the [OTEL gRPC metrics exporter][] and [OTEL HTTP metrics exporter][], which pushes metrics by grpc/http to a remote OTEL collector. - -Users can extend these in two ways: - -#### Downstream Collection - -Based on the exported data, other tools can collect, process, and export telemetry as needed. Some examples include: - -+ Metrics in **PULL** mode: The OTEL collector can scrape Prometheus and export to X. -+ Metrics in **PUSH** mode: The OTEL collector can receive OTEL gRPC/HTTP exporter metrics and export to X. - -While the examples above involve OTEL collectors, there are numerous other systems available. - -#### Vendor extensions - -The OTEL libraries allow for the registration of Providers/Handlers. While we will offer the default ones (PULL via Prometheus, PUSH via OTEL HTTP metrics exporter) mentioned in Envoy Gateway's extensibility, we can easily allow custom builds of Envoy Gateway to plug in alternatives if the default options don't meet their needs. - -For instance, users may prefer to write metrics over the OTLP gRPC metrics exporter instead of the HTTP metrics exporter. This is perfectly acceptable -- and almost impossible to prevent. The OTEL has ways to register their providers/exporters, and Envoy Gateway can ensure its usage is such that it's not overly difficult to swap out a different provider/exporter. - -### Stability - -Observability is, in essence, a user-facing API. Its primary purpose is to be consumed - by both humans and tooling. Therefore, having well-defined guarantees around their formats is crucial. - -Please note that this refers only to the contents of the telemetry - what we emit, the names of things, semantics, etc. Other settings like Prometheus vs OTLP, JSON vs plaintext, logging levels, etc., are not considered. - -I propose the following: - -#### Metrics - -Metrics offer the greatest potential for providing guarantees. They often directly influence alerts and dashboards, making changes highly impactful. This contrasts with traces and logs, which are often used for ad-hoc analysis, where minor changes to information can be easily understood by a human. - -Moreover, there is precedent for this: [Kubernetes Metrics Lifecycle][] has well-defined processes, and Envoy Gateway's dataplane (Envoy Proxy) metrics are de facto stable. - -Currently, all Envoy Gateway metrics lack defined stability. I suggest we categorize all existing metrics as either: - -+ ***Deprecated***: a metric that is intended to be phased out. -+ ***Experimental***: a metric that is off by default. -+ ***Alpha***: a metric that is on by default. - -We should aim to promote a core set of metrics to **Stable** within a few releases. - -## Envoy Gateway API Types - -New APIs will be added to Envoy Gateway config, which are used to manage Control Plane Telemetry bootstrap configs. - -### EnvoyGatewayTelemetry - -``` go -// EnvoyGatewayTelemetry defines telemetry configurations for envoy gateway control plane. -// Control plane will focus on metrics observability telemetry and tracing telemetry later. -type EnvoyGatewayTelemetry struct { - // Metrics defines metrics configuration for envoy gateway. - Metrics *EnvoyGatewayMetrics `json:"metrics,omitempty"` -} -``` - -### EnvoyGatewayMetrics - -> Prometheus will be exposed on 0.0.0.0:19001, which is not supported to be configured yet. - -``` go -// EnvoyGatewayMetrics defines control plane push/pull metrics configurations. -type EnvoyGatewayMetrics struct { - // Sinks defines the metric sinks where metrics are sent to. - Sinks []EnvoyGatewayMetricSink `json:"sinks,omitempty"` - // Prometheus defines the configuration for prometheus endpoint. - Prometheus *EnvoyGatewayPrometheusProvider `json:"prometheus,omitempty"` -} - -// EnvoyGatewayMetricSink defines control plane -// metric sinks where metrics are sent to. -type EnvoyGatewayMetricSink struct { - // Type defines the metric sink type. - // EG control plane currently supports OpenTelemetry. - // +kubebuilder:validation:Enum=OpenTelemetry - // +kubebuilder:default=OpenTelemetry - Type MetricSinkType `json:"type"` - // OpenTelemetry defines the configuration for OpenTelemetry sink. - // It's required if the sink type is OpenTelemetry. - OpenTelemetry *EnvoyGatewayOpenTelemetrySink `json:"openTelemetry,omitempty"` -} - -type EnvoyGatewayOpenTelemetrySink struct { - // Host define the sink service hostname. - Host string `json:"host"` - // Protocol define the sink service protocol. - // +kubebuilder:validation:Enum=grpc;http - Protocol string `json:"protocol"` - // Port defines the port the sink service is exposed on. - // - // +optional - // +kubebuilder:validation:Minimum=0 - // +kubebuilder:default=4317 - Port int32 `json:"port,omitempty"` -} - -// EnvoyGatewayPrometheusProvider will expose prometheus endpoint in pull mode. -type EnvoyGatewayPrometheusProvider struct { - // Disable defines if disables the prometheus metrics in pull mode. - // - Disable bool `json:"disable,omitempty"` -} - -``` - -#### Example - -+ The following is an example to disable prometheus metric. - -``` yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -gateway: - controllerName: gateway.envoyproxy.io/gatewayclass-controller -logging: - level: null - default: info -provider: - type: Kubernetes -telemetry: - metrics: - prometheus: - disable: true -``` - -+ The following is an example to send metric via Open Telemetry sink to OTEL gRPC Collector. - -``` yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -gateway: - controllerName: gateway.envoyproxy.io/gatewayclass-controller -logging: - level: null - default: info -provider: - type: Kubernetes -telemetry: - metrics: - sinks: - - type: OpenTelemetry - openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 - protocol: grpc -``` - -+ The following is an example to disable prometheus metric and send metric via Open Telemetry sink to OTEL HTTP Collector at the same time. - -``` yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -gateway: - controllerName: gateway.envoyproxy.io/gatewayclass-controller -logging: - level: null - default: info -provider: - type: Kubernetes -telemetry: - metrics: - prometheus: - disable: false - sinks: - - type: OpenTelemetry - openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4318 - protocol: http -``` - -[OpenTelemetry]: https://opentelemetry.io/ -[OpenTelemetry SDK]: https://opentelemetry.io/docs/specs/otel/metrics/sdk/ -[Semantic Conventions]: https://opentelemetry.io/docs/concepts/semantic-conventions/ -[Kubernetes specific ones]: https://opentelemetry.io/docs/specs/otel/resource/semantic_conventions/k8s/ -[OTEL gRPC metrics exporter]: https://opentelemetry.io/docs/specs/otel/metrics/sdk_exporters/otlp/#general -[OTEL HTTP metrics exporter]: https://opentelemetry.io/docs/specs/otel/metrics/sdk_exporters/otlp/#general -[Kubernetes Metrics Lifecycle]: https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/#metric-lifecycle diff --git a/site/content/en/v1.0.1/contributions/design/egctl.md b/site/content/en/v1.0.1/contributions/design/egctl.md deleted file mode 100644 index 4bc8876092d..00000000000 --- a/site/content/en/v1.0.1/contributions/design/egctl.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: "egctl Design" ---- - -## Motivation - -EG should provide a command line tool with following capabilities: - -- Collect configuration from envoy proxy and gateway -- Analyse system configuration to diagnose any issues in envoy gateway - -This tool is named `egctl`. - -## Syntax - -Use the following syntax to run `egctl` commands from your terminal window: - -```console -egctl [command] [entity] [name] [flags] -``` - -where `command`, `name`, and `flags` are: - -* `command`: Specifies the operation that you want to perform on one or more resources, - for example `config`, `version`. - -* `entity`: Specifies the entity the operation is being performed on such as `envoy-proxy` or `envoy-gateway`. - -* `name`: Specifies the name of the specified instance. - -* `flags`: Specifies optional flags. For example, you can use the `-c` or `--config` flags to specify the values for installing. - -If you need help, run `egctl help` from the terminal window. - -## Operation - -The following table includes short descriptions and the general syntax for all the `egctl` operations: - -| Operation | Syntax | Description | -| --------------| -------------------------------- | -------------------------------------------------------------------------------------| -| `version` | `egctl version` | Prints out build version information. | -| `config` | `egctl config ENTITY` | Retrieve information about proxy configuration from envoy proxy and gateway | -| `analyze` | `egctl analyze` | Analyze EG configuration and print validation messages | -| `experimental`| `egctl experimental` | Subcommand for experimental features. These do not guarantee backwards compatibility | - -## Examples - -Use the following set of examples to help you familiarize yourself with running the commonly used `egctl` operations: - -```console -# Retrieve all information about proxy configuration from envoy -egctl config envoy-proxy all - -# Retrieve listener information about proxy configuration from envoy -egctl config envoy-proxy listener - -# Retrieve the relevant rate limit configuration from the Rate Limit instance -egctl config envoy-ratelimit -``` diff --git a/site/content/en/v1.0.1/contributions/design/extending-envoy-gateway.md b/site/content/en/v1.0.1/contributions/design/extending-envoy-gateway.md deleted file mode 100644 index 0b549460b65..00000000000 --- a/site/content/en/v1.0.1/contributions/design/extending-envoy-gateway.md +++ /dev/null @@ -1,327 +0,0 @@ ---- -title: "Envoy Gateway Extensions Design" ---- - -As outlined in the [official goals][] for the Envoy Gateway project, one of the main goals is to "provide a common foundation for vendors to build value-added products -without having to re-engineer fundamental interactions". Development of the Envoy Gateway project has been focused on developing the core features for the project and -Kubernetes Gateway API conformance. This system focuses on the “common foundation for vendors” component by introducing a way for vendors to extend Envoy Gateway. - -To meaningfully extend Envoy Gateway and provide additional features, Extensions need to be able to introduce their own custom resources and have a high level of control -over the configuration generated by Envoy Gateway. Simply applying some static xDS configuration patches or relying on the existing Gateway API resources are both insufficient on their own -as means to add larger features that require dynamic user-configuration. - -As an example, an extension developer may wish to provide their own out-of-the-box authentication filters that require configuration from the end-user. This is a scenario where the ability to introduce -custom resources and attach them to [HTTPRoute][]s as an [ExtensionRef][] is necessary. Providing the same feature through a series of xDS patch resources would be too cumbersome for many end-users that want to avoid -that level of complexity when managing their clusters. - -## Goals - -- Provide a foundation for extending the Envoy Gateway control plane -- Allow Extension Developers to introduce their own custom resources for extending the Gateway-API via [ExtensionRefs][], [policyAttachments][] (future) and [backendRefs][] (future). -- Extension developers should **NOT** have to maintain a custom fork of Envoy Gateway -- Provide a system for extending Envoy Gateway which allows extension projects to ship updates independent of Envoy Gateway's release schedule -- Modify the generated Envoy xDS config -- Setup a foundation for the initial iteration of Extending Envoy Gateway -- Allow an Extension to hook into the infra manager pipeline (future) - -## Non-Goals - -- The initial design does not capture every hook that Envoy Gateway will eventually support. -- Extend [Gateway API Policy Attachments][]. At some point, these will be addressed using this extension system, but the initial implementation omits these. -- Support multiple extensions at the same time. Due to the fact that extensions will be modifying xDS resources after they are generated, handling the order of extension execution for each individual hook point is a challenge. Additionally, there is no -real way to prevent one extension from overwriting or breaking modifications to xDS resources that were made by another extension that was executed first. - -## Overview - -Envoy Gateway can be extended by vendors by means of an extension server developed by the vendor and deployed alongside Envoy Gateway. -An extension server can make use of one or more pre/post hooks inside Envoy Gateway before and after its major components (translator, etc.) to allow the extension to modify the data going into or coming out of these components. -An extension can be created external to Envoy Gateway as its own Kubernetes deployment or loaded as a sidecar. gRPC is used for the calls between Envoy Gateway and an extension. In the hook call, Envoy Gateway sends data as well -as context information to the extension and expects a reply with a modified version of the data that was sent to the extension. Since extensions fundamentally alter the logic and data that Envoy Gateway provides, Extension projects assume responsibility for any bugs and issues -they create as a direct result of their modification of Envoy Gateway. - -## Diagram - -![Architecture](/img/extension-example.png) - -## Registering Extensions in Envoy Gateway - -Information about the extension that Envoy Gateway needs to load is configured in the Envoy Gateway config. - -An example configuration: - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -extensionManager: - resources: - - group: example.myextension.io - version: v2 - kind: OAuth2Filter - hooks: - xdsTranslator: - post: - - Route - - VirtualHost - - HTTPListener - - Translation - service: - host: my-extension.example - port: 443 - tls: - certificateRef: - name: my-secret - namespace: default -``` - -An extension must supply connection information in the `extension.service` field so that Envoy Gateway can communicate with the extension. The `tls` configuration is optional. - -If the extension wants Envoy Gateway to watch resources for it then the extension must configure the optional `extension.resources` field and supply a list of: - -- `group`: the API group of the resource -- `version`: the API version of the resource -- `kind`: the Kind of resource - -The extension can configure the `extensionManager.hooks` field to specify which hook points it would like to support. If a given hook is not listed here then it will not be executed even -if the extension is configured properly. This allows extension developers to only opt-in to the hook points they want to make use of. - -This configuration is required to be provided at bootstrap and modifying the registered extension during runtime is not currently supported. -Envoy Gateway will keep track of the registered extension and its API `groups` and `kinds` when processing Gateway API resources. - -## Extending Gateway API and the Data Plane - -Envoy Gateway manages [Envoy][] deployments, which act as the data plane that handles actual user traffic. Users configure the data plane using the K8s Gateway API resources which Envoy -Gateway converts into [Envoy specific configuration (xDS)][] to send over to Envoy. - -Gateway API offers [ExtensionRef filters][] and [Policy Attachments][] as extension points for implementers to use. Envoy Gateway extends the Gateway API using these extension points to provide support for [rate limiting][] -and [authentication][] native to the project. The initial design of Envoy Gateway extensions will primarily focus on ExtensionRef filters so that extension developers can reference their own resources as HTTP Filters in the same way -that Envoy Gateway has native support for rate limiting and authentication filters. - -When Envoy Gateway encounters an [HTTPRoute][] or [GRPCRoute][] that has an `ExtensionRef` `filter` with a `group` and `kind` that Envoy Gateway does not support, it will first -check the registered extension to determine if it supports the referenced object before considering it a configuration error. - -This allows users to be able to reference additional filters provided by their Envoy Gateway Extension, in their `HTTPRoute`s / `GRPCRoute`s: - -```yaml -apiVersion: example.myextension.io/v1alpha1 -kind: OAuth2Filter -metadata: - name: oauth2-filter -spec: - ... - ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example -spec: - parentRefs: - - name: eg - hostnames: - - www.example.com - rules: - - clientSelectors: - - path: - type: PathPrefix - value: / - filters: - - type: ExtensionRef - extensionRef: - group: example.myextension.io - kind: OAuth2Filter - name: oauth2-filter - backendRefs: - - name: backend - port: 3000 -``` - -In order to enable the usage of new resources introduced by an extension for translation and xDS modification, Envoy Gateway provides hook points within the translation pipeline, where it calls out to the extension service registered in the [EnvoyGateway config][] -if they specify an `group` that matches the `group` of an `ExtensionRef` filter. The extension will then be able to modify the xDS that Envoy Gateway generated and send back the -modified configuration. If an extension is not registered or if the registered extension does not specify support for the `group` of an `ExtensionRef` filter then Envoy Gateway will treat it as an unknown resource -and provide an error to the user. - -**Note:** Currently (as of [v1][]) Gateway API does not provide a means to specify the namespace or version of an object referenced as an `ExtensionRef`. The extension mechanism will assume that -the namespace of any `ExtensionRef` is the same as the namespace of the `HTTPRoute` or `GRPCRoute` it is attached to rather than treating the `name` field of an `ExtensionRef` as a `name.namespace` string. -If Gateway API adds support for these fields then the design of the Envoy Gateway extensions will be updated to support them. - -## Watching New Resources - -Envoy Gateway will dynamically create new watches on resources introduced by the registered Extension. It does so by using the [controller-runtime][] to create new watches on [Unstructured][] resources that match the `version`s, `group`s, and `kind`s that the -registered extension configured. When communicating with an extension, Envoy Gateway sends these Unstructured resources over to the extension. This eliminates the need for the extension to create its own watches which would have a strong chance of creating race conditions and reconciliation loops when resources change. When an extension receives the Unstructured resources from Envoy Gateway it can perform its own type validation on them. Currently we make the simplifying assumption that the registered extension's `Kinds` are filters referenced by `extensionRef` in `HTTPRouteFilter`s . Support for Policy attachments will be introduced at a later time. - -## xDS Hooks API - -Envoy Gateway supports the following hooks as the initial foundation of the Extension system. Additional hooks can be developed using this extension system at a later point as new use-cases and needs are discovered. The primary iteration of the extension hooks -focuses solely on the modification of xDS resources. - -### Route Modification Hook - -The [Route][] level Hook provides a way for extensions to modify a route generated by Envoy Gateway before it is finalized. -Doing so allows extensions to configure/modify route fields configured by Envoy Gateway and also to configure the -Route's TypedPerFilterConfig which may be desirable to do things such as pass settings and information to ext_authz filters. -The Post Route Modify hook also passes a list of Unstructured data for the externalRefs owned by the extension on the HTTPRoute that created this xDS route -This hook is always executed when an extension is loaded that has added `Route` to the `EnvoyProxy.extensionManager.hooks.xdsTranslator.post`, and only on Routes which were generated from an HTTPRoute that uses extension resources as externalRef filters. - -```go -// PostRouteModifyRequest sends a Route that was generated by Envoy Gateway along with context information to an extension so that the Route can be modified -message PostRouteModifyRequest { - envoy.config.route.v3.Route route = 1; - PostRouteExtensionContext post_route_context = 2; -} - -// RouteExtensionContext provides resources introduced by an extension and watched by Envoy Gateway -// additional context information can be added to this message as more use-cases are discovered -message PostRouteExtensionContext { - // Resources introduced by the extension that were used as extensionRefs in an HTTPRoute/GRPCRoute - repeated ExtensionResource extension_resources = 1; - - // hostnames are the fully qualified domain names attached to the HTTPRoute - repeated string hostnames = 2; -} - -// ExtensionResource stores the data for a K8s API object referenced in an HTTPRouteFilter -// extensionRef. It is constructed from an unstructured.Unstructured marshalled to JSON. An extension -// can marshal the bytes from this resource back into an unstructured.Unstructured and then -// perform type checking to obtain the resource. -message ExtensionResource { - bytes unstructured_bytes = 1; -} - -// PostRouteModifyResponse is the expected response from an extension and contains a modified version of the Route that was sent -// If an extension returns a nil Route then it will not be modified -message PostRouteModifyResponse { - envoy.config.route.v3.Route route = 1; -} -``` - -### VirtualHost Modification Hook - -The [VirtualHost][] Hook provides a way for extensions to modify a VirtualHost generated by Envoy Gateway before it is finalized. -An extension can also make use of this hook to generate and insert entirely new Routes not generated by Envoy Gateway. -This hook is always executed when an extension is loaded that has added `VirtualHost` to the `EnvoyProxy.extensionManager.hooks.xdsTranslator.post`. -An extension may return nil to not make any changes to the VirtualHost. - -```protobuf -// PostVirtualHostModifyRequest sends a VirtualHost that was generated by Envoy Gateway along with context information to an extension so that the VirtualHost can be modified -message PostVirtualHostModifyRequest { - envoy.config.route.v3.VirtualHost virtual_host = 1; - PostVirtualHostExtensionContext post_virtual_host_context = 2; -} - -// Empty for now but we can add fields to the context as use-cases are discovered without -// breaking any clients that use the API -// additional context information can be added to this message as more use-cases are discovered -message PostVirtualHostExtensionContext {} - -// PostVirtualHostModifyResponse is the expected response from an extension and contains a modified version of the VirtualHost that was sent -// If an extension returns a nil Virtual Host then it will not be modified -message PostVirtualHostModifyResponse { - envoy.config.route.v3.VirtualHost virtual_host = 1; -} -``` - -### HTTP Listener Modification Hook - -The HTTP [Listener][] modification hook is the broadest xDS modification Hook available and allows an extension to make changes to a Listener generated by Envoy Gateway before it is finalized. -This hook is always executed when an extension is loaded that has added `HTTPListener` to the `EnvoyProxy.extensionManager.hooks.xdsTranslator.post`. An extension may return nil -in order to not make any changes to the Listener. - -```protobuf -// PostVirtualHostModifyRequest sends a Listener that was generated by Envoy Gateway along with context information to an extension so that the Listener can be modified -message PostHTTPListenerModifyRequest { - envoy.config.listener.v3.Listener listener = 1; - PostHTTPListenerExtensionContext post_listener_context = 2; -} - -// Empty for now but we can add fields to the context as use-cases are discovered without -// breaking any clients that use the API -// additional context information can be added to this message as more use-cases are discovered -message PostHTTPListenerExtensionContext {} - -// PostHTTPListenerModifyResponse is the expected response from an extension and contains a modified version of the Listener that was sent -// If an extension returns a nil Listener then it will not be modified -message PostHTTPListenerModifyResponse { - envoy.config.listener.v3.Listener listener = 1; -} -``` - -### Post xDS Translation Modify Hook - -The Post Translate Modify hook allows an extension to modify the clusters and secrets in the xDS config. -This allows for inserting clusters that may change along with extension specific configuration to be dynamically created rather than -using custom bootstrap config which would be sufficient for clusters that are static and not prone to have their configurations changed. -An example of how this may be used is to inject a cluster that will be used by an ext_authz http filter created by the extension. -The list of clusters and secrets returned by the extension are used as the final list of all clusters and secrets -This hook is always executed when an extension is loaded that has added `Translation` to the `EnvoyProxy.extensionManager.hooks.xdsTranslator.post`. - -```protobuf -// PostTranslateModifyRequest currently sends only clusters and secrets to an extension. -// The extension is free to add/modify/remove the resources it received. -message PostTranslateModifyRequest { - PostTranslateExtensionContext post_translate_context = 1; - repeated envoy.config.cluster.v3.Cluster clusters = 2; - repeated envoy.extensions.transport_sockets.tls.v3.Secret secrets = 3; -} - -// PostTranslateModifyResponse is the expected response from an extension and contains -// the full list of xDS clusters and secrets to be used for the xDS config. -message PostTranslateModifyResponse { - repeated envoy.config.cluster.v3.Cluster clusters = 1; - repeated envoy.extensions.transport_sockets.tls.v3.Secret secrets = 2; -} -``` - -### Extension Service - -Currently, an extension must implement all of the following hooks although it may return the input(s) it received -if no modification of the resource is desired. A future expansion of the extension hooks will allow an Extension to specify -with config which Hooks it would like to "subscribe" to and which Hooks it does not wish to support. These specific Hooks were chosen -in order to provide extensions with the ability to have both broad and specific control over xDS resources and to minimize the amount of data being sent. - -```protobuf -service EnvoyGatewayExtension { - rpc PostRouteModify (PostRouteModifyRequest) returns (PostRouteModifyResponse) {}; - rpc PostVirtualHostModify(PostVirtualHostModifyRequest) returns (PostVirtualHostModifyResponse) {}; - rpc PostHTTPListenerModify(PostHTTPListenerModifyRequest) returns (PostHTTPListenerModifyResponse) {}; - rpc PostTranslateModify(PostTranslateModifyRequest) returns (PostTranslateModifyResponse) {}; -} -``` - -## Design Decisions - -- Envoy Gateway watches new custom resources introduced by a loaded extension and passes the resources back to the extension when they are used. - - This decision was made to solve the problem about how resources introduced by an extension get watched. If an extension server watches its own resources then it would need some way to trigger an Envoy Gateway reconfigure when a resource that Envoy Gateway is not watching gets updated. Having Envoy Gateway watch all resources removes any concern about creating race confitions or reconcile loops that would result from Envoy Gateway and the extension server both having so much separate state that needs to be synchronized. -- The Extension Server takes ownership of producing the correct xDS configuration in the hook responses -- The Extension Server will be responsible for ensuring the performance of the hook processing time -- The Post xDS level gRPC hooks all currently send a context field even though it contains nothing for several hooks. These fields exist so that they can be updadated in the future to pass -additional information to extensions as new use-cases and needs are discovered. -- The initial design supplies the scaffolding for both "pre xDS" and "post xDS" hooks. Only the post hooks are currently implemented which operate on xDS resources after they have been generated. -The pre hooks will be implemented at a later date along with one or more hooks in the infra manager. The infra manager level hook(s) will exist to power use-cases such as dynamically creating Deployments/Services for the extension the -whenever Envoy Gateway creates an instance of Envoy Proxy. An extension developer might want to take advantage of this functionality to inject a new authorization service as a sidecar on the Envoy Proxy deployment for reduced latency. -- Multiple extensions are not be supported at the same time. Preventing conflict between multiple extensions that are mangling xDS resources is too difficult to ensure compatibility with and is likely to only generate issues. - -## Known Challenges - -Extending Envoy Gateway by using an external extension server which makes use of hook points in Envoy Gateway does comes with a few trade-offs. One known trade-off is the impact of the time that it takes for the hook calls to be executed. Since an extension would make use of hook points in Envoy Gateway that use gRPC for communication, the time it takes to perform these requests could become a concern for some extension developers. One way to minimize the request time of the hook calls is to load the extension server as a sidecar to Envoy Gateway to minimize the impact of networking on the hook calls. - -[official goals]: https://github.com/envoyproxy/gateway/blob/main/GOALS.md#extensibility -[ExtensionRef filters]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.LocalObjectReference -[ExtensionRef]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.LocalObjectReference -[ExtensionRefs]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.LocalObjectReference -[backendRefs]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.BackendObjectReference -[Gateway API Policy attachments]: https://gateway-api.sigs.k8s.io/references/policy-attachment/?h=policy -[Policy Attachments]: https://gateway-api.sigs.k8s.io/references/policy-attachment/?h=policy -[policyAttachments]: https://gateway-api.sigs.k8s.io/references/policy-attachment/?h=policy -[Envoy]: https://www.envoyproxy.io/ -[Envoy specific configuration (xDS)]: https://www.envoyproxy.io/docs/envoy/v1.25.1/configuration/configuration -[v1]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1 -[rate limiting]: ./rate-limit -[authentication]: ../../tasks/security/jwt-authentication -[HTTPRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRoute -[GRPCRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRoute -[EnvoyGateway config]: ../../api/extension_types/#envoygateway -[controller-runtime]: https://github.com/kubernetes-sigs/controller-runtime -[Unstructured]: https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured -[Listener]: https://www.envoyproxy.io/docs/envoy/v1.23.0/api-v3/config/listener/v3/listener.proto#config-listener-v3-listener -[VirtualHost]: https://www.envoyproxy.io/docs/envoy/v1.23.0/api-v3/config/route/v3/route_components.proto#config-route-v3-virtualhost -[Route]: https://www.envoyproxy.io/docs/envoy/v1.23.0/api-v3/config/route/v3/route_components.proto#config-route-v3-route diff --git a/site/content/en/v1.0.1/contributions/design/gatewayapi-translator.md b/site/content/en/v1.0.1/contributions/design/gatewayapi-translator.md deleted file mode 100644 index a086b80bfee..00000000000 --- a/site/content/en/v1.0.1/contributions/design/gatewayapi-translator.md +++ /dev/null @@ -1,253 +0,0 @@ ---- -title: "Gateway API Translator Design" -weight: 4 ---- - -The Gateway API translates external resources, e.g. GatewayClass, from the configured Provider to the Intermediate -Representation (IR). - -## Assumptions - -Initially target core conformance features only, to be followed by extended conformance features. - -## Inputs and Outputs - -The main inputs to the Gateway API translator are: - -- GatewayClass, Gateway, HTTPRoute, TLSRoute, Service, ReferenceGrant, Namespace, and Secret resources. - -__Note:__ ReferenceGrant is not fully implemented as of v0.2. - -The outputs of the Gateway API translator are: - -- Xds and Infra Internal Representations (IRs). -- Status updates for GatewayClass, Gateways, HTTPRoutes - -## Listener Compatibility - -Envoy Gateway follows Gateway API listener compatibility spec: -> Each listener in a Gateway must have a unique combination of Hostname, Port, and Protocol. An implementation MAY group -> Listeners by Port and then collapse each group of Listeners into a single Listener if the implementation determines -> that the Listeners in the group are “compatible”. - -__Note:__ Envoy Gateway does not collapse listeners across multiple Gateways. - -### Listener Compatibility Examples - -#### Example 1: Gateway with compatible Listeners (same port & protocol, different hostnames) - -```yaml -kind: Gateway -apiVersion: gateway.networking.k8s.io/v1 -metadata: - name: gateway-1 - namespace: envoy-gateway -spec: - gatewayClassName: envoy-gateway - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All - hostname: "*.envoygateway.io" - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All - hostname: whales.envoygateway.io -``` - -#### Example 2: Gateway with compatible Listeners (same port & protocol, one hostname specified, one not) - -```yaml -kind: Gateway -apiVersion: gateway.networking.k8s.io/v1 -metadata: - name: gateway-1 - namespace: envoy-gateway -spec: - gatewayClassName: envoy-gateway - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All - hostname: "*.envoygateway.io" - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All -``` - -#### Example 3: Gateway with incompatible Listeners (same port, protocol and hostname) - -```yaml -kind: Gateway -apiVersion: gateway.networking.k8s.io/v1 -metadata: - name: gateway-1 - namespace: envoy-gateway -spec: - gatewayClassName: envoy-gateway - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All - hostname: whales.envoygateway.io - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All - hostname: whales.envoygateway.io -``` - -#### Example 4: Gateway with incompatible Listeners (neither specify a hostname) - -```yaml -kind: Gateway -apiVersion: gateway.networking.k8s.io/v1 -metadata: - name: gateway-1 - namespace: envoy-gateway -spec: - gatewayClassName: envoy-gateway - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All -``` - -## Computing Status - -Gateway API specifies a rich set of status fields & conditions for each resource. To achieve conformance, Envoy Gateway -must compute the appropriate status fields and conditions for managed resources. - -Status is computed and set for: - -- The managed GatewayClass (`gatewayclass.status.conditions`). -- Each managed Gateway, based on its Listeners' status (`gateway.status.conditions`). For the Kubernetes provider, the - Envoy Deployment and Service status are also included to calculate Gateway status. -- Listeners for each Gateway (`gateway.status.listeners`). -- The ParentRef for each Route (`route.status.parents`). - -The Gateway API translator is responsible for calculating status conditions while translating Gateway API resources to -the IR and publishing status over the [message bus][]. The Status Manager subscribes to these status messages and -updates the resource status using the configured provider. For example, the Status Manager uses a Kubernetes client to -update resource status on the Kubernetes API server. - -## Outline - -The following roughly outlines the translation process. Each step may produce (1) IR; and (2) status updates on Gateway -API resources. - -1. Process Gateway Listeners - - Validate unique hostnames, ports, and protocols. - - Validate and compute supported kinds. - - Validate allowed namespaces (validate selector if specified). - - Validate TLS fields if specified, including resolving referenced Secrets. - -2. Process HTTPRoutes - - foreach route rule: - - compute matches - - [core] path exact, path prefix - - [core] header exact - - [extended] query param exact - - [extended] HTTP method - - compute filters - - [core] request header modifier (set/add/remove) - - [core] request redirect (hostname, statuscode) - - [extended] request mirror - - compute backends - - [core] Kubernetes services - - foreach route parent ref: - - get matching listeners (check Gateway, section name, listener validation status, listener allowed routes, hostname intersection) - - foreach matching listener: - - foreach hostname intersection with route: - - add each computed route rule to host - -## Context Structs - -To help store, access and manipulate information as it's processed during the translation process, a set of context -structs are used. These structs wrap a given Gateway API type, and add additional fields and methods to support -processing. - -`GatewayContext` wraps a Gateway and provides helper methods for setting conditions, accessing Listeners, etc. - -```go -type GatewayContext struct { - // The managed Gateway - *v1beta1.Gateway - - // A list of Gateway ListenerContexts. - listeners []*ListenerContext -} -``` - -`ListenerContext` wraps a Listener and provides helper methods for setting conditions and other status information on -the associated Gateway. - -```go -type ListenerContext struct { - // The Gateway listener. - *v1beta1.Listener - - // The Gateway this Listener belongs to. - gateway *v1beta1.Gateway - - // An index used for managing this listener in the list of Gateway listeners. - listenerStatusIdx int - - // Only Routes in namespaces selected by the selector may be attached - // to the Gateway this listener belongs to. - namespaceSelector labels.Selector - - // The TLS Secret for this Listener, if applicable. - tlsSecret *v1.Secret -} -``` - -`RouteContext` represents a generic Route object (HTTPRoute, TLSRoute, etc.) that can reference Gateway objects. - -```go -type RouteContext interface { - client.Object - - // GetRouteType returns the Kind of the Route object, HTTPRoute, - // TLSRoute, TCPRoute, UDPRoute etc. - GetRouteType() string - - // GetHostnames returns the hosts targeted by the Route object. - GetHostnames() []string - - // GetParentReferences returns the ParentReference of the Route object. - GetParentReferences() []v1beta1.ParentReference - - // GetRouteParentContext returns RouteParentContext by using the Route - // objects' ParentReference. - GetRouteParentContext(forParentRef v1beta1.ParentReference) *RouteParentContext -} -``` - -[message bus]: ../watching/ diff --git a/site/content/en/v1.0.1/contributions/design/goals.md b/site/content/en/v1.0.1/contributions/design/goals.md deleted file mode 100644 index fd38b2004c6..00000000000 --- a/site/content/en/v1.0.1/contributions/design/goals.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: "Goals" -weight: 1 ---- - -The high-level goal of the Envoy Gateway project is to attract more users to Envoy by lowering barriers to adoption -through expressive, extensible, role-oriented APIs that support a multitude of ingress and L7/L4 traffic routing -use cases; and provide a common foundation for vendors to build value-added products without having to re-engineer -fundamental interactions. - -## Objectives - -### Expressive API - -The Envoy Gateway project will expose a simple and expressive API, with defaults set for many capabilities. - -The API will be the Kubernetes-native [Gateway API][], plus Envoy-specific extensions and extension points. This -expressive and familiar API will make Envoy accessible to more users, especially application developers, and make Envoy -a stronger option for "getting started" as compared to other proxies. Application developers will use the API out of -the box without needing to understand in-depth concepts of Envoy Proxy or use OSS wrappers. The API will use familiar -nouns that [users](#personas) understand. - -The core full-featured Envoy xDS APIs will remain available for those who need more capability and for those who -add functionality on top of Envoy Gateway, such as commercial API gateway products. - -This expressive API will not be implemented by Envoy Proxy, but rather an officially supported translation layer -on top. - -### Batteries included - -Envoy Gateway will simplify how Envoy is deployed and managed, allowing application developers to focus on -delivering core business value. - -The project plans to include additional infrastructure components required by users to fulfill their Ingress and API -gateway needs: It will handle Envoy infrastructure provisioning (e.g. Kubernetes Service, Deployment, et cetera), and -possibly infrastructure provisioning of related sidecar services. It will include sensible defaults with the ability to -override. It will include channels for improving ops by exposing status through API conditions and Kubernetes status -sub-resources. - -Making an application accessible needs to be a trivial task for any developer. Similarly, infrastructure administrators -will enjoy a simplified management model that doesn't require extensive knowledge of the solution's architecture to -operate. - -### All environments - -Envoy Gateway will support running natively in Kubernetes environments as well as non-Kubernetes deployments. - -Initially, Kubernetes will receive the most focus, with the aim of having Envoy Gateway become the de facto -standard for Kubernetes ingress supporting the [Gateway API][]. -Additional goals include multi-cluster support and various runtime environments. - -### Extensibility - -Vendors will have the ability to provide value-added products built on the Envoy Gateway foundation. - -It will remain easy for end-users to leverage common Envoy Proxy extension points such as providing an implementation -for authentication methods and rate-limiting. For advanced use cases, users will have the ability to use the full power -of xDS. - -Since a general-purpose API cannot address all use cases, Envoy Gateway will provide additional extension points -for flexibility. As such, Envoy Gateway will form the base of vendor-provided managed control plane solutions, -allowing vendors to shift to a higher management plane layer. - -## Non-objectives - -### Cannibalize vendor models - -Vendors need to have the ability to drive commercial value, so the goal is not to cannibalize any existing vendor -monetization model, though some vendors may be affected by it. - -### Disrupt current Envoy usage patterns - -Envoy Gateway is purely an additive convenience layer and is not meant to disrupt any usage pattern of any user -with Envoy Proxy, xDS, or go-control-plane. - -## Personas - -_In order of priority_ - -### 1. Application developer - -The application developer spends the majority of their time developing business logic code. They require the ability to -manage access to their application. - -### 2. Infrastructure administrators - -The infrastructure administrators are responsible for the installation, maintenance, and operation of -API gateways appliances in infrastructure, such as CRDs, roles, service accounts, certificates, etc. -Infrastructure administrators support the needs of application developers by managing instances of Envoy Gateway. - -[Gateway API]: https://gateway-api.sigs.k8s.io/ diff --git a/site/content/en/v1.0.1/contributions/design/local-envoy-gateway.md b/site/content/en/v1.0.1/contributions/design/local-envoy-gateway.md deleted file mode 100644 index aad0dc5f6f2..00000000000 --- a/site/content/en/v1.0.1/contributions/design/local-envoy-gateway.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "Running Envoy Gateway locally" ---- - -## Overview - -Today, Envoy Gateway runs only on Kubernetes. This is an ideal solution -when the applications are running in Kubernetes. -However there might be cases when the applications are running on the host which would -require Envoy Gateway to run locally. - -## Goals - -* Define an API to allow Envoy Gateway to retrieve configuration while running locally. -* Define an API to allow Envoy Gateway to deploy the managed Envoy Proxy fleet on the host -machine. - -## Non Goals - -* Support multiple ways to retrieve configuration while running locally. -* Support multiple ways to deploy the Envoy Proxy fleet locally on the host. - -## API - -* The `provider` field within the `EnvoyGateway` configuration only supports -`Kubernetes` today which provides two features - the ability to retrieve -resources from the Kubernetes API Server as well as deploy the managed -Envoy Proxy fleet on Kubernetes. -* This document proposes adding a new top level `provider` type called `Custom` -with two fields called `resource` and `infrastructure` to allow the user to configure -the sub providers for providing resource configuration and an infrastructure to deploy -the Envoy Proxy data plane in. -* A `File` resource provider will be introduced to enable retrieveing configuration locally -by reading from the configuration from a file. -* A `Host` infrastructure provider will be introduced to allow Envoy Gateway to spawn a -Envoy Proxy child process on the host. - -Here is an example configuration - -``` -provider: - type: Custom - custom: - resource: - type: File - file: - paths: - - "config.yaml" - infrastructure: - type: Host - host: {} -``` diff --git a/site/content/en/v1.0.1/contributions/design/metrics.md b/site/content/en/v1.0.1/contributions/design/metrics.md deleted file mode 100644 index 78b05eea98e..00000000000 --- a/site/content/en/v1.0.1/contributions/design/metrics.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: "Observability: Metrics" ---- - -## Overview - -Envoy provide robust platform for metrics, Envoy support three different kinds of stats: counter, gauges, histograms. - -Envoy enables prometheus format output via the `/stats/prometheus` [admin endpoint][]. - -Envoy support different kinds of sinks, but EG will only support [Open Telemetry sink][]. - -Envoy Gateway leverages [Gateway API][] for configuring managed Envoy proxies. Gateway API defines core, extended, and implementation-specific API [support levels][] for implementers such as Envoy Gateway to expose features. Since metrics is not covered by `Core` or `Extended` APIs, EG should provide an easy to config metrics per `EnvoyProxy`. - -## Goals - -- Support expose metrics in prometheus way(reuse probe port). -- Support Open Telemetry stats sink. - -## Non-Goals - -- Support other stats sink. - -## Use-Cases - -- Enable prometheus metric by default -- Disable prometheus metric -- Push metrics via Open Telemetry Sink -- TODO: Customize histogram buckets of target metric -- TODO: Support stats matcher - -### ProxyMetric API Type - -```golang mdox-exec="sed '1,7d' api/v1alpha1/metric_types.go" -type ProxyMetrics struct { - // Prometheus defines the configuration for Admin endpoint `/stats/prometheus`. - Prometheus *PrometheusProvider `json:"prometheus,omitempty"` - // Sinks defines the metric sinks where metrics are sent to. - Sinks []MetricSink `json:"sinks,omitempty"` -} - -type MetricSinkType string - -const ( - MetricSinkTypeOpenTelemetry MetricSinkType = "OpenTelemetry" -) - -type MetricSink struct { - // Type defines the metric sink type. - // EG currently only supports OpenTelemetry. - // +kubebuilder:validation:Enum=OpenTelemetry - // +kubebuilder:default=OpenTelemetry - Type MetricSinkType `json:"type"` - // OpenTelemetry defines the configuration for OpenTelemetry sink. - // It's required if the sink type is OpenTelemetry. - OpenTelemetry *OpenTelemetrySink `json:"openTelemetry,omitempty"` -} - -type OpenTelemetrySink struct { - // Host define the service hostname. - Host string `json:"host"` - // Port defines the port the service is exposed on. - // - // +optional - // +kubebuilder:validation:Minimum=0 - // +kubebuilder:validation:Maximum=65535 - // +kubebuilder:default=4317 - Port int32 `json:"port,omitempty"` - - // TODO: add support for customizing OpenTelemetry sink in https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/stat_sinks/open_telemetry/v3/open_telemetry.proto#envoy-v3-api-msg-extensions-stat-sinks-open-telemetry-v3-sinkconfig -} - -type PrometheusProvider struct { - // Disable the Prometheus endpoint. - Disable bool `json:"disable,omitempty"` -} -``` - -### Example - -- The following is an example to disable prometheus metric. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/metric/disable-prometheus.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: prometheus - namespace: envoy-gateway-system -spec: - telemetry: - metrics: - prometheus: - disable: true -``` - -- The following is an example to send metric via Open Telemetry sink. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/metric/otel-sink.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: otel-sink - namespace: envoy-gateway-system -spec: - telemetry: - metrics: - sinks: - - type: OpenTelemetry - openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 -``` - -[admin endpoint]: https://www.envoyproxy.io/docs/envoy/latest/operations/admin -[Open Telemetry sink]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/stat_sinks/open_telemetry/v3/open_telemetry.proto -[Gateway API]: https://gateway-api.sigs.k8s.io/ -[support levels]: https://gateway-api.sigs.k8s.io/concepts/conformance/?h=extended#2-support-levels diff --git a/site/content/en/v1.0.1/contributions/design/pprof.md b/site/content/en/v1.0.1/contributions/design/pprof.md deleted file mode 100644 index 40d75ea8f83..00000000000 --- a/site/content/en/v1.0.1/contributions/design/pprof.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: "Debug support in Envoy Gateway" ---- - -## Overview - -Envoy Gateway exposes endpoints at `localhost:19000/debug/pprof` to run Golang profiles to aid in live debugging. - -The endpoints are equivalent to those found in the http/pprof package. `/debug/pprof/` returns an HTML page listing the available profiles. - -## Goals - -* Add admin server to Envoy Gateway control plane, separated with admin server. -* Add pprof support to Envoy Gateway control plane. -* Define an API to allow Envoy Gateway to custom admin server configuration. -* Define an API to allow Envoy Gateway to open envoy gateway config dump in logs. - -The following are the different types of profiles end-user can run: - -PROFILE | FUNCTION --- | -- -/debug/pprof/allocs | Returns a sampling of all past memory allocations. -/debug/pprof/block | Returns stack traces of goroutines that led to blocking on synchronization primitives. -/debug/pprof/cmdline | Returns the command line that was invoked by the current program. -/debug/pprof/goroutine | Returns stack traces of all current goroutines. -/debug/pprof/heap | Returns a sampling of memory allocations of live objects. -/debug/pprof/mutex | Returns stack traces of goroutines holding contended mutexes. -/debug/pprof/profile | Returns pprof-formatted cpu profile. You can specify the duration using the seconds GET parameter. The default duration is 30 seconds. -/debug/pprof/symbol | Returns the program counters listed in the request. -/debug/pprof/threadcreate | Returns stack traces that led to creation of new OS threads. -/debug/pprof/trace | Returns the execution trace in binary form. You can specify the duration using the seconds GET parameter. The default duration is 1 second. - -## Non Goals - -## API - -* Add `admin` field in EnvoyGateway config. -* Add `address` field under `admin` field. -* Add `port` and `host` under `address` field. -* Add `enableDumpConfig` field under `admin field. -* Add `enablePprof` field under `admin field. - -Here is an example configuration to open admin server and enable Pprof: - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -gateway: - controllerName: "gateway.envoyproxy.io/gatewayclass-controller" -kind: EnvoyGateway -provider: - type: "Kubernetes" -admin: - enablePprof: true - address: - host: 127.0.0.1 - port: 19000 -``` - -Here is an example configuration to open envoy gateway config dump in logs: - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -gateway: - controllerName: "gateway.envoyproxy.io/gatewayclass-controller" -kind: EnvoyGateway -provider: - type: "Kubernetes" -admin: - enableDumpConfig: true -``` diff --git a/site/content/en/v1.0.1/contributions/design/rate-limit.md b/site/content/en/v1.0.1/contributions/design/rate-limit.md deleted file mode 100644 index 8dfda7680e8..00000000000 --- a/site/content/en/v1.0.1/contributions/design/rate-limit.md +++ /dev/null @@ -1,447 +0,0 @@ ---- -title: "Rate Limit Design" ---- - -## Overview - -Rate limit is a feature that allows the user to limit the number of incoming requests -to a predefined value based on attributes within the traffic flow. - -Here are some reasons why a user may want to implement Rate limits - -* To prevent malicious activity such as DDoS attacks. -* To prevent applications and its resources (such as a database) from getting overloaded. -* To create API limits based on user entitlements. - -## Scope Types - -The rate limit type here describes the scope of rate limits. - -* Global - In this case, the rate limit is common across all the instances of Envoy proxies -where its applied i.e. if the data plane has 2 replicas of Envoy running, and the rate limit is -10 requests/second, this limit is common and will be hit if 5 requests pass through the first replica -and 5 requests pass through the second replica within the same second. - -* Local - In this case, the rate limits are specific to each instance/replica of Envoy running. -Note - This is not part of the initial design and will be added as a future enhancement. - -## Match Types - -### Rate limit a specific traffic flow - -* Here is an example of a ratelimit implemented by the application developer to limit a specific user -by matching on a custom `x-user-id` header with a value set to `one` - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ratelimit-specific-user -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - rateLimit: - type: Global - global: - rules: - - clientSelectors: - - headers: - - name: x-user-id - value: one - limit: - requests: 10 - unit: Hour ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example -spec: - parentRefs: - - name: eg - hostnames: - - www.example.com - rules: - - matches: - - path: - type: PathPrefix - value: /foo - filters: - - type: ExtensionRef - extensionRef: - group: gateway.envoyproxy.io - kind: RateLimitFilter - name: ratelimit-specific-user - backendRefs: - - name: backend - port: 3000 -``` - -### Rate limit all traffic flows - -* Here is an example of a rate limit implemented by the application developer that limits the total requests made -to a specific route to safeguard health of internal application components. In this case, no specific `headers` match -is specified, and the rate limit is applied to all traffic flows accepted by this `HTTPRoute`. - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ratelimit-all-requests -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - rateLimit: - type: Global - global: - rules: - - limit: - requests: 1000 - unit: Second ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example -spec: - parentRefs: - - name: eg - hostnames: - - www.example.com - rules: - - matches: - - path: - type: PathPrefix - value: /foo - filters: - - type: ExtensionRef - extensionRef: - group: gateway.envoyproxy.io - kind: RateLimitFilter - name: ratelimit-all-requests - backendRefs: - - name: backend - port: 3000 -``` - -### Rate limit per distinct value - -* Here is an example of a rate limit implemented by the application developer to limit any unique user -by matching on a custom `x-user-id` header. Here, user A (recognised from the traffic flow using the header -`x-user-id` and value `a`) will be rate limited at 10 requests/hour and so will user B -(recognised from the traffic flow using the header `x-user-id` and value `b`). - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ratelimit-per-user -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - rateLimit: - type: Global - global: - rules: - - clientSelectors: - - headers: - - type: Distinct - name: x-user-id - limit: - requests: 10 - unit: Hour ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example -spec: - parentRefs: - - name: eg - hostnames: - - www.example.com - rules: - - matches: - - path: - type: PathPrefix - value: /foo - filters: - - type: ExtensionRef - extensionRef: - group: gateway.envoyproxy.io - kind: RateLimitFilter - name: ratelimit-per-user - backendRefs: - - name: backend - port: 3000 -``` - -### Rate limit per source IP - -* Here is an example of a rate limit implemented by the application developer that limits the total requests made -to a specific route by matching on source IP. In this case, requests from `x.x.x.x` will be rate limited at 10 requests/hour. - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ratelimit-per-ip -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - rateLimit: - type: Global - global: - rules: - - clientSelectors: - - sourceIP: x.x.x.x/32 - limit: - requests: 10 - unit: Hour ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example -spec: - parentRefs: - - name: eg - hostnames: - - www.example.com - rules: - - matches: - - path: - type: PathPrefix - value: /foo - filters: - - type: ExtensionRef - extensionRef: - group: gateway.envoyproxy.io - kind: RateLimitFilter - name: ratelimit-per-user - backendRefs: - - name: backend - port: 3000 -``` - -### Rate limit based on JWT claims - -* Here is an example of rate limit implemented by the application developer that limits the total requests made -to a specific route by matching on the jwt claim. In this case, requests with jwt claim information of `{"name":"John Doe"}` -will be rate limited at 10 requests/hour. - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: SecurityPolicy -metadata: - name: jwt-example -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - jwt: - providers: - - name: example - remoteJWKS: - uri: https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/jwks.json - claimToHeaders: - - claim: name - header: custom-request-header ---- -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ratelimit-specific-user -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - rateLimit: - type: Global - global: - rules: - - clientSelectors: - - headers: - - name: custom-request-header - value: John Doe - limit: - requests: 10 - unit: Hour ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example -spec: - parentRefs: - - name: eg - hostnames: - - "www.example.com" - rules: - - backendRefs: - - group: "" - kind: Service - name: backend - port: 3000 - weight: 1 - matches: - - path: - type: PathPrefix - value: /foo -``` - - -## Multiple RateLimitFilters, rules and clientSelectors -* Users can create multiple `RateLimitFilter`s and apply it to the same `HTTPRoute`. In such a case each -`RateLimitFilter` will be applied to the route and matched (and limited) in a mutually exclusive way, independent of each other. -* Rate limits are applied for each `RateLimitFilter` `rule` when ALL the conditions under `clientSelectors` hold true. - -Here's an example highlighting this - - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ratelimit-all-safeguard-app -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - rateLimit: - type: Global - global: - rules: - - limit: - requests: 100 - unit: Hour ---- -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ratelimit-per-user -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - rateLimit: - type: Global - global: - rules: - - clientSelectors: - - headers: - - type: Distinct - name: x-user-id - limit: - requests: 100 - unit: Hour ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example -spec: - parentRefs: - - name: eg - hostnames: - - www.example.com - rules: - - matches: - - path: - type: PathPrefix - value: /foo - filters: - - type: ExtensionRef - extensionRef: - group: gateway.envoyproxy.io - kind: RateLimitFilter - name: ratelimit-per-user - - type: ExtensionRef - extensionRef: - group: gateway.envoyproxy.io - kind: RateLimitFilter - name: ratelimit-all-safeguard-app - backendRefs: - - name: backend - port: 3000 -``` - -* The user has created two `RateLimitFilter`s and has attached it to a `HTTPRoute` - one(`ratelimit-all-safeguard-app`) to -ensure that the backend does not get overwhelmed with requests, any excess requests are rate limited irrespective of -the attributes within the traffic flow, and another(`ratelimit-per-user`) to rate limit each distinct user client -who can be differentiated using the `x-user-id` header, to ensure that each client does not make exessive requests to the backend. -* If user `baz` (identified with the header and value of `x-user-id: baz`) sends 90 requests within the first second, and -user `bar` sends 11 more requests during that same interval of 1 second, and user `bar` sends the 101th request within that second, -the rule defined in `ratelimit-all-safeguard-app` gets activated and Envoy Gateway will ratelimit the request sent by `bar` (and any other -request sent within that 1 second). After 1 second, the rate limit counter associated with the `ratelimit-all-safeguard-app` rule -is reset and again evaluated. -* If user `bar` also ends up sending 90 more requests within the hour, summing up `bar`'s total request count to 101, the rate limit rule -defined within `ratelimit-per-user` will get activated, and `bar`'s requests will be rate limited again until the hour interval ends. -* Within the same above hour, if `baz` sends 991 more requests, summing up `baz`'s total request count to 1001, the rate limit rule defined -within `ratelimit-per-user` will get activated for `baz`, and `baz`'s requests will also be rate limited until the hour interval ends. - -## Design Decisions - -* The initial design uses an Extension filter to apply the Rate Limit functionality on a specific [HTTPRoute][]. -This was preferred over the [PolicyAttachment][] extension mechanism, because it is unclear whether Rate Limit -will be required to be enforced or overridden by the platform administrator or not. -* The RateLimitFilter can only be applied as a filter to a [HTTPRouteRule][], applying it across all backends within a [HTTPRoute][] -and cannot be applied a filter within a [HTTPBackendRef][] for a specific backend. -* The [HTTPRoute][] API has a [matches][] field within each [rule][] to select a specific traffic flow to be routed to -the destination backend. The RateLimitFilter API that can be attached to an HTTPRoute via an [extensionRef][] filter, -also has a `clientSelectors` field within each `rule` to select attributes within the traffic flow to rate limit specific clients. -The two levels of selectors/matches allow for flexibility and aim to hold match information specific to its use, allowing the author/owner -of each configuration to be different. It also allows the `clientSelectors` field within the RateLimitFilter to be enhanced with other matchable -attribute such as [IP subnet][] in the future that are not relevant in the [HTTPRoute][] API. - -## Implementation Details - -### Global Rate limiting - -* [Global rate limiting][] in Envoy Proxy can be achieved using the following - - * [Actions][] can be configured per [xDS Route][]. - * If the match criteria defined within these actions is met for a specific HTTP Request, a set of key value pairs called [descriptors][] - defined within the above actions is sent to a remote [rate limit service][], whose configuration (such as the URL for the rate limit service) is defined - using a [rate limit filter][]. - * Based on information received by the rate limit service and its programmed configuration, a decision is computed, whether to rate limit - the HTTP Request or not, and is sent back to Envoy, which enforces this decision on the data plane. -* Envoy Gateway will leverage this Envoy Proxy feature by - - * Translating the user facing RateLimitFilter API into Rate limit [Actions][] as well as Rate limit service configuration to implement - the desired API intent. - * Envoy Gateway will use the existing [reference implementation][] of the rate limit service. - * The Infrastructure administrator will need to enable the rate limit service using new settings that will be defined in the [EnvoyGateway][] config API. - * The xDS IR will be enhanced to hold the user facing rate limit intent. - * The xDS Translator will be enhanced to translate the rate limit field within the xDS IR into Rate limit [Actions][] as well as instantiate the [rate limit filter][]. - * A new runner called `rate-limit` will be added that subscribes to the xDS IR messages and translates it into a new Rate Limit Infra IR which contains - the [rate limit service configuration][] as well as other information needed to deploy the rate limit service. - * The infrastructure service will be enhanced to subscribe to the Rate Limit Infra IR and deploy a provider specific rate limit service runnable entity. - * A Status field within the RateLimitFilter API will be added to reflect whether the specific configuration was programmed correctly in these multiple locations or not. - -[PolicyAttachment]: https://gateway-api.sigs.k8s.io/references/policy-attachment/ -[HTTPRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRoute -[HTTPRouteRule]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteRule -[HTTPBackendRef]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPBackendRef -[matches]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteMatch -[rule]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteMatch -[extensionRef]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteFilterType -[IP subnet]: https://en.wikipedia.org/wiki/Subnetwork -[Actions]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-ratelimit-action -[descriptors]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/rate_limit_filter.html?highlight=descriptor#example-1 -[Global rate limiting]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_features/global_rate_limiting -[xDS Route]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-routeaction -[rate limit filter]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ratelimit/v3/rate_limit.proto#envoy-v3-api-msg-extensions-filters-http-ratelimit-v3-ratelimit -[rate limit service]: https://www.envoyproxy.io/docs/envoy/latest/configuration/other_features/rate_limit#config-rate-limit-service -[reference implementation]: https://github.com/envoyproxy/ratelimit -[EnvoyGateway]: https://github.com/envoyproxy/gateway/blob/main/api/v1alpha1/envoygateway_types.go -[rate limit service configuration]: https://github.com/envoyproxy/ratelimit#configuration diff --git a/site/content/en/v1.0.1/contributions/design/security-policy.md b/site/content/en/v1.0.1/contributions/design/security-policy.md deleted file mode 100644 index b39165feb03..00000000000 --- a/site/content/en/v1.0.1/contributions/design/security-policy.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: "SecurityPolicy " ---- - -## Overview - -This design document introduces the `SecurityPolicy` API allowing system administrators to configure -authentication and authorization policies to the traffic entering the gateway. - -## Goals -* Add an API definition to hold settings for configuring authentication and authorization rules -on the traffic entering the gateway. - -## Non Goals -* Define the API configuration fields in this API. - -## Implementation -`SecurityPolicy` is a [Policy Attachment][] type API that can be used to extend [Gateway API][] -to define authentication and authorization rules. - -### Example -Here is an example highlighting how a user can configure this API. - -``` -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: SecurityPolicy -metadata: - name: jwt-authn-policy - namespace: default -spec: - jwt: - providers: - - name: example - remoteJWKS: - uri: https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/jwks.json - 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 -* JWT based authentication -* OIDC Authentication -* External Authorization -* Basic Auth -* API Key Auth -* CORS - -## Design Decisions -* This API will only support a single `targetRef` and can bind to a `Gateway` resource or a `HTTPRoute` or `GRPCRoute`. -* This API resource MUST be part of same namespace as the targetRef resource -* There can be only be ONE policy resource attached to a specific targetRef e.g. a `Listener` (section) within a `Gateway` -* 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 multiple polices target the same resource, the oldest resource (based on creation timestamp) will -attach to the Gateway Listeners, the others will not. -* 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 xRoute (`HTTPRoute` or `GRPCRoute`) overrides a Policy targeting a Listener that is -this route's parentRef which in turn 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][]. - -[Policy Attachment]: https://gateway-api.sigs.k8s.io/references/policy-attachment -[Gateway API]: https://gateway-api.sigs.k8s.io/ diff --git a/site/content/en/v1.0.1/contributions/design/system-design.md b/site/content/en/v1.0.1/contributions/design/system-design.md deleted file mode 100644 index fe24f628f9d..00000000000 --- a/site/content/en/v1.0.1/contributions/design/system-design.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -title: "System Design" -weight: 2 ---- - -## Goals - -* Define the system components needed to satisfy the requirements of Envoy Gateway. - -## Non-Goals - -* Create a detailed design and interface specification for each system component. - -## Terminology - -* Control Plane- A collection of inter-related software components for providing application gateway and routing - functionality. The control plane is implemented by Envoy Gateway and provides services for managing the data plane. - These services are detailed in the [components](#components) section. -* Data Plane- Provides intelligent application-level traffic routing and is implemented as one or more Envoy proxies. - -## Architecture - -![Architecture](/img/architecture.png) - -## Configuration - -Envoy Gateway is configured statically at startup and the managed data plane is configured dynamically through -Kubernetes resources, primarily [Gateway API][gw_api] objects. - -### Static Configuration - -Static configuration is used to configure Envoy Gateway at startup, i.e. change the GatewayClass controllerName, -configure a Provider, etc. Currently, Envoy Gateway only supports configuration through a configuration file. If the -configuration file is not provided, Envoy Gateway starts-up with default configuration parameters. - -### Dynamic Configuration - -Dynamic configuration is based on the concept of a declaring the desired state of the data plane and using -reconciliation loops to drive the actual state toward the desired state. The desired state of the data plane is -defined as Kubernetes resources that provide the following services: - -* Infrastructure Management- Manage the data plane infrastructure, i.e. deploy, upgrade, etc. This configuration is - expressed through [GatewayClass][gc] and [Gateway][gw] resources. The `EnvoyProxy` [Custom Resource][cr] can be - referenced by `gatewayclass.spec.parametersRef` to modify data plane infrastructure default parameters, - e.g. expose Envoy network endpoints using a `ClusterIP` service instead of a `LoadBalancer` service. -* Traffic Routing- Define how to handle application-level requests to backend services. For example, route all HTTP - requests for "www.example.com" to a backend service running a web server. This configuration is expressed through - [HTTPRoute][hroute] and [TLSRoute][troute] resources that match, filter, and route traffic to a [backend][be]. - Although a backend can be any valid Kubernetes Group/Kind resource, Envoy Gateway only supports a [Service][svc] - reference. - -## Components - -Envoy Gateway is made up of several components that communicate in-process; how this communication happens is described -in the [Watching Components Design][wcd]. - -### Provider - -A Provider is an infrastructure component that Envoy Gateway calls to establish its runtime configuration, resolve -services, persist data, etc. As of v0.2, Kubernetes is the only implemented provider. A file provider is on the roadmap -via [Issue #37][]. Other providers can be added in the future as Envoy Gateway use cases are better understood. A -provider is configured at start up through Envoy Gateway's [static configuration](#static-configuration). - -#### Kubernetes Provider - -* Uses Kubernetes-style controllers to reconcile Kubernetes resources that comprise the - [dynamic configuration](#dynamic-configuration). -* Manages the data plane through Kubernetes API CRUD operations. -* Uses Kubernetes for Service discovery. -* Uses etcd (via Kubernetes API) to persist data. - -#### File Provider - -* Uses a file watcher to watch files in a directory that define the data plane configuration. -* Manages the data plane by calling internal APIs, e.g. `CreateDataPlane()`. -* Uses the host's DNS for Service discovery. -* If needed, the local filesystem is used to persist data. - -### Resource Watcher - -The Resource Watcher watches resources used to establish and maintain Envoy Gateway's dynamic configuration. The -mechanics for watching resources is provider-specific, e.g. informers, caches, etc. are used for the Kubernetes -provider. The Resource Watcher uses the configured provider for input and provides resources to the Resource Translator -as output. - -### Resource Translator - -The Resource Translator translates external resources, e.g. GatewayClass, from the Resource Watcher to the Intermediate -Representation (IR). It is responsible for: - -* Translating infrastructure-specific resources/fields from the Resource Watcher to the Infra IR. -* Translating proxy configuration resources/fields from the Resource Watcher to the xDS IR. - -__Note:__ The Resource Translator is implemented as the `Translator` API type in the `gatewayapi` package. - -### Intermediate Representation (IR) - -The Intermediate Representation defines internal data models that external resources are translated into. This allows -Envoy Gateway to be decoupled from the external resources used for dynamic configuration. The IR consists of an Infra IR -used as input for the Infra Manager and an xDS IR used as input for the xDS Translator. - -* Infra IR- Used as the internal definition of the managed data plane infrastructure. -* xDS IR- Used as the internal definition of the managed data plane xDS configuration. - -### xDS Translator - -The xDS Translator translates the xDS IR into xDS Resources that are consumed by the xDS server. - -### xDS Server - -The xDS Server is a xDS gRPC Server based on [Go Control Plane][go_cp]. Go Control Plane implements the Delta xDS Server -Protocol and is responsible for using xDS to configure the data plane. - -### Infra Manager - -The Infra Manager is a provider-specific component responsible for managing the following infrastructure: - -* Data Plane - Manages all the infrastructure required to run the managed Envoy proxies. For example, CRUD Deployment, - Service, etc. resources to run Envoy in a Kubernetes cluster. -* Auxiliary Control Planes - Optional infrastructure needed to implement application Gateway features that require - external integrations with the managed Envoy proxies. For example, [Global Rate Limiting][grl] requires provisioning - and configuring the [Envoy Rate Limit Service][rls] and the [Rate Limit filter][rlf]. Such features are exposed to - users through the [Custom Route Filters][crf] extension. - -The Infra Manager consumes the Infra IR as input to manage the data plane infrastructure. - -## Design Decisions - -* Envoy Gateway can consume multiple [GatewayClass][gc] by comparing its configured controller name with - `spec.controllerName` of a GatewayClass. - `gatewayclass.spec.parametersRef` refers to the `EnvoyProxy` custom resource for configuring the managed proxy - infrastructure. If unspecified, default configuration parameters are used for the managed proxy infrastructure. -* Envoy Gateway manages [Gateways][gw] that reference its GatewayClass. - * A Gateway resource causes Envoy Gateway to provision managed Envoy proxy infrastructure. - * Envoy Gateway groups Listeners by Port and collapses each group of Listeners into a single Listener if the Listeners - in the group are compatible. Envoy Gateway considers Listeners to be compatible if all the following conditions are - met: - * Either each Listener within the group specifies the “HTTP” Protocol or each Listener within the group specifies - either the “HTTPS” or “TLS” Protocol. - * Each Listener within the group specifies a unique "Hostname". - * As a special case, one Listener within a group may omit "Hostname", in which case this Listener matches when no - other Listener matches. - * Envoy Gateway does __not__ merge listeners across multiple Gateways. -* Envoy Gateway follows Gateway API [guidelines][gwapi_conflicts] to resolve any conflicts. - * A Gateway `listener` corresponds to an Envoy proxy [Listener][listener]. -* An [HTTPRoute][hroute] resource corresponds to an Envoy proxy [Route][route]. - * Each [backendRef][be_ref] corresponds to an Envoy proxy [Cluster][cluster]. -* The goal is to make Envoy Gateway components extensible in the future. See the [roadmap][] for additional details. - -The draft for this document is [here][draft_design]. - -[gw_api]: https://gateway-api.sigs.k8s.io -[gc]: https://gateway-api.sigs.k8s.io/concepts/api-overview/#gatewayclass -[gw]: https://gateway-api.sigs.k8s.io/concepts/api-overview/#gateway -[hroute]: https://gateway-api.sigs.k8s.io/concepts/api-overview/#httproute -[troute]: https://gateway-api.sigs.k8s.io/concepts/api-overview/#tlsroute -[go_cp]: https://github.com/envoyproxy/go-control-plane -[grl]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_features/global_rate_limiting -[rls]: https://github.com/envoyproxy/ratelimit -[rlf]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ratelimit/v3/rate_limit.proto#envoy-v3-api-msg-extensions-filters-http-ratelimit-v3-ratelimit -[crf]: https://gateway-api.sigs.k8s.io/api-types/httproute/#filters-optional -[gwapi_conflicts]: https://gateway-api.sigs.k8s.io/concepts/guidelines/#conflicts -[listener]: https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/listeners#config-listeners -[route]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-route -[be_ref]: https://gateway-api.sigs.k8s.io/api-types/httproute/#backendrefs-optional -[cluster]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster -[draft_design]: https://docs.google.com/document/d/1riyTPPYuvNzIhBdrAX8dpfxTmcobWZDSYTTB5NeybuY/edit -[cr]: https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/ -[be]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.BackendObjectReference -[svc]: https://kubernetes.io/docs/concepts/services-networking/service/ -[wcd]: ../watching -[Issue #37]: https://github.com/envoyproxy/gateway/issues/37 -[roadmap]: ../../contributions/roadmap/ diff --git a/site/content/en/v1.0.1/contributions/design/tcp-udp-design.md b/site/content/en/v1.0.1/contributions/design/tcp-udp-design.md deleted file mode 100644 index 8dc29830164..00000000000 --- a/site/content/en/v1.0.1/contributions/design/tcp-udp-design.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "TCP and UDP Proxy Design " ---- - -Even though most of the use cases for Envoy Gateway are at Layer-7, Envoy Gateway can also work at Layer-4 to proxy TCP -and UDP traffic. This document will explore the options we have when operating Envoy Gateway at Layer-4 and explain the -design decision. - -Envoy can work as a non-transparent proxy or a transparent proxy for both [TCP][] - and [UDP][] -, so ideally, Envoy Gateway should also be able to work in these two modes: - -## Non-transparent Proxy Mode -For TCP, Envoy terminates the downstream connection, connects the upstream with its own IP address, and proxies the -TCP traffic from the downstream to the upstream. - -For UDP, Envoy receives UDP datagrams from the downstream, and uses its own IP address as the sender IP address when -proxying the UDP datagrams to the upstream. - -In this mode, the upstream will see Envoy's IP address and port. - -## Transparent Proxy Mode -For TCP, Envoy terminates the downstream connection, connects the upstream with the downstream IP address, and proxies -the TCP traffic from the downstream to the upstream. - -For UDP, Envoy receives UDP datagrams from the downstream, and uses the downstream IP address as the sender IP address -when proxying the UDP datagrams to the upstream. - -In this mode, the upstream will see the original downstream IP address and Envoy's mac address. - -Note: Even in transparent mode, the upstream can't see the port number of the downstream because Envoy doesn't forward -the port number. - -## The Implications of Transparent Proxy Mode - -### Escalated Privilege -Envoy needs to bind to the downstream IP when connecting to the upstream, which means Envoy requires escalated -CAP_NET_ADMIN privileges. This is often considered as a bad security practice and not allowed in some sensitive deployments. - -### Routing -The upstream can see the original source IP, but the original port number won't be passed, so the return -traffic from the upstream must be routed back to Envoy because only Envoy knows how to send the return traffic back -to the right port number of the downstream, which requires routing at the upstream side to be set up. -In a Kubernetes cluster, Envoy Gateway will have to carefully cooperate with CNI plugins to get the routing right. - -## The Design Decision (For Now) - -The implementation will only support proxying in non-transparent mode i.e. the backend will see the source IP and -port of the deployed Envoy instance instead of the client. - -[TCP]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_features/ip_transparency#arch-overview-ip-transparency-original-src-listener -[UDP]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/udp/udp_proxy/v3/udp_proxy.proto#envoy-v3-api-msg-extensions-filters-udp-udp-proxy-v3-udpproxyconfig diff --git a/site/content/en/v1.0.1/contributions/design/tracing.md b/site/content/en/v1.0.1/contributions/design/tracing.md deleted file mode 100644 index a2790690fa6..00000000000 --- a/site/content/en/v1.0.1/contributions/design/tracing.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -title: "Observability: Tracing" ---- - -## Overview - -Envoy supports extensible tracing to different sinks, Zipkin, OpenTelemetry etc. Overview of Envoy tracing can be found [here][tracing]. - -Envoy Gateway leverages [Gateway API][] for configuring managed Envoy proxies. Gateway API defines core, extended, and implementation-specific API [support levels][] for implementers such as Envoy Gateway to expose features. Since tracing is not covered by `Core` or `Extended` APIs, EG should provide an easy to config tracing per `EnvoyProxy`. - -Only OpenTelemetry sink can be configured currently, you can use [OpenTelemetry Collector][] to export to other tracing backends. - -## Goals - -- Support send tracing to `OpenTelemetry` backend -- Support configurable sampling rate -- Support propagate tag from `Literal`, `Environment` and `Request Header` - -## Non-Goals - -- Support other tracing backend, e.g. `Zipkin`, `Jaeger` - -## Use-Cases - -- Configure accesslog for a `EnvoyProxy` to `File` - -### ProxyAccessLog API Type - -```golang mdox-exec="sed '1,7d' api/config/v1alpha1/tracing_types.go" -type ProxyTracing struct { - // SamplingRate controls the rate at which traffic will be - // selected for tracing if no prior sampling decision has been made. - // Defaults to 100, valid values [0-100]. 100 indicates 100% sampling. - // +kubebuilder:validation:Minimum=0 - // +kubebuilder:validation:Maximum=100 - // +kubebuilder:default=100 - // +optional - SamplingRate *uint32 `json:"samplingRate,omitempty"` - // CustomTags defines the custom tags to add to each span. - // If provider is kubernetes, pod name and namespace are added by default. - CustomTags map[string]CustomTag `json:"customTags,omitempty"` - // Provider defines the tracing provider. - // Only OpenTelemetry is supported currently. - Provider TracingProvider `json:"provider"` -} - -type TracingProviderType string - -const ( - TracingProviderTypeOpenTelemetry TracingProviderType = "OpenTelemetry" -) - -type TracingProvider struct { - // Type defines the tracing provider type. - // EG currently only supports OpenTelemetry. - // +kubebuilder:validation:Enum=OpenTelemetry - // +kubebuilder:default=OpenTelemetry - Type TracingProviderType `json:"type"` - // Host define the provider service hostname. - Host string `json:"host"` - // Port defines the port the provider service is exposed on. - // - // +optional - // +kubebuilder:validation:Minimum=0 - // +kubebuilder:default=4317 - Port int32 `json:"port,omitempty"` -} - -type CustomTagType string - -const ( - // CustomTagTypeLiteral adds hard-coded value to each span. - CustomTagTypeLiteral CustomTagType = "Literal" - // CustomTagTypeEnvironment adds value from environment variable to each span. - CustomTagTypeEnvironment CustomTagType = "Environment" - // CustomTagTypeRequestHeader adds value from request header to each span. - CustomTagTypeRequestHeader CustomTagType = "RequestHeader" -) - -type CustomTag struct { - // Type defines the type of custom tag. - // +kubebuilder:validation:Enum=Literal;Environment;RequestHeader - // +unionDiscriminator - // +kubebuilder:default=Literal - Type CustomTagType `json:"type"` - // Literal adds hard-coded value to each span. - // It's required when the type is "Literal". - Literal *LiteralCustomTag `json:"literal,omitempty"` - // Environment adds value from environment variable to each span. - // It's required when the type is "Environment". - Environment *EnvironmentCustomTag `json:"environment,omitempty"` - // RequestHeader adds value from request header to each span. - // It's required when the type is "RequestHeader". - RequestHeader *RequestHeaderCustomTag `json:"requestHeader,omitempty"` - - // TODO: add support for Metadata tags in the future. - // EG currently doesn't support metadata for route or cluster. -} - -// LiteralCustomTag adds hard-coded value to each span. -type LiteralCustomTag struct { - // Value defines the hard-coded value to add to each span. - Value string `json:"value"` -} - -// EnvironmentCustomTag adds value from environment variable to each span. -type EnvironmentCustomTag struct { - // Name defines the name of the environment variable which to extract the value from. - Name string `json:"name"` - // DefaultValue defines the default value to use if the environment variable is not set. - // +optional - DefaultValue *string `json:"defaultValue,omitempty"` -} - -// RequestHeaderCustomTag adds value from request header to each span. -type RequestHeaderCustomTag struct { - // Name defines the name of the request header which to extract the value from. - Name string `json:"name"` - // DefaultValue defines the default value to use if the request header is not set. - // +optional - DefaultValue *string `json:"defaultValue,omitempty"` -} -``` - -### Example - -1. The following is an example to config tracing. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/tracing/default.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: tracing - namespace: envoy-gateway-system -spec: - telemetry: - tracing: - # sample 100% of requests - samplingRate: 100 - provider: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 - customTags: - # This is an example of using a literal as a tag value - key1: - type: Literal - literal: - value: "val1" - # This is an example of using an environment variable as a tag value - env1: - type: Environment - environment: - name: ENV1 - defaultValue: "-" - # This is an example of using a header value as a tag value - header1: - type: RequestHeader - requestHeader: - name: X-Header-1 - defaultValue: "-" -``` - -[tracing]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/observability/tracing -[Gateway API]: https://gateway-api.sigs.k8s.io/ -[support levels]: https://gateway-api.sigs.k8s.io/concepts/conformance/?h=extended#2-support-levels -[OpenTelemetry Collector]: https://opentelemetry.io/docs/collector/ diff --git a/site/content/en/v1.0.1/contributions/design/watching.md b/site/content/en/v1.0.1/contributions/design/watching.md deleted file mode 100644 index 5eabad7b3f9..00000000000 --- a/site/content/en/v1.0.1/contributions/design/watching.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: "Watching Components Design" -weight: 3 ---- - -Envoy Gateway is made up of several components that communicate in-process. Some of them (namely Providers) watch -external resources, and "publish" what they see for other components to consume; others watch what another publishes and -act on it (such as the resource translator watches what the providers publish, and then publishes its own results that -are watched by another component). Some of these internally published results are consumed by multiple components. - -To facilitate this communication use the [watchable][] library. The `watchable.Map` type is very similar to the -standard library's `sync.Map` type, but supports a `.Subscribe` (and `.SubscribeSubset`) method that promotes a pub/sub -pattern. - -## Pub - -Many of the things we communicate around are naturally named, either by a bare "name" string or by a "name"/"namespace" -tuple. And because `watchable.Map` is typed, it makes sense to have one map for each type of thing (very similar to if -we were using native Go `map`s). For example, a struct that might be written to by the Kubernetes provider, and read by -the IR translator: - - ```go - type ResourceTable struct { - // gateway classes are cluster-scoped; no namespace - GatewayClasses watchable.Map[string, *gwapiv1.GatewayClass] - - // gateways are namespace-scoped, so use a k8s.io/apimachinery/pkg/types.NamespacedName as the map key. - Gateways watchable.Map[types.NamespacedName, *gwapiv1.Gateway] - - HTTPRoutes watchable.Map[types.NamespacedName, *gwapiv1.HTTPRoute] - } - ``` - -The Kubernetes provider updates the table by calling `table.Thing.Store(name, val)` and `table.Thing.Delete(name)`; -updating a map key with a value that is deep-equal (usually `reflect.DeepEqual`, but you can implement your own `.Equal` -method) the current value is a no-op; it won't trigger an event for subscribers. This is handy so that the publisher -doesn't have as much state to keep track of; it doesn't need to know "did I already publish this thing", it can just -`.Store` its data and `watchable` will do the right thing. - -## Sub - -Meanwhile, the translator and other interested components subscribe to it with `table.Thing.Subscribe` (or -`table.Thing.SubscribeSubset` if they only care about a few "Thing"s). So the translator goroutine might look like: - - ```go - func(ctx context.Context) error { - for snapshot := range k8sTable.HTTPRoutes.Subscribe(ctx) { - fullState := irInput{ - GatewayClasses: k8sTable.GatewayClasses.LoadAll(), - Gateways: k8sTable.Gateways.LoadAll(), - HTTPRoutes: snapshot.State, - } - translate(irInput) - } - } - ``` - -Or, to watch multiple maps in the same loop: - - ```go - func worker(ctx context.Context) error { - classCh := k8sTable.GatewayClasses.Subscribe(ctx) - gwCh := k8sTable.Gateways.Subscribe(ctx) - routeCh := k8sTable.HTTPRoutes.Subscribe(ctx) - for ctx.Err() == nil { - var arg irInput - select { - case snapshot := <-classCh: - arg.GatewayClasses = snapshot.State - case snapshot := <-gwCh: - arg.Gateways = snapshot.State - case snapshot := <-routeCh: - arg.Routes = snapshot.State - } - if arg.GateWayClasses == nil { - arg.GatewayClasses = k8sTable.GateWayClasses.LoadAll() - } - if arg.GateWays == nil { - arg.Gateways = k8sTable.GateWays.LoadAll() - } - if arg.HTTPRoutes == nil { - arg.HTTPRoutes = k8sTable.HTTPRoutes.LoadAll() - } - translate(irInput) - } - } - ``` - -From the updates it gets from `.Subscribe`, it can get a full view of the map being subscribed to via `snapshot.State`; -but it must read the other maps explicitly. Like `sync.Map`, `watchable.Map`s are thread-safe; while `.Subscribe` is a -handy way to know when to run, `.Load` and friends can be used without subscribing. - -There can be any number of subscribers. For that matter, there can be any number of publishers `.Store`ing things, but -it's probably wise to just have one publisher for each map. - -The channel returned from `.Subscribe` **is immediately readable** with a snapshot of the map as it existed when -`.Subscribe` was called; and becomes readable again whenever `.Store` or `.Delete` mutates the map. If multiple -mutations happen between reads (or if mutations happen between `.Subscribe` and the first read), they are coalesced in -to one snapshot to be read; the `snapshot.State` is the most-recent full state, and `snapshot.Updates` is a listing of -each of the mutations that cause this snapshot to be different than the last-read one. This way subscribers don't need -to worry about a backlog accumulating if they can't keep up with the rate of changes from the publisher. - -If the map contains anything before `.Subscribe` is called, that very first read won't include `snapshot.Updates` -entries for those pre-existing items; if you are working with `snapshot.Update` instead of `snapshot.State`, then you -must add special handling for your first read. We have a utility function `./internal/message.HandleSubscription` to -help with this. - -## Other Notes - -The common pattern will likely be that the entrypoint that launches the goroutines for each component instantiates the -map, and passes them to the appropriate publishers and subscribers; same as if they were communicating via a dumb -`chan`. - -A limitation of `watchable.Map` is that in order to ensure safety between goroutines, it does require that value types -be deep-copiable; either by having a `DeepCopy` method, being a `proto.Message`, or by containing no reference types and -so can be deep-copied by naive assignment. Fortunately, we're using `controller-gen` anyway, and `controller-gen` can -generate `DeepCopy` methods for us: just stick a `// +k8s:deepcopy-gen=true` on the types that you want it to generate -methods for. - -[watchable]: https://pkg.go.dev/github.com/telepresenceio/watchable diff --git a/site/content/en/v1.0.1/contributions/roadmap.md b/site/content/en/v1.0.1/contributions/roadmap.md deleted file mode 100644 index 955af2a9623..00000000000 --- a/site/content/en/v1.0.1/contributions/roadmap.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "Roadmap" -weight: -1 -description: "This section records the roadmap of Envoy Gateway." ---- - -This document serves as a high-level reference for Envoy Gateway users and contributors to understand the direction of -the project. - -## Contributing to the Roadmap - -- To add a feature to the roadmap, create an [issue][issue] or join a [community meeting][meeting] to discuss your use - case. If your feature is accepted, a maintainer will assign your issue to a [release milestone][milestones] and update - this document accordingly. -- To help with an existing roadmap item, comment on or assign yourself to the associated issue. -- If a roadmap item doesn't have an issue, create one, assign yourself to the issue, and reference this document. A - maintainer will submit a [pull request][PR] to add the feature to the roadmap. __Note:__ The feature should be - discussed in an issue or a community meeting before implementing it. - -If you don't know where to start contributing, help is needed to reduce technical, automation, and documentation debt. -Look for issues with the `help wanted` label to get started. - -## Details - -Roadmap features and timelines may change based on feedback, community contributions, etc. If you depend on a specific -roadmap item, you're encouraged to attend a community meeting to discuss the details, or help us deliver the feature by -contributing to the project. - -`Last Updated: April 2023` - -### [v0.2.0][v0.2.0]: Establish a Solid Foundation - -- Complete the core Envoy Gateway implementation- [Issue #60][60]. -- Establish initial testing, e2e, integration, etc- [Issue #64][64]. -- Establish user and developer project documentation- [Issue #17][17]. -- Achieve Gateway API conformance (e.g. routing, LB, Header transformation, etc.)- [Issue #65][65]. -- Setup a CI/CD pipeline- [Issue #63][63]. - -### [v0.3.0][v0.3.0]: Drive Advanced Features through Extension Mechanisms - -- Support extended Gateway API fields [Issue #707][707]. -- Support experimental Gateway APIs such as TCPRoute [Issue #643][643], UDPRoute [Issue #641][641] and GRPCRoute [Issue #642][642]. -- Establish guidelines for leveragaing Gateway API extensions [Issue #675][675]. -- Rate Limiting [Issue #670][670]. -- Authentication [Issue #336][336]. - -### [v0.4.0][v0.4.0]: Customizing Envoy Gateway - -- Extending Envoy Gateway control plane [Issue #20][20] -- Helm based installation for Envoy Gateway [Issue #650][650] -- Customizing managed Envoy Proxy Kubernetes resource fields [Issue #648][648] -- Configuring xDS Bootstrap [Issue #31][31] - -### [v0.5.0][v0.5.0]: Observability and Scale - -- Observability for data plane [Issue #699][699]. -- Allow users to configure xDS Resources [Issue #24][24]. - -### [v0.6.0][v0.6.0]: Preparation for GA - -- Observability for control plane [Issue #700][700]. -- Compute and document Envoy Gateway performance [Issue #1365][1365]. -- Add TrafficPolicy APIs for advanced features [Issue #1492][1492]. -- Envoy Gateway meets readiness criteria [Issue #1160][1160]. - -[issue]: https://github.com/envoyproxy/gateway/issues -[meeting]: https://docs.google.com/document/d/1leqwsHX8N-XxNEyTflYjRur462ukFxd19Rnk3Uzy55I/edit?usp=sharing -[pr]: https://github.com/envoyproxy/gateway/compare -[milestones]: https://github.com/envoyproxy/gateway/milestones -[v0.2.0]: https://github.com/envoyproxy/gateway/milestone/1 -[v0.3.0]: https://github.com/envoyproxy/gateway/milestone/7 -[v0.4.0]: https://github.com/envoyproxy/gateway/milestone/12 -[v0.5.0]: https://github.com/envoyproxy/gateway/milestone/13 -[v0.6.0]: https://github.com/envoyproxy/gateway/milestone/15 -[17]: https://github.com/envoyproxy/gateway/issues/17 -[20]: https://github.com/envoyproxy/gateway/issues/20 -[24]: https://github.com/envoyproxy/gateway/issues/24 -[31]: https://github.com/envoyproxy/gateway/issues/31 -[60]: https://github.com/envoyproxy/gateway/issues/60 -[63]: https://github.com/envoyproxy/gateway/issues/63 -[64]: https://github.com/envoyproxy/gateway/issues/64 -[65]: https://github.com/envoyproxy/gateway/issues/65 -[336]: https://github.com/envoyproxy/gateway/issues/336 -[641]: https://github.com/envoyproxy/gateway/issues/641 -[642]: https://github.com/envoyproxy/gateway/issues/642 -[648]: https://github.com/envoyproxy/gateway/issues/648 -[650]: https://github.com/envoyproxy/gateway/issues/650 -[643]: https://github.com/envoyproxy/gateway/issues/643 -[670]: https://github.com/envoyproxy/gateway/issues/670 -[675]: https://github.com/envoyproxy/gateway/issues/675 -[699]: https://github.com/envoyproxy/gateway/issues/699 -[700]: https://github.com/envoyproxy/gateway/issues/700 -[707]: https://github.com/envoyproxy/gateway/issues/707 -[1160]: https://github.com/envoyproxy/gateway/issues/1160 -[1365]: https://github.com/envoyproxy/gateway/issues/1365 -[1492]: https://github.com/envoyproxy/gateway/issues/1492 diff --git a/site/content/en/v1.0.1/install/install-helm.md b/site/content/en/v1.0.1/install/install-helm.md index 908eaf3eb8f..bb26969b722 100644 --- a/site/content/en/v1.0.1/install/install-helm.md +++ b/site/content/en/v1.0.1/install/install-helm.md @@ -28,7 +28,7 @@ You can visit [Envoy Gateway Helm Chart](https://hub.docker.com/r/envoyproxy/gat Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one. {{% alert title="Developer Guide" color="primary" %}} -Refer to the [Developer Guide](/latest/contributions/develop) to learn more. +Refer to the [Developer Guide](../../contributions/develop) to learn more. {{% /alert %}} Install the Gateway API CRDs and Envoy Gateway: diff --git a/site/content/en/v1.0.1/install/install-yaml.md b/site/content/en/v1.0.1/install/install-yaml.md index 177ede14889..e00107fbe2e 100644 --- a/site/content/en/v1.0.1/install/install-yaml.md +++ b/site/content/en/v1.0.1/install/install-yaml.md @@ -25,7 +25,7 @@ Refer to the [Version Compatibility Matrix](./matrix) to learn more. Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one. {{% alert title="Developer Guide" color="primary" %}} -Refer to the [Developer Guide](/latest/contributions/develop) to learn more. +Refer to the [Developer Guide](../../contributions/develop) to learn more. {{% /alert %}} 1. In your terminal, run the following command: diff --git a/site/content/en/v1.0.1/tasks/quickstart.md b/site/content/en/v1.0.1/tasks/quickstart.md index 7bc01e4c7c3..14471133d9e 100644 --- a/site/content/en/v1.0.1/tasks/quickstart.md +++ b/site/content/en/v1.0.1/tasks/quickstart.md @@ -101,4 +101,4 @@ helm uninstall eg -n envoy-gateway-system ## Next Steps -Checkout the [Developer Guide](../contributions/develop) to get involved in the project. +Checkout the [Developer Guide](../../contributions/develop) to get involved in the project. diff --git a/site/content/en/v1.0.1/tasks/security/basic-auth.md b/site/content/en/v1.0.1/tasks/security/basic-auth.md index a969cb1470a..62b7f669624 100644 --- a/site/content/en/v1.0.1/tasks/security/basic-auth.md +++ b/site/content/en/v1.0.1/tasks/security/basic-auth.md @@ -188,9 +188,9 @@ kubectl delete secret/example-cert ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [http Basic authentication]: https://tools.ietf.org/html/rfc2617 [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/v1.0.1/tasks/security/cors.md b/site/content/en/v1.0.1/tasks/security/cors.md index dea4f04361d..b66077d5e28 100644 --- a/site/content/en/v1.0.1/tasks/security/cors.md +++ b/site/content/en/v1.0.1/tasks/security/cors.md @@ -132,9 +132,9 @@ kubectl delete securitypolicy/cors-example ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [cors]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/v1.0.1/tasks/security/ext-auth.md b/site/content/en/v1.0.1/tasks/security/ext-auth.md index efcd8b62467..5cc55964853 100644 --- a/site/content/en/v1.0.1/tasks/security/ext-auth.md +++ b/site/content/en/v1.0.1/tasks/security/ext-auth.md @@ -304,8 +304,8 @@ kubectl delete backendtlspolicy/grpc-ext-auth-btls ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/v1.0.1/tasks/security/jwt-authentication.md b/site/content/en/v1.0.1/tasks/security/jwt-authentication.md index a8204fdae5d..26caabf3ad7 100644 --- a/site/content/en/v1.0.1/tasks/security/jwt-authentication.md +++ b/site/content/en/v1.0.1/tasks/security/jwt-authentication.md @@ -160,9 +160,9 @@ kubectl delete securitypolicy/jwt-example ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [jwt]: https://tools.ietf.org/html/rfc7519 [jwks]: https://tools.ietf.org/html/rfc7517 [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway diff --git a/site/content/en/v1.0.1/tasks/security/oidc.md b/site/content/en/v1.0.1/tasks/security/oidc.md index 392650640e7..81bdaa882ac 100644 --- a/site/content/en/v1.0.1/tasks/security/oidc.md +++ b/site/content/en/v1.0.1/tasks/security/oidc.md @@ -155,10 +155,10 @@ kubectl delete httproute/myapp ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. [oidc]: https://openid.net/connect/ [google-oidc]: https://developers.google.com/identity/protocols/oauth2/openid-connect -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/v1.0.1/tasks/security/secure-gateways.md b/site/content/en/v1.0.1/tasks/security/secure-gateways.md index 9028de8b6b6..06cfef2fdde 100644 --- a/site/content/en/v1.0.1/tasks/security/secure-gateways.md +++ b/site/content/en/v1.0.1/tasks/security/secure-gateways.md @@ -450,6 +450,6 @@ Refer to the steps mentioned earlier in the guide under [Testing in clusters wit ## Next Steps -Checkout the [Developer Guide](../../contributions/develop) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. [ReferenceGrant]: https://gateway-api.sigs.k8s.io/api-types/referencegrant/ diff --git a/site/content/en/v1.0.1/tasks/security/threat-model.md b/site/content/en/v1.0.1/tasks/security/threat-model.md index d5a375a5401..79a69b482c6 100644 --- a/site/content/en/v1.0.1/tasks/security/threat-model.md +++ b/site/content/en/v1.0.1/tasks/security/threat-model.md @@ -528,7 +528,7 @@ When considering internal threat actors, we chose to follow the [security model] **Threat**: Threat actors establish persistence and move laterally through the cluster unnoticed. - **Recommendation**: Configure [access logging](https://gateway.envoyproxy.io/latest/contributions/design/accesslog/) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout. + **Recommendation**: Configure [access logging](../../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout. Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR). @@ -589,33 +589,33 @@ Set runAsUser and runAsGroup security context options to specific UIDs (e.g., ru ### Identified Threats by Priority -|ID|UID|Category|Risk|Threat|Priority| Recommendation | -|-|-|-|-|-|-|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -|EGTM-001|EGTM-GW-001|Gateway API| Self-signed certificates (which do not comply with PKI best practices) could lead to unauthorised access to the private key associated with the certificate used for inbound TLS termination at Envoy Proxy, compromising the confidentiality and integrity of proxied traffic.

| Compromise of the private key associated with the certificate used for inbound TLS terminating at Envoy Proxy.

|High| The Envoy Gateway quickstart guide demonstrates how to set up a Secure Gateway using an example where a self-signed root certificate is created using openssl. As stated in the Envoy Gateway documentation, this is not a suitable configuration for Production usage. It is recommended that PKI best practices are followed, whereby certificates are signed by an Intermediary CA which sits underneath an organisational \'offline\' Root CA.

PKI best practices should also apply to the management of client certificates when using mTLS. The Envoy Gateway [mTLS](../security/mutual-tls) guide shows how to set up client certificates using self-signed certificates. In the same way as gateway certificates and, as mentioned in the documentation, this configuration should not be used in production environments. | -|EGTM-002|EGTM-CS-001|Container Security| There is a risk that a threat actor could compromise the Kubernetes secret containing the Envoy private key, allowing the attacker to decrypt Envoy Proxy traffic, compromising the confidentiality of proxied traffic.

| Kubernetes secret containing the Envoy private key is compromised and used to decrypt proxied traffic.

|High| Certificate management best practices mandate short-lived key material where practical, meaning that a mechanism for rotation of private keys and certificates is required, along with a way for certificates to be mounted into Envoy containers. If Kubernetes secrets are used, when a certificate expires, the associated secret must be updated, and Envoy containers must be redeployed. Instead of a manual configuration, it is recommended that [cert-manager](https://github.com/cert-manager/cert-manager) is used. | -|EGTM-004|EGTM-K8-002|Container Security| There is a risk that a threat actor could abuse misconfigured RBAC to access the Envoy Gateway ClusterRole (envoy-gateway-role) and use it to expose all secrets across the cluster, thus compromising the confidentiality and integrity of tenant data.

| Compromised Envoy Gateway or misconfigured ClusterRoleBinding (envoy-gateway-rolebinding) to Envoy Gateway ClusterRole (envoy-gateway-role), provides access to resources and secrets in different namespaces.

|High| Users should be aware that Envoy Gateway uses a ClusterRole (envoy-gateway-role) when deployed via the Helm chart, to allow management of Envoy Proxies across different namespaces. This ClusterRole is powerful and includes the ability to read secrets in namespaces which may not be within the purview of Envoy Gateway.

Kubernetes best-practices involve restriction of ClusterRoleBindings, with the use of RoleBindings where possible to limit access per namespace by specifying the namespace in metadata. Namespace isolation reduces the impact of compromise from cluster-scoped roles. Ideally, fine-grained K8s roles should be created per the principle of least privilege to ensure they have the minimum access necessary for role functions.

The pull request \#[1656](https://github.com/envoyproxy/gateway/pull/1656) introduced the use of Roles and RoleBindings in [namespaced mode](https://gateway.envoyproxy.io/latest/api/extension_types/#kuberneteswatchmode). This feature can be leveraged to reduce the amount of permissions required by the Envoy Gateway. | -|EGTM-007|EGTM-EG-002|Envoy Gateway| There is a risk that a threat actor could exploit misconfigured Kubernetes RBAC to create or modify Gateway API resources with no business need, potentially leading to the compromise of the confidentiality, integrity, and availability of resources and traffic within the cluster.

| Unauthorised creation or misconfiguration of Gateway API resources by a threat actor with cluster-scoped access.

|High| Configure the apiGroup and resource fields in RBAC policies to restrict access to [Gateway](https://gateway-api.sigs.k8s.io/) and [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/) resources. Enable namespace isolation by using the namespace field, preventing unauthorised access to gateways in other namespaces. | -|EGTM-009|EGTM-GW-002|Gateway API| There is a risk that a co-tenant misconfigures Gateway or Route resources, compromising the confidentiality, integrity, and availability of routed traffic through Envoy Gateway.

| Malicious or accidental co-tenant misconfiguration of Gateways and Routes associated with other application teams.

|High| Dedicated Envoy Gateways should be provided to each tenant within their respective namespace. A one-to-one relationship should be established between GatewayClass and Gateway resources, meaning that each tenant namespace should have their own GatewayClass watched by a unique Envoy Gateway Controller as defined here in the [Deployment Mode](../operations/deployment-mode) documentation.

Application Admins should have write permissions on the Gateway resource, but only in their specific namespaces, and Application Developers should only hold write permissions on Route resources. To enact this access control schema, follow the [Write Permissions for Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model) described in the Kubernetes Gateway API security model. Examples of secured gateway-route topologies can be found [here](https://gateway-api.sigs.k8s.io/concepts/api-overview/#attaching-routes-to-gateways) within the Kubernetes Gateway API docs.

Optionally, consider a GitOps model, where only the GitOps operator has the permission to deploy or modify custom resources in production. | -|EGTM-014|EGTM-CS-006|Container Security| There is a risk that a supply chain attack on Envoy Gateway results in an arbitrary compromise of the confidentiality, integrity or availability of tenant data.

| Supply chain threat actor introduces malicious code into Envoy Gateway or Proxy.

|High| The Envoy Gateway project should continue to work towards conformance with supply-chain security best practices throughout the project lifecycle (for example, as set out in the [CNCF Software Supply Chain Best Practices Whitepaper](https://github.com/cncf/tag-security/blob/main/supply-chain-security/supply-chain-security-paper/CNCF_SSCP_v1.pdf). Adherence to [Supply-chain Levels for Software Artefacts](https://slsa.dev/) (SLSA) standards is crucial for maintaining the security of the system. Employ version control systems to monitor the source and build platforms and assign responsibility to a specific stakeholder.

Integrate a supply chain security tool such as Sigstore, which provides native capabilities for signing and verifying container images and software artefacts. [Software Bill of Materials](https://www.cisa.gov/sbom) (SBOM), [Vulnerability Exploitability eXchange](https://www.ntia.gov/files/ntia/publications/vex_one-page_summary.pdf) (VEX), and signed artefacts should also be incorporated into the security protocol. | -|EGTM-020|EGTM-CS-009|Container Security| There is a risk that a threat actor exploits an Envoy Proxy vulnerability to remote code execution (RCE) due to out of date or misconfigured Envoy Proxy pod deployment, compromising the confidentiality and integrity of Envoy Proxy along with the availability of the proxy service.

| Deployment of an Envoy Proxy or Gateway image containing exploitable CVEs.

|High| Always use the latest version of the Envoy Proxy image. Regularly check for updates and patch the system as soon as updates become available. Implement a CI/CD pipeline that includes security checks for images and prevents deployment of insecure configurations. A tool such as Snyk can be used to provide container vulnerability scanning to mitigate the risk of known vulnerabilities.

Utilise the [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) controller to enforce [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) and configure the [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) to limit its capabilities per the principle of least privilege. | -|EGTM-022|EGTM-CS-010|Container Security| There is a risk that the OIDC client secret (for OIDC authentication) and user password hashes (for basic authentication) get leaked due to misconfigured RBAC permissions.

| Unauthorised access to the application due to credential leakage.

|High| Ensure that only authorised users and service accounts are able to access secrets. This is especially important in namespaces where SecurityPolicy objects are configured, since those namespaces are the ones to store secrets containing the client secret (in OIDC scenarios) and user password hashes (in basic authentication scenarios).

To do so, minimise the use of ClusterRoles and Roles allowing listing and getting secrets. Perform periodic audits of RBAC permissions. | -|EGTM-023|EGTM-EG-007|Envoy Gateway| There is a risk of unauthorised access due to the use of basic authentication, which does not enforce any password restriction in terms of complexity and length. In addition, password hashes are stored in SHA1 format, which is a deprecated hashing function.

| Unauthorised access to the application due to weak authentication mechanisms.

|High| It is recommended to make use of stronger authentication mechanisms (i.e. JWT authentication and OIDC authentication) instead of basic authentication. These authentication mechanisms have many advantages, such as the use of short-lived credentials and a central management of security policies through the identity provider. | -|EGTM-008|EGTM-EG-003|Envoy Gateway| There is a risk of a threat actor misconfiguring static config and compromising the integrity of Envoy Gateway, ultimately leading to the compromised confidentiality, integrity, or availability of tenant data and cluster resources.

| Accidental or deliberate misconfiguration of static configuration leads to a misconfigured deployment of Envoy Gateway, for example logging parameters could be modified or global rate limiting configuration misconfigured.

|Medium| Implement a GitOps model, utilising Kubernetes\' Role-Based Access Control (RBAC) and adhering to the principle of least privilege to minimise human intervention on the cluster. For instance, tools like [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) can be used for declarative GitOps deployments, ensuring all changes are tracked and reviewed. Additionally, configure your source control management (SCM) system to include mandatory pull request (PR) reviews, commit signing, and protected branches to ensure only authorised changes can be committed to the start-up configuration. | -|EGTM-010|EGTM-CS-005|Container Security| There is a risk that a threat actor exploits a weak pod security context, compromising the CIA of a node and the resources / services which run on it.

| Threat Actor who has compromised a pod exploits weak security context to escape to a node, potentially leading to the compromise of Envoy Proxy or Gateway running on the same node.

|Medium| To mitigate this risk, apply [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) at a minimum of [Baseline](https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline) level to all namespaces, especially those containing Envoy Gateway and Proxy Pods. Pod security standards are implemented through K8s [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) to provide [admission control modes](https://kubernetes.io/docs/concepts/security/pod-security-admission/#pod-security-admission-labels-for-namespaces) (enforce, audit, and warn) for namespaces. Pod security standards can be enforced by namespace labels as shown [here](https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/), to enforce a baseline level of pod security to specific namespaces.

Further enhance the security by implementing a sandboxing solution such as [gVisor](https://gvisor.dev/) for Envoy Gateway and Proxy Pods to isolate the application from the host kernel. This can be set within the runtimeClassName of the Pod specification. | -|EGTM-012|EGTM-GW-004|Gateway API| There is a risk that a threat actor could abuse excessive RBAC privileges to create ReferenceGrant resources. These resources could then be used to create cross-namespace communication, leading to unauthorised access to the application. This could compromise the confidentiality and integrity of resources and configuration in the affected namespaces and potentially disrupt the availability of services that rely on these object references.

| A ReferenceGrant is created, which validates traffic to cross namespace trust boundaries without a valid business reason, such as a route in one tenant\'s namespace referencing a backend in another.

|Medium| Ensure that the ability to create ReferenceGrant resources is restricted to the minimum number of people. Pay special attention to ClusterRoles that allow that action. | +|ID|UID|Category|Risk|Threat|Priority| Recommendation | +|-|-|-|-|-|-|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|EGTM-001|EGTM-GW-001|Gateway API| Self-signed certificates (which do not comply with PKI best practices) could lead to unauthorised access to the private key associated with the certificate used for inbound TLS termination at Envoy Proxy, compromising the confidentiality and integrity of proxied traffic.

| Compromise of the private key associated with the certificate used for inbound TLS terminating at Envoy Proxy.

|High| The Envoy Gateway quickstart guide demonstrates how to set up a Secure Gateway using an example where a self-signed root certificate is created using openssl. As stated in the Envoy Gateway documentation, this is not a suitable configuration for Production usage. It is recommended that PKI best practices are followed, whereby certificates are signed by an Intermediary CA which sits underneath an organisational \'offline\' Root CA.

PKI best practices should also apply to the management of client certificates when using mTLS. The Envoy Gateway [mTLS](../security/mutual-tls) guide shows how to set up client certificates using self-signed certificates. In the same way as gateway certificates and, as mentioned in the documentation, this configuration should not be used in production environments. | +|EGTM-002|EGTM-CS-001|Container Security| There is a risk that a threat actor could compromise the Kubernetes secret containing the Envoy private key, allowing the attacker to decrypt Envoy Proxy traffic, compromising the confidentiality of proxied traffic.

| Kubernetes secret containing the Envoy private key is compromised and used to decrypt proxied traffic.

|High| Certificate management best practices mandate short-lived key material where practical, meaning that a mechanism for rotation of private keys and certificates is required, along with a way for certificates to be mounted into Envoy containers. If Kubernetes secrets are used, when a certificate expires, the associated secret must be updated, and Envoy containers must be redeployed. Instead of a manual configuration, it is recommended that [cert-manager](https://github.com/cert-manager/cert-manager) is used. | +|EGTM-004|EGTM-K8-002|Container Security| There is a risk that a threat actor could abuse misconfigured RBAC to access the Envoy Gateway ClusterRole (envoy-gateway-role) and use it to expose all secrets across the cluster, thus compromising the confidentiality and integrity of tenant data.

| Compromised Envoy Gateway or misconfigured ClusterRoleBinding (envoy-gateway-rolebinding) to Envoy Gateway ClusterRole (envoy-gateway-role), provides access to resources and secrets in different namespaces.

|High| Users should be aware that Envoy Gateway uses a ClusterRole (envoy-gateway-role) when deployed via the Helm chart, to allow management of Envoy Proxies across different namespaces. This ClusterRole is powerful and includes the ability to read secrets in namespaces which may not be within the purview of Envoy Gateway.

Kubernetes best-practices involve restriction of ClusterRoleBindings, with the use of RoleBindings where possible to limit access per namespace by specifying the namespace in metadata. Namespace isolation reduces the impact of compromise from cluster-scoped roles. Ideally, fine-grained K8s roles should be created per the principle of least privilege to ensure they have the minimum access necessary for role functions.

The pull request \#[1656](https://github.com/envoyproxy/gateway/pull/1656) introduced the use of Roles and RoleBindings in [namespaced mode](https://gateway.envoyproxy.io/latest/api/extension_types/#kuberneteswatchmode). This feature can be leveraged to reduce the amount of permissions required by the Envoy Gateway. | +|EGTM-007|EGTM-EG-002|Envoy Gateway| There is a risk that a threat actor could exploit misconfigured Kubernetes RBAC to create or modify Gateway API resources with no business need, potentially leading to the compromise of the confidentiality, integrity, and availability of resources and traffic within the cluster.

| Unauthorised creation or misconfiguration of Gateway API resources by a threat actor with cluster-scoped access.

|High| Configure the apiGroup and resource fields in RBAC policies to restrict access to [Gateway](https://gateway-api.sigs.k8s.io/) and [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/) resources. Enable namespace isolation by using the namespace field, preventing unauthorised access to gateways in other namespaces. | +|EGTM-009|EGTM-GW-002|Gateway API| There is a risk that a co-tenant misconfigures Gateway or Route resources, compromising the confidentiality, integrity, and availability of routed traffic through Envoy Gateway.

| Malicious or accidental co-tenant misconfiguration of Gateways and Routes associated with other application teams.

|High| Dedicated Envoy Gateways should be provided to each tenant within their respective namespace. A one-to-one relationship should be established between GatewayClass and Gateway resources, meaning that each tenant namespace should have their own GatewayClass watched by a unique Envoy Gateway Controller as defined here in the [Deployment Mode](../operations/deployment-mode) documentation.

Application Admins should have write permissions on the Gateway resource, but only in their specific namespaces, and Application Developers should only hold write permissions on Route resources. To enact this access control schema, follow the [Write Permissions for Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model) described in the Kubernetes Gateway API security model. Examples of secured gateway-route topologies can be found [here](https://gateway-api.sigs.k8s.io/concepts/api-overview/#attaching-routes-to-gateways) within the Kubernetes Gateway API docs.

Optionally, consider a GitOps model, where only the GitOps operator has the permission to deploy or modify custom resources in production. | +|EGTM-014|EGTM-CS-006|Container Security| There is a risk that a supply chain attack on Envoy Gateway results in an arbitrary compromise of the confidentiality, integrity or availability of tenant data.

| Supply chain threat actor introduces malicious code into Envoy Gateway or Proxy.

|High| The Envoy Gateway project should continue to work towards conformance with supply-chain security best practices throughout the project lifecycle (for example, as set out in the [CNCF Software Supply Chain Best Practices Whitepaper](https://github.com/cncf/tag-security/blob/main/supply-chain-security/supply-chain-security-paper/CNCF_SSCP_v1.pdf). Adherence to [Supply-chain Levels for Software Artefacts](https://slsa.dev/) (SLSA) standards is crucial for maintaining the security of the system. Employ version control systems to monitor the source and build platforms and assign responsibility to a specific stakeholder.

Integrate a supply chain security tool such as Sigstore, which provides native capabilities for signing and verifying container images and software artefacts. [Software Bill of Materials](https://www.cisa.gov/sbom) (SBOM), [Vulnerability Exploitability eXchange](https://www.ntia.gov/files/ntia/publications/vex_one-page_summary.pdf) (VEX), and signed artefacts should also be incorporated into the security protocol. | +|EGTM-020|EGTM-CS-009|Container Security| There is a risk that a threat actor exploits an Envoy Proxy vulnerability to remote code execution (RCE) due to out of date or misconfigured Envoy Proxy pod deployment, compromising the confidentiality and integrity of Envoy Proxy along with the availability of the proxy service.

| Deployment of an Envoy Proxy or Gateway image containing exploitable CVEs.

|High| Always use the latest version of the Envoy Proxy image. Regularly check for updates and patch the system as soon as updates become available. Implement a CI/CD pipeline that includes security checks for images and prevents deployment of insecure configurations. A tool such as Snyk can be used to provide container vulnerability scanning to mitigate the risk of known vulnerabilities.

Utilise the [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) controller to enforce [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) and configure the [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) to limit its capabilities per the principle of least privilege. | +|EGTM-022|EGTM-CS-010|Container Security| There is a risk that the OIDC client secret (for OIDC authentication) and user password hashes (for basic authentication) get leaked due to misconfigured RBAC permissions.

| Unauthorised access to the application due to credential leakage.

|High| Ensure that only authorised users and service accounts are able to access secrets. This is especially important in namespaces where SecurityPolicy objects are configured, since those namespaces are the ones to store secrets containing the client secret (in OIDC scenarios) and user password hashes (in basic authentication scenarios).

To do so, minimise the use of ClusterRoles and Roles allowing listing and getting secrets. Perform periodic audits of RBAC permissions. | +|EGTM-023|EGTM-EG-007|Envoy Gateway| There is a risk of unauthorised access due to the use of basic authentication, which does not enforce any password restriction in terms of complexity and length. In addition, password hashes are stored in SHA1 format, which is a deprecated hashing function.

| Unauthorised access to the application due to weak authentication mechanisms.

|High| It is recommended to make use of stronger authentication mechanisms (i.e. JWT authentication and OIDC authentication) instead of basic authentication. These authentication mechanisms have many advantages, such as the use of short-lived credentials and a central management of security policies through the identity provider. | +|EGTM-008|EGTM-EG-003|Envoy Gateway| There is a risk of a threat actor misconfiguring static config and compromising the integrity of Envoy Gateway, ultimately leading to the compromised confidentiality, integrity, or availability of tenant data and cluster resources.

| Accidental or deliberate misconfiguration of static configuration leads to a misconfigured deployment of Envoy Gateway, for example logging parameters could be modified or global rate limiting configuration misconfigured.

|Medium| Implement a GitOps model, utilising Kubernetes\' Role-Based Access Control (RBAC) and adhering to the principle of least privilege to minimise human intervention on the cluster. For instance, tools like [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) can be used for declarative GitOps deployments, ensuring all changes are tracked and reviewed. Additionally, configure your source control management (SCM) system to include mandatory pull request (PR) reviews, commit signing, and protected branches to ensure only authorised changes can be committed to the start-up configuration. | +|EGTM-010|EGTM-CS-005|Container Security| There is a risk that a threat actor exploits a weak pod security context, compromising the CIA of a node and the resources / services which run on it.

| Threat Actor who has compromised a pod exploits weak security context to escape to a node, potentially leading to the compromise of Envoy Proxy or Gateway running on the same node.

|Medium| To mitigate this risk, apply [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) at a minimum of [Baseline](https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline) level to all namespaces, especially those containing Envoy Gateway and Proxy Pods. Pod security standards are implemented through K8s [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) to provide [admission control modes](https://kubernetes.io/docs/concepts/security/pod-security-admission/#pod-security-admission-labels-for-namespaces) (enforce, audit, and warn) for namespaces. Pod security standards can be enforced by namespace labels as shown [here](https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/), to enforce a baseline level of pod security to specific namespaces.

Further enhance the security by implementing a sandboxing solution such as [gVisor](https://gvisor.dev/) for Envoy Gateway and Proxy Pods to isolate the application from the host kernel. This can be set within the runtimeClassName of the Pod specification. | +|EGTM-012|EGTM-GW-004|Gateway API| There is a risk that a threat actor could abuse excessive RBAC privileges to create ReferenceGrant resources. These resources could then be used to create cross-namespace communication, leading to unauthorised access to the application. This could compromise the confidentiality and integrity of resources and configuration in the affected namespaces and potentially disrupt the availability of services that rely on these object references.

| A ReferenceGrant is created, which validates traffic to cross namespace trust boundaries without a valid business reason, such as a route in one tenant\'s namespace referencing a backend in another.

|Medium| Ensure that the ability to create ReferenceGrant resources is restricted to the minimum number of people. Pay special attention to ClusterRoles that allow that action. | |EGTM-018|EGTM-GW-006|Gateway API| There is a risk that malicious requests could lead to a Denial of Service (DoS) attack, thereby reducing API gateway availability due to misconfigurations in rate-limiting or load balancing controls, or a lack of route timeout enforcement.

| Reduced API gateway availability due to an attacker\'s maliciously crafted request (e.g., QoD) potentially inducing a Denial of Service (DoS) attack.

|Medium| To ensure high availability and to mitigate potential security threats, adhere to the Envoy Gateway documentation for the configuration of a [rate-limiting](https://gateway.envoyproxy.io/v0.6.0/user/rate-limit/) filter and load balancing.

Further, adhere to best practices for configuring Envoy Proxy as an edge proxy documented [here](https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/edge#configuring-envoy-as-an-edge-proxy) within the EnvoyProxy docs. This involves configuring TCP and HTTP proxies with specific settings, including restricting access to the admin endpoint, setting the [overload manager](https://www.envoyproxy.io/docs/envoy/latest/configuration/operations/overload_manager/overload_manager#config-overload-manager) and [listener](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto#envoy-v3-api-field-config-listener-v3-listener-per-connection-buffer-limit-bytes) / [cluster](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#envoy-v3-api-field-config-cluster-v3-cluster-per-connection-buffer-limit-bytes) buffer limits, enabling [use_remote_address](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-use-remote-address), setting [connection and stream timeouts](https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/timeouts#faq-configuration-timeouts), limiting [maximum concurrent streams](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-max-concurrent-streams), setting [initial stream window size limit](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size), and configuring action on [headers_with_underscores](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-headers-with-underscores-action).

[Path normalisation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-normalize-path) should be enabled to minimise path confusion vulnerabilities. These measures help protect against volumetric threats such as Denial of Service (DoS)nattacks. Utilise custom resources to implement policy attachment, thereby exposing request limit configuration for route types. | -|EGTM-019|EGTM-DP-004|Container Security| There is a risk that replay attacks using stolen or reused JSON Web Tokens (JWTs) can compromise transmission integrity, thereby undermining the confidentiality and integrity of the data plane.

| Transmission integrity is compromised due to replay attacks using stolen or reused JSON Web Tokens (JWTs).

|Medium| Comply with JWT best practices for enhanced security, paying special attention to the use of short-lived tokens, which reduce the window of opportunity for a replay attack. The [exp](https://datatracker.ietf.org/doc/html/rfc7519#page-9) claim can be used to set token expiration times. | -|EGTM-024|EGTM-EG-008|Envoy Gateway| There is a risk of developers getting more privileges than required due to the use of SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy and BackendTrafficPolicy. These resources can be attached to a Gateway resource. Therefore, a developer with permission to deploy them would be able to modify a Gateway configuration by targeting the gateway in the policy manifest. This conflicts with the [Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model), where developers do not have write permissions on Gateways.

| Excessive developer permissions lead to a misconfiguration and/or unauthorised access.

|Medium| Considering the Tenant C scenario (represented in the Architecture Diagram), if a developer can create SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy or BackendTrafficPolicy objects in namespace C, they would be able to modify a Gateway configuration by attaching the policy to the gateway. In such scenarios, it is recommended to either:

a. Create a separate namespace, where developers have no permissions, > to host tenant C\'s gateway. Note that, due to design decisions, > the > SecurityPolicy/EnvoyPatchPolicy/ClientTrafficPolicy/BackendTrafficPolicy > object can only target resources deployed in the same namespace. > Therefore, having a separate namespace for the gateway would > prevent developers from attaching the policy to the gateway.

b. Forbid the creation of these policies for developers in namespace C.

On the other hand, in scenarios similar to tenants A and B, where a shared gateway namespace is in place, this issue is more limited. Note that in this scenario, developers don\'t have access to the shared gateway namespace.

In addition, it is important to mention that EnvoyPatchPolicy resources can also be attached to GatewayClass resources. This means that, in order to comply with the Advanced 4 Tier model, individuals with the Application Administrator role should not have access to this resource either. | -|EGTM-003|EGTM-EG-001|Envoy Gateway| There is a risk that a threat actor could downgrade the security of proxied connections by configuring a weak set of cipher suites, compromising the confidentiality and integrity of proxied traffic.

| Exploit weak cipher suite configuration to downgrade security of proxied connections.

|Low| Users operating in highly regulated environments may need to tightly control the TLS protocol and associated cipher suites, blocking non-conforming incoming connections to the gateway.

EnvoyProxy bootstrap config can be customised as per the [customise EnvoyProxy](../operations/customize-envoyproxy) documentation. In addition, from v.1.0.0, it is possible to configure common TLS properties for a Gateway or XRoute through the [ClientTrafficPolicy](https://gateway.envoyproxy.io/latest/api/extension_types/#clienttrafficpolicy) object. | -|EGTM-005|EGTM-CP-002|Container Security| Threat actor who has obtained access to Envoy Gateway pod could exploit the lack of AppArmor and Seccomp profiles in the Envoy Gateway deployment to attempt a container breakout, given the presence of an exploitable vulnerability, potentially impacting the confidentiality and integrity of namespace resources.

| Unauthorised syscalls and malicious code running in the Envoy Gateway pod.

|Low| Implement [AppArmor](https://kubernetes.io/docs/tutorials/security/apparmor/) policies by setting \: \ within container.apparmor.security.beta.kubernetes.io (note, this config is set *per container*). Well-defined AppArmor policies may provide greater protection from unknown threats.

Enforce [Seccomp](https://kubernetes.io/docs/tutorials/security/seccomp/) profiles by setting the seccompProfile under securityContext. Ideally, a [fine-grained](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-with-a-seccomp-profile-that-only-allows-necessary-syscalls) profile should be used to restrict access to only necessary syscalls, however the \--seccomp-default flag can be set to resort to [RuntimeDefault](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-that-uses-the-container-runtime-default-seccomp-profile) which provides a container runtime specific. Example seccomp profiles can be found [here](https://kubernetes.io/docs/tutorials/security/seccomp/#download-profiles).

To further enhance pod security, consider implementing [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) via seLinuxOptions for additional syscall attack surface reduction. Setting readOnlyRootFilesystem == true enforces an immutable root filesystem, preventing the addition of malicious binaries to the PATH and increasing the attack cost. Together, these configuration items improve the pods [Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). | -|EGTM-006|EGTM-CS-004|Container Security| There is a risk that a threat actor exploits a vulnerability in Envoy Proxy to expose a reverse shell, enabling them to compromise the confidentiality, integrity and availability of tenant data via a secondary attack.

| If an external attacker managed to exploit a vulnerability in Envoy, the presence of a shell would be greatly helpful for the attacker in terms of potentially pivoting, escalating, or establishing some form of persistence.

|Low| By default, Envoy uses a [distroless](https://github.com/GoogleContainerTools/distroless) image since v.0.6.0, which does not ship a shell. Therefore, ensure EnvoyProxy image is up-to-date and patched with the latest stable version.

If using private EnvoyProxy images, use a lightweight EnvoyProxy image without a shell or debugging tool(s) which may be useful for an attacker.

An [AuditPolicy](https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/#audit-policy) (audit.k8s.io/v1beta1) can be configured to record API calls made within your cluster, allowing for identification of malicious traffic and enabling incident response. Requests are recorded based on stages which delineate between the lifecycle stage of the request made (e.g., RequestReceived, ResponseStarted, & ResponseComplete). | -|EGTM-011|EGTM-GW-003|Gateway API| There is a risk that a gateway owner (or someone with the ability to set namespace labels) maliciously or accidentally binds routes across namespace boundaries, potentially compromising the confidentiality and integrity of traffic in a multitenant scenario.

| If a Route Binding within a Gateway Listener is configured based on a custom label, it could allow a malicious internal actor with the ability to label namespaces to change the set of namespaces supported by the Gateway

|Low| Consider the use of custom admission control to restrict what labels can be set on namespaces through tooling such as [Kubewarden](https://kyverno.io/policies/pod-security/), [Kyverno](https://github.com/kubewarden), and [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Route binding should follow the Kubernetes Gateway API security model, as shown [here](https://gateway-api.sigs.k8s.io/concepts/security-model/#1-route-binding), to connect gateways in different namespaces. | -|EGTM-013|EGTM-GW-005|Gateway API| There is a risk that an unauthorised actor deploys an unauthorised GatewayClass due to GatewayClass namespace validation not being configured, leading to non-compliance with business and security requirements.

| Unauthorised deployment of Gateway resource via GatewayClass template which crosses namespace trust boundaries.

|Low| Leverage GatewayClass namespace validation to limit the namespaces where GatewayClasses can be run through a tool such as using [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Reference pull request \#[24](https://github.com/open-policy-agent/gatekeeper-library/pull/24) within gatekeeper-library which outlines how to add GatewayClass namespace validation through a GatewayClassNamespaces API resource kind within the constraints.gatekeeper.sh/v1beta1 apiGroup. | -|EGTM-015|EGTM-CS-007|Container Security| There is a risk that threat actors could exploit ServiceAccount tokens for illegitimate authentication, thereby leading to privilege escalation and the undermining of gateway API resources\' integrity, confidentiality, and availability.

| The threat arises from threat actors impersonating the envoy-gateway ServiceAccount through the replay of ServiceAccount tokens, thereby achieving escalated privileges and gaining unauthorised access to Kubernetes resources.

|Low| Limit the creation of ServiceAccounts to only when necessary, specifically refraining from using default service account tokens, especially for high-privilege service accounts. For legacy clusters running Kubernetes version 1.21 or earlier, note that ServiceAccount tokens are long-lived by default. To disable the automatic mounting of the service account token, set automountServiceAccountToken: false in the PodSpec. | -|EGTM-016|EGTM-EG-004|Envoy Gateway| There is a risk that threat actors establish persistence and move laterally through the cluster unnoticed due to limited visibility into access and application-level activity.

| Threat actors establish persistence and move laterally through the cluster unnoticed.

|Low| Configure [access logging](../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.

Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR). | -|EGTM-017|EGTM-EG-005|Envoy Gateway| There is a risk that an insider misconfigures an envoy gateway component and goes unnoticed due to a low-touch logging configuration (via default) which responsible stakeholders are not aptly aware of or have immediate access to.

| The threat emerges from an insider misconfiguring an Envoy Gateway component without detection.

|Low| Configure the logging level of the Envoy Gateway using the \'level\' field in [EnvoyGatewayLogging](https://gateway.envoyproxy.io/latest/api/extension_types/#envoygatewaylogging). Ensure the appropriate logging levels are set for relevant components such as \'gateway-api\', \'xds-translator\', or \'global-ratelimit\'. If left unspecified, the logging level defaults to \"info\", which may not provide sufficient detail for security monitoring.

Employ a centralised logging mechanism, like [Fluentd](https://github.com/fluent/fluentd), to enhance visibility into application-level activity and to enable efficient incident response. | -|EGTM-021|EGTM-EG-006|Envoy Gateway| There is a risk that the admin interface is exposed without valid business reason, increasing the attack surface.

| Exposed admin interfaces give internal attackers the option to affect production traffic in unauthorised ways, and the option to exploit any vulnerabilities which may be present in the admin interface (e.g. by orchestrating malicious GET requests to the admin interface through CSRF, compromising Envoy Proxy global configuration or shutting off the service entirely (e.g., /quitquitquit).

|Low| The Envoy Proxy admin interface is only exposed to localhost, meaning that it is secure by default. However, due to the risk of misconfiguration, this recommendation is included.

Due to the importance of the admin interface, it is recommended to ensure that Envoy Proxies have not been accidentally misconfigured to expose the admin interface to untrusted networks. | -|EGTM-025 | EGTM-CS-011 | Container Security | The presence of a vulnerability, be it in the kernel or another system component, when coupled with containers running as root, could enable a threat actor to escape the container, thereby compromising the confidentiality, integrity, or availability of cluster resources. | The Envoy Proxy container's root-user configuration can be leveraged by an attacker to escalate privileges, execute a container breakout, and traverse across trust boundaries. | Low | By default, Envoy Gateway deployments do not use root users. Nonetheless, in case a custom image or deployment manifest is to be used, make sure Envoy Proxy pods run as a non-root user with a high UID within the container. Set runAsUser and runAsGroup security context options to specific UIDs (e.g., runAsUser: 1000 & runAsGroup: 3000) to ensure the container operates with the stipulated non-root user and group ID. If using helm chart deployment, define the user and group ID in the values.yaml file or via the command line during helm install / upgrade. | +|EGTM-019|EGTM-DP-004|Container Security| There is a risk that replay attacks using stolen or reused JSON Web Tokens (JWTs) can compromise transmission integrity, thereby undermining the confidentiality and integrity of the data plane.

| Transmission integrity is compromised due to replay attacks using stolen or reused JSON Web Tokens (JWTs).

|Medium| Comply with JWT best practices for enhanced security, paying special attention to the use of short-lived tokens, which reduce the window of opportunity for a replay attack. The [exp](https://datatracker.ietf.org/doc/html/rfc7519#page-9) claim can be used to set token expiration times. | +|EGTM-024|EGTM-EG-008|Envoy Gateway| There is a risk of developers getting more privileges than required due to the use of SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy and BackendTrafficPolicy. These resources can be attached to a Gateway resource. Therefore, a developer with permission to deploy them would be able to modify a Gateway configuration by targeting the gateway in the policy manifest. This conflicts with the [Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model), where developers do not have write permissions on Gateways.

| Excessive developer permissions lead to a misconfiguration and/or unauthorised access.

|Medium| Considering the Tenant C scenario (represented in the Architecture Diagram), if a developer can create SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy or BackendTrafficPolicy objects in namespace C, they would be able to modify a Gateway configuration by attaching the policy to the gateway. In such scenarios, it is recommended to either:

a. Create a separate namespace, where developers have no permissions, > to host tenant C\'s gateway. Note that, due to design decisions, > the > SecurityPolicy/EnvoyPatchPolicy/ClientTrafficPolicy/BackendTrafficPolicy > object can only target resources deployed in the same namespace. > Therefore, having a separate namespace for the gateway would > prevent developers from attaching the policy to the gateway.

b. Forbid the creation of these policies for developers in namespace C.

On the other hand, in scenarios similar to tenants A and B, where a shared gateway namespace is in place, this issue is more limited. Note that in this scenario, developers don\'t have access to the shared gateway namespace.

In addition, it is important to mention that EnvoyPatchPolicy resources can also be attached to GatewayClass resources. This means that, in order to comply with the Advanced 4 Tier model, individuals with the Application Administrator role should not have access to this resource either. | +|EGTM-003|EGTM-EG-001|Envoy Gateway| There is a risk that a threat actor could downgrade the security of proxied connections by configuring a weak set of cipher suites, compromising the confidentiality and integrity of proxied traffic.

| Exploit weak cipher suite configuration to downgrade security of proxied connections.

|Low| Users operating in highly regulated environments may need to tightly control the TLS protocol and associated cipher suites, blocking non-conforming incoming connections to the gateway.

EnvoyProxy bootstrap config can be customised as per the [customise EnvoyProxy](../operations/customize-envoyproxy) documentation. In addition, from v.1.0.0, it is possible to configure common TLS properties for a Gateway or XRoute through the [ClientTrafficPolicy](https://gateway.envoyproxy.io/latest/api/extension_types/#clienttrafficpolicy) object. | +|EGTM-005|EGTM-CP-002|Container Security| Threat actor who has obtained access to Envoy Gateway pod could exploit the lack of AppArmor and Seccomp profiles in the Envoy Gateway deployment to attempt a container breakout, given the presence of an exploitable vulnerability, potentially impacting the confidentiality and integrity of namespace resources.

| Unauthorised syscalls and malicious code running in the Envoy Gateway pod.

|Low| Implement [AppArmor](https://kubernetes.io/docs/tutorials/security/apparmor/) policies by setting \: \ within container.apparmor.security.beta.kubernetes.io (note, this config is set *per container*). Well-defined AppArmor policies may provide greater protection from unknown threats.

Enforce [Seccomp](https://kubernetes.io/docs/tutorials/security/seccomp/) profiles by setting the seccompProfile under securityContext. Ideally, a [fine-grained](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-with-a-seccomp-profile-that-only-allows-necessary-syscalls) profile should be used to restrict access to only necessary syscalls, however the \--seccomp-default flag can be set to resort to [RuntimeDefault](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-that-uses-the-container-runtime-default-seccomp-profile) which provides a container runtime specific. Example seccomp profiles can be found [here](https://kubernetes.io/docs/tutorials/security/seccomp/#download-profiles).

To further enhance pod security, consider implementing [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) via seLinuxOptions for additional syscall attack surface reduction. Setting readOnlyRootFilesystem == true enforces an immutable root filesystem, preventing the addition of malicious binaries to the PATH and increasing the attack cost. Together, these configuration items improve the pods [Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). | +|EGTM-006|EGTM-CS-004|Container Security| There is a risk that a threat actor exploits a vulnerability in Envoy Proxy to expose a reverse shell, enabling them to compromise the confidentiality, integrity and availability of tenant data via a secondary attack.

| If an external attacker managed to exploit a vulnerability in Envoy, the presence of a shell would be greatly helpful for the attacker in terms of potentially pivoting, escalating, or establishing some form of persistence.

|Low| By default, Envoy uses a [distroless](https://github.com/GoogleContainerTools/distroless) image since v.0.6.0, which does not ship a shell. Therefore, ensure EnvoyProxy image is up-to-date and patched with the latest stable version.

If using private EnvoyProxy images, use a lightweight EnvoyProxy image without a shell or debugging tool(s) which may be useful for an attacker.

An [AuditPolicy](https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/#audit-policy) (audit.k8s.io/v1beta1) can be configured to record API calls made within your cluster, allowing for identification of malicious traffic and enabling incident response. Requests are recorded based on stages which delineate between the lifecycle stage of the request made (e.g., RequestReceived, ResponseStarted, & ResponseComplete). | +|EGTM-011|EGTM-GW-003|Gateway API| There is a risk that a gateway owner (or someone with the ability to set namespace labels) maliciously or accidentally binds routes across namespace boundaries, potentially compromising the confidentiality and integrity of traffic in a multitenant scenario.

| If a Route Binding within a Gateway Listener is configured based on a custom label, it could allow a malicious internal actor with the ability to label namespaces to change the set of namespaces supported by the Gateway

|Low| Consider the use of custom admission control to restrict what labels can be set on namespaces through tooling such as [Kubewarden](https://kyverno.io/policies/pod-security/), [Kyverno](https://github.com/kubewarden), and [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Route binding should follow the Kubernetes Gateway API security model, as shown [here](https://gateway-api.sigs.k8s.io/concepts/security-model/#1-route-binding), to connect gateways in different namespaces. | +|EGTM-013|EGTM-GW-005|Gateway API| There is a risk that an unauthorised actor deploys an unauthorised GatewayClass due to GatewayClass namespace validation not being configured, leading to non-compliance with business and security requirements.

| Unauthorised deployment of Gateway resource via GatewayClass template which crosses namespace trust boundaries.

|Low| Leverage GatewayClass namespace validation to limit the namespaces where GatewayClasses can be run through a tool such as using [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Reference pull request \#[24](https://github.com/open-policy-agent/gatekeeper-library/pull/24) within gatekeeper-library which outlines how to add GatewayClass namespace validation through a GatewayClassNamespaces API resource kind within the constraints.gatekeeper.sh/v1beta1 apiGroup. | +|EGTM-015|EGTM-CS-007|Container Security| There is a risk that threat actors could exploit ServiceAccount tokens for illegitimate authentication, thereby leading to privilege escalation and the undermining of gateway API resources\' integrity, confidentiality, and availability.

| The threat arises from threat actors impersonating the envoy-gateway ServiceAccount through the replay of ServiceAccount tokens, thereby achieving escalated privileges and gaining unauthorised access to Kubernetes resources.

|Low| Limit the creation of ServiceAccounts to only when necessary, specifically refraining from using default service account tokens, especially for high-privilege service accounts. For legacy clusters running Kubernetes version 1.21 or earlier, note that ServiceAccount tokens are long-lived by default. To disable the automatic mounting of the service account token, set automountServiceAccountToken: false in the PodSpec. | +|EGTM-016|EGTM-EG-004|Envoy Gateway| There is a risk that threat actors establish persistence and move laterally through the cluster unnoticed due to limited visibility into access and application-level activity.

| Threat actors establish persistence and move laterally through the cluster unnoticed.

|Low| Configure [access logging](../../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.

Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR). | +|EGTM-017|EGTM-EG-005|Envoy Gateway| There is a risk that an insider misconfigures an envoy gateway component and goes unnoticed due to a low-touch logging configuration (via default) which responsible stakeholders are not aptly aware of or have immediate access to.

| The threat emerges from an insider misconfiguring an Envoy Gateway component without detection.

|Low| Configure the logging level of the Envoy Gateway using the \'level\' field in [EnvoyGatewayLogging](https://gateway.envoyproxy.io/latest/api/extension_types/#envoygatewaylogging). Ensure the appropriate logging levels are set for relevant components such as \'gateway-api\', \'xds-translator\', or \'global-ratelimit\'. If left unspecified, the logging level defaults to \"info\", which may not provide sufficient detail for security monitoring.

Employ a centralised logging mechanism, like [Fluentd](https://github.com/fluent/fluentd), to enhance visibility into application-level activity and to enable efficient incident response. | +|EGTM-021|EGTM-EG-006|Envoy Gateway| There is a risk that the admin interface is exposed without valid business reason, increasing the attack surface.

| Exposed admin interfaces give internal attackers the option to affect production traffic in unauthorised ways, and the option to exploit any vulnerabilities which may be present in the admin interface (e.g. by orchestrating malicious GET requests to the admin interface through CSRF, compromising Envoy Proxy global configuration or shutting off the service entirely (e.g., /quitquitquit).

|Low| The Envoy Proxy admin interface is only exposed to localhost, meaning that it is secure by default. However, due to the risk of misconfiguration, this recommendation is included.

Due to the importance of the admin interface, it is recommended to ensure that Envoy Proxies have not been accidentally misconfigured to expose the admin interface to untrusted networks. | +|EGTM-025 | EGTM-CS-011 | Container Security | The presence of a vulnerability, be it in the kernel or another system component, when coupled with containers running as root, could enable a threat actor to escape the container, thereby compromising the confidentiality, integrity, or availability of cluster resources. | The Envoy Proxy container's root-user configuration can be leveraged by an attacker to escalate privileges, execute a container breakout, and traverse across trust boundaries. | Low | By default, Envoy Gateway deployments do not use root users. Nonetheless, in case a custom image or deployment manifest is to be used, make sure Envoy Proxy pods run as a non-root user with a high UID within the container. Set runAsUser and runAsGroup security context options to specific UIDs (e.g., runAsUser: 1000 & runAsGroup: 3000) to ensure the container operates with the stipulated non-root user and group ID. If using helm chart deployment, define the user and group ID in the values.yaml file or via the command line during helm install / upgrade. | ## Attack Trees diff --git a/site/content/en/v1.0.1/tasks/security/tls-passthrough.md b/site/content/en/v1.0.1/tasks/security/tls-passthrough.md index 63fefa94197..501c80e4eb3 100644 --- a/site/content/en/v1.0.1/tasks/security/tls-passthrough.md +++ b/site/content/en/v1.0.1/tasks/security/tls-passthrough.md @@ -116,4 +116,4 @@ kubectl delete secret/server-certs ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. diff --git a/site/content/en/v1.0.1/tasks/traffic/gatewayapi-support.md b/site/content/en/v1.0.1/tasks/traffic/gatewayapi-support.md index 778a9972d62..7ea0e91e54b 100644 --- a/site/content/en/v1.0.1/tasks/traffic/gatewayapi-support.md +++ b/site/content/en/v1.0.1/tasks/traffic/gatewayapi-support.md @@ -94,7 +94,7 @@ these types of cross-namespace references. Envoy Gateway supports the following namespace. - Allowing a Gateway's [SecretObjectReference][] to reference a secret in a different namespace. -[system design]: ../../contributions/design/system-design/ +[system design]: ../../../contributions/design/system-design [Gateway API]: https://gateway-api.sigs.k8s.io/ [GatewayClass]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass [parameters reference]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.ParametersReference @@ -110,7 +110,7 @@ these types of cross-namespace references. Envoy Gateway supports the following [TLSRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TLSRoute [ReferenceGrant]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.ReferenceGrant [SecretObjectReference]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.SecretObjectReference -[rate limiting]: ../../contributions/design/rate-limit +[rate limiting]: ../../../contributions/design/rate-limit [request authentication]: ../security/jwt-authentication [EnvoyProxy]: ../../../api/extension_types#envoyproxy [resolving conflicts]: https://gateway-api.sigs.k8s.io/concepts/guidelines/?h=conflict#conflicts diff --git a/site/content/en/v1.0.1/tasks/traffic/udp-routing.md b/site/content/en/v1.0.1/tasks/traffic/udp-routing.md index 6f1d8c192c7..f657df4fb2b 100644 --- a/site/content/en/v1.0.1/tasks/traffic/udp-routing.md +++ b/site/content/en/v1.0.1/tasks/traffic/udp-routing.md @@ -141,7 +141,7 @@ kubectl delete udproute/coredns ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. [UDPRoute]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.UDPRoute [UDP proxy documentation]: https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/udp_filters/udp_proxy diff --git a/site/content/zh/_index.md b/site/content/zh/_index.md index cb2619140f1..48f75da8899 100644 --- a/site/content/zh/_index.md +++ b/site/content/zh/_index.md @@ -6,7 +6,7 @@ title: Envoy Gateway 开始使用 - + 参与贡献

将 Envoy 代理作为独立或基于 Kubernetes 的 API 网关进行管理

@@ -66,8 +66,7 @@ title: Envoy Gateway {{% /blocks/feature %}} {{% blocks/feature icon="fab fa-github" title="欢迎贡献!" - url="/latest/contributions/" %}} -We do a [Pull Request](https://github.com/envoyproxy/gateway/pulls) contributions workflow on **GitHub**. + url="/contributions/" %}} 我们在 **GitHub** 通过 [Pull Request](https://github.com/envoyproxy/gateway/pulls) 开启贡献流程。 {{% /blocks/feature %}} diff --git a/site/hugo.toml b/site/hugo.toml index a658bd29a28..72319373893 100644 --- a/site/hugo.toml +++ b/site/hugo.toml @@ -238,47 +238,43 @@ enable = true desc = "与其他项目开发人员沟通" [menu] + [[menu.main]] + name = "Contributions" + weight = -98 + url = "/contributions" [[menu.main]] name = "Blog" weight = -99 - pre = "" url = "/blog" [[menu.main]] name = "About" weight = -100 - pre = "" url = "/about" [[menu.main]] name = "Announcements" weight = -101 - pre = "" url = "/announcements" [[menu.main]] name = "Documentation" weight = -102 - pre = "" url = "/v1.0.1" # i18n for Chinese [[languages.zh.menu.main]] name = "博客" weight = -99 - pre = "" url = "/blog" [[languages.zh.menu.main]] name = "关于" weight = -100 - pre = "" url = "/about" [[languages.zh.menu.main]] name = "公告" weight = -101 - pre = "" url = "/announcements" [[languages.zh.menu.main]] name = "文档" weight = -102 - pre = "" url = "/latest" [[params.versions]] From 92b4a9b8261be5a3400a4453e368e47dcba8587e Mon Sep 17 00:00:00 2001 From: zirain Date: Fri, 12 Apr 2024 12:27:12 +0800 Subject: [PATCH 08/10] chore: update golint (#3177) * chore: update golint Signed-off-by: zirain * fix lint Signed-off-by: zirain --------- Signed-off-by: zirain --- test/cel-validation/backendtrafficpolicy_test.go | 10 ++++------ test/cel-validation/main_test.go | 7 +++++-- tools/make/lint.mk | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/test/cel-validation/backendtrafficpolicy_test.go b/test/cel-validation/backendtrafficpolicy_test.go index 673ed81ef4d..64968c9e009 100644 --- a/test/cel-validation/backendtrafficpolicy_test.go +++ b/test/cel-validation/backendtrafficpolicy_test.go @@ -16,9 +16,7 @@ import ( "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/utils/pointer" "k8s.io/utils/ptr" - gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" @@ -436,8 +434,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { { desc: " valid config: min, max, nil", mutate: func(btp *egv1a1.BackendTrafficPolicy) { - valMax := pointer.Int64(4294967295) - valMin := pointer.Int64(0) + valMax := ptr.To[int64](4294967295) + valMin := ptr.To[int64](0) btp.Spec = egv1a1.BackendTrafficPolicySpec{ TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ @@ -459,8 +457,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { { desc: " invalid config: min and max values", mutate: func(btp *egv1a1.BackendTrafficPolicy) { - valOverMax := pointer.Int64(4294967296) - valUnderMin := pointer.Int64(-1) + valOverMax := ptr.To[int64](4294967296) + valUnderMin := ptr.To[int64](-1) btp.Spec = egv1a1.BackendTrafficPolicySpec{ TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ diff --git a/test/cel-validation/main_test.go b/test/cel-validation/main_test.go index 64915388439..30ab253d7de 100644 --- a/test/cel-validation/main_test.go +++ b/test/cel-validation/main_test.go @@ -28,6 +28,10 @@ import ( var c client.Client func TestMain(m *testing.M) { + os.Exit(runTest(m)) +} + +func runTest(m *testing.M) int { // Setup the test environment. testEnv, restCfg, err := startEnv() if err != nil { @@ -47,8 +51,7 @@ func TestMain(m *testing.M) { panic(fmt.Sprintf("Error initializing client: %v", err)) } _ = egv1a1.AddToScheme(c.Scheme()) - - os.Exit(m.Run()) + return m.Run() } func startEnv() (*envtest.Environment, *rest.Config, error) { diff --git a/tools/make/lint.mk b/tools/make/lint.mk index 57bf36dffff..8c1435e2cb1 100644 --- a/tools/make/lint.mk +++ b/tools/make/lint.mk @@ -20,7 +20,7 @@ lint: lint.golint lint-deps: $(tools/golangci-lint) lint.golint: $(tools/golangci-lint) @$(LOG_TARGET) - $(tools/golangci-lint) run $(GOLANGCI_LINT_FLAGS) --build-tags=e2e --config=tools/linter/golangci-lint/.golangci.yml + $(tools/golangci-lint) run $(GOLANGCI_LINT_FLAGS) --build-tags=e2e,celvalidation --config=tools/linter/golangci-lint/.golangci.yml .PHONY: lint.yamllint lint: lint.yamllint From d383ba54020a1bd38e2787eff230b055713f35e3 Mon Sep 17 00:00:00 2001 From: zirain Date: Fri, 12 Apr 2024 15:49:42 +0800 Subject: [PATCH 09/10] docs: support notImplementedHide (#2849) * docs: support hidefromdoc Signed-off-by: zirain * update Signed-off-by: zirain * rename to notimplementedhide Signed-off-by: zirain * case sensitive Signed-off-by: zirain * notImplementedHide Signed-off-by: zirain --------- Signed-off-by: zirain --- api/v1alpha1/backendtrafficpolicy_types.go | 1 + site/content/en/latest/api/extension_types.md | 291 +++++++++--------- tools/crd-ref-docs/config.yaml | 3 + tools/crd-ref-docs/templates/type.tpl | 9 +- tools/src/crd-ref-docs/go.mod | 24 +- tools/src/crd-ref-docs/go.sum | 58 ++-- 6 files changed, 193 insertions(+), 193 deletions(-) diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go index b47deebc02c..b5efbeff7c7 100644 --- a/api/v1alpha1/backendtrafficpolicy_types.go +++ b/api/v1alpha1/backendtrafficpolicy_types.go @@ -95,6 +95,7 @@ type BackendTrafficPolicySpec struct { // The compression config for the http streams. // // +optional + // +notImplementedHide Compression []*Compression `json:"compression,omitempty"` } diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 21f5bab7250..43bdc15f8b4 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -52,6 +52,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `timeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | false | Timeout defines the time to wait for a health check response. | | `interval` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | false | Interval defines the time between active health checks. | | `unhealthyThreshold` | _integer_ | false | UnhealthyThreshold defines the number of unhealthy health checks required before a backend host is marked unhealthy. | @@ -60,7 +61,6 @@ _Appears in:_ | `http` | _[HTTPActiveHealthChecker](#httpactivehealthchecker)_ | false | HTTP defines the configuration of http health checker.
It's required while the health checker type is HTTP. | | `tcp` | _[TCPActiveHealthChecker](#tcpactivehealthchecker)_ | false | TCP defines the configuration of tcp health checker.
It's required while the health checker type is TCP. | - #### ActiveHealthCheckPayload @@ -73,11 +73,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[ActiveHealthCheckPayloadType](#activehealthcheckpayloadtype)_ | true | Type defines the type of the payload. | | `text` | _string_ | false | Text payload in plain text. | | `binary` | _integer array_ | false | Binary payload base64 encoded. | - #### ActiveHealthCheckPayloadType _Underlying type:_ _string_ @@ -111,10 +111,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `baseInterval` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | true | BaseInterval is the base interval between retries. | | `maxInterval` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | false | MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval | - #### BackendRef @@ -128,13 +128,13 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `group` | _[Group](#group)_ | false | Group is the group of the referent. For example, "gateway.networking.k8s.io".
When unspecified or empty string, core API group is inferred. | | `kind` | _[Kind](#kind)_ | false | Kind is the Kubernetes resource kind of the referent. For example
"Service".

Defaults to "Service" when not specified.

ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.

Support: Core (Services with a type other than ExternalName)

Support: Implementation-specific (Services with type ExternalName) | | `name` | _[ObjectName](#objectname)_ | true | Name is the name of the referent. | | `namespace` | _[Namespace](#namespace)_ | false | Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.

Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.

Support: Core | | `port` | _[PortNumber](#portnumber)_ | false | Port specifies the destination port number to use for this resource.
Port is required when the referent is a Kubernetes Service. In this
case, the port number is the service port number, not the target port.
For other resources, destination port might be derived from the referent
resource or this field. | - #### BackendTrafficPolicy @@ -149,10 +149,10 @@ _Appears in:_ | --- | --- | --- | --- | | `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1` | `kind` | _string_ | |`BackendTrafficPolicy` + | `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` | _[BackendTrafficPolicySpec](#backendtrafficpolicyspec)_ | true | spec defines the desired state of BackendTrafficPolicy. | - #### BackendTrafficPolicyList @@ -165,10 +165,10 @@ BackendTrafficPolicyList contains a list of BackendTrafficPolicy resources. | --- | --- | --- | --- | | `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1` | `kind` | _string_ | |`BackendTrafficPolicyList` + | `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` | _[BackendTrafficPolicy](#backendtrafficpolicy) array_ | true | | - #### BackendTrafficPolicySpec @@ -180,6 +180,7 @@ _Appears in:_ | 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 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. | | `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests
to a predefined value based on attributes within the traffic flow. | | `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to
the backend endpoints | @@ -190,8 +191,6 @@ _Appears in:_ | `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests.
If not set, circuit breakers will be enabled with the default thresholds | | `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
If not set, retry will be disabled. | | `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. | -| `compression` | _[Compression](#compression) array_ | false | The compression config for the http streams. | - #### BasicAuth @@ -204,8 +203,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `users` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | The Kubernetes secret which contains the username-password pairs in
htpasswd format, used to verify user credentials in the "Authorization"
header.

This is an Opaque secret. The username-password pairs should be stored in
the key ".htpasswd". As the key name indicates, the value needs to be the
htpasswd format, for example: "user1:{SHA}hashed_user1_password".
Right now, only SHA hash algorithm is supported.
Reference to https://httpd.apache.org/docs/2.4/programs/htpasswd.html
for more details.

Note: The secret must be in the same namespace as the SecurityPolicy. | +| `users` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | The Kubernetes secret which contains the username-password pairs in
htpasswd format, used to verify user credentials in the "Authorization"
header.

This is an Opaque secret. The username-password pairs should be stored in
the key ".htpasswd". As the key name indicates, the value needs to be the
htpasswd format, for example: "user1:{SHA}hashed_user1_password".
Right now, only SHA hash algorithm is supported.
Reference to https://httpd.apache.org/docs/2.4/programs/htpasswd.html
for more details.

Note: The secret must be in the same namespace as the SecurityPolicy. | #### BootstrapType @@ -229,6 +228,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `allowOrigins` | _[Origin](#origin) array_ | true | AllowOrigins defines the origins that are allowed to make requests. | | `allowMethods` | _string array_ | true | AllowMethods defines the methods that are allowed to make requests. | | `allowHeaders` | _string array_ | true | AllowHeaders defines the headers that are allowed to be sent with requests. | @@ -236,7 +236,6 @@ _Appears in:_ | `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | true | MaxAge defines how long the results of a preflight request can be cached. | | `allowCredentials` | _boolean_ | true | AllowCredentials indicates whether a request can include user credentials
like cookies, authentication headers, or TLS client certificates. | - #### CircuitBreaker @@ -248,13 +247,13 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `maxConnections` | _integer_ | false | The maximum number of connections that Envoy will establish to the referenced backend defined within a xRoute rule. | | `maxPendingRequests` | _integer_ | false | The maximum number of pending requests that Envoy will queue to the referenced backend defined within a xRoute rule. | | `maxParallelRequests` | _integer_ | false | The maximum number of parallel requests that Envoy will make to the referenced backend defined within a xRoute rule. | | `maxParallelRetries` | _integer_ | false | The maximum number of parallel retries that Envoy will make to the referenced backend defined within a xRoute rule. | | `maxRequestsPerConnection` | _integer_ | false | The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
Default: unlimited. | - #### ClaimToHeader @@ -266,10 +265,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `header` | _string_ | true | Header defines the name of the HTTP request header that the JWT Claim will be saved into. | | `claim` | _string_ | true | Claim is the JWT Claim that should be saved into the header : it can be a nested claim of type
(eg. "claim.nested.key", "sub"). The nested claim name must use dot "."
to separate the JSON name path. | - #### ClientIPDetectionSettings @@ -281,10 +280,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `xForwardedFor` | _[XForwardedForSettings](#xforwardedforsettings)_ | false | XForwardedForSettings provides configuration for using X-Forwarded-For headers for determining the client IP address. | | `customHeader` | _[CustomHeaderExtensionSettings](#customheaderextensionsettings)_ | false | CustomHeader provides configuration for determining the client IP address for a request based on
a trusted custom HTTP header. This uses the the custom_header original IP detection extension.
Refer to https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto
for more details. | - #### ClientTimeout @@ -296,8 +295,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `http` | _[HTTPClientTimeout](#httpclienttimeout)_ | false | Timeout settings for HTTP. | +| `http` | _[HTTPClientTimeout](#httpclienttimeout)_ | false | Timeout settings for HTTP. | #### ClientTrafficPolicy @@ -313,10 +312,10 @@ _Appears in:_ | --- | --- | --- | --- | | `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1` | `kind` | _string_ | |`ClientTrafficPolicy` + | `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` | _[ClientTrafficPolicySpec](#clienttrafficpolicyspec)_ | true | Spec defines the desired state of ClientTrafficPolicy. | - #### ClientTrafficPolicyList @@ -329,10 +328,10 @@ ClientTrafficPolicyList contains a list of ClientTrafficPolicy resources. | --- | --- | --- | --- | | `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1` | `kind` | _string_ | |`ClientTrafficPolicyList` + | `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` | _[ClientTrafficPolicy](#clienttrafficpolicy) array_ | true | | - #### ClientTrafficPolicySpec @@ -344,6 +343,7 @@ _Appears in:_ | 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 | | `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the downstream client connection.
If defined, sets SO_KEEPALIVE on the listener socket to enable TCP Keepalives.
Disabled by default. | | `enableProxyProtocol` | _boolean_ | false | EnableProxyProtocol interprets the ProxyProtocol header and adds the
Client Address into the X-Forwarded-For header.
Note Proxy Protocol must be present when this field is set, else the connection
is closed. | @@ -356,7 +356,6 @@ _Appears in:_ | `timeout` | _[ClientTimeout](#clienttimeout)_ | false | Timeout settings for the client connections. | | `connection` | _[Connection](#connection)_ | false | Connection includes client connection settings. | - #### ClientValidationContext @@ -370,8 +369,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `caCertificateRefs` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference) array_ | false | CACertificateRefs contains one or more references to
Kubernetes objects that contain TLS certificates of
the Certificate Authorities that can be used
as a trust anchor to validate the certificates presented by the client.

A single reference to a Kubernetes ConfigMap or a Kubernetes Secret,
with the CA certificate in a key named `ca.crt` is currently supported.

References to a resource in different namespace are invalid UNLESS there
is a ReferenceGrant in the target namespace that allows the certificate
to be attached. | +| `caCertificateRefs` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference) array_ | false | CACertificateRefs contains one or more references to
Kubernetes objects that contain TLS certificates of
the Certificate Authorities that can be used
as a trust anchor to validate the certificates presented by the client.

A single reference to a Kubernetes ConfigMap or a Kubernetes Secret,
with the CA certificate in a key named `ca.crt` is currently supported.

References to a resource in different namespace are invalid UNLESS there
is a ReferenceGrant in the target namespace that allows the certificate
to be attached. | #### Compression @@ -385,10 +384,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[CompressorType](#compressortype)_ | true | CompressorType defines the compressor type to use for compression. | | `gzip` | _[GzipCompressor](#gzipcompressor)_ | false | The configuration for GZIP compressor. | - #### CompressorType _Underlying type:_ _string_ @@ -411,10 +410,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `connectionLimit` | _[ConnectionLimit](#connectionlimit)_ | false | ConnectionLimit defines limits related to connections | | `bufferLimit` | _[Quantity](#quantity)_ | false | BufferLimit provides configuration for the maximum buffer size in bytes for each incoming connection.
For example, 20Mi, 1Gi, 256Ki etc.
Note that when the suffix is not provided, the value is interpreted as bytes.
Default: 32768 bytes. | - #### ConnectionLimit @@ -426,10 +425,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `value` | _integer_ | true | 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 @@ -442,8 +441,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `type` | _[ConsistentHashType](#consistenthashtype)_ | true | | +| `type` | _[ConsistentHashType](#consistenthashtype)_ | true | | #### ConsistentHashType @@ -470,10 +469,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `name` | _string_ | true | Name of the header containing the original downstream remote address, if present. | | `failClosed` | _boolean_ | false | FailClosed is a switch used to control the flow of traffic when client IP detection
fails. If set to true, the listener will respond with 403 Forbidden when the client
IP address cannot be determined. | - #### CustomTag @@ -485,12 +484,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[CustomTagType](#customtagtype)_ | true | Type defines the type of custom tag. | | `literal` | _[LiteralCustomTag](#literalcustomtag)_ | true | Literal adds hard-coded value to each span.
It's required when the type is "Literal". | | `environment` | _[EnvironmentCustomTag](#environmentcustomtag)_ | true | Environment adds value from environment variable to each span.
It's required when the type is "Environment". | | `requestHeader` | _[RequestHeaderCustomTag](#requestheadercustomtag)_ | true | RequestHeader adds value from request header to each span.
It's required when the type is "RequestHeader". | - #### CustomTagType _Underlying type:_ _string_ @@ -513,10 +512,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `name` | _string_ | true | Name defines the name of the environment variable which to extract the value from. | | `defaultValue` | _string_ | false | DefaultValue defines the default value to use if the environment variable is not set. | - #### EnvoyExtensionPolicy @@ -530,10 +529,10 @@ _Appears in:_ | --- | --- | --- | --- | | `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 @@ -546,10 +545,10 @@ EnvoyExtensionPolicyList contains a list of EnvoyExtensionPolicy resources. | --- | --- | --- | --- | | `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 @@ -561,11 +560,11 @@ _Appears in:_ | 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 | | `wasm` | _[Wasm](#wasm) array_ | false | WASM is a list of Wasm extensions to be loaded by the Gateway.
Order matters, as the extensions will be loaded in the order they are
defined in this list. | | `extProc` | _[ExtProc](#extproc) array_ | true | ExtProc is an ordered list of external processing filters
that should added to the envoy filter chain | - #### EnvoyGateway @@ -578,6 +577,7 @@ EnvoyGateway is the schema for the envoygateways API. | --- | --- | --- | --- | | `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1` | `kind` | _string_ | |`EnvoyGateway` + | `gateway` | _[Gateway](#gateway)_ | false | Gateway defines desired Gateway API specific configuration. If unset,
default configuration parameters will apply. | | `provider` | _[EnvoyGatewayProvider](#envoygatewayprovider)_ | false | Provider defines the desired provider and provider-specific configuration.
If unspecified, the Kubernetes provider is used with default configuration
parameters. | | `logging` | _[EnvoyGatewayLogging](#envoygatewaylogging)_ | false | Logging defines logging parameters for Envoy Gateway. | @@ -587,7 +587,6 @@ EnvoyGateway is the schema for the envoygateways API. | `extensionManager` | _[ExtensionManager](#extensionmanager)_ | false | ExtensionManager defines an extension manager to register for the Envoy Gateway Control Plane. | | `extensionApis` | _[ExtensionAPISettings](#extensionapisettings)_ | false | ExtensionAPIs defines the settings related to specific Gateway API Extensions
implemented by Envoy Gateway | - #### EnvoyGatewayAdmin @@ -600,11 +599,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `address` | _[EnvoyGatewayAdminAddress](#envoygatewayadminaddress)_ | false | Address defines the address of Envoy Gateway Admin Server. | | `enableDumpConfig` | _boolean_ | false | EnableDumpConfig defines if enable dump config in Envoy Gateway logs. | | `enablePprof` | _boolean_ | false | EnablePprof defines if enable pprof in Envoy Gateway Admin Server. | - #### EnvoyGatewayAdminAddress @@ -616,10 +615,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `port` | _integer_ | false | Port defines the port the admin server is exposed on. | | `host` | _string_ | false | Host defines the admin server hostname. | - #### EnvoyGatewayCustomProvider @@ -631,10 +630,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `resource` | _[EnvoyGatewayResourceProvider](#envoygatewayresourceprovider)_ | true | Resource defines the desired resource provider.
This provider is used to specify the provider to be used
to retrieve the resource configurations such as Gateway API
resources | | `infrastructure` | _[EnvoyGatewayInfrastructureProvider](#envoygatewayinfrastructureprovider)_ | true | Infrastructure defines the desired infrastructure provider.
This provider is used to specify the provider to be used
to provide an environment to deploy the out resources like
the Envoy Proxy data plane. | - #### EnvoyGatewayFileResourceProvider @@ -646,8 +645,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `paths` | _string array_ | true | Paths are the paths to a directory or file containing the resource configuration.
Recursive sub directories are not currently supported. | +| `paths` | _string array_ | true | Paths are the paths to a directory or file containing the resource configuration.
Recursive sub directories are not currently supported. | #### EnvoyGatewayHostInfrastructureProvider @@ -671,10 +670,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[InfrastructureProviderType](#infrastructureprovidertype)_ | true | Type is the type of infrastructure providers to use. Supported types are "Host". | | `host` | _[EnvoyGatewayHostInfrastructureProvider](#envoygatewayhostinfrastructureprovider)_ | false | Host defines the configuration of the Host provider. Host provides runtime
deployment of the data plane as a child process on the host environment. | - #### EnvoyGatewayKubernetesProvider @@ -686,13 +685,13 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `rateLimitDeployment` | _[KubernetesDeploymentSpec](#kubernetesdeploymentspec)_ | false | RateLimitDeployment defines the desired state of the Envoy ratelimit deployment resource.
If unspecified, default settings for the managed Envoy ratelimit deployment resource
are applied. | | `watch` | _[KubernetesWatchMode](#kuberneteswatchmode)_ | false | Watch holds configuration of which input resources should be watched and reconciled. | | `deploy` | _[KubernetesDeployMode](#kubernetesdeploymode)_ | false | Deploy holds configuration of how output managed resources such as the Envoy Proxy data plane
should be deployed | | `overwriteControlPlaneCerts` | _boolean_ | false | OverwriteControlPlaneCerts updates the secrets containing the control plane certs, when set. | | `leaderElection` | _[LeaderElection](#leaderelection)_ | false | LeaderElection specifies the configuration for leader election.
If it's not set up, leader election will be active by default, using Kubernetes' standard settings. | - #### EnvoyGatewayLogComponent _Underlying type:_ _string_ @@ -716,8 +715,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `level` | _object (keys:[EnvoyGatewayLogComponent](#envoygatewaylogcomponent), values:[LogLevel](#loglevel))_ | true | Level is the logging level. If unspecified, defaults to "info".
EnvoyGatewayLogComponent options: default/provider/gateway-api/xds-translator/xds-server/infrastructure/global-ratelimit.
LogLevel options: debug/info/error/warn. | +| `level` | _object (keys:[EnvoyGatewayLogComponent](#envoygatewaylogcomponent), values:[LogLevel](#loglevel))_ | true | Level is the logging level. If unspecified, defaults to "info".
EnvoyGatewayLogComponent options: default/provider/gateway-api/xds-translator/xds-server/infrastructure/global-ratelimit.
LogLevel options: debug/info/error/warn. | #### EnvoyGatewayMetricSink @@ -731,10 +730,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[MetricSinkType](#metricsinktype)_ | true | Type defines the metric sink type.
EG control plane currently supports OpenTelemetry. | | `openTelemetry` | _[EnvoyGatewayOpenTelemetrySink](#envoygatewayopentelemetrysink)_ | true | OpenTelemetry defines the configuration for OpenTelemetry sink.
It's required if the sink type is OpenTelemetry. | - #### EnvoyGatewayMetrics @@ -746,10 +745,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `sinks` | _[EnvoyGatewayMetricSink](#envoygatewaymetricsink) array_ | true | Sinks defines the metric sinks where metrics are sent to. | | `prometheus` | _[EnvoyGatewayPrometheusProvider](#envoygatewayprometheusprovider)_ | true | Prometheus defines the configuration for prometheus endpoint. | - #### EnvoyGatewayOpenTelemetrySink @@ -761,11 +760,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `host` | _string_ | true | Host define the sink service hostname. | | `protocol` | _string_ | true | Protocol define the sink service protocol. | | `port` | _integer_ | false | Port defines the port the sink service is exposed on. | - #### EnvoyGatewayPrometheusProvider @@ -777,8 +776,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `disable` | _boolean_ | true | Disable defines if disables the prometheus metrics in pull mode. | +| `disable` | _boolean_ | true | Disable defines if disables the prometheus metrics in pull mode. | #### EnvoyGatewayProvider @@ -792,11 +791,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[ProviderType](#providertype)_ | true | Type is the type of provider to use. Supported types are "Kubernetes". | | `kubernetes` | _[EnvoyGatewayKubernetesProvider](#envoygatewaykubernetesprovider)_ | false | Kubernetes defines the configuration of the Kubernetes provider. Kubernetes
provides runtime configuration via the Kubernetes API. | | `custom` | _[EnvoyGatewayCustomProvider](#envoygatewaycustomprovider)_ | false | Custom defines the configuration for the Custom provider. This provider
allows you to define a specific resource provider and a infrastructure
provider. | - #### EnvoyGatewayResourceProvider @@ -808,10 +807,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[ResourceProviderType](#resourceprovidertype)_ | true | Type is the type of resource provider to use. Supported types are "File". | | `file` | _[EnvoyGatewayFileResourceProvider](#envoygatewayfileresourceprovider)_ | false | File defines the configuration of the File provider. File provides runtime
configuration defined by one or more files. | - #### EnvoyGatewaySpec @@ -823,6 +822,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `gateway` | _[Gateway](#gateway)_ | false | Gateway defines desired Gateway API specific configuration. If unset,
default configuration parameters will apply. | | `provider` | _[EnvoyGatewayProvider](#envoygatewayprovider)_ | false | Provider defines the desired provider and provider-specific configuration.
If unspecified, the Kubernetes provider is used with default configuration
parameters. | | `logging` | _[EnvoyGatewayLogging](#envoygatewaylogging)_ | false | Logging defines logging parameters for Envoy Gateway. | @@ -832,7 +832,6 @@ _Appears in:_ | `extensionManager` | _[ExtensionManager](#extensionmanager)_ | false | ExtensionManager defines an extension manager to register for the Envoy Gateway Control Plane. | | `extensionApis` | _[ExtensionAPISettings](#extensionapisettings)_ | false | ExtensionAPIs defines the settings related to specific Gateway API Extensions
implemented by Envoy Gateway | - #### EnvoyGatewayTelemetry @@ -846,8 +845,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `metrics` | _[EnvoyGatewayMetrics](#envoygatewaymetrics)_ | true | Metrics defines metrics configuration for envoy gateway. | +| `metrics` | _[EnvoyGatewayMetrics](#envoygatewaymetrics)_ | true | Metrics defines metrics configuration for envoy gateway. | #### EnvoyJSONPatchConfig @@ -861,11 +860,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[EnvoyResourceType](#envoyresourcetype)_ | true | Type is the typed URL of the Envoy xDS Resource | | `name` | _string_ | true | Name is the name of the resource | | `operation` | _[JSONPatchOperation](#jsonpatchoperation)_ | true | Patch defines the JSON Patch Operation | - #### EnvoyPatchPolicy @@ -880,10 +879,10 @@ _Appears in:_ | --- | --- | --- | --- | | `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1` | `kind` | _string_ | |`EnvoyPatchPolicy` + | `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` | _[EnvoyPatchPolicySpec](#envoypatchpolicyspec)_ | true | Spec defines the desired state of EnvoyPatchPolicy. | - #### EnvoyPatchPolicyList @@ -896,10 +895,10 @@ EnvoyPatchPolicyList contains a list of EnvoyPatchPolicy resources. | --- | --- | --- | --- | | `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1` | `kind` | _string_ | |`EnvoyPatchPolicyList` + | `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` | _[EnvoyPatchPolicy](#envoypatchpolicy) array_ | true | | - #### EnvoyPatchPolicySpec @@ -911,12 +910,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[EnvoyPatchType](#envoypatchtype)_ | true | Type decides the type of patch.
Valid EnvoyPatchType values are "JSONPatch". | | `jsonPatches` | _[EnvoyJSONPatchConfig](#envoyjsonpatchconfig) array_ | false | JSONPatch defines the JSONPatch configuration. | | `targetRef` | _[PolicyTargetReference](#policytargetreference)_ | true | TargetRef is the name of the Gateway API resource this policy
is being attached to.
By default attaching to Gateway is supported and
when mergeGateways is enabled it should attach to GatewayClass.
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_ | true | Priority of the EnvoyPatchPolicy.
If multiple EnvoyPatchPolicies are applied to the same
TargetRef, they will be applied 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. | - #### EnvoyPatchType _Underlying type:_ _string_ @@ -940,10 +939,10 @@ EnvoyProxy is the schema for the envoyproxies API. | --- | --- | --- | --- | | `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1` | `kind` | _string_ | |`EnvoyProxy` + | `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` | _[EnvoyProxySpec](#envoyproxyspec)_ | true | EnvoyProxySpec defines the desired state of EnvoyProxy. | - #### EnvoyProxyKubernetesProvider @@ -956,11 +955,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `envoyDeployment` | _[KubernetesDeploymentSpec](#kubernetesdeploymentspec)_ | false | EnvoyDeployment defines the desired state of the Envoy deployment resource.
If unspecified, default settings for the managed Envoy deployment resource
are applied. | | `envoyService` | _[KubernetesServiceSpec](#kubernetesservicespec)_ | false | EnvoyService defines the desired state of the Envoy service resource.
If unspecified, default settings for the managed Envoy service resource
are applied. | | `envoyHpa` | _[KubernetesHorizontalPodAutoscalerSpec](#kuberneteshorizontalpodautoscalerspec)_ | false | EnvoyHpa defines the Horizontal Pod Autoscaler settings for Envoy Proxy Deployment.
Once the HPA is being set, Replicas field from EnvoyDeployment will be ignored. | - #### EnvoyProxyProvider @@ -972,10 +971,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[ProviderType](#providertype)_ | true | Type is the type of resource provider to use. A resource provider provides
infrastructure resources for running the data plane, e.g. Envoy proxy, and
optional auxiliary control planes. Supported types are "Kubernetes". | | `kubernetes` | _[EnvoyProxyKubernetesProvider](#envoyproxykubernetesprovider)_ | false | Kubernetes defines the desired state of the Kubernetes resource provider.
Kubernetes provides infrastructure resources for running the data plane,
e.g. Envoy proxy. If unspecified and type is "Kubernetes", default settings
for managed Kubernetes resources are applied. | - #### EnvoyProxySpec @@ -987,6 +986,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `provider` | _[EnvoyProxyProvider](#envoyproxyprovider)_ | false | Provider defines the desired resource provider and provider-specific configuration.
If unspecified, the "Kubernetes" resource provider is used with default configuration
parameters. | | `logging` | _[ProxyLogging](#proxylogging)_ | true | Logging defines logging parameters for managed proxies. | | `telemetry` | _[ProxyTelemetry](#proxytelemetry)_ | false | Telemetry defines telemetry parameters for managed proxies. | @@ -998,7 +998,6 @@ _Appears in:_ - #### EnvoyResourceType _Underlying type:_ _string_ @@ -1021,12 +1020,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `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. | - #### ExtProc @@ -1038,8 +1037,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `backendRef` | _[ExtProcBackendRef](#extprocbackendref)_ | true | Service defines the configuration of the external processing service | +| `backendRef` | _[ExtProcBackendRef](#extprocbackendref)_ | true | Service defines the configuration of the external processing service | #### ExtProcBackendRef @@ -1054,13 +1053,13 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `group` | _[Group](#group)_ | false | Group is the group of the referent. For example, "gateway.networking.k8s.io".
When unspecified or empty string, core API group is inferred. | | `kind` | _[Kind](#kind)_ | false | Kind is the Kubernetes resource kind of the referent. For example
"Service".

Defaults to "Service" when not specified.

ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.

Support: Core (Services with a type other than ExternalName)

Support: Implementation-specific (Services with type ExternalName) | | `name` | _[ObjectName](#objectname)_ | true | Name is the name of the referent. | | `namespace` | _[Namespace](#namespace)_ | false | Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.

Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.

Support: Core | | `port` | _[PortNumber](#portnumber)_ | false | Port specifies the destination port number to use for this resource.
Port is required when the referent is a Kubernetes Service. In this
case, the port number is the service port number, not the target port.
For other resources, destination port might be derived from the referent
resource or this field. | - #### ExtensionAPISettings @@ -1073,8 +1072,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `enableEnvoyPatchPolicy` | _boolean_ | true | EnableEnvoyPatchPolicy enables Envoy Gateway to
reconcile and implement the EnvoyPatchPolicy resources. | +| `enableEnvoyPatchPolicy` | _boolean_ | true | EnableEnvoyPatchPolicy enables Envoy Gateway to
reconcile and implement the EnvoyPatchPolicy resources. | #### ExtensionHooks @@ -1087,8 +1086,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `xdsTranslator` | _[XDSTranslatorHooks](#xdstranslatorhooks)_ | true | XDSTranslator defines all the supported extension hooks for the xds-translator runner | +| `xdsTranslator` | _[XDSTranslatorHooks](#xdstranslatorhooks)_ | true | XDSTranslator defines all the supported extension hooks for the xds-translator runner | #### ExtensionManager @@ -1103,11 +1102,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `resources` | _[GroupVersionKind](#groupversionkind) array_ | false | Resources defines the set of K8s resources the extension will handle. | | `hooks` | _[ExtensionHooks](#extensionhooks)_ | true | Hooks defines the set of hooks the extension supports | | `service` | _[ExtensionService](#extensionservice)_ | true | Service defines the configuration of the extension service that the Envoy
Gateway Control Plane will call through extension hooks. | - #### ExtensionService @@ -1119,11 +1118,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `host` | _string_ | true | Host define the extension service hostname. | | `port` | _integer_ | false | Port defines the port the extension service is exposed on. | | `tls` | _[ExtensionTLS](#extensiontls)_ | false | TLS defines TLS configuration for communication between Envoy Gateway and
the extension service. | - #### ExtensionTLS @@ -1135,8 +1134,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `certificateRef` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | CertificateRef contains a references to objects (Kubernetes objects or otherwise) that
contains a TLS certificate and private keys. These certificates are used to
establish a TLS handshake to the extension server.

CertificateRef can only reference a Kubernetes Secret at this time. | +| `certificateRef` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | CertificateRef contains a references to objects (Kubernetes objects or otherwise) that
contains a TLS certificate and private keys. These certificates are used to
establish a TLS handshake to the extension server.

CertificateRef can only reference a Kubernetes Secret at this time. | #### FaultInjection @@ -1150,10 +1149,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `delay` | _[FaultInjectionDelay](#faultinjectiondelay)_ | false | If specified, a delay will be injected into the request. | | `abort` | _[FaultInjectionAbort](#faultinjectionabort)_ | false | If specified, the request will be aborted if it meets the configuration criteria. | - #### FaultInjectionAbort @@ -1165,11 +1164,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `httpStatus` | _integer_ | false | StatusCode specifies the HTTP status code to be returned | | `grpcStatus` | _integer_ | false | GrpcStatus specifies the GRPC status code to be returned | | `percentage` | _float_ | false | Percentage specifies the percentage of requests to be aborted. Default 100%, if set 0, no requests will be aborted. Accuracy to 0.0001%. | - #### FaultInjectionDelay @@ -1181,10 +1180,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `fixedDelay` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | true | FixedDelay specifies the fixed delay duration | | `percentage` | _float_ | false | Percentage specifies the percentage of requests to be delayed. Default 100%, if set 0, no requests will be delayed. Accuracy to 0.0001%. | - #### FileEnvoyProxyAccessLog @@ -1196,8 +1195,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `path` | _string_ | true | Path defines the file path used to expose envoy access log(e.g. /dev/stdout). | +| `path` | _string_ | true | Path defines the file path used to expose envoy access log(e.g. /dev/stdout). | #### GRPCExtAuthService @@ -1212,8 +1211,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `backendRef` | _[BackendObjectReference](#backendobjectreference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
Only service Kind is supported for now. | +| `backendRef` | _[BackendObjectReference](#backendobjectreference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
Only service Kind is supported for now. | #### Gateway @@ -1227,8 +1226,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `controllerName` | _string_ | false | ControllerName defines the name of the Gateway API controller. If unspecified,
defaults to "gateway.envoyproxy.io/gatewayclass-controller". See the following
for additional details:
https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass | +| `controllerName` | _string_ | false | ControllerName defines the name of the Gateway API controller. If unspecified,
defaults to "gateway.envoyproxy.io/gatewayclass-controller". See the following
for additional details:
https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass | #### GlobalRateLimit @@ -1241,8 +1240,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `rules` | _[RateLimitRule](#ratelimitrule) array_ | true | Rules are a list of RateLimit selectors and limits. Each rule and its
associated limit is applied in a mutually exclusive way. If a request
matches multiple rules, each of their associated limits get applied, so a
single request might increase the rate limit counters for multiple rules
if selected. The rate limit service will return a logical OR of the individual
rate limit decisions of all matching rules. For example, if a request
matches two rules, one rate limited and one not, the final decision will be
to rate limit the request. | +| `rules` | _[RateLimitRule](#ratelimitrule) array_ | true | Rules are a list of RateLimit selectors and limits. Each rule and its
associated limit is applied in a mutually exclusive way. If a request
matches multiple rules, each of their associated limits get applied, so a
single request might increase the rate limit counters for multiple rules
if selected. The rate limit service will return a logical OR of the individual
rate limit decisions of all matching rules. For example, if a request
matches two rules, one rate limited and one not, the final decision will be
to rate limit the request. | #### GroupVersionKind @@ -1256,11 +1255,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `group` | _string_ | true | | | `version` | _string_ | true | | | `kind` | _string_ | true | | - #### GzipCompressor @@ -1285,8 +1284,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `useDefaultHost` | _boolean_ | false | UseDefaultHost defines if the HTTP/1.0 request is missing the Host header,
then the hostname associated with the listener should be injected into the
request.
If this is not set and an HTTP/1.0 request arrives without a host, then
it will be rejected. | +| `useDefaultHost` | _boolean_ | false | UseDefaultHost defines if the HTTP/1.0 request is missing the Host header,
then the hostname associated with the listener should be injected into the
request.
If this is not set and an HTTP/1.0 request arrives without a host, then
it will be rejected. | #### HTTP1Settings @@ -1299,11 +1298,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `enableTrailers` | _boolean_ | false | EnableTrailers defines if HTTP/1 trailers should be proxied by Envoy. | | `preserveHeaderCase` | _boolean_ | false | PreserveHeaderCase defines if Envoy should preserve the letter case of headers.
By default, Envoy will lowercase all the headers. | | `http10` | _[HTTP10Settings](#http10settings)_ | false | HTTP10 turns on support for HTTP/1.0 and HTTP/0.9 requests. | - #### HTTP3Settings @@ -1326,12 +1325,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `path` | _string_ | true | Path defines the HTTP path that will be requested during health checking. | | `method` | _string_ | false | Method defines the HTTP method used for health checking.
Defaults to GET | | `expectedStatuses` | _[HTTPStatus](#httpstatus) array_ | false | ExpectedStatuses defines a list of HTTP response statuses considered healthy.
Defaults to 200 only | | `expectedResponse` | _[ActiveHealthCheckPayload](#activehealthcheckpayload)_ | false | ExpectedResponse defines a list of HTTP expected responses to match. | - #### HTTPClientTimeout @@ -1343,10 +1342,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `requestReceivedTimeout` | _[Duration](#duration)_ | false | RequestReceivedTimeout is the duration envoy waits for the complete request reception. This timer starts upon request
initiation and stops when either the last byte of the request is sent upstream or when the response begins. | | `idleTimeout` | _[Duration](#duration)_ | false | IdleTimeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
Default: 1 hour. | - #### HTTPExtAuthService @@ -1358,11 +1357,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `backendRef` | _[BackendObjectReference](#backendobjectreference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
Only service Kind is supported for now. | | `path` | _string_ | true | Path is the path of the HTTP External Authorization service.
If path is specified, the authorization request will be sent to that path,
or else the authorization request will be sent to the root path. | | `headersToBackend` | _string array_ | false | HeadersToBackend are the authorization response headers that will be added
to the original client request before sending it to the backend server.
Note that coexisting headers will be overridden.
If not specified, no authorization response headers will be added to the
original client request. | - #### HTTPStatus _Underlying type:_ _integer_ @@ -1386,10 +1385,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `connectionIdleTimeout` | _[Duration](#duration)_ | false | The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
Default: 1 hour. | | `maxConnectionDuration` | _[Duration](#duration)_ | false | The maximum duration of an HTTP connection.
Default: unlimited. | - #### HTTPWasmCodeSource @@ -1401,8 +1400,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `url` | _string_ | true | URL is the URL containing the wasm code. | +| `url` | _string_ | true | URL is the URL containing the wasm code. | @@ -1429,10 +1428,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `enableEnvoyHeaders` | _boolean_ | false | EnableEnvoyHeaders configures Envoy Proxy to add the "X-Envoy-" headers to requests
and responses. | | `withUnderscoresAction` | _[WithUnderscoresAction](#withunderscoresaction)_ | false | WithUnderscoresAction configures the action to take when an HTTP header with underscores
is encountered. The default action is to reject the request. | - #### HealthCheck @@ -1445,10 +1444,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `active` | _[ActiveHealthCheck](#activehealthcheck)_ | false | Active health check configuration | | `passive` | _[PassiveHealthCheck](#passivehealthcheck)_ | false | Passive passive check configuration | - #### ImageWasmCodeSource @@ -1460,10 +1459,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `url` | _string_ | true | URL is the URL of the OCI image. | | `pullSecret` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | PullSecretRef is a reference to the secret containing the credentials to pull the image. | - #### InfrastructureProviderType _Underlying type:_ _string_ @@ -1487,12 +1486,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `op` | _[JSONPatchOperationType](#jsonpatchoperationtype)_ | true | Op is the type of operation to perform | | `path` | _string_ | true | Path is the location of the target document/field where the operation will be performed
Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. | | `from` | _string_ | false | From is the source location of the value to be copied or moved. Only valid
for move or copy operations
Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. | | `value` | _[JSON](#json)_ | false | Value is the new value of the path location. The value is only used by
the `add` and `replace` operations. | - #### JSONPatchOperationType _Underlying type:_ _string_ @@ -1515,8 +1514,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `providers` | _[JWTProvider](#jwtprovider) array_ | true | Providers defines the JSON Web Token (JWT) authentication provider type.
When multiple JWT providers are specified, the JWT is considered valid if
any of the providers successfully validate the JWT. For additional details,
see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter.html. | +| `providers` | _[JWTProvider](#jwtprovider) array_ | true | Providers defines the JSON Web Token (JWT) authentication provider type.
When multiple JWT providers are specified, the JWT is considered valid if
any of the providers successfully validate the JWT. For additional details,
see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter.html. | #### JWTExtractor @@ -1531,11 +1530,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `headers` | _[JWTHeaderExtractor](#jwtheaderextractor) array_ | false | Headers represents a list of HTTP request headers to extract the JWT token from. | | `cookies` | _string array_ | false | Cookies represents a list of cookie names to extract the JWT token from. | | `params` | _string array_ | false | Params represents a list of query parameters to extract the JWT token from. | - #### JWTHeaderExtractor @@ -1547,10 +1546,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `name` | _string_ | true | Name is the HTTP header name to retrieve the token | | `valuePrefix` | _string_ | false | ValuePrefix is the prefix that should be stripped before extracting the token.
The format would be used by Envoy like "{ValuePrefix}".
For example, "Authorization: Bearer ", then the ValuePrefix="Bearer " with a space at the end. | - #### JWTProvider @@ -1562,6 +1561,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `name` | _string_ | true | Name defines a unique name for the JWT provider. A name can have a variety of forms,
including RFC1123 subdomains, RFC 1123 labels, or RFC 1035 labels. | | `issuer` | _string_ | false | Issuer is the principal that issued the JWT and takes the form of a URL or email address.
For additional details, see https://tools.ietf.org/html/rfc7519#section-4.1.1 for
URL format and https://rfc-editor.org/rfc/rfc5322.html for email format. If not provided,
the JWT issuer is not checked. | | `audiences` | _string array_ | false | Audiences is a list of JWT audiences allowed access. For additional details, see
https://tools.ietf.org/html/rfc7519#section-4.1.3. If not provided, JWT audiences
are not checked. | @@ -1570,7 +1570,6 @@ _Appears in:_ | `recomputeRoute` | _boolean_ | false | RecomputeRoute clears the route cache and recalculates the routing decision.
This field must be enabled if the headers generated from the claim are used for
route matching decisions. If the recomputation selects a new route, features targeting
the new matched route will be applied. | | `extractFrom` | _[JWTExtractor](#jwtextractor)_ | false | ExtractFrom defines different ways to extract the JWT token from HTTP request.
If empty, it defaults to extract JWT token from the Authorization HTTP request header using Bearer schema
or access_token from query parameters. | - #### KubernetesContainerSpec @@ -1582,13 +1581,13 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `env` | _[EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#envvar-v1-core) array_ | false | List of environment variables to set in the container. | | `resources` | _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#resourcerequirements-v1-core)_ | false | Resources required by this container.
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | | `securityContext` | _[SecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#securitycontext-v1-core)_ | false | SecurityContext defines the security options the container should be run with.
If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.
More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ | | `image` | _string_ | false | Image specifies the EnvoyProxy container image to be used, instead of the default image. | | `volumeMounts` | _[VolumeMount](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#volumemount-v1-core) array_ | false | VolumeMounts are volumes to mount into the container's filesystem.
Cannot be updated. | - #### KubernetesDeployMode @@ -1613,6 +1612,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `patch` | _[KubernetesPatchSpec](#kubernetespatchspec)_ | false | Patch defines how to perform the patch operation to deployment | | `replicas` | _integer_ | false | Replicas is the number of desired pods. Defaults to 1. | | `strategy` | _[DeploymentStrategy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#deploymentstrategy-v1-apps)_ | false | The deployment strategy to use to replace existing pods with new ones. | @@ -1620,7 +1620,6 @@ _Appears in:_ | `container` | _[KubernetesContainerSpec](#kubernetescontainerspec)_ | false | Container defines the desired specification of main container. | | `initContainers` | _[Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#container-v1-core) array_ | false | List of initialization containers belonging to the pod.
More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ | - #### KubernetesHorizontalPodAutoscalerSpec @@ -1635,12 +1634,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `minReplicas` | _integer_ | false | minReplicas is the lower limit for the number of replicas to which the autoscaler
can scale down. It defaults to 1 replica. | | `maxReplicas` | _integer_ | true | maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up.
It cannot be less that minReplicas. | | `metrics` | _[MetricSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#metricspec-v2-autoscaling) array_ | false | metrics contains the specifications for which to use to calculate the
desired replica count (the maximum replica count across all metrics will
be used).
If left empty, it defaults to being based on CPU utilization with average on 80% usage. | | `behavior` | _[HorizontalPodAutoscalerBehavior](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#horizontalpodautoscalerbehavior-v2-autoscaling)_ | false | behavior configures the scaling behavior of the target
in both Up and Down directions (scaleUp and scaleDown fields respectively).
If not set, the default HPAScalingRules for scale up and scale down are used.
See k8s.io.autoscaling.v2.HorizontalPodAutoScalerBehavior. | - #### KubernetesPatchSpec @@ -1653,10 +1652,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[MergeType](#mergetype)_ | false | Type is the type of merge operation to perform

By default, StrategicMerge is used as the patch type. | | `value` | _[JSON](#json)_ | true | Object contains the raw configuration for merged object | - #### KubernetesPodSpec @@ -1668,6 +1667,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `annotations` | _object (keys:string, values:string)_ | false | Annotations are the annotations that should be appended to the pods.
By default, no pod annotations are appended. | | `labels` | _object (keys:string, values:string)_ | false | Labels are the additional labels that should be tagged to the pods.
By default, no additional pod labels are tagged. | | `securityContext` | _[PodSecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#podsecuritycontext-v1-core)_ | false | SecurityContext holds pod-level security attributes and common container settings.
Optional: Defaults to empty. See type description for default values of each field. | @@ -1678,7 +1678,6 @@ _Appears in:_ | `nodeSelector` | _object (keys:string, values:string)_ | false | NodeSelector is a selector which must be true for the pod to fit on a node.
Selector which must match a node's labels for the pod to be scheduled on that node.
More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ | | `topologySpreadConstraints` | _[TopologySpreadConstraint](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#topologyspreadconstraint-v1-core) array_ | false | TopologySpreadConstraints describes how a group of pods ought to spread across topology
domains. Scheduler will schedule pods in a way which abides by the constraints.
All topologySpreadConstraints are ANDed. | - #### KubernetesServiceSpec @@ -1690,6 +1689,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `annotations` | _object (keys:string, values:string)_ | false | Annotations that should be appended to the service.
By default, no annotations are appended. | | `type` | _[ServiceType](#servicetype)_ | false | Type determines how the Service is exposed. Defaults to LoadBalancer.
Valid options are ClusterIP, LoadBalancer and NodePort.
"LoadBalancer" means a service will be exposed via an external load balancer (if the cloud provider supports it).
"ClusterIP" means a service will only be accessible inside the cluster, via the cluster IP.
"NodePort" means a service will be exposed on a static Port on all Nodes of the cluster. | | `loadBalancerClass` | _string_ | false | LoadBalancerClass, when specified, allows for choosing the LoadBalancer provider
implementation if more than one are available or is otherwise expected to be specified | @@ -1698,7 +1698,6 @@ _Appears in:_ | `externalTrafficPolicy` | _[ServiceExternalTrafficPolicy](#serviceexternaltrafficpolicy)_ | false | ExternalTrafficPolicy determines the externalTrafficPolicy for the Envoy Service. Valid options
are Local and Cluster. Default is "Local". "Local" means traffic will only go to pods on the node
receiving the traffic. "Cluster" means connections are loadbalanced to all pods in the cluster. | | `patch` | _[KubernetesPatchSpec](#kubernetespatchspec)_ | false | Patch defines how to perform the patch operation to the service | - #### KubernetesWatchMode @@ -1710,11 +1709,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[KubernetesWatchModeType](#kuberneteswatchmodetype)_ | true | Type indicates what watch mode to use. KubernetesWatchModeTypeNamespaces and
KubernetesWatchModeTypeNamespaceSelector are currently supported
By default, when this field is unset or empty, Envoy Gateway will watch for input namespaced resources
from all namespaces. | | `namespaces` | _string array_ | true | Namespaces holds the list of namespaces that Envoy Gateway will watch for namespaced scoped
resources such as Gateway, HTTPRoute and Service.
Note that Envoy Gateway will continue to reconcile relevant cluster scoped resources such as
GatewayClass that it is linked to. Precisely one of Namespaces and NamespaceSelector must be set. | | `namespaceSelector` | _[LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#labelselector-v1-meta)_ | true | NamespaceSelector holds the label selector used to dynamically select namespaces.
Envoy Gateway will watch for namespaces matching the specified label selector.
Precisely one of Namespaces and NamespaceSelector must be set. | - #### KubernetesWatchModeType _Underlying type:_ _string_ @@ -1737,12 +1736,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `leaseDuration` | _[Duration](#duration)_ | true | LeaseDuration defines the time non-leader contenders will wait before attempting to claim leadership.
It's based on the timestamp of the last acknowledged signal. The default setting is 15 seconds. | | `renewDeadline` | _[Duration](#duration)_ | true | RenewDeadline represents the time frame within which the current leader will attempt to renew its leadership
status before relinquishing its position. The default setting is 10 seconds. | | `retryPeriod` | _[Duration](#duration)_ | true | RetryPeriod denotes the interval at which LeaderElector clients should perform action retries.
The default setting is 2 seconds. | | `disable` | _boolean_ | true | Disable provides the option to turn off leader election, which is enabled by default. | - #### LiteralCustomTag @@ -1754,8 +1753,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `value` | _string_ | true | Value defines the hard-coded value to add to each span. | +| `value` | _string_ | true | Value defines the hard-coded value to add to each span. | #### LoadBalancer @@ -1768,11 +1767,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[LoadBalancerType](#loadbalancertype)_ | true | Type decides the type of Load Balancer policy.
Valid LoadBalancerType values are
"ConsistentHash",
"LeastRequest",
"Random",
"RoundRobin", | | `consistentHash` | _[ConsistentHash](#consistenthash)_ | false | ConsistentHash defines the configuration when the load balancer type is
set to ConsistentHash | | `slowStart` | _[SlowStart](#slowstart)_ | false | SlowStart defines the configuration related to the slow start load balancer policy.
If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
Currently this is only supported for RoundRobin and LeastRequest load balancers | - #### LoadBalancerType _Underlying type:_ _string_ @@ -1795,8 +1794,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `rules` | _[RateLimitRule](#ratelimitrule) array_ | false | Rules are a list of RateLimit selectors and limits. If a request matches
multiple rules, the strictest limit is applied. For example, if a request
matches two rules, one with 10rps and one with 20rps, the final limit will
be based on the rule with 10rps. | +| `rules` | _[RateLimitRule](#ratelimitrule) array_ | false | Rules are a list of RateLimit selectors and limits. If a request matches
multiple rules, the strictest limit is applied. For example, if a request
matches two rules, one with 10rps and one with 20rps, the final limit will
be based on the rule with 10rps. | #### LogLevel @@ -1835,6 +1834,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `provider` | _[OIDCProvider](#oidcprovider)_ | true | The OIDC Provider configuration. | | `clientID` | _string_ | true | The client ID to be used in the OIDC
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). | | `clientSecret` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | true | The Kubernetes secret which contains the OIDC client secret to be used in the
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).

This is an Opaque secret. The client secret should be stored in the key
"client-secret". | @@ -1843,7 +1843,6 @@ _Appears in:_ | `redirectURL` | _string_ | true | The redirect URL to be used in the OIDC
[Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest).
If not specified, uses the default redirect URI "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" | | `logoutPath` | _string_ | true | The path to log a user out, clearing their credential cookies.
If not specified, uses a default logout path "/logout" | - #### OIDCProvider @@ -1855,11 +1854,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `issuer` | _string_ | true | The OIDC Provider's [issuer identifier](https://openid.net/specs/openid-connect-discovery-1_0.html#IssuerDiscovery).
Issuer MUST be a URI RFC 3986 [RFC3986] with a scheme component that MUST
be https, a host component, and optionally, port and path components and
no query or fragment components. | | `authorizationEndpoint` | _string_ | false | The OIDC Provider's [authorization endpoint](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint).
If not provided, EG will try to discover it from the provider's [Well-Known Configuration Endpoint](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse). | | `tokenEndpoint` | _string_ | false | The OIDC Provider's [token endpoint](https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint).
If not provided, EG will try to discover it from the provider's [Well-Known Configuration Endpoint](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse). | - #### OpenTelemetryEnvoyProxyAccessLog @@ -1871,12 +1870,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `host` | _string_ | false | Host define the extension service hostname.
Deprecated: Use BackendRef instead. | | `port` | _integer_ | false | Port defines the port the extension service is exposed on.
Deprecated: Use BackendRef instead. | | `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the accesslog will be sent.
Only service Kind is supported for now. | | `resources` | _object (keys:string, values:string)_ | false | Resources is a set of labels that describe the source of a log entry, including envoy node info.
It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). | - #### Origin _Underlying type:_ _string_ @@ -1913,6 +1912,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `splitExternalLocalOriginErrors` | _boolean_ | false | SplitExternalLocalOriginErrors enables splitting of errors between external and local origin. | | `interval` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | false | Interval defines the time between passive health checks. | | `consecutiveLocalOriginFailures` | _integer_ | false | ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
Parameter takes effect only when split_external_local_origin_errors is set to true. | @@ -1921,7 +1921,6 @@ _Appears in:_ | `baseEjectionTime` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | false | BaseEjectionTime defines the base duration for which a host will be ejected on consecutive failures. | | `maxEjectionPercent` | _integer_ | false | MaxEjectionPercent sets the maximum percentage of hosts in a cluster that can be ejected. | - #### PathEscapedSlashAction _Underlying type:_ _string_ @@ -1945,10 +1944,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `escapedSlashesAction` | _[PathEscapedSlashAction](#pathescapedslashaction)_ | false | EscapedSlashesAction determines how %2f, %2F, %5c, or %5C sequences in the path URI
should be handled.
The default is UnescapeAndRedirect. | | `disableMergeSlashes` | _boolean_ | false | DisableMergeSlashes allows disabling the default configuration of merging adjacent
slashes in the path.
Note that slash merging is not part of the HTTP spec and is provided for convenience. | - #### PerRetryPolicy @@ -1960,10 +1959,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `timeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | false | Timeout is the timeout per retry attempt. | | `backOff` | _[BackOffPolicy](#backoffpolicy)_ | false | Backoff is the backoff policy to be applied per retry attempt. gateway uses a fully jittered exponential
back-off algorithm for retries. For additional details,
see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries | - #### ProviderType _Underlying type:_ _string_ @@ -1987,10 +1986,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `disable` | _boolean_ | true | Disable disables access logging for managed proxies if set to true. | | `settings` | _[ProxyAccessLogSetting](#proxyaccesslogsetting) array_ | false | Settings defines accesslog settings for managed proxies.
If unspecified, will send default format to stdout. | - #### ProxyAccessLogFormat @@ -2003,11 +2002,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[ProxyAccessLogFormatType](#proxyaccesslogformattype)_ | true | Type defines the type of accesslog format. | | `text` | _string_ | false | Text defines the text accesslog format, following Envoy accesslog formatting,
It's required when the format type is "Text".
Envoy [command operators](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators) may be used in the format.
The [format string documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#config-access-log-format-strings) provides more information. | | `json` | _object (keys:string, values:string)_ | false | JSON is additional attributes that describe the specific event occurrence.
Structured format for the envoy access logs. Envoy [command operators](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators)
can be used as values for fields within the Struct.
It's required when the format type is "JSON". | - #### ProxyAccessLogFormatType _Underlying type:_ _string_ @@ -2030,10 +2029,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `format` | _[ProxyAccessLogFormat](#proxyaccesslogformat)_ | true | Format defines the format of accesslog. | | `sinks` | _[ProxyAccessLogSink](#proxyaccesslogsink) array_ | true | Sinks defines the sinks of accesslog. | - #### ProxyAccessLogSink @@ -2045,11 +2044,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[ProxyAccessLogSinkType](#proxyaccesslogsinktype)_ | true | Type defines the type of accesslog sink. | | `file` | _[FileEnvoyProxyAccessLog](#fileenvoyproxyaccesslog)_ | false | File defines the file accesslog sink. | | `openTelemetry` | _[OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)_ | false | OpenTelemetry defines the OpenTelemetry accesslog sink. | - #### ProxyAccessLogSinkType _Underlying type:_ _string_ @@ -2072,10 +2071,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[BootstrapType](#bootstraptype)_ | false | Type is the type of the bootstrap configuration, it should be either Replace or Merge.
If unspecified, it defaults to Replace. | | `value` | _string_ | true | Value is a YAML string of the bootstrap. | - #### ProxyLogComponent _Underlying type:_ _string_ @@ -2098,8 +2097,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `level` | _object (keys:[ProxyLogComponent](#proxylogcomponent), values:[LogLevel](#loglevel))_ | true | Level is a map of logging level per component, where the component is the key
and the log level is the value. If unspecified, defaults to "default: warn". | +| `level` | _object (keys:[ProxyLogComponent](#proxylogcomponent), values:[LogLevel](#loglevel))_ | true | Level is a map of logging level per component, where the component is the key
and the log level is the value. If unspecified, defaults to "default: warn". | #### ProxyMetricSink @@ -2113,10 +2112,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[MetricSinkType](#metricsinktype)_ | true | Type defines the metric sink type.
EG currently only supports OpenTelemetry. | | `openTelemetry` | _[ProxyOpenTelemetrySink](#proxyopentelemetrysink)_ | false | OpenTelemetry defines the configuration for OpenTelemetry sink.
It's required if the sink type is OpenTelemetry. | - #### ProxyMetrics @@ -2128,12 +2127,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `prometheus` | _[ProxyPrometheusProvider](#proxyprometheusprovider)_ | true | Prometheus defines the configuration for Admin endpoint `/stats/prometheus`. | | `sinks` | _[ProxyMetricSink](#proxymetricsink) array_ | true | Sinks defines the metric sinks where metrics are sent to. | | `matches` | _[StringMatch](#stringmatch) array_ | true | Matches defines configuration for selecting specific metrics instead of generating all metrics stats
that are enabled by default. This helps reduce CPU and memory overhead in Envoy, but eliminating some stats
may after critical functionality. Here are the stats that we strongly recommend not disabling:
`cluster_manager.warming_clusters`, `cluster..membership_total`,`cluster..membership_healthy`,
`cluster..membership_degraded`,reference https://github.com/envoyproxy/envoy/issues/9856,
https://github.com/envoyproxy/envoy/issues/14610 | | `enableVirtualHostStats` | _boolean_ | true | EnableVirtualHostStats enables envoy stat metrics for virtual hosts. | - #### ProxyOpenTelemetrySink @@ -2145,11 +2144,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `host` | _string_ | false | Host define the service hostname.
Deprecated: Use BackendRef instead. | | `port` | _integer_ | false | Port defines the port the service is exposed on.
Deprecated: Use BackendRef instead. | | `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the metric will be sent.
Only service Kind is supported for now. | - #### ProxyPrometheusProvider @@ -2161,8 +2160,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `disable` | _boolean_ | true | Disable the Prometheus endpoint. | +| `disable` | _boolean_ | true | Disable the Prometheus endpoint. | #### ProxyProtocol @@ -2176,8 +2175,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `version` | _[ProxyProtocolVersion](#proxyprotocolversion)_ | true | Version of ProxyProtol
Valid ProxyProtocolVersion values are
"V1"
"V2" | +| `version` | _[ProxyProtocolVersion](#proxyprotocolversion)_ | true | Version of ProxyProtol
Valid ProxyProtocolVersion values are
"V1"
"V2" | #### ProxyProtocolVersion @@ -2201,11 +2200,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `accessLog` | _[ProxyAccessLog](#proxyaccesslog)_ | false | AccessLogs defines accesslog parameters for managed proxies.
If unspecified, will send default format to stdout. | | `tracing` | _[ProxyTracing](#proxytracing)_ | false | Tracing defines tracing configuration for managed proxies.
If unspecified, will not send tracing data. | | `metrics` | _[ProxyMetrics](#proxymetrics)_ | true | Metrics defines metrics configuration for managed proxies. | - #### ProxyTracing @@ -2217,11 +2216,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `samplingRate` | _integer_ | false | SamplingRate controls the rate at which traffic will be
selected for tracing if no prior sampling decision has been made.
Defaults to 100, valid values [0-100]. 100 indicates 100% sampling. | | `customTags` | _object (keys:string, values:[CustomTag](#customtag))_ | true | CustomTags defines the custom tags to add to each span.
If provider is kubernetes, pod name and namespace are added by default. | | `provider` | _[TracingProvider](#tracingprovider)_ | true | Provider defines the tracing provider.
Only OpenTelemetry is supported currently. | - #### RateLimit @@ -2235,12 +2234,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `backend` | _[RateLimitDatabaseBackend](#ratelimitdatabasebackend)_ | true | Backend holds the configuration associated with the
database backend used by the rate limit service to store
state associated with global ratelimiting. | | `timeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | false | Timeout specifies the timeout period for the proxy to access the ratelimit server
If not set, timeout is 20ms. | | `failClosed` | _boolean_ | true | FailClosed is a switch used to control the flow of traffic
when the response from the ratelimit server cannot be obtained.
If FailClosed is false, let the traffic pass,
otherwise, don't let the traffic pass and return 500.
If not set, FailClosed is False. | | `telemetry` | _[RateLimitTelemetry](#ratelimittelemetry)_ | false | Telemetry defines telemetry configuration for RateLimit. | - #### RateLimitDatabaseBackend @@ -2253,10 +2252,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[RateLimitDatabaseBackendType](#ratelimitdatabasebackendtype)_ | true | Type is the type of database backend to use. Supported types are:
* Redis: Connects to a Redis database. | | `redis` | _[RateLimitRedisSettings](#ratelimitredissettings)_ | false | Redis defines the settings needed to connect to a Redis database. | - #### RateLimitDatabaseBackendType _Underlying type:_ _string_ @@ -2280,8 +2279,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `prometheus` | _[RateLimitMetricsPrometheusProvider](#ratelimitmetricsprometheusprovider)_ | true | Prometheus defines the configuration for prometheus endpoint. | +| `prometheus` | _[RateLimitMetricsPrometheusProvider](#ratelimitmetricsprometheusprovider)_ | true | Prometheus defines the configuration for prometheus endpoint. | #### RateLimitMetricsPrometheusProvider @@ -2294,8 +2293,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `disable` | _boolean_ | true | Disable the Prometheus endpoint. | +| `disable` | _boolean_ | true | Disable the Prometheus endpoint. | #### RateLimitRedisSettings @@ -2308,10 +2307,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `url` | _string_ | true | URL of the Redis Database. | | `tls` | _[RedisTLSSettings](#redistlssettings)_ | false | TLS defines TLS configuration for connecting to redis database. | - #### RateLimitRule @@ -2325,10 +2324,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `clientSelectors` | _[RateLimitSelectCondition](#ratelimitselectcondition) array_ | false | ClientSelectors holds the list of select conditions to select
specific clients using attributes from the traffic flow.
All individual select conditions must hold True for this rule
and its limit to be applied.

If no client selectors are specified, the rule applies to all traffic of
the targeted Route.

If the policy targets a Gateway, the rule applies to each Route of the Gateway.
Please note that each Route has its own rate limit counters. For example,
if a Gateway has two Routes, and the policy has a rule with limit 10rps,
each Route will have its own 10rps limit. | | `limit` | _[RateLimitValue](#ratelimitvalue)_ | true | Limit holds the rate limit values.
This limit is applied for traffic flows when the selectors
compute to True, causing the request to be counted towards the limit.
The limit is enforced and the request is ratelimited, i.e. a response with
429 HTTP status code is sent back to the client when
the selected requests have reached the limit. | - #### RateLimitSelectCondition @@ -2342,10 +2341,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `headers` | _[HeaderMatch](#headermatch) array_ | false | Headers is a list of request headers to match. Multiple header values are ANDed together,
meaning, a request MUST match all the specified headers.
At least one of headers or sourceCIDR condition must be specified. | | `sourceCIDR` | _[SourceMatch](#sourcematch)_ | false | SourceCIDR is the client IP Address range to match on.
At least one of headers or sourceCIDR condition must be specified. | - #### RateLimitSpec @@ -2357,11 +2356,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[RateLimitType](#ratelimittype)_ | true | Type decides the scope for the RateLimits.
Valid RateLimitType values are "Global" or "Local". | | `global` | _[GlobalRateLimit](#globalratelimit)_ | false | Global defines global rate limit configuration. | | `local` | _[LocalRateLimit](#localratelimit)_ | false | Local defines local rate limit configuration. | - #### RateLimitTelemetry @@ -2373,10 +2372,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `metrics` | _[RateLimitMetrics](#ratelimitmetrics)_ | true | Metrics defines metrics configuration for RateLimit. | | `tracing` | _[RateLimitTracing](#ratelimittracing)_ | true | Tracing defines traces configuration for RateLimit. | - #### RateLimitTracing @@ -2388,10 +2387,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `samplingRate` | _integer_ | false | SamplingRate controls the rate at which traffic will be
selected for tracing if no prior sampling decision has been made.
Defaults to 100, valid values [0-100]. 100 indicates 100% sampling. | | `provider` | _[RateLimitTracingProvider](#ratelimittracingprovider)_ | true | Provider defines the rateLimit tracing provider.
Only OpenTelemetry is supported currently. | - #### RateLimitTracingProvider @@ -2403,12 +2402,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[RateLimitTracingProviderType](#ratelimittracingprovidertype)_ | true | Type defines the tracing provider type.
Since to RateLimit Exporter currently using OpenTelemetry, only OpenTelemetry is supported | | `url` | _string_ | true | URL is the endpoint of the trace collector that supports the OTLP protocol | - #### RateLimitType _Underlying type:_ _string_ @@ -2443,10 +2442,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `requests` | _integer_ | true | | | `unit` | _[RateLimitUnit](#ratelimitunit)_ | true | | - #### RedisTLSSettings @@ -2458,8 +2457,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `certificateRef` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | false | CertificateRef defines the client certificate reference for TLS connections.
Currently only a Kubernetes Secret of type TLS is supported. | +| `certificateRef` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | false | CertificateRef defines the client certificate reference for TLS connections.
Currently only a Kubernetes Secret of type TLS is supported. | #### RemoteJWKS @@ -2473,8 +2472,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `uri` | _string_ | true | URI is the HTTPS URI to fetch the JWKS. Envoy's system trust bundle is used to
validate the server certificate. | +| `uri` | _string_ | true | URI is the HTTPS URI to fetch the JWKS. Envoy's system trust bundle is used to
validate the server certificate. | #### RequestHeaderCustomTag @@ -2487,10 +2486,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `name` | _string_ | true | Name defines the name of the request header which to extract the value from. | | `defaultValue` | _string_ | false | DefaultValue defines the default value to use if the request header is not set. | - #### ResourceProviderType _Underlying type:_ _string_ @@ -2513,11 +2512,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `numRetries` | _integer_ | false | NumRetries is the number of retries to be attempted. Defaults to 2. | | `retryOn` | _[RetryOn](#retryon)_ | false | RetryOn specifies the retry trigger condition.

If not specified, the default is to retry on connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes(503). | | `perRetry` | _[PerRetryPolicy](#perretrypolicy)_ | false | PerRetry is the retry policy to be applied per retry attempt. | - #### RetryOn @@ -2529,10 +2528,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `triggers` | _[TriggerEnum](#triggerenum) array_ | false | Triggers specifies the retry trigger condition(Http/Grpc). | | `httpStatusCodes` | _[HTTPStatus](#httpstatus) array_ | false | HttpStatusCodes specifies the http status codes to be retried.
The retriable-status-codes trigger must also be configured for these status codes to trigger a retry. | - #### SecurityPolicy @@ -2547,10 +2546,10 @@ _Appears in:_ | --- | --- | --- | --- | | `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1` | `kind` | _string_ | |`SecurityPolicy` + | `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` | _[SecurityPolicySpec](#securitypolicyspec)_ | true | Spec defines the desired state of SecurityPolicy. | - #### SecurityPolicyList @@ -2563,10 +2562,10 @@ SecurityPolicyList contains a list of SecurityPolicy resources. | --- | --- | --- | --- | | `apiVersion` | _string_ | |`gateway.envoyproxy.io/v1alpha1` | `kind` | _string_ | |`SecurityPolicyList` + | `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` | _[SecurityPolicy](#securitypolicy) array_ | true | | - #### SecurityPolicySpec @@ -2578,6 +2577,7 @@ _Appears in:_ | 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. | | `cors` | _[CORS](#cors)_ | false | CORS defines the configuration for Cross-Origin Resource Sharing (CORS). | | `basicAuth` | _[BasicAuth](#basicauth)_ | false | BasicAuth defines the configuration for the HTTP Basic Authentication. | @@ -2587,7 +2587,6 @@ _Appears in:_ - #### ServiceExternalTrafficPolicy _Underlying type:_ _string_ @@ -2623,10 +2622,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `drainTimeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | false | DrainTimeout defines the graceful drain timeout. This should be less than the pod's terminationGracePeriodSeconds.
If unspecified, defaults to 600 seconds. | | `minDrainDuration` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | false | MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete.
If unspecified, defaults to 5 seconds. | - #### SlowStart @@ -2638,8 +2637,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `window` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | true | Window defines the duration of the warm up period for newly added host.
During slow start window, traffic sent to the newly added hosts will gradually increase.
Currently only supports linear growth of traffic. For additional details,
see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig | +| `window` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | true | Window defines the duration of the warm up period for newly added host.
During slow start window, traffic sent to the newly added hosts will gradually increase.
Currently only supports linear growth of traffic. For additional details,
see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig | @@ -2667,10 +2666,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[StringMatchType](#stringmatchtype)_ | false | Type specifies how to match against a string. | | `value` | _string_ | true | Value specifies the string value that the match must have. | - #### StringMatchType _Underlying type:_ _string_ @@ -2694,10 +2693,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `send` | _[ActiveHealthCheckPayload](#activehealthcheckpayload)_ | false | Send defines the request payload. | | `receive` | _[ActiveHealthCheckPayload](#activehealthcheckpayload)_ | false | Receive defines the expected response payload. | - #### TCPKeepalive @@ -2710,11 +2709,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `probes` | _integer_ | false | The total number of unacknowledged probes to send before deciding
the connection is dead.
Defaults to 9. | | `idleTime` | _[Duration](#duration)_ | false | The duration a connection needs to be idle before keep-alive
probes start being sent.
The duration format is
Defaults to `7200s`. | | `interval` | _[Duration](#duration)_ | false | The duration between keep-alive probes.
Defaults to `75s`. | - #### TCPTimeout @@ -2726,8 +2725,8 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `connectTimeout` | _[Duration](#duration)_ | false | The timeout for network connection establishment, including TCP and TLS handshakes.
Default: 10 seconds. | +| `connectTimeout` | _[Duration](#duration)_ | false | The timeout for network connection establishment, including TCP and TLS handshakes.
Default: 10 seconds. | #### TLSSettings @@ -2740,6 +2739,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `minVersion` | _[TLSVersion](#tlsversion)_ | false | Min specifies the minimal TLS protocol version to allow.
The default is TLS 1.2 if this is not specified. | | `maxVersion` | _[TLSVersion](#tlsversion)_ | false | Max specifies the maximal TLS protocol version to allow
The default is TLS 1.3 if this is not specified. | | `ciphers` | _string array_ | false | Ciphers specifies the set of cipher suites supported when
negotiating TLS 1.0 - 1.2. This setting has no effect for TLS 1.3.
In non-FIPS Envoy Proxy builds the default cipher list is:
- [ECDHE-ECDSA-AES128-GCM-SHA256\|ECDHE-ECDSA-CHACHA20-POLY1305]
- [ECDHE-RSA-AES128-GCM-SHA256\|ECDHE-RSA-CHACHA20-POLY1305]
- ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-RSA-AES256-GCM-SHA384
In builds using BoringSSL FIPS the default cipher list is:
- ECDHE-ECDSA-AES128-GCM-SHA256
- ECDHE-RSA-AES128-GCM-SHA256
- ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-RSA-AES256-GCM-SHA384 | @@ -2748,7 +2748,6 @@ _Appears in:_ | `alpnProtocols` | _[ALPNProtocol](#alpnprotocol) array_ | false | ALPNProtocols supplies the list of ALPN protocols that should be
exposed by the listener. By default h2 and http/1.1 are enabled.
Supported values are:
- http/1.0
- http/1.1
- h2 | | `clientValidation` | _[ClientValidationContext](#clientvalidationcontext)_ | false | ClientValidation specifies the configuration to validate the client
initiating the TLS connection to the Gateway listener. | - #### TLSVersion _Underlying type:_ _string_ @@ -2771,10 +2770,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `tcp` | _[TCPTimeout](#tcptimeout)_ | false | Timeout settings for TCP. | | `http` | _[HTTPTimeout](#httptimeout)_ | false | Timeout settings for HTTP. | - #### TracingProvider @@ -2786,12 +2785,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[TracingProviderType](#tracingprovidertype)_ | true | Type defines the tracing provider type.
EG currently only supports OpenTelemetry. | | `host` | _string_ | false | Host define the provider service hostname.
Deprecated: Use BackendRef instead. | | `port` | _integer_ | false | Port defines the port the provider service is exposed on.
Deprecated: Use BackendRef instead. | | `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the accesslog will be sent.
Only service Kind is supported for now. | - #### TracingProviderType _Underlying type:_ _string_ @@ -2829,12 +2828,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `name` | _string_ | true | Name is a unique name for this Wasm extension. It is used to identify the
Wasm extension if multiple extensions are handled by the same vm_id and root_id.
It's also used for logging/debugging. | | `code` | _[WasmCodeSource](#wasmcodesource)_ | true | Code is the wasm code for the extension. | | `config` | _[JSON](#json)_ | true | Config is the configuration for the Wasm extension.
This configuration will be passed as a JSON string to the Wasm extension. | | `failOpen` | _boolean_ | false | FailOpen is a switch used to control the behavior when a fatal error occurs
during the initialization or the execution of the Wasm extension.
If FailOpen is set to true, the system bypasses the Wasm extension and
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
an HTTP 5xx error. | - #### WasmCodeSource @@ -2846,11 +2845,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `type` | _[WasmCodeSourceType](#wasmcodesourcetype)_ | true | Type is the type of the source of the wasm code.
Valid WasmCodeSourceType values are "HTTP" or "Image". | | `http` | _[HTTPWasmCodeSource](#httpwasmcodesource)_ | false | HTTP is the HTTP URL containing the wasm code.

Note that the HTTP server must be accessible from the Envoy proxy. | | `image` | _[ImageWasmCodeSource](#imagewasmcodesource)_ | false | Image is the OCI image containing the wasm code.

Note that the image must be accessible from the Envoy Gateway. | - #### WasmCodeSourceType _Underlying type:_ _string_ @@ -2897,10 +2896,10 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `pre` | _[XDSTranslatorHook](#xdstranslatorhook) array_ | true | | | `post` | _[XDSTranslatorHook](#xdstranslatorhook) array_ | true | | - #### XForwardedForSettings @@ -2912,6 +2911,6 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `numTrustedHops` | _integer_ | false | NumTrustedHops controls the number of additional ingress proxy hops from the right side of XFF HTTP
headers to trust when determining the origin client's IP address.
Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for
for more details. | +| `numTrustedHops` | _integer_ | false | NumTrustedHops controls the number of additional ingress proxy hops from the right side of XFF HTTP
headers to trust when determining the origin client's IP address.
Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for
for more details. | diff --git a/tools/crd-ref-docs/config.yaml b/tools/crd-ref-docs/config.yaml index 18e84746d4c..d6fa4e4fc1f 100644 --- a/tools/crd-ref-docs/config.yaml +++ b/tools/crd-ref-docs/config.yaml @@ -6,6 +6,9 @@ processor: ignoreFields: - "status$" - "TypeMeta$" + customMarkers: + - name: "notImplementedHide" + target: "field" render: # Version of Kubernetes to use when generating links to Kubernetes API documentation. diff --git a/tools/crd-ref-docs/templates/type.tpl b/tools/crd-ref-docs/templates/type.tpl index 581cd8fcd9a..fa15a93fd3e 100644 --- a/tools/crd-ref-docs/templates/type.tpl +++ b/tools/crd-ref-docs/templates/type.tpl @@ -24,10 +24,11 @@ _Appears in:_ {{ end -}} {{ range $type.Members -}} +{{- with .Markers.notImplementedHide -}} +{{ else }} | `{{ .Name }}` | _{{ markdownRenderType .Type }}_ | {{ with .Markers.optional }} {{ "false" }} {{ else }} {{ "true" }} {{end}} | {{ template "type_members" . }} | -{{ end -}} - -{{ end -}} - +{{- end -}} +{{- end -}} +{{- end -}} {{- end -}} {{- end -}} diff --git a/tools/src/crd-ref-docs/go.mod b/tools/src/crd-ref-docs/go.mod index eb1f6e419eb..609d3a99a7c 100644 --- a/tools/src/crd-ref-docs/go.mod +++ b/tools/src/crd-ref-docs/go.mod @@ -2,7 +2,10 @@ module local go 1.22 -require github.com/elastic/crd-ref-docs v0.0.11 +// TODO: remove this after https://github.com/elastic/crd-ref-docs/pull/76 is merged +replace github.com/elastic/crd-ref-docs => github.com/zirain/crd-ref-docs v0.0.0-20240330085406-9336d26578da + +require github.com/elastic/crd-ref-docs v0.0.10 require ( github.com/Masterminds/goutils v1.1.1 // indirect @@ -11,7 +14,7 @@ require ( github.com/fatih/color v1.16.0 // indirect github.com/go-logr/logr v1.3.0 // indirect github.com/gobuffalo/flect v1.0.2 // indirect - github.com/goccy/go-yaml v1.11.0 // indirect + github.com/goccy/go-yaml v1.11.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.3.0 // indirect @@ -27,20 +30,19 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/sys v0.16.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/mod v0.16.0 // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.16.1 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + golang.org/x/tools v0.19.0 // indirect + golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/apiextensions-apiserver v0.29.0 // indirect - k8s.io/apimachinery v0.29.0 // indirect + k8s.io/apimachinery v0.29.3 // indirect k8s.io/klog/v2 v2.110.1 // indirect k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect sigs.k8s.io/controller-tools v0.14.0 // indirect diff --git a/tools/src/crd-ref-docs/go.sum b/tools/src/crd-ref-docs/go.sum index 53559cc9ef3..71a99bbc539 100644 --- a/tools/src/crd-ref-docs/go.sum +++ b/tools/src/crd-ref-docs/go.sum @@ -4,14 +4,10 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/crd-ref-docs v0.0.11 h1:/wNYycaIOQSnWPDdteRnx3IqvTBTzieQ6PHJS+g6nO4= -github.com/elastic/crd-ref-docs v0.0.11/go.mod h1:B4kHxcBLQ41TbGnUTjdliNmuG6Dv7MFrH2pmYTjN4IQ= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= @@ -26,8 +22,8 @@ github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7a github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= -github.com/goccy/go-yaml v1.11.0 h1:n7Z+zx8S9f9KgzG6KtQKf+kwqXZlLNR2F6018Dgau54= -github.com/goccy/go-yaml v1.11.0/go.mod h1:H+mJrWtjPTJAHvRbV09MCK9xYwODM+wRTVFFTWckfng= +github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I= +github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -70,8 +66,6 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -86,45 +80,45 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +github.com/zirain/crd-ref-docs v0.0.0-20240330085406-9336d26578da h1:hWtaeh12ZlN8dCexpNFhzK68LayDbql4nNgfe+cYUPc= +github.com/zirain/crd-ref-docs v0.0.0-20240330085406-9336d26578da/go.mod h1:X83mMBdJt05heJUYiS3T0yJ/JkCuliuhSUNav5Gjo/U= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= +golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= @@ -133,14 +127,14 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= @@ -156,8 +150,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= -k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= -k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= +k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU= +k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= From 231b3b476bb897b9679f7e303904e8a4e9cc3999 Mon Sep 17 00:00:00 2001 From: sh2 Date: Fri, 12 Apr 2024 19:34:26 +0800 Subject: [PATCH 10/10] refactor: group xds security features for security policy (#3019) * group security features for security policy Signed-off-by: shawnh2 * change SP xds Any to Empty, return deepcopy for SP Printable method Signed-off-by: shawnh2 * fix deepcopy and test data Signed-off-by: shawnh2 --------- Signed-off-by: shawnh2 --- internal/gatewayapi/securitypolicy.go | 58 ++++----- .../testdata/conflicting-policies.out.yaml | 29 ++--- .../merge-with-isolated-policies-2.out.yaml | 93 ++++++++------- .../merge-with-isolated-policies.out.yaml | 31 ++--- .../securitypolicy-override-replace.out.yaml | 102 ++++++++-------- .../securitypolicy-status-conditions.out.yaml | 2 + .../securitypolicy-with-basic-auth.out.yaml | 21 ++-- .../securitypolicy-with-cors.out.yaml | 111 +++++++++--------- ...-extauth-invalid-no-matching-port.out.yaml | 1 + ...licy-with-extauth-invalid-no-port.out.yaml | 1 + ...xtauth-invalid-no-reference-grant.out.yaml | 1 + ...y-with-extauth-invalid-no-service.out.yaml | 1 + ...ith-extauth-with-backendtlspolicy.out.yaml | 92 ++++++++------- .../securitypolicy-with-extauth.out.yaml | 107 +++++++++-------- ...ypolicy-with-jwt-and-invalid-oidc.out.yaml | 46 ++++---- ...cy-with-jwt-with-custom-extractor.out.yaml | 80 +++++++------ .../testdata/securitypolicy-with-jwt.out.yaml | 64 +++++----- .../securitypolicy-with-oidc.out.yaml | 66 ++++++----- internal/ir/xds.go | 80 +++++++++---- internal/ir/xds_test.go | 18 +-- internal/ir/zz_generated.deepcopy.go | 70 +++++++---- internal/xds/translator/basicauth.go | 12 +- internal/xds/translator/cors.go | 19 +-- internal/xds/translator/extauth.go | 18 +-- internal/xds/translator/jwt.go | 15 +-- internal/xds/translator/oidc.go | 20 ++-- .../testdata/in/xds-ir/basic-auth.yaml | 21 ++-- .../translator/testdata/in/xds-ir/cors.yaml | 39 +++--- .../testdata/in/xds-ir/ext-auth.yaml | 107 +++++++++-------- .../in/xds-ir/jwt-custom-extractor.yaml | 33 +++--- .../jwt-multi-route-multi-provider.yaml | 86 +++++++------- .../jwt-multi-route-single-provider.yaml | 40 ++++--- .../testdata/in/xds-ir/jwt-ratelimit.yaml | 17 +-- .../xds-ir/jwt-single-route-single-match.yaml | 17 +-- ...ners-same-port-with-different-filters.yaml | 75 ++++++------ .../translator/testdata/in/xds-ir/oidc.yaml | 74 ++++++------ 36 files changed, 889 insertions(+), 778 deletions(-) diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index b0c0976534d..d0f1c69958d 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -380,19 +380,21 @@ func (t *Translator) translateSecurityPolicyForRoute( // Note: there are multiple features in a security policy, even if some of them // are invalid, we still want to apply the valid ones. prefix := irRoutePrefix(route) - for _, ir := range xdsIR { - for _, http := range ir.HTTP { - for _, r := range http.Routes { + for _, x := range xdsIR { + for _, h := range x.HTTP { + for _, r := range h.Routes { // Apply if there is a match - // TODO zhaohuabing: extract a utils function to check if an HTTP // route is associated with a Gateway API xRoute if strings.HasPrefix(r.Name, prefix) { - // This security policy matches the current route. It should only be accepted if it doesn't match any other route - r.CORS = cors - r.JWT = jwt - r.OIDC = oidc - r.BasicAuth = basicAuth - r.ExtAuth = extAuth + // This security policy matches the current route. + // It should only be accepted if it doesn't match any other route + r.Security = &ir.SecurityFeatures{ + CORS: cors, + JWT: jwt, + OIDC: oidc, + BasicAuth: basicAuth, + ExtAuth: extAuth, + } } } } @@ -454,44 +456,32 @@ func (t *Translator) translateSecurityPolicyForGateway( // are invalid, we still want to apply the valid ones. irKey := t.getIRKey(gateway.Gateway) // Should exist since we've validated this - ir := xdsIR[irKey] + x := xdsIR[irKey] policyTarget := irStringKey( string(ptr.Deref(policy.Spec.TargetRef.Namespace, gwv1a2.Namespace(policy.Namespace))), string(policy.Spec.TargetRef.Name), ) - for _, http := range ir.HTTP { - gatewayName := http.Name[0:strings.LastIndex(http.Name, "/")] + for _, h := range x.HTTP { + gatewayName := h.Name[0:strings.LastIndex(h.Name, "/")] if t.MergeGateways && gatewayName != policyTarget { continue } // A Policy targeting the most specific scope(xRoute) wins over a policy // targeting a lesser specific scope(Gateway). - for _, r := range http.Routes { + for _, r := range h.Routes { // If any of the features are already set, it means that a more specific // policy(targeting xRoute) has already set it, so we skip it. - // TODO: zhaohuabing group the features into a struct and check if all of them are set - if r.CORS != nil || - r.JWT != nil || - r.OIDC != nil || - r.BasicAuth != nil || - r.ExtAuth != nil { + if !r.Security.Empty() { continue } - if r.CORS == nil { - r.CORS = cors - } - if r.JWT == nil { - r.JWT = jwt - } - if r.OIDC == nil { - r.OIDC = oidc - } - if r.BasicAuth == nil { - r.BasicAuth = basicAuth - } - if r.ExtAuth == nil { - r.ExtAuth = extAuth + + r.Security = &ir.SecurityFeatures{ + CORS: cors, + JWT: jwt, + OIDC: oidc, + BasicAuth: basicAuth, + ExtAuth: extAuth, } } } diff --git a/internal/gatewayapi/testdata/conflicting-policies.out.yaml b/internal/gatewayapi/testdata/conflicting-policies.out.yaml index d8b882d368a..6ffd1c911bd 100644 --- a/internal/gatewayapi/testdata/conflicting-policies.out.yaml +++ b/internal/gatewayapi/testdata/conflicting-policies.out.yaml @@ -308,20 +308,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowCredentials: true - allowMethods: - - PUT - - GET - - POST - - DELETE - - PATCH - - OPTIONS - allowOrigins: - - distinct: false - name: "" - safeRegex: http://.*\.foo\.com - maxAge: 10m0s destination: name: httproute/default/mfqjpuycbgjrtdww/rule/0 settings: @@ -338,3 +324,18 @@ xdsIR: distinct: false name: "" prefix: / + security: + cors: + allowCredentials: true + allowMethods: + - PUT + - GET + - POST + - DELETE + - PATCH + - OPTIONS + allowOrigins: + - distinct: false + name: "" + safeRegex: http://.*\.foo\.com + maxAge: 10m0s diff --git a/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml b/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml index 15e35504f91..20515adf5c2 100755 --- a/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml +++ b/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml @@ -519,21 +519,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-5 - - x-header-6 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: .* - exposeHeaders: - - x-header-7 - - x-header-8 - maxAge: 33m20s destination: name: httproute/default/httproute-1/rule/0 settings: @@ -550,6 +535,22 @@ xdsIR: distinct: false name: "" prefix: / + security: + cors: + allowHeaders: + - x-header-5 + - x-header-6 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: .* + exposeHeaders: + - x-header-7 + - x-header-8 + maxAge: 33m20s tcpKeepalive: idleTime: 1200 interval: 60 @@ -570,21 +571,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-5 - - x-header-6 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: .* - exposeHeaders: - - x-header-7 - - x-header-8 - maxAge: 33m20s destination: name: httproute/default/httproute-2/rule/0 settings: @@ -601,6 +587,22 @@ xdsIR: distinct: false name: "" prefix: / + security: + cors: + allowHeaders: + - x-header-5 + - x-header-6 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: .* + exposeHeaders: + - x-header-7 + - x-header-8 + maxAge: 33m20s tcpKeepalive: idleTime: 1200 interval: 60 @@ -621,21 +623,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-5 - - x-header-6 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: .* - exposeHeaders: - - x-header-7 - - x-header-8 - maxAge: 33m20s destination: name: httproute/default/httproute-3/rule/0 settings: @@ -652,6 +639,22 @@ xdsIR: distinct: false name: "" prefix: / + security: + cors: + allowHeaders: + - x-header-5 + - x-header-6 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: .* + exposeHeaders: + - x-header-7 + - x-header-8 + maxAge: 33m20s - address: 0.0.0.0 hostnames: - foo.example.com diff --git a/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml b/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml index 2da58361ab6..fd669713ef0 100644 --- a/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml +++ b/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml @@ -309,21 +309,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-5 - - x-header-6 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: .* - exposeHeaders: - - x-header-7 - - x-header-8 - maxAge: 33m20s destination: name: httproute/default/httproute-1/rule/0 settings: @@ -340,6 +325,22 @@ xdsIR: distinct: false name: "" prefix: / + security: + cors: + allowHeaders: + - x-header-5 + - x-header-6 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: .* + exposeHeaders: + - x-header-7 + - x-header-8 + maxAge: 33m20s tcpKeepalive: idleTime: 1200 interval: 60 diff --git a/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml b/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml index 1224320c631..303fd72292f 100755 --- a/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml @@ -251,24 +251,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-5 - - x-header-6 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: https://.*\.test\.com:8080 - - distinct: false - exact: https://www.test.org:8080 - name: "" - exposeHeaders: - - x-header-7 - - x-header-8 - maxAge: 33m20s destination: name: httproute/default/httproute-1/rule/0 settings: @@ -285,30 +267,28 @@ xdsIR: distinct: false name: "" prefix: /foo + security: + cors: + allowHeaders: + - x-header-5 + - x-header-6 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: https://.*\.test\.com:8080 + - distinct: false + exact: https://www.test.org:8080 + name: "" + exposeHeaders: + - x-header-7 + - x-header-8 + maxAge: 33m20s - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-1 - - x-header-2 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: http://.*\.example\.com - - distinct: false - exact: http://foo.bar.com - name: "" - - distinct: false - name: "" - safeRegex: https://.* - exposeHeaders: - - x-header-3 - - x-header-4 - maxAge: 16m40s destination: name: httproute/default/httproute-2/rule/0 settings: @@ -320,19 +300,41 @@ xdsIR: weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false - jwt: - providers: - - audiences: - - one.foo.com - claimToHeaders: - - claim: claim1 - header: one-route-example-key - issuer: https://one.example.com - name: example1 - remoteJWKS: - uri: https://one.example.com/jwt/public-key/jwks.json name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io pathMatch: distinct: false name: "" prefix: /bar + security: + cors: + allowHeaders: + - x-header-1 + - x-header-2 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: http://.*\.example\.com + - distinct: false + exact: http://foo.bar.com + name: "" + - distinct: false + name: "" + safeRegex: https://.* + exposeHeaders: + - x-header-3 + - x-header-4 + maxAge: 16m40s + jwt: + providers: + - audiences: + - one.foo.com + claimToHeaders: + - claim: claim1 + header: one-route-example-key + issuer: https://one.example.com + name: example1 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json diff --git a/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml index 853da756488..44100b06203 100755 --- a/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml @@ -435,6 +435,7 @@ xdsIR: distinct: false name: "" prefix: / + security: {} envoy-gateway/gateway-2: accessLog: text: @@ -462,3 +463,4 @@ xdsIR: hostname: '*' isHTTP2: true name: grpcroute/envoy-gateway/grpcroute-1/rule/0/match/0/* + security: {} diff --git a/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml index 3681d60e018..ebaf4a53218 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml @@ -227,9 +227,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - basicAuth: - name: securitypolicy/default/policy-for-http-route-1 - users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= destination: name: httproute/default/httproute-1/rule/0 settings: @@ -246,12 +243,13 @@ xdsIR: distinct: false name: "" prefix: /foo1 + security: + basicAuth: + name: securitypolicy/default/policy-for-http-route-1 + users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= - 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: @@ -268,12 +266,13 @@ xdsIR: distinct: false name: "" prefix: /foo2 + security: + basicAuth: + name: securitypolicy/default/policy-for-http-route-1 + users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= - backendWeights: invalid: 0 valid: 0 - basicAuth: - name: securitypolicy/default/policy-for-gateway-1 - users: Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo= destination: name: httproute/default/httproute-2/rule/0 settings: @@ -290,3 +289,7 @@ xdsIR: distinct: false name: "" prefix: /bar + security: + basicAuth: + name: securitypolicy/default/policy-for-gateway-1 + users: Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo= diff --git a/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml index 943ea81307a..d7d1f9b209d 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml @@ -418,27 +418,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-1 - - x-header-2 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: http://.*\.example\.com - - distinct: false - exact: http://foo.bar.com - name: "" - - distinct: false - name: "" - safeRegex: https://.* - exposeHeaders: - - x-header-3 - - x-header-4 - maxAge: 16m40s destination: name: grpcroute/default/grpcroute-1/rule/0 settings: @@ -451,6 +430,28 @@ xdsIR: hostname: '*' isHTTP2: true name: grpcroute/default/grpcroute-1/rule/0/match/-1/* + security: + cors: + allowHeaders: + - x-header-1 + - x-header-2 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: http://.*\.example\.com + - distinct: false + exact: http://foo.bar.com + name: "" + - distinct: false + name: "" + safeRegex: https://.* + exposeHeaders: + - x-header-3 + - x-header-4 + maxAge: 16m40s envoy-gateway/gateway-2: accessLog: text: @@ -469,24 +470,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-5 - - x-header-6 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: https://.*\.test\.com:8080 - - distinct: false - exact: https://www.test.org:8080 - name: "" - exposeHeaders: - - x-header-7 - - x-header-8 - maxAge: 33m20s destination: name: httproute/default/httproute-1/rule/0 settings: @@ -503,6 +486,25 @@ xdsIR: distinct: false name: "" prefix: / + security: + cors: + allowHeaders: + - x-header-5 + - x-header-6 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: https://.*\.test\.com:8080 + - distinct: false + exact: https://www.test.org:8080 + name: "" + exposeHeaders: + - x-header-7 + - x-header-8 + maxAge: 33m20s envoy-gateway/gateway-3: accessLog: text: @@ -521,21 +523,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-5 - - x-header-6 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: .* - exposeHeaders: - - x-header-7 - - x-header-8 - maxAge: 33m20s destination: name: httproute/default/httproute-2/rule/0 settings: @@ -552,3 +539,19 @@ xdsIR: distinct: false name: "" prefix: / + security: + cors: + allowHeaders: + - x-header-5 + - x-header-6 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: .* + exposeHeaders: + - x-header-7 + - x-header-8 + maxAge: 33m20s 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 20a44008251..b2102a0db78 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 @@ -166,3 +166,4 @@ xdsIR: distinct: false name: "" prefix: /foo + security: {} 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 4ade06fec09..bcb049d8fa2 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 @@ -166,3 +166,4 @@ xdsIR: distinct: false name: "" prefix: /foo + security: {} 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 82fc12d534c..46a0d7dc20c 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 @@ -167,3 +167,4 @@ xdsIR: distinct: false name: "" prefix: /foo + security: {} 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 980d29cce01..e83e1a419a2 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 @@ -166,3 +166,4 @@ xdsIR: distinct: false name: "" prefix: /foo + security: {} 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 e964b48155c..6116c4c30c7 100755 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml @@ -306,28 +306,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - extAuth: - failOpen: true - grpc: - authority: grpc-backend.default:9000 - destination: - name: securitypolicy/default/policy-for-http-route/default/grpc-backend - settings: - - addressType: IP - endpoints: - - host: 8.8.8.8 - port: 9000 - protocol: GRPC - tls: - caCertificate: - certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - name: policy-btls-grpc/default-ca - sni: grpc-backend - weight: 1 - headersToExtAuth: - - header1 - - header2 - 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 @@ -335,6 +313,29 @@ xdsIR: distinct: false name: "" prefix: /foo + security: + extAuth: + failOpen: true + grpc: + authority: grpc-backend.default:9000 + destination: + name: securitypolicy/default/policy-for-http-route/default/grpc-backend + settings: + - addressType: IP + endpoints: + - host: 8.8.8.8 + port: 9000 + protocol: GRPC + tls: + caCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: policy-btls-grpc/default-ca + sni: grpc-backend + weight: 1 + headersToExtAuth: + - header1 + - header2 + name: securitypolicy/default/policy-for-http-route - backendWeights: invalid: 0 valid: 0 @@ -347,29 +348,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - extAuth: - failOpen: false - http: - authority: http-backend.envoy-gateway:80 - destination: - name: securitypolicy/default/policy-for-gateway/envoy-gateway/http-backend - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 80 - protocol: HTTP - tls: - caCertificate: - certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - name: policy-btls-http/default-ca - sni: http-backend - weight: 1 - headersToBackend: - - header1 - - header2 - path: /auth - name: securitypolicy/default/policy-for-gateway hostname: www.bar.com isHTTP2: false name: httproute/default/httproute-2/rule/0/match/0/www_bar_com @@ -377,3 +355,27 @@ xdsIR: distinct: false name: "" prefix: /bar + security: + extAuth: + failOpen: false + http: + authority: http-backend.envoy-gateway:80 + destination: + name: securitypolicy/default/policy-for-gateway/envoy-gateway/http-backend + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 80 + protocol: HTTP + tls: + caCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: policy-btls-http/default-ca + sni: http-backend + weight: 1 + headersToBackend: + - header1 + - header2 + path: /auth + name: securitypolicy/default/policy-for-gateway diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml index f9243d6f420..0b65a634a56 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml @@ -246,23 +246,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - extAuth: - failOpen: true - 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: 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 @@ -270,6 +253,24 @@ xdsIR: distinct: false name: "" prefix: /foo1 + security: + extAuth: + failOpen: true + 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: securitypolicy/default/policy-for-http-route-1 - backendWeights: invalid: 0 valid: 0 @@ -282,23 +283,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - extAuth: - failOpen: true - 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: 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 @@ -306,6 +290,24 @@ xdsIR: distinct: false name: "" prefix: /foo2 + security: + extAuth: + failOpen: true + 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: securitypolicy/default/policy-for-http-route-1 - backendWeights: invalid: 0 valid: 0 @@ -318,24 +320,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - extAuth: - failOpen: false - 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 - 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 @@ -343,3 +327,22 @@ xdsIR: distinct: false name: "" prefix: /bar + security: + extAuth: + failOpen: false + 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 + name: securitypolicy/default/policy-for-gateway-1 diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml index a8e01e48023..64e1e0d210a 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml @@ -260,22 +260,23 @@ xdsIR: weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false - jwt: - providers: - - audiences: - - one.foo.com - claimToHeaders: - - claim: claim1 - header: one-route-example-key - issuer: https://one.example.com - name: example1 - remoteJWKS: - uri: https://one.example.com/jwt/public-key/jwks.json name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io pathMatch: distinct: false name: "" prefix: /foo + security: + jwt: + providers: + - audiences: + - one.foo.com + claimToHeaders: + - claim: claim1 + header: one-route-example-key + issuer: https://one.example.com + name: example1 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json - backendWeights: invalid: 0 valid: 0 @@ -290,19 +291,20 @@ xdsIR: weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false - jwt: - providers: - - audiences: - - two.foo.com - claimToHeaders: - - claim: claim2 - header: one-route-example-key - issuer: https://two.example.com - name: example2 - remoteJWKS: - uri: https://one.example.com/jwt/public-key/jwks.json name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io pathMatch: distinct: false name: "" prefix: /bar + security: + jwt: + providers: + - audiences: + - two.foo.com + claimToHeaders: + - claim: claim2 + header: one-route-example-key + issuer: https://two.example.com + name: example2 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.out.yaml index 2ea03bafc0b..4570b796638 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.out.yaml @@ -306,27 +306,28 @@ xdsIR: weight: 1 hostname: '*' isHTTP2: true - jwt: - providers: - - audiences: - - one.foo.com - claimToHeaders: - - claim: claim1 - header: one-route-example-key - issuer: https://one.example.com - name: example1 - remoteJWKS: - uri: https://one.example.com/jwt/public-key/jwks.json - - audiences: - - two.foo.com - claimToHeaders: - - claim: claim2 - header: two-route-example-key - issuer: https://two.example.com - name: example2 - remoteJWKS: - uri: https://two.example.com/jwt/public-key/jwks.json name: grpcroute/default/grpcroute-1/rule/0/match/-1/* + security: + jwt: + providers: + - audiences: + - one.foo.com + claimToHeaders: + - claim: claim1 + header: one-route-example-key + issuer: https://one.example.com + name: example1 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json + - audiences: + - two.foo.com + claimToHeaders: + - claim: claim2 + header: two-route-example-key + issuer: https://two.example.com + name: example2 + remoteJWKS: + uri: https://two.example.com/jwt/public-key/jwks.json envoy-gateway/gateway-2: accessLog: text: @@ -356,27 +357,28 @@ xdsIR: weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false - jwt: - providers: - - audiences: - - three.foo.com - claimToHeaders: - - claim: claim3 - header: three-route-example-key - extractFrom: - cookies: - - session_access_token - headers: - - name: Authorization - valuePrefix: 'Bearer ' - params: - - token - issuer: https://three.example.com - name: example3 - remoteJWKS: - uri: https://three.example.com/jwt/public-key/jwks.json name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io pathMatch: distinct: false name: "" prefix: / + security: + jwt: + providers: + - audiences: + - three.foo.com + claimToHeaders: + - claim: claim3 + header: three-route-example-key + extractFrom: + cookies: + - session_access_token + headers: + - name: Authorization + valuePrefix: 'Bearer ' + params: + - token + issuer: https://three.example.com + name: example3 + remoteJWKS: + uri: https://three.example.com/jwt/public-key/jwks.json diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt.out.yaml index 6af406789f9..2da32b26f8e 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt.out.yaml @@ -298,27 +298,28 @@ xdsIR: weight: 1 hostname: '*' isHTTP2: true - jwt: - providers: - - audiences: - - one.foo.com - claimToHeaders: - - claim: claim1 - header: one-route-example-key - issuer: https://one.example.com - name: example1 - remoteJWKS: - uri: https://one.example.com/jwt/public-key/jwks.json - - audiences: - - two.foo.com - claimToHeaders: - - claim: claim2 - header: two-route-example-key - issuer: http://two.example.com - name: example2 - remoteJWKS: - uri: http://two.example.com/jwt/public-key/jwks.json name: grpcroute/default/grpcroute-1/rule/0/match/-1/* + security: + jwt: + providers: + - audiences: + - one.foo.com + claimToHeaders: + - claim: claim1 + header: one-route-example-key + issuer: https://one.example.com + name: example1 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json + - audiences: + - two.foo.com + claimToHeaders: + - claim: claim2 + header: two-route-example-key + issuer: http://two.example.com + name: example2 + remoteJWKS: + uri: http://two.example.com/jwt/public-key/jwks.json envoy-gateway/gateway-2: accessLog: text: @@ -348,19 +349,20 @@ xdsIR: weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false - jwt: - providers: - - audiences: - - three.foo.com - claimToHeaders: - - claim: claim3 - header: three-route-example-key - issuer: https://three.example.com - name: example3 - remoteJWKS: - uri: https://three.example.com/jwt/public-key/jwks.json name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io pathMatch: distinct: false name: "" prefix: / + security: + jwt: + providers: + - audiences: + - three.foo.com + claimToHeaders: + - claim: claim3 + header: three-route-example-key + issuer: https://three.example.com + name: example3 + remoteJWKS: + uri: https://three.example.com/jwt/public-key/jwks.json diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml index b0cff9eac83..15f0189dec3 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml @@ -253,28 +253,29 @@ xdsIR: hostname: www.example.com isHTTP2: false name: httproute/default/httproute-1/rule/0/match/0/www_example_com - oidc: - clientID: client2.oauth.foo.com - clientSecret: Y2xpZW50MTpzZWNyZXQK - 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 - redirectPath: /foo/oauth2/callback - redirectURL: https://www.example.com/foo/oauth2/callback - resources: - - api - scopes: - - openid - - email - - profile pathMatch: distinct: false name: "" prefix: /foo + security: + oidc: + clientID: client2.oauth.foo.com + clientSecret: Y2xpZW50MTpzZWNyZXQK + 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 + redirectPath: /foo/oauth2/callback + redirectURL: https://www.example.com/foo/oauth2/callback + resources: + - api + scopes: + - openid + - email + - profile - backendWeights: invalid: 0 valid: 0 @@ -290,21 +291,22 @@ xdsIR: hostname: www.example.com isHTTP2: false name: httproute/default/httproute-2/rule/0/match/0/www_example_com - oidc: - clientID: client1.apps.googleusercontent.com - clientSecret: Y2xpZW50MTpzZWNyZXQK - 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 - redirectPath: /bar/oauth2/callback - redirectURL: https://www.example.com/bar/oauth2/callback - scopes: - - openid pathMatch: distinct: false name: "" prefix: /bar + security: + oidc: + clientID: client1.apps.googleusercontent.com + clientSecret: Y2xpZW50MTpzZWNyZXQK + 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 + redirectPath: /bar/oauth2/callback + redirectURL: https://www.example.com/bar/oauth2/callback + scopes: + - openid diff --git a/internal/ir/xds.go b/internal/ir/xds.go index c2d444ef8a8..3b330d3fef6 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -180,12 +180,8 @@ func (x Xds) Printable() *Xds { for _, route := range listener.Routes { // Omit field - if route.OIDC != nil { - route.OIDC.ClientSecret = redacted - route.OIDC.HMACSecret = redacted - } - if route.BasicAuth != nil { - route.BasicAuth.Users = redacted + if route.Security != nil { + route.Security = route.Security.Printable() } } } @@ -467,18 +463,8 @@ type HTTPRoute struct { RateLimit *RateLimit `json:"rateLimit,omitempty" yaml:"rateLimit,omitempty"` // load balancer policy to use when routing to the backend endpoints. LoadBalancer *LoadBalancer `json:"loadBalancer,omitempty" yaml:"loadBalancer,omitempty"` - // CORS policy for the route. - CORS *CORS `json:"cors,omitempty" yaml:"cors,omitempty"` - // JWT defines the schema for authenticating HTTP requests using JSON Web Tokens (JWT). - JWT *JWT `json:"jwt,omitempty" yaml:"jwt,omitempty"` - // OIDC defines the schema for authenticating HTTP requests using OpenID Connect (OIDC). - OIDC *OIDC `json:"oidc,omitempty" yaml:"oidc,omitempty"` // Proxy Protocol Settings ProxyProtocol *ProxyProtocol `json:"proxyProtocol,omitempty" yaml:"proxyProtocol,omitempty"` - // BasicAuth defines the schema for the HTTP Basic Authentication. - BasicAuth *BasicAuth `json:"basicAuth,omitempty" yaml:"basicAuth,omitempty"` - // ExtAuth defines the schema for the external authorization. - ExtAuth *ExtAuth `json:"extAuth,omitempty" yaml:"extAuth,omitempty"` // HealthCheck defines the configuration for health checking on the upstream. HealthCheck *HealthCheck `json:"healthCheck,omitempty" yaml:"healthCheck,omitempty"` // FaultInjection defines the schema for injecting faults into HTTP requests. @@ -495,6 +481,61 @@ type HTTPRoute struct { Retry *Retry `json:"retry,omitempty" yaml:"retry,omitempty"` // External Processing extensions ExtProcs []ExtProc `json:"extProc,omitempty" yaml:"extProc,omitempty"` + + // Security holds the features associated with SecurityPolicy + Security *SecurityFeatures `json:"security,omitempty" yaml:"security,omitempty"` +} + +// SecurityFeatures holds the information associated with the Security Policy. +// +k8s:deepcopy-gen=true +type SecurityFeatures struct { + // CORS policy for the route. + CORS *CORS `json:"cors,omitempty" yaml:"cors,omitempty"` + // JWT defines the schema for authenticating HTTP requests using JSON Web Tokens (JWT). + JWT *JWT `json:"jwt,omitempty" yaml:"jwt,omitempty"` + // OIDC defines the schema for authenticating HTTP requests using OpenID Connect (OIDC). + OIDC *OIDC `json:"oidc,omitempty" yaml:"oidc,omitempty"` + // BasicAuth defines the schema for the HTTP Basic Authentication. + BasicAuth *BasicAuth `json:"basicAuth,omitempty" yaml:"basicAuth,omitempty"` + // ExtAuth defines the schema for the external authorization. + ExtAuth *ExtAuth `json:"extAuth,omitempty" yaml:"extAuth,omitempty"` +} + +// Empty returns true if all the features are not set. +func (s *SecurityFeatures) Empty() bool { + if s == nil { + return true + } + + return s.CORS == nil && + s.JWT == nil && + s.OIDC == nil && + s.BasicAuth == nil && + s.ExtAuth == nil +} + +func (s *SecurityFeatures) Printable() *SecurityFeatures { + out := s.DeepCopy() + if out.OIDC != nil { + out.OIDC.ClientSecret = redacted + out.OIDC.HMACSecret = redacted + } + if out.BasicAuth != nil { + out.BasicAuth.Users = redacted + } + return out +} + +func (s *SecurityFeatures) Validate() error { + var errs error + + if s.JWT != nil { + if err := s.JWT.Validate(); err != nil { + errs = errors.Join(errs, err) + } + } + + return errs } // UnstructuredRef holds unstructured data for an arbitrary k8s resource introduced by an extension @@ -810,8 +851,8 @@ func (h HTTPRoute) Validate() error { errs = errors.Join(errs, err) } } - if h.JWT != nil { - if err := h.JWT.validate(); err != nil { + if h.Security != nil { + if err := h.Security.Validate(); err != nil { errs = errors.Join(errs, err) } } @@ -824,7 +865,7 @@ func (h HTTPRoute) Validate() error { return errs } -func (j *JWT) validate() error { +func (j *JWT) Validate() error { var errs error if err := egv1a1validation.ValidateJWTProvider(j.Providers); err != nil { @@ -1824,7 +1865,6 @@ type TLSUpstreamConfig struct { // Connection settings for downstream connections // +k8s:deepcopy-gen=true type Connection struct { - // // ConnectionLimit is the limit of number of connections ConnectionLimit *ConnectionLimit `json:"limit,omitempty" yaml:"limit,omitempty"` // BufferLimitBytes is the maximum number of bytes that can be buffered for a connection. diff --git a/internal/ir/xds_test.go b/internal/ir/xds_test.go index 2f4d9a46a33..8b16cf6e9a4 100644 --- a/internal/ir/xds_test.go +++ b/internal/ir/xds_test.go @@ -446,12 +446,14 @@ var ( PathMatch: &StringMatch{ Exact: ptr.To("jwtauthen"), }, - JWT: &JWT{ - Providers: []egv1a1.JWTProvider{ - { - Name: "test1", - RemoteJWKS: egv1a1.RemoteJWKS{ - URI: "https://test1.local", + Security: &SecurityFeatures{ + JWT: &JWT{ + Providers: []egv1a1.JWTProvider{ + { + Name: "test1", + RemoteJWKS: egv1a1.RemoteJWKS{ + URI: "https://test1.local", + }, }, }, }, @@ -1153,9 +1155,9 @@ func TestValidateJWT(t *testing.T) { test := tests[i] t.Run(test.name, func(t *testing.T) { if test.want == nil { - require.NoError(t, test.input.validate()) + require.NoError(t, test.input.Validate()) } else { - require.EqualError(t, test.input.validate(), test.want.Error()) + require.EqualError(t, test.input.Validate(), test.want.Error()) } }) } diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index e633075feaf..94e14661375 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -971,36 +971,11 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) { *out = new(LoadBalancer) (*in).DeepCopyInto(*out) } - if in.CORS != nil { - in, out := &in.CORS, &out.CORS - *out = new(CORS) - (*in).DeepCopyInto(*out) - } - if in.JWT != nil { - in, out := &in.JWT, &out.JWT - *out = new(JWT) - (*in).DeepCopyInto(*out) - } - if in.OIDC != nil { - in, out := &in.OIDC, &out.OIDC - *out = new(OIDC) - (*in).DeepCopyInto(*out) - } if in.ProxyProtocol != nil { in, out := &in.ProxyProtocol, &out.ProxyProtocol *out = new(ProxyProtocol) **out = **in } - if in.BasicAuth != nil { - in, out := &in.BasicAuth, &out.BasicAuth - *out = new(BasicAuth) - (*in).DeepCopyInto(*out) - } - if in.ExtAuth != nil { - in, out := &in.ExtAuth, &out.ExtAuth - *out = new(ExtAuth) - (*in).DeepCopyInto(*out) - } if in.HealthCheck != nil { in, out := &in.HealthCheck, &out.HealthCheck *out = new(HealthCheck) @@ -1049,6 +1024,11 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Security != nil { + in, out := &in.Security, &out.Security + *out = new(SecurityFeatures) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRoute. @@ -1876,6 +1856,46 @@ func (in *RouteDestination) DeepCopy() *RouteDestination { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityFeatures) DeepCopyInto(out *SecurityFeatures) { + *out = *in + if in.CORS != nil { + in, out := &in.CORS, &out.CORS + *out = new(CORS) + (*in).DeepCopyInto(*out) + } + if in.JWT != nil { + in, out := &in.JWT, &out.JWT + *out = new(JWT) + (*in).DeepCopyInto(*out) + } + if in.OIDC != nil { + in, out := &in.OIDC, &out.OIDC + *out = new(OIDC) + (*in).DeepCopyInto(*out) + } + if in.BasicAuth != nil { + in, out := &in.BasicAuth, &out.BasicAuth + *out = new(BasicAuth) + (*in).DeepCopyInto(*out) + } + if in.ExtAuth != nil { + in, out := &in.ExtAuth, &out.ExtAuth + *out = new(ExtAuth) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityFeatures. +func (in *SecurityFeatures) DeepCopy() *SecurityFeatures { + if in == nil { + return nil + } + out := new(SecurityFeatures) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SlowStart) DeepCopyInto(out *SlowStart) { *out = *in diff --git a/internal/xds/translator/basicauth.go b/internal/xds/translator/basicauth.go index f9c88d58175..f24b9cc76ab 100644 --- a/internal/xds/translator/basicauth.go +++ b/internal/xds/translator/basicauth.go @@ -54,11 +54,11 @@ func (*basicAuth) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTP // 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)) { + if hcmContainsFilter(mgr, basicAuthFilterName(route.Security.BasicAuth)) { continue } - filter, err := buildHCMBasicAuthFilter(route.BasicAuth) + filter, err := buildHCMBasicAuthFilter(route.Security.BasicAuth) if err != nil { errs = errors.Join(errs, err) continue @@ -108,7 +108,9 @@ func basicAuthConfig(basicAuth *ir.BasicAuth) *basicauthv3.BasicAuth { // routeContainsBasicAuth returns true if BasicAuth exists for the provided route. func routeContainsBasicAuth(irRoute *ir.HTTPRoute) bool { - if irRoute != nil && irRoute.BasicAuth != nil { + if irRoute != nil && + irRoute.Security != nil && + irRoute.Security.BasicAuth != nil { return true } return false @@ -127,10 +129,10 @@ func (*basicAuth) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error if irRoute == nil { return errors.New("ir route is nil") } - if irRoute.BasicAuth == nil { + if irRoute.Security == nil || irRoute.Security.BasicAuth == nil { return nil } - filterName := basicAuthFilterName(irRoute.BasicAuth) + filterName := basicAuthFilterName(irRoute.Security.BasicAuth) if err := enableFilterOnRoute(route, filterName); err != nil { return err } diff --git a/internal/xds/translator/cors.go b/internal/xds/translator/cors.go index 94c3855f86e..cd46b6f41a6 100644 --- a/internal/xds/translator/cors.go +++ b/internal/xds/translator/cors.go @@ -92,7 +92,7 @@ func listenerContainsCORS(irListener *ir.HTTPListener) bool { } for _, route := range irListener.Routes { - if route.CORS != nil { + if route.Security != nil && route.Security.CORS != nil { return true } } @@ -108,7 +108,7 @@ func (*cors) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { if irRoute == nil { return errors.New("ir route is nil") } - if irRoute.CORS == nil { + if irRoute.Security == nil || irRoute.Security.CORS == nil { return nil } @@ -126,21 +126,22 @@ func (*cors) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { exposeHeaders string maxAge string allowCredentials *wrappers.BoolValue + c = irRoute.Security.CORS ) //nolint:gocritic - for _, origin := range irRoute.CORS.AllowOrigins { + for _, origin := range c.AllowOrigins { allowOrigins = append(allowOrigins, buildXdsStringMatcher(origin)) } - allowMethods = strings.Join(irRoute.CORS.AllowMethods, ", ") - allowHeaders = strings.Join(irRoute.CORS.AllowHeaders, ", ") - exposeHeaders = strings.Join(irRoute.CORS.ExposeHeaders, ", ") - if irRoute.CORS.MaxAge != nil { - maxAge = strconv.Itoa(int(irRoute.CORS.MaxAge.Seconds())) + allowMethods = strings.Join(c.AllowMethods, ", ") + allowHeaders = strings.Join(c.AllowHeaders, ", ") + exposeHeaders = strings.Join(c.ExposeHeaders, ", ") + if c.MaxAge != nil { + maxAge = strconv.Itoa(int(c.MaxAge.Seconds())) } - allowCredentials = &wrappers.BoolValue{Value: irRoute.CORS.AllowCredentials} + allowCredentials = &wrappers.BoolValue{Value: c.AllowCredentials} routeCfgProto := &corsv3.CorsPolicy{ AllowOriginStringMatch: allowOrigins, diff --git a/internal/xds/translator/extauth.go b/internal/xds/translator/extauth.go index eb79779f8e9..43712564e16 100644 --- a/internal/xds/translator/extauth.go +++ b/internal/xds/translator/extauth.go @@ -58,11 +58,11 @@ func (*extAuth) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPLi // 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)) { + if hcmContainsFilter(mgr, extAuthFilterName(route.Security.ExtAuth)) { continue } - filter, err := buildHCMExtAuthFilter(route.ExtAuth) + filter, err := buildHCMExtAuthFilter(route.Security.ExtAuth) if err != nil { errs = errors.Join(errs, err) continue @@ -202,7 +202,9 @@ func grpcService(grpc *ir.GRPCExtAuthService) *corev3.GrpcService_EnvoyGrpc { // routeContainsExtAuth returns true if ExtAuth exists for the provided route. func routeContainsExtAuth(irRoute *ir.HTTPRoute) bool { - if irRoute != nil && irRoute.ExtAuth != nil { + if irRoute != nil && + irRoute.Security != nil && + irRoute.Security.ExtAuth != nil { return true } return false @@ -220,15 +222,15 @@ func (*extAuth) patchResources(tCtx *types.ResourceVersionTable, if !routeContainsExtAuth(route) { continue } - if route.ExtAuth.HTTP != nil { + if route.Security.ExtAuth.HTTP != nil { if err := createExtServiceXDSCluster( - &route.ExtAuth.HTTP.Destination, tCtx); err != nil && !errors.Is( + &route.Security.ExtAuth.HTTP.Destination, tCtx); err != nil && !errors.Is( err, ErrXdsClusterExists) { errs = errors.Join(errs, err) } } else { if err := createExtServiceXDSCluster( - &route.ExtAuth.GRPC.Destination, tCtx); err != nil && !errors.Is( + &route.Security.ExtAuth.GRPC.Destination, tCtx); err != nil && !errors.Is( err, ErrXdsClusterExists) { errs = errors.Join(errs, err) } @@ -247,10 +249,10 @@ func (*extAuth) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { if irRoute == nil { return errors.New("ir route is nil") } - if irRoute.ExtAuth == nil { + if irRoute.Security == nil || irRoute.Security.ExtAuth == nil { return nil } - filterName := extAuthFilterName(irRoute.ExtAuth) + filterName := extAuthFilterName(irRoute.Security.ExtAuth) if err := enableFilterOnRoute(route, filterName); err != nil { return err } diff --git a/internal/xds/translator/jwt.go b/internal/xds/translator/jwt.go index 72e8029f1c4..beb0bebcca4 100644 --- a/internal/xds/translator/jwt.go +++ b/internal/xds/translator/jwt.go @@ -106,8 +106,8 @@ func buildJWTAuthn(irListener *ir.HTTPListener) (*jwtauthnv3.JwtAuthentication, } var reqs []*jwtauthnv3.JwtRequirement - for i := range route.JWT.Providers { - irProvider := route.JWT.Providers[i] + for i := range route.Security.JWT.Providers { + irProvider := route.Security.JWT.Providers[i] // Create the cluster for the remote jwks, if it doesn't exist. jwksCluster, err := url2Cluster(irProvider.RemoteJWKS.URI) if err != nil { @@ -261,7 +261,7 @@ func (*jwt) patchResources(tCtx *types.ResourceVersionTable, routes []*ir.HTTPRo continue } - for i := range route.JWT.Providers { + for i := range route.Security.JWT.Providers { var ( jwks *urlCluster ds *ir.DestinationSetting @@ -269,7 +269,7 @@ func (*jwt) patchResources(tCtx *types.ResourceVersionTable, routes []*ir.HTTPRo err error ) - provider := route.JWT.Providers[i] + provider := route.Security.JWT.Providers[i] jwks, err = url2Cluster(provider.RemoteJWKS.URI) if err != nil { errs = errors.Join(errs, err) @@ -324,9 +324,10 @@ func listenerContainsJWTAuthn(irListener *ir.HTTPListener) bool { // provided route. func routeContainsJWTAuthn(irRoute *ir.HTTPRoute) bool { if irRoute != nil && - irRoute.JWT != nil && - irRoute.JWT.Providers != nil && - len(irRoute.JWT.Providers) > 0 { + irRoute.Security != nil && + irRoute.Security.JWT != nil && + irRoute.Security.JWT.Providers != nil && + len(irRoute.Security.JWT.Providers) > 0 { return true } return false diff --git a/internal/xds/translator/oidc.go b/internal/xds/translator/oidc.go index 5b14a00f871..f7202a7f407 100644 --- a/internal/xds/translator/oidc.go +++ b/internal/xds/translator/oidc.go @@ -59,11 +59,11 @@ func (*oidc) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListe // 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)) { + if hcmContainsFilter(mgr, oauth2FilterName(route.Security.OIDC)) { continue } - filter, err := buildHCMOAuth2Filter(route.OIDC) + filter, err := buildHCMOAuth2Filter(route.Security.OIDC) if err != nil { errs = errors.Join(errs, err) continue @@ -178,7 +178,9 @@ func oauth2Config(oidc *ir.OIDC) (*oauth2v3.OAuth2, error) { // routeContainsOIDC returns true if OIDC exists for the provided route. func routeContainsOIDC(irRoute *ir.HTTPRoute) bool { - if irRoute != nil && irRoute.OIDC != nil { + if irRoute != nil && + irRoute.Security != nil && + irRoute.Security.OIDC != nil { return true } return false @@ -216,7 +218,7 @@ func createOAuth2TokenEndpointClusters(tCtx *types.ResourceVersionTable, err error ) - cluster, err = url2Cluster(route.OIDC.Provider.TokenEndpoint) + cluster, err = url2Cluster(route.Security.OIDC.Provider.TokenEndpoint) if err != nil { errs = errors.Join(errs, err) continue @@ -228,7 +230,7 @@ func createOAuth2TokenEndpointClusters(tCtx *types.ResourceVersionTable, if cluster.endpointType == EndpointTypeStatic { errs = errors.Join(errs, fmt.Errorf( "static IP cluster is not allowed: %s", - route.OIDC.Provider.TokenEndpoint)) + route.Security.OIDC.Provider.TokenEndpoint)) continue } @@ -275,12 +277,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.OIDC) + clientSecret := buildOAuth2ClientSecret(route.Security.OIDC) if err := addXdsSecret(tCtx, clientSecret); err != nil { errs = errors.Join(errs, err) } - if err := addXdsSecret(tCtx, buildOAuth2HMACSecret(route.OIDC)); err != nil { + if err := addXdsSecret(tCtx, buildOAuth2HMACSecret(route.Security.OIDC)); err != nil { errs = errors.Join(errs, err) } } @@ -339,10 +341,10 @@ func (*oidc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { if irRoute == nil { return errors.New("ir route is nil") } - if irRoute.OIDC == nil { + if irRoute.Security == nil || irRoute.Security.OIDC == nil { return nil } - filterName := oauth2FilterName(irRoute.OIDC) + filterName := oauth2FilterName(irRoute.Security.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 36df412f728..48bbbebadc2 100644 --- a/internal/xds/translator/testdata/in/xds-ir/basic-auth.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/basic-auth.yaml @@ -28,9 +28,10 @@ http: port: 8080 protocol: HTTP weight: 1 - basicAuth: - name: securitypolicy/default/policy-for-http-route-1 - users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= + security: + 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 @@ -50,9 +51,10 @@ http: port: 8080 protocol: HTTP weight: 1 - basicAuth: - name: securitypolicy/default/policy-for-http-route-1 - users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= + security: + 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 @@ -72,6 +74,7 @@ http: port: 8080 protocol: HTTP weight: 1 - basicAuth: - name: securitypolicy/default/policy-for-gateway-1 - users: Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo= + security: + basicAuth: + name: securitypolicy/default/policy-for-gateway-1 + users: Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo= diff --git a/internal/xds/translator/testdata/in/xds-ir/cors.yaml b/internal/xds/translator/testdata/in/xds-ir/cors.yaml index c5a07bee840..dd9eff3418f 100644 --- a/internal/xds/translator/testdata/in/xds-ir/cors.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/cors.yaml @@ -18,22 +18,23 @@ http: - endpoints: - host: "1.2.3.4" port: 50000 - cors: - allowOrigins: - - name: example.com - stringMatch: - safeRegex: "*.example.com" - - name: foo.bar.com - stringMatch: - exact: foo.bar.com - allowMethods: - - GET - - POST - allowHeaders: - - "x-header-1" - - "x-header-2" - exposeHeaders: - - "x-header-3" - - "x-header-4" - allowCredentials: true - maxAge: 1000s + security: + cors: + allowOrigins: + - name: example.com + stringMatch: + safeRegex: "*.example.com" + - name: foo.bar.com + stringMatch: + exact: foo.bar.com + allowMethods: + - GET + - POST + allowHeaders: + - "x-header-1" + - "x-header-2" + exposeHeaders: + - "x-header-3" + - "x-header-4" + allowCredentials: true + maxAge: 1000s 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 32d5522e6df..bedbbae996c 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml @@ -28,23 +28,24 @@ http: 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 + security: + 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 @@ -64,23 +65,24 @@ http: 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 + security: + 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 @@ -100,21 +102,22 @@ http: 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 + security: + 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/jwt-custom-extractor.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-custom-extractor.yaml index 2a362a469dc..8d24373fd6a 100644 --- a/internal/xds/translator/testdata/in/xds-ir/jwt-custom-extractor.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/jwt-custom-extractor.yaml @@ -12,22 +12,23 @@ http: hostname: "*" pathMatch: exact: "foo/bar" - jwt: - providers: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJWKS: - uri: https://localhost/jwt/public-key/jwks.json - extractFrom: - cookies: - - session_access_token - headers: - - name: Authorization - valuePrefix: 'Bearer ' - params: - - token + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: https://localhost/jwt/public-key/jwks.json + extractFrom: + cookies: + - session_access_token + headers: + - name: Authorization + valuePrefix: 'Bearer ' + params: + - token destination: name: "first-route-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-multi-provider.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-multi-provider.yaml index 558049ed562..88f88f5aa35 100644 --- a/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-multi-provider.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-multi-provider.yaml @@ -12,30 +12,31 @@ http: hostname: "*" pathMatch: exact: "foo/bar" - jwt: - providers: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJWKS: - uri: http://localhost/jwt/public-key/jwks.json - claimToHeaders: - - header: one-route-example-key1 - claim: claim.neteased.key - - name: example2 - issuer: https://www.two.example.com - audiences: - - one.foo.com - - two.foo.com - remoteJWKS: - uri: https://192.168.1.250:8080/jwt/public-key/jwks.json - recomputeRoute: true - claimToHeaders: - - header: one-route-example2-key1 - claim: claim.neteased.key - - header: one-route-example2-key2 - claim: name + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: http://localhost/jwt/public-key/jwks.json + claimToHeaders: + - header: one-route-example-key1 + claim: claim.neteased.key + - name: example2 + issuer: https://www.two.example.com + audiences: + - one.foo.com + - two.foo.com + remoteJWKS: + uri: https://192.168.1.250:8080/jwt/public-key/jwks.json + recomputeRoute: true + claimToHeaders: + - header: one-route-example2-key1 + claim: claim.neteased.key + - header: one-route-example2-key2 + claim: name destination: name: "first-route-www.test.com-dest" settings: @@ -46,24 +47,25 @@ http: hostname: "*" pathMatch: exact: "foo/baz" - jwt: - providers: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJWKS: - uri: http://localhost/jwt/public-key/jwks.json - claimToHeaders: - - header: second-route-example-key1 - claim: claim.neteased.key - - name: example2 - issuer: https://www.two.example.com - audiences: - - one.foo.com - - two.foo.com - remoteJWKS: - uri: https://192.168.1.250:8080/jwt/public-key/jwks.json + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: http://localhost/jwt/public-key/jwks.json + claimToHeaders: + - header: second-route-example-key1 + claim: claim.neteased.key + - name: example2 + issuer: https://www.two.example.com + audiences: + - one.foo.com + - two.foo.com + remoteJWKS: + uri: https://192.168.1.250:8080/jwt/public-key/jwks.json destination: name: "second-route-www.test.com-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-single-provider.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-single-provider.yaml index 7dd2a4b73c2..324f54d9311 100644 --- a/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-single-provider.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-single-provider.yaml @@ -15,17 +15,18 @@ http: hostname: "*" pathMatch: exact: "foo/bar" - jwt: - providers: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJWKS: - uri: https://localhost/jwt/public-key/jwks.json - claimToHeaders: - - header: first-route-key - claim: claim.neteased.key + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: https://localhost/jwt/public-key/jwks.json + claimToHeaders: + - header: first-route-key + claim: claim.neteased.key destination: name: "first-route-dest" settings: @@ -36,14 +37,15 @@ http: hostname: "*" pathMatch: exact: "foo/baz" - jwt: - providers: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJWKS: - uri: https://localhost/jwt/public-key/jwks.json + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: https://localhost/jwt/public-key/jwks.json destination: name: "second-route-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml index 9857cb58da2..a4682250ad4 100644 --- a/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml @@ -27,14 +27,15 @@ http: - endpoints: - host: "1.2.3.4" port: 50000 - jwt: - providers: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJWKS: - uri: https://192.168.1.250/jwt/public-key/jwks.json + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: https://192.168.1.250/jwt/public-key/jwks.json - name: "second-route" hostname: "*" rateLimit: diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-single-route-single-match.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-single-route-single-match.yaml index 4ff905bdc5d..a5b72e0ff53 100644 --- a/internal/xds/translator/testdata/in/xds-ir/jwt-single-route-single-match.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/jwt-single-route-single-match.yaml @@ -12,14 +12,15 @@ http: hostname: "*" pathMatch: exact: "foo/bar" - jwt: - providers: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJWKS: - uri: https://localhost/jwt/public-key/jwks.json + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: https://localhost/jwt/public-key/jwks.json destination: name: "first-route-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port-with-different-filters.yaml b/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port-with-different-filters.yaml index bec261bee5b..07075307b1b 100644 --- a/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port-with-different-filters.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port-with-different-filters.yaml @@ -33,9 +33,10 @@ http: port: 8080 protocol: HTTP weight: 1 - basicAuth: - name: securitypolicy/default/policy-for-http-route-1 - users: "dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo=" + security: + basicAuth: + name: securitypolicy/default/policy-for-http-route-1 + users: "dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo=" - name: httproute/default/httproute-2/rule/0/match/0/www_foo_com hostname: www.foo.com isHTTP2: false @@ -55,24 +56,25 @@ http: port: 8080 protocol: HTTP weight: 1 - extAuth: - name: securitypolicy/default/policy-for-http-route-2 - failOpen: true - http: - authority: http-backend.envoy-gateway:80 - destination: - name: securitypolicy/default/policy-for-http-route-2/envoy-gateway/http-backend - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 80 - protocol: HTTP - weight: 1 - headersToBackend: - - header1 - - header2 - path: /auth + security: + extAuth: + name: securitypolicy/default/policy-for-http-route-2 + failOpen: true + http: + authority: http-backend.envoy-gateway:80 + destination: + name: securitypolicy/default/policy-for-http-route-2/envoy-gateway/http-backend + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 80 + protocol: HTTP + weight: 1 + headersToBackend: + - header1 + - header2 + path: /auth - name: default/gateway-2/http address: 0.0.0.0 hostnames: @@ -102,18 +104,19 @@ http: port: 8080 protocol: HTTP weight: 1 - oidc: - name: securitypolicy/default/policy-for-gateway-2 - clientID: client.oauth.foo.com - clientSecret: Y2xpZW50MTpzZWNyZXQK - provider: - authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth - tokenEndpoint: https://oauth.foo.com/token - scopes: - - openid - - email - - profile - redirectURL: "https://www.example.com/foo/oauth2/callback" - redirectPath: "/foo/oauth2/callback" - logoutPath: "/foo/logout" - cookieSuffix: 5F93C2E4 + security: + oidc: + name: securitypolicy/default/policy-for-gateway-2 + clientID: client.oauth.foo.com + clientSecret: Y2xpZW50MTpzZWNyZXQK + provider: + authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth + tokenEndpoint: https://oauth.foo.com/token + scopes: + - openid + - email + - profile + redirectURL: "https://www.example.com/foo/oauth2/callback" + redirectPath: "/foo/oauth2/callback" + logoutPath: "/foo/logout" + cookieSuffix: 5F93C2E4 diff --git a/internal/xds/translator/testdata/in/xds-ir/oidc.yaml b/internal/xds/translator/testdata/in/xds-ir/oidc.yaml index e2ef1ca7a0f..b2e395f8320 100644 --- a/internal/xds/translator/testdata/in/xds-ir/oidc.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/oidc.yaml @@ -18,24 +18,25 @@ http: - endpoints: - host: "1.2.3.4" port: 50000 - oidc: - name: securitypolicy/default/policy-for-first-route - clientID: client.oauth.foo.com - clientSecret: Y2xpZW50MTpzZWNyZXQK - hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= - provider: - authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth - tokenEndpoint: https://oauth.foo.com/token - scopes: - - openid - - email - - profile - resources: - - api - redirectURL: "https://www.example.com/foo/oauth2/callback" - redirectPath: "/foo/oauth2/callback" - logoutPath: "/foo/logout" - cookieSuffix: 5F93C2E4 + security: + oidc: + name: securitypolicy/default/policy-for-first-route + clientID: client.oauth.foo.com + clientSecret: Y2xpZW50MTpzZWNyZXQK + hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= + provider: + authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth + tokenEndpoint: https://oauth.foo.com/token + scopes: + - openid + - email + - profile + resources: + - api + redirectURL: "https://www.example.com/foo/oauth2/callback" + redirectPath: "/foo/oauth2/callback" + logoutPath: "/foo/logout" + cookieSuffix: 5F93C2E4 - name: "second-route" hostname: "*" pathMatch: @@ -46,21 +47,22 @@ http: - endpoints: - host: "1.2.3.4" port: 50000 - oidc: - name: securitypolicy/default/policy-for-second-route - clientID: client.oauth.bar.com - clientSecret: Y2xpZW50MTpzZWNyZXQK - hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= - provider: - authorizationEndpoint: https://oauth.bar.com/oauth2/v2/auth - tokenEndpoint: https://oauth.bar.com/token - scopes: - - openid - - email - - profile - resources: - - api - redirectURL: "https://www.example.com/bar/oauth2/callback" - redirectPath: "/bar/oauth2/callback" - logoutPath: "/bar/logout" - cookieSuffix: 5f93c2e4 + security: + oidc: + name: securitypolicy/default/policy-for-second-route + clientID: client.oauth.bar.com + clientSecret: Y2xpZW50MTpzZWNyZXQK + hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= + provider: + authorizationEndpoint: https://oauth.bar.com/oauth2/v2/auth + tokenEndpoint: https://oauth.bar.com/token + scopes: + - openid + - email + - profile + resources: + - api + redirectURL: "https://www.example.com/bar/oauth2/callback" + redirectPath: "/bar/oauth2/callback" + logoutPath: "/bar/logout" + cookieSuffix: 5f93c2e4