Merge branch 'v3.0' of github.com:traefik/traefik

Signed-off-by: baalajimaestro <me@baalajimaestro.me>
This commit is contained in:
baalajimaestro 2024-01-10 10:54:52 +05:30
commit 8cb5e0ac30
Signed by: baalajimaestro
GPG key ID: F93C394FE9BBAFD5
298 changed files with 18920 additions and 8669 deletions

View file

@ -1,3 +1,31 @@
## [v2.11.0-rc1](https://github.com/traefik/traefik/tree/v2.11.0-rc1) (2024-01-02)
[All Commits](https://github.com/traefik/traefik/compare/0a7964300166d167f68d5502bc245b3b9c8842b4...v2.11.0-rc1)
**Enhancements:**
- **[middleware]** Deprecate IPWhiteList middleware in favor of IPAllowList ([#10249](https://github.com/traefik/traefik/pull/10249) by [lbenguigui](https://github.com/lbenguigui))
- **[redis]** Add Redis Sentinel support ([#10245](https://github.com/traefik/traefik/pull/10245) by [youkoulayley](https://github.com/youkoulayley))
- **[server]** Add KeepAliveMaxTime and KeepAliveMaxRequests features to entrypoints ([#10247](https://github.com/traefik/traefik/pull/10247) by [juliens](https://github.com/juliens))
- **[sticky-session]** Hash WRR sticky cookies ([#10243](https://github.com/traefik/traefik/pull/10243) by [youkoulayley](https://github.com/youkoulayley))
**Bug fixes:**
- **[file]** Update github.com/fsnotify/fsnotify to v1.7.0 ([#10313](https://github.com/traefik/traefik/pull/10313) by [ldez](https://github.com/ldez))
- **[http3]** Update quic-go to v0.40.1 ([#10296](https://github.com/traefik/traefik/pull/10296) by [ldez](https://github.com/ldez))
- **[server]** Fix ReadHeaderTimeout for PROXY protocol ([#10320](https://github.com/traefik/traefik/pull/10320) by [juliens](https://github.com/juliens))
**Documentation:**
- **[acme]** Fix TLS challenge explanation ([#10293](https://github.com/traefik/traefik/pull/10293) by [cavokz](https://github.com/cavokz))
- **[docker,acme]** Fix typo ([#10294](https://github.com/traefik/traefik/pull/10294) by [youpsla](https://github.com/youpsla))
- **[docker]** Update wording of compose example ([#10276](https://github.com/traefik/traefik/pull/10276) by [svx](https://github.com/svx))
- **[k8s/crd]** Adjust deprecation notice for Kubernetes CRD provider ([#10317](https://github.com/traefik/traefik/pull/10317) by [rtribotte](https://github.com/rtribotte))
- Fix description for anonymous usage statistics references ([#10287](https://github.com/traefik/traefik/pull/10287) by [ariyonaty](https://github.com/ariyonaty))
- Documentation enhancements ([#10261](https://github.com/traefik/traefik/pull/10261) by [svx](https://github.com/svx))
## [v2.10.7](https://github.com/traefik/traefik/tree/v2.10.7) (2023-12-06)
[All Commits](https://github.com/traefik/traefik/compare/v2.10.6...v2.10.7)
**Bug fixes:**
- **[logs]** Fixed datadog logs json format issue ([#10233](https://github.com/traefik/traefik/pull/10233) by [sssash18](https://github.com/sssash18))
## [v3.0.0-beta5](https://github.com/traefik/traefik/tree/v3.0.0-beta5) (2023-11-29) ## [v3.0.0-beta5](https://github.com/traefik/traefik/tree/v3.0.0-beta5) (2023-11-29)
[All Commits](https://github.com/traefik/traefik/compare/v3.0.0-beta4...v3.0.0-beta5) [All Commits](https://github.com/traefik/traefik/compare/v3.0.0-beta4...v3.0.0-beta5)

View file

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Copyright (c) 2016-2020 Containous SAS; 2020-2024 Traefik Labs
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -5,6 +5,7 @@ import (
"crypto/x509" "crypto/x509"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
stdlog "log" stdlog "log"
"net/http" "net/http"
"os" "os"
@ -43,9 +44,9 @@ import (
"github.com/traefik/traefik/v3/pkg/tcp" "github.com/traefik/traefik/v3/pkg/tcp"
traefiktls "github.com/traefik/traefik/v3/pkg/tls" traefiktls "github.com/traefik/traefik/v3/pkg/tls"
"github.com/traefik/traefik/v3/pkg/tracing" "github.com/traefik/traefik/v3/pkg/tracing"
"github.com/traefik/traefik/v3/pkg/tracing/jaeger"
"github.com/traefik/traefik/v3/pkg/types" "github.com/traefik/traefik/v3/pkg/types"
"github.com/traefik/traefik/v3/pkg/version" "github.com/traefik/traefik/v3/pkg/version"
"go.opentelemetry.io/otel/trace"
) )
func main() { func main() {
@ -265,10 +266,9 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
managerFactory := service.NewManagerFactory(*staticConfiguration, routinesPool, metricsRegistry, roundTripperManager, acmeHTTPHandler) managerFactory := service.NewManagerFactory(*staticConfiguration, routinesPool, metricsRegistry, roundTripperManager, acmeHTTPHandler)
// Router factory // Router factory
accessLog := setupAccessLog(staticConfiguration.AccessLog) accessLog := setupAccessLog(staticConfiguration.AccessLog)
tracer := setupTracing(staticConfiguration.Tracing)
tracer, tracerCloser := setupTracing(staticConfiguration.Tracing)
chainBuilder := middleware.NewChainBuilder(metricsRegistry, accessLog, tracer) chainBuilder := middleware.NewChainBuilder(metricsRegistry, accessLog, tracer)
routerFactory := server.NewRouterFactory(*staticConfiguration, managerFactory, tlsManager, chainBuilder, pluginBuilder, metricsRegistry, dialerManager) routerFactory := server.NewRouterFactory(*staticConfiguration, managerFactory, tlsManager, chainBuilder, pluginBuilder, metricsRegistry, dialerManager)
@ -351,7 +351,7 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
} }
}) })
return server.NewServer(routinesPool, serverEntryPointsTCP, serverEntryPointsUDP, watcher, chainBuilder, accessLog), nil return server.NewServer(routinesPool, serverEntryPointsTCP, serverEntryPointsUDP, watcher, chainBuilder, accessLog, tracerCloser), nil
} }
func getHTTPChallengeHandler(acmeProviders []*acme.Provider, httpChallengeProvider http.Handler) http.Handler { func getHTTPChallengeHandler(acmeProviders []*acme.Provider, httpChallengeProvider http.Handler) http.Handler {
@ -564,78 +564,18 @@ func setupAccessLog(conf *types.AccessLog) *accesslog.Handler {
return accessLoggerMiddleware return accessLoggerMiddleware
} }
func setupTracing(conf *static.Tracing) *tracing.Tracing { func setupTracing(conf *static.Tracing) (trace.Tracer, io.Closer) {
if conf == nil { if conf == nil {
return nil return nil, nil
} }
var backend tracing.Backend tracer, closer, err := tracing.NewTracing(conf)
if conf.Jaeger != nil {
backend = conf.Jaeger
}
if conf.Zipkin != nil {
if backend != nil {
log.Error().Msg("Multiple tracing backend are not supported: cannot create Zipkin backend.")
} else {
backend = conf.Zipkin
}
}
if conf.Datadog != nil {
if backend != nil {
log.Error().Msg("Multiple tracing backend are not supported: cannot create Datadog backend.")
} else {
backend = conf.Datadog
}
}
if conf.Instana != nil {
if backend != nil {
log.Error().Msg("Multiple tracing backend are not supported: cannot create Instana backend.")
} else {
backend = conf.Instana
}
}
if conf.Haystack != nil {
if backend != nil {
log.Error().Msg("Multiple tracing backend are not supported: cannot create Haystack backend.")
} else {
backend = conf.Haystack
}
}
if conf.Elastic != nil {
if backend != nil {
log.Error().Msg("Multiple tracing backend are not supported: cannot create Elastic backend.")
} else {
backend = conf.Elastic
}
}
if conf.OpenTelemetry != nil {
if backend != nil {
log.Error().Msg("Tracing backends are all mutually exclusive: cannot create OpenTelemetry backend.")
} else {
backend = conf.OpenTelemetry
}
}
if backend == nil {
log.Debug().Msg("Could not initialize tracing, using Jaeger by default")
defaultBackend := &jaeger.Config{}
defaultBackend.SetDefaults()
backend = defaultBackend
}
tracer, err := tracing.NewTracing(conf.ServiceName, conf.SpanNameLimit, backend)
if err != nil { if err != nil {
log.Warn().Err(err).Msg("Unable to create tracer") log.Warn().Err(err).Msg("Unable to create tracer")
return nil return nil, nil
} }
return tracer
return tracer, closer
} }
func checkNewVersion() { func checkNewVersion() {

View file

@ -4,20 +4,23 @@ This page is maintained and updated periodically to reflect our roadmap and any
| Feature | Deprecated | End of Support | Removal | | Feature | Deprecated | End of Support | Removal |
|----------------------------------------------------------------------------------------------------------------------|------------|----------------|---------| |----------------------------------------------------------------------------------------------------------------------|------------|----------------|---------|
| [Kubernetes CRDs API Version `traefik.io/v1alpha1`](#kubernetes-crds-api-version-traefikiov1alpha1) | N/A | N/A | 3.0 | | [Kubernetes CRD Provider API Version `traefik.io/v1alpha1`](#kubernetes-crd-provider-api-version-traefikiov1alpha1) | 3.0 | N/A | 4.0 |
| [Kubernetes Ingress API Version `networking.k8s.io/v1beta1`](#kubernetes-ingress-api-version-networkingk8siov1beta1) | N/A | N/A | 3.0 | | [Kubernetes Ingress API Version `networking.k8s.io/v1beta1`](#kubernetes-ingress-api-version-networkingk8siov1beta1) | N/A | N/A | 3.0 |
| [CRD API Version `apiextensions.k8s.io/v1beta1`](#kubernetes-ingress-api-version-networkingk8siov1beta1) | N/A | N/A | 3.0 | | [CRD API Version `apiextensions.k8s.io/v1beta1`](#kubernetes-ingress-api-version-networkingk8siov1beta1) | N/A | N/A | 3.0 |
## Impact ## Impact
### Kubernetes CRDs API Version `traefik.io/v1alpha1` ### Kubernetes CRD Provider API Version `traefik.io/v1alpha1`
The newly introduced Kubernetes CRD API Version `traefik.io/v1alpha1` will subsequently be removed in Traefik v3. The following version will be `traefik.io/v1`. The Kubernetes CRD provider API Version `traefik.io/v1alpha1` is deprecated in Traefik v3.
Please use the API Group `traefik.io/v1` instead.
### Kubernetes Ingress API Version `networking.k8s.io/v1beta1` ### Kubernetes Ingress API Version `networking.k8s.io/v1beta1`
The Kubernetes Ingress API Version `networking.k8s.io/v1beta1` is removed in v3. Please use the API Group `networking.k8s.io/v1` instead. The Kubernetes Ingress API Version `networking.k8s.io/v1beta1` support is removed in v3.
Please use the API Group `networking.k8s.io/v1` instead.
### Traefik CRD API Version `apiextensions.k8s.io/v1beta1` ### Traefik CRD Definitions API Version `apiextensions.k8s.io/v1beta1`
The Traefik CRD API Version `apiextensions.k8s.io/v1beta1` is removed in v3. Please use the API Group `apiextensions.k8s.io/v1` instead. The Traefik CRD definitions API Version `apiextensions.k8s.io/v1beta1` support is removed in v3.
Please use the API Group `apiextensions.k8s.io/v1` instead.

View file

@ -82,11 +82,11 @@ docker run traefik[:version] --help
# ex: docker run traefik:v3.0 --help # ex: docker run traefik:v3.0 --help
``` ```
All available arguments can also be found [here](../reference/static-configuration/cli.md). Check the [CLI reference](../reference/static-configuration/cli.md "Link to CLI reference overview") for an overview about all available arguments.
### Environment Variables ### Environment Variables
All available environment variables can be found [here](../reference/static-configuration/env.md) All available environment variables can be found in the [static configuration environment overview](../reference/static-configuration/env.md).
## Available Configuration Options ## Available Configuration Options

View file

@ -29,7 +29,7 @@ Not to mention that dynamic configuration changes potentially make that kind of
Therefore, in this dynamic context, Therefore, in this dynamic context,
the static configuration of an `entryPoint` does not give any hint whatsoever about how the traffic going through that `entryPoint` is going to be routed. the static configuration of an `entryPoint` does not give any hint whatsoever about how the traffic going through that `entryPoint` is going to be routed.
Or whether it's even going to be routed at all, Or whether it's even going to be routed at all,
i.e. whether there is a Router matching the kind of traffic going through it. that is whether there is a Router matching the kind of traffic going through it.
### `404 Not found` ### `404 Not found`
@ -71,7 +71,7 @@ Traefik returns a `502` response code when an error happens while contacting the
### `503 Service Unavailable` ### `503 Service Unavailable`
Traefik returns a `503` response code when a Router has been matched Traefik returns a `503` response code when a Router has been matched,
but there are no servers ready to handle the request. but there are no servers ready to handle the request.
This situation is encountered when a service has been explicitly configured without servers, This situation is encountered when a service has been explicitly configured without servers,
@ -84,7 +84,7 @@ Sometimes, the `404` response code doesn't play well with other parties or servi
In these situations, you may want Traefik to always reply with a `503` response code, In these situations, you may want Traefik to always reply with a `503` response code,
instead of a `404` response code. instead of a `404` response code.
To achieve this behavior, a simple catchall router, To achieve this behavior, a catchall router,
with the lowest possible priority and routing to a service without servers, with the lowest possible priority and routing to a service without servers,
can handle all the requests when no other router has been matched. can handle all the requests when no other router has been matched.
@ -216,7 +216,7 @@ error: field not found, node: -badField-
The "field not found" error occurs, when an unknown property is encountered in the dynamic or static configuration. The "field not found" error occurs, when an unknown property is encountered in the dynamic or static configuration.
One easy way to check whether a configuration file is well-formed, is to validate it with: One way to check whether a configuration file is well-formed, is to validate it with:
- [JSON Schema of the static configuration](https://json.schemastore.org/traefik-v2.json) - [JSON Schema of the static configuration](https://json.schemastore.org/traefik-v2.json)
- [JSON Schema of the dynamic configuration](https://json.schemastore.org/traefik-v2-file-provider.json) - [JSON Schema of the dynamic configuration](https://json.schemastore.org/traefik-v2-file-provider.json)
@ -226,11 +226,11 @@ One easy way to check whether a configuration file is well-formed, is to validat
As a common tip, if a resource is dropped/not created by Traefik after the dynamic configuration was evaluated, As a common tip, if a resource is dropped/not created by Traefik after the dynamic configuration was evaluated,
one should look for an error in the logs. one should look for an error in the logs.
If found, the error obviously confirms that something went wrong while creating the resource, If found, the error confirms that something went wrong while creating the resource,
and the message should help in figuring out the mistake(s) in the configuration, and how to fix it. and the message should help in figuring out the mistake(s) in the configuration, and how to fix it.
When using the file provider, When using the file provider,
one easy way to check if the dynamic configuration is well-formed is to validate it with the [JSON Schema of the dynamic configuration](https://json.schemastore.org/traefik-v2-file-provider.json). one way to check if the dynamic configuration is well-formed is to validate it with the [JSON Schema of the dynamic configuration](https://json.schemastore.org/traefik-v2-file-provider.json).
## Why does Let's Encrypt wildcard certificate renewal/generation with DNS challenge fail? ## Why does Let's Encrypt wildcard certificate renewal/generation with DNS challenge fail?
@ -248,6 +248,6 @@ then it could be due to `CNAME` support.
In which case, you should make sure your infrastructure is properly set up for a In which case, you should make sure your infrastructure is properly set up for a
`DNS` challenge that does not rely on `CNAME`, and you should try disabling `CNAME` support with: `DNS` challenge that does not rely on `CNAME`, and you should try disabling `CNAME` support with:
```bash ```shell
LEGO_DISABLE_CNAME_SUPPORT=true LEGO_DISABLE_CNAME_SUPPORT=true
``` ```

View file

@ -19,7 +19,7 @@ Choose one of the [official Docker images](https://hub.docker.com/_/traefik) and
* [YAML](https://raw.githubusercontent.com/traefik/traefik/v3.0/traefik.sample.yml) * [YAML](https://raw.githubusercontent.com/traefik/traefik/v3.0/traefik.sample.yml)
* [TOML](https://raw.githubusercontent.com/traefik/traefik/v3.0/traefik.sample.toml) * [TOML](https://raw.githubusercontent.com/traefik/traefik/v3.0/traefik.sample.toml)
```bash ```shell
docker run -d -p 8080:8080 -p 80:80 \ docker run -d -p 8080:8080 -p 80:80 \
-v $PWD/traefik.yml:/etc/traefik/traefik.yml traefik:v3.0 -v $PWD/traefik.yml:/etc/traefik/traefik.yml traefik:v3.0
``` ```
@ -59,7 +59,7 @@ You can update the chart repository by running:
helm repo update helm repo update
``` ```
And install it with the `helm` command line: And install it with the Helm command line:
```bash ```bash
helm install traefik traefik/traefik helm install traefik traefik/traefik
@ -106,7 +106,7 @@ helm install traefik traefik/traefik
### Exposing the Traefik dashboard ### Exposing the Traefik dashboard
This HelmChart does not expose the Traefik dashboard by default, for security concerns. This Helm chart does not expose the Traefik dashboard by default, for security concerns.
Thus, there are multiple ways to expose the dashboard. Thus, there are multiple ways to expose the dashboard.
For instance, the dashboard access could be achieved through a port-forward: For instance, the dashboard access could be achieved through a port-forward:

View file

@ -1,11 +1,11 @@
--- ---
title: "Traefik Getting Started With Kubernetes" title: "Traefik Getting Started With Kubernetes"
description: "Looking to get started with Traefik Proxy? Read the technical documentation to learn a simple use case that leverages Kubernetes." description: "Get started with Traefik Proxy and Kubernetes."
--- ---
# Quick Start # Quick Start
A Simple Use Case of Traefik Proxy and Kubernetes A Use Case of Traefik Proxy and Kubernetes
{: .subtitle } {: .subtitle }
This guide is an introduction to using Traefik Proxy in a Kubernetes environment. This guide is an introduction to using Traefik Proxy in a Kubernetes environment.
@ -16,7 +16,7 @@ It presents and explains the basic blocks required to start with Traefik such as
Traefik uses the Kubernetes API to discover running services. Traefik uses the Kubernetes API to discover running services.
In order to use the Kubernetes API, Traefik needs some permissions. To use the Kubernetes API, Traefik needs some permissions.
This [permission mechanism](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) is based on roles defined by the cluster administrator. This [permission mechanism](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) is based on roles defined by the cluster administrator.
The role is then bound to an account used by an application, in this case, Traefik Proxy. The role is then bound to an account used by an application, in this case, Traefik Proxy.
@ -88,7 +88,7 @@ roleRef:
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: traefik-account name: traefik-account
namespace: default # Using "default" because we did not specify a namespace when creating the ClusterAccount. namespace: default # This tutorial uses the "default" K8s namespace.
``` ```
!!! info "`roleRef` is the Kubernetes reference to the role created in `00-role.yml`." !!! info "`roleRef` is the Kubernetes reference to the role created in `00-role.yml`."
@ -146,7 +146,7 @@ These arguments are the static configuration for Traefik.
From here, it is possible to enable the dashboard, From here, it is possible to enable the dashboard,
configure entry points, configure entry points,
select dynamic configuration providers, select dynamic configuration providers,
and [more](../reference/static-configuration/cli.md)... and [more](../reference/static-configuration/cli.md).
In this deployment, In this deployment,
the static configuration enables the Traefik dashboard, the static configuration enables the Traefik dashboard,
@ -214,7 +214,7 @@ The only part still missing is the business application behind the reverse proxy
For this guide, we use the example application [traefik/whoami](https://github.com/traefik/whoami), For this guide, we use the example application [traefik/whoami](https://github.com/traefik/whoami),
but the principles are applicable to any other application. but the principles are applicable to any other application.
The `whoami` application is a simple HTTP server running on port 80 which answers host-related information to the incoming requests. The `whoami` application is an HTTP server running on port 80 which answers host-related information to the incoming requests.
As usual, start by creating a file called `03-whoami.yml` and paste the following `Deployment` resource: As usual, start by creating a file called `03-whoami.yml` and paste the following `Deployment` resource:
```yaml tab="03-whoami.yml" ```yaml tab="03-whoami.yml"

View file

@ -1,11 +1,11 @@
--- ---
title: "Traefik Getting Started Quickly" title: "Traefik Getting Started Quickly"
description: "Looking to get started with Traefik Proxy quickly? Read the technical documentation to see a basic use case that leverages Docker." description: "Get started with Traefik Proxy and Docker."
--- ---
# Quick Start # Quick Start
A Basic Use Case Using Docker A Use Case Using Docker
{: .subtitle } {: .subtitle }
![quickstart-diagram](../assets/img/quickstart-diagram.png) ![quickstart-diagram](../assets/img/quickstart-diagram.png)
@ -19,9 +19,9 @@ version: '3'
services: services:
reverse-proxy: reverse-proxy:
# The official v3 Traefik Docker image # The official v2 Traefik docker image
image: traefik:v3.0 image: traefik:v3.0
# Enables the web UI and tells Traefik to listen to Docker # Enables the web UI and tells Traefik to listen to docker
command: --api.insecure=true --providers.docker command: --api.insecure=true --providers.docker
ports: ports:
# The HTTP port # The HTTP port
@ -41,11 +41,11 @@ Start your `reverse-proxy` with the following command:
docker-compose up -d reverse-proxy docker-compose up -d reverse-proxy
``` ```
You can open a browser and go to `http://localhost:8080/api/rawdata` to see Traefik's API rawdata (we'll go back there once we have launched a service in step 2). You can open a browser and go to `http://localhost:8080/api/rawdata` to see Traefik's API rawdata (you'll go back there once you have launched a service in step 2).
## Traefik Detects New Services and Creates the Route for You ## Traefik Detects New Services and Creates the Route for You
Now that we have a Traefik instance up and running, we will deploy new services. Now that you have a Traefik instance up and running, you will deploy new services.
Edit your `docker-compose.yml` file and add the following at the end of your file. Edit your `docker-compose.yml` file and add the following at the end of your file.
@ -63,7 +63,7 @@ services:
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)" - "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
``` ```
The above defines [`whoami`](https://github.com/traefik/whoami "Link to whoami app on GitHub"), a web service that outputs information about the machine it is deployed on (its IP address, host, etc.). The above defines `whoami`: a web service that outputs information about the machine it is deployed on (its IP address, host, and others).
Start the `whoami` service with the following command: Start the `whoami` service with the following command:
@ -73,7 +73,7 @@ docker-compose up -d whoami
Browse `http://localhost:8080/api/rawdata` and see that Traefik has automatically detected the new container and updated its own configuration. Browse `http://localhost:8080/api/rawdata` and see that Traefik has automatically detected the new container and updated its own configuration.
When Traefik detects new services, it creates the corresponding routes, so you can call them ... _let's see!_ (Here, we're using curl) When Traefik detects new services, it creates the corresponding routes, so you can call them ... _let's see!_ (Here, you're using curl)
```shell ```shell
curl -H Host:whoami.docker.localhost http://127.0.0.1 curl -H Host:whoami.docker.localhost http://127.0.0.1
@ -103,7 +103,7 @@ Finally, see that Traefik load-balances between the two instances of your servic
curl -H Host:whoami.docker.localhost http://127.0.0.1 curl -H Host:whoami.docker.localhost http://127.0.0.1
``` ```
The output will show alternatively one of the followings: The output will show alternatively one of the following:
```yaml ```yaml
Hostname: a656c8ddca6c Hostname: a656c8ddca6c

View file

@ -18,7 +18,7 @@ Traefik is natively compliant with every major cluster technology, such as Kuber
With Traefik, there is no need to maintain and synchronize a separate configuration file: everything happens automatically, in real time (no restarts, no connection interruptions). With Traefik, there is no need to maintain and synchronize a separate configuration file: everything happens automatically, in real time (no restarts, no connection interruptions).
With Traefik, you spend time developing and deploying new features to your system, not on configuring and maintaining its working state. With Traefik, you spend time developing and deploying new features to your system, not on configuring and maintaining its working state.
Developing Traefik, our main goal is to make it simple to use, and we're sure you'll enjoy it. Developing Traefik, our main goal is to make it effortless to use, and we're sure you'll enjoy it.
-- The Traefik Maintainer Team -- The Traefik Maintainer Team

View file

@ -8,7 +8,21 @@ description: "Learn how to use IPAllowList in HTTP middleware for limiting clien
Limiting Clients to Specific IPs Limiting Clients to Specific IPs
{: .subtitle } {: .subtitle }
<<<<<<<< HEAD:docs/content/middlewares/http/ipallowlist.md
IPAllowList accepts / refuses requests based on the client IP. IPAllowList accepts / refuses requests based on the client IP.
|||||||| dae0491b6:docs/content/middlewares/http/ipwhitelist.md
![IpWhiteList](../../assets/img/middleware/ipwhitelist.png)
IPWhitelist accepts / refuses requests based on the client IP.
========
![IPWhiteList](../../assets/img/middleware/ipwhitelist.png)
IPWhiteList accepts / refuses requests based on the client IP.
!!! warning
This middleware is deprecated, please use the [IPAllowList](./ipallowlist.md) middleware instead.
>>>>>>>> upstream/v2.11:docs/content/middlewares/http/ipwhitelist.md
## Configuration Examples ## Configuration Examples
@ -193,3 +207,45 @@ http:
[http.middlewares.test-ipallowlist.ipAllowList.ipStrategy] [http.middlewares.test-ipallowlist.ipAllowList.ipStrategy]
excludedIPs = ["127.0.0.1/32", "192.168.1.7"] excludedIPs = ["127.0.0.1/32", "192.168.1.7"]
``` ```
### `rejectStatusCode`
The `rejectStatusCode` option sets HTTP status code for refused requests. If not set, the default is 403 (Forbidden).
```yaml tab="Docker & Swarm"
# Reject requests with a 404 rather than a 403
labels:
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.rejectstatuscode=404"
```
```yaml tab="Kubernetes"
# Reject requests with a 404 rather than a 403
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-ipallowlist
spec:
ipAllowList:
rejectStatusCode: 404
```
```yaml tab="Consul Catalog"
# Reject requests with a 404 rather than a 403
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.rejectstatuscode=404"
```
```yaml tab="File (YAML)"
# Reject requests with a 404 rather than a 403
http:
middlewares:
test-ipallowlist:
ipAllowList:
rejectStatusCode: 404
```
```toml tab="File (TOML)"
# Reject requests with a 404 rather than a 403
[http.middlewares]
[http.middlewares.test-ipallowlist.ipAllowList]
rejectStatusCode = 404
```

View file

@ -8,7 +8,7 @@ description: "Learn how to use IPAllowList in TCP middleware for limiting client
Limiting Clients to Specific IPs Limiting Clients to Specific IPs
{: .subtitle } {: .subtitle }
IPAllowList accepts / refuses connections based on the client IP. IPWhitelist accepts / refuses connections based on the client IP.
## Configuration Examples ## Configuration Examples

View file

@ -10,28 +10,335 @@ How to Migrate from Traefik v2 to Traefik v3.
The version 3 of Traefik introduces a number of breaking changes, The version 3 of Traefik introduces a number of breaking changes,
which require one to update their configuration when they migrate from v2 to v3. which require one to update their configuration when they migrate from v2 to v3.
The goal of this page is to recapitulate all of these changes, and in particular to give examples, The goal of this page is to recapitulate all of these changes,
feature by feature, of how the configuration looked like in v2, and how it now looks like in v3. and in particular to give examples, feature by feature,
of how the configuration looked like in v2,
and how it now looks like in v3.
## IPWhiteList ## Static configuration
### Docker & Docker Swarm
In v3, the provider Docker has been split into 2 providers:
- Docker provider (without Swarm support)
- Swarm provider (Swarm support only)
??? example "An example usage of v2 Docker provider with Swarm"
```yaml tab="File (YAML)"
providers:
docker:
swarmMode: true
```
```toml tab="File (TOML)"
[providers.docker]
swarmMode=true
```
```bash tab="CLI"
--providers.docker.swarmMode=true
```
This configuration is now unsupported and would prevent Traefik to start.
#### Remediation
In v3, the `swarmMode` should not be used with the Docker provider, and, to use Swarm, the Swarm provider should be used instead.
??? example "An example usage of the Swarm provider"
```yaml tab="File (YAML)"
providers:
swarm:
endpoint: "tcp://127.0.0.1:2377"
```
```toml tab="File (TOML)"
[providers.swarm]
endpoint="tcp://127.0.0.1:2377"
```
```bash tab="CLI"
--providers.swarm.endpoint=tcp://127.0.0.1:2377
```
### HTTP3 Experimental Configuration
In v3, HTTP/3 is no longer an experimental feature.
It can be enabled on entry points without the associated `experimental.http3` option, which is now removed.
It is now unsupported and would prevent Traefik to start.
??? example "An example usage of v2 Experimental `http3` option"
```yaml tab="File (YAML)"
experimental:
http3: true
```
```toml tab="File (TOML)"
[experimental]
http3=true
```
```bash tab="CLI"
--experimental.http3=true
```
#### Remediation
The `http3` option should be removed from the static configuration experimental section.
### Consul provider
The Consul provider `namespace` option was deprecated in v2 and is now removed in v3.
It is now unsupported and would prevent Traefik to start.
??? example "An example usage of v2 Consul `namespace` option"
```yaml tab="File (YAML)"
consul:
namespace: foobar
```
```toml tab="File (TOML)"
[consul]
namespace=foobar
```
```bash tab="CLI"
--consul.namespace=foobar
```
#### Remediation
In v3, the `namespaces` option should be used instead of the `namespace` option.
??? example "An example usage of Consul `namespaces` option"
```yaml tab="File (YAML)"
consul:
namespaces:
- foobar
```
```toml tab="File (TOML)"
[consul]
namespaces=["foobar"]
```
```bash tab="CLI"
--consul.namespaces=foobar
```
### ConsulCatalog provider
The ConsulCatalog provider `namespace` option was deprecated in v2 and is now removed in v3.
It is now unsupported and would prevent Traefik to start.
??? example "An example usage of v2 ConsulCatalog `namespace` option"
```yaml tab="File (YAML)"
consulCatalog:
namespace: foobar
```
```toml tab="File (TOML)"
[consulCatalog]
namespace=foobar
```
```bash tab="CLI"
--consulCatalog.namespace=foobar
```
#### Remediation
In v3, the `namespaces` option should be used instead of the `namespace` option.
??? example "An example usage of ConsulCatalog `namespaces` option"
```yaml tab="File (YAML)"
consulCatalog:
namespaces:
- foobar
```
```toml tab="File (TOML)"
[consulCatalog]
namespaces=["foobar"]
```
```bash tab="CLI"
--consulCatalog.namespaces=foobar
```
### Nomad provider
The Nomad provider `namespace` option was deprecated in v2 and is now removed in v3.
It is now unsupported and would prevent Traefik to start.
??? example "An example usage of v2 Nomad `namespace` option"
```yaml tab="File (YAML)"
nomad:
namespace: foobar
```
```toml tab="File (TOML)"
[nomad]
namespace=foobar
```
```bash tab="CLI"
--nomad.namespace=foobar
```
#### Remediation
In v3, the `namespaces` option should be used instead of the `namespace` option.
??? example "An example usage of Nomad `namespaces` option"
```yaml tab="File (YAML)"
nomad:
namespaces:
- foobar
```
```toml tab="File (TOML)"
[nomad]
namespaces=["foobar"]
```
```bash tab="CLI"
--nomad.namespaces=foobar
```
### Rancher v1 Provider
In v3, the Rancher v1 provider has been removed because Rancher v1 is [no longer actively maintaned](https://rancher.com/docs/os/v1.x/en/support/),
and Rancher v2 is supported as a standard Kubernetes provider.
??? example "An example of Traefik v2 Rancher v1 configuration"
```yaml tab="File (YAML)"
providers:
rancher: {}
```
```toml tab="File (TOML)"
[providers.rancher]
```
```bash tab="CLI"
--providers.rancher=true
```
This configuration is now unsupported and would prevent Traefik to start.
#### Remediation
Rancher 2.x requires Kubernetes and does not have a metadata endpoint of its own for Traefik to query.
As such, Rancher 2.x users should utilize the [Kubernetes CRD provider](../providers/kubernetes-crd.md) directly.
Also, all Rancher provider related configuration should be removed from the static configuration.
### Marathon provider
Marathon maintenance [ended on October 31, 2021](https://github.com/mesosphere/marathon/blob/master/README.md).
In v3, the Marathon provider has been removed.
??? example "An example of v2 Marathon provider configuration"
```yaml tab="File (YAML)"
providers:
marathon: {}
```
```toml tab="File (TOML)"
[providers.marathon]
```
```bash tab="CLI"
--providers.marathon=true
```
This configuration is now unsupported and would prevent Traefik to start.
#### Remediation
All Marathon provider related configuration should be removed from the static configuration.
### InfluxDB v1
InfluxDB v1.x maintenance [ended in 2021](https://www.influxdata.com/blog/influxdb-oss-and-enterprise-roadmap-update-from-influxdays-emea/).
In v3, the InfluxDB v1 metrics provider has been removed.
??? example "An example of Traefik v2 InfluxDB v1 metrics configuration"
```yaml tab="File (YAML)"
metrics:
influxDB: {}
```
```toml tab="File (TOML)"
[metrics.influxDB]
```
```bash tab="CLI"
--metrics.influxDB=true
```
This configuration is now unsupported and would prevent Traefik to start.
#### Remediation
All InfluxDB v1 metrics provider related configuration should be removed from the static configuration.
### Pilot
Traefik Pilot is no longer available since October 4th, 2022.
??? example "An example of v2 Pilot configuration"
```yaml tab="File (YAML)"
pilot:
token: foobar
```
```toml tab="File (TOML)"
[pilot]
token=foobar
```
```bash tab="CLI"
--pilot.token=foobar
```
In v2, Pilot configuration was deprecated and ineffective,
it is now unsupported and would prevent Traefik to start.
#### Remediation
All Pilot related configuration should be removed from the static configuration.
## Dynamic configuration
### IPWhiteList
In v3, we renamed the `IPWhiteList` middleware to `IPAllowList` without changing anything to the configuration. In v3, we renamed the `IPWhiteList` middleware to `IPAllowList` without changing anything to the configuration.
## gRPC Metrics ### Deprecated Options Removal
In v3, the reported status code for gRPC requests is now the value of the `Grpc-Status` header.
## Deprecated Options Removal
- The `pilot` option has been removed from the static configuration.
- The `tracing.datadog.globaltag` option has been removed. - The `tracing.datadog.globaltag` option has been removed.
- The `namespace` option of Consul, Consul Catalog and Nomad providers has been removed.
- The `tls.caOptional` option has been removed from the ForwardAuth middleware, as well as from the HTTP, Consul, Etcd, Redis, ZooKeeper, Consul Catalog, and Docker providers. - The `tls.caOptional` option has been removed from the ForwardAuth middleware, as well as from the HTTP, Consul, Etcd, Redis, ZooKeeper, Consul Catalog, and Docker providers.
- `sslRedirect`, `sslTemporaryRedirect`, `sslHost`, `sslForceHost` and `featurePolicy` options of the Headers middleware have been removed. - `sslRedirect`, `sslTemporaryRedirect`, `sslHost`, `sslForceHost` and `featurePolicy` options of the Headers middleware have been removed.
- The `forceSlash` option of the StripPrefix middleware has been removed. - The `forceSlash` option of the StripPrefix middleware has been removed.
- The `preferServerCipherSuites` option has been removed. - The `preferServerCipherSuites` option has been removed.
## Matchers ### Matchers
In v3, the `Headers` and `HeadersRegexp` matchers have been renamed to `Header` and `HeaderRegexp` respectively. In v3, the `Headers` and `HeadersRegexp` matchers have been renamed to `Header` and `HeaderRegexp` respectively.
@ -48,61 +355,63 @@ and should be explicitly combined using logical operators to mimic previous beha
`HostHeader` has been removed, use `Host` instead. `HostHeader` has been removed, use `Host` instead.
## Content-Type Auto-Detection
In v3, the `Content-Type` header is not auto-detected anymore when it is not set by the backend.
One should use the `ContentType` middleware to enable the `Content-Type` header value auto-detection.
## HTTP/3
In v3, HTTP/3 is no longer an experimental feature.
The `experimental.http3` option has been removed from the static configuration.
## TCP ServersTransport
In v3, the support of `TCPServersTransport` has been introduced.
When using the KubernetesCRD provider, it is therefore necessary to update [RBAC](../reference/dynamic-configuration/kubernetes-crd.md#rbac) and [CRD](../reference/dynamic-configuration/kubernetes-crd.md) manifests.
### TCP LoadBalancer `terminationDelay` option ### TCP LoadBalancer `terminationDelay` option
The TCP LoadBalancer `terminationDelay` option has been removed. The TCP LoadBalancer `terminationDelay` option has been removed.
This option can now be configured directly on the `TCPServersTransport` level, please take a look at this [documentation](../routing/services/index.md#terminationdelay) This option can now be configured directly on the `TCPServersTransport` level, please take a look at this [documentation](../routing/services/index.md#terminationdelay)
## Rancher v1 ### Kubernetes CRDs API Group `traefik.containo.us`
In v3, the rancher v1 provider has been removed because Rancher v1 is [no longer actively maintaned](https://rancher.com/docs/os/v1.x/en/support/) and v2 is supported as a standard Kubernetes provider.
Rancher 2.x requires Kubernetes and does not have a metadata endpoint of its own for Traefik to query.
As such, Rancher 2.x users should utilize the [Kubernetes CRD provider](../providers/kubernetes-crd.md) directly.
## Marathon provider
In v3, the Marathon provider has been removed.
## InfluxDB v1
In v3, the InfluxDB v1 metrics provider has been removed because InfluxDB v1.x maintenance [ended in 2021](https://www.influxdata.com/blog/influxdb-oss-and-enterprise-roadmap-update-from-influxdays-emea/).
## Kubernetes CRDs API Group `traefik.containo.us`
In v3, the Kubernetes CRDs API Group `traefik.containo.us` has been removed. In v3, the Kubernetes CRDs API Group `traefik.containo.us` has been removed.
Please use the API Group `traefik.io` instead. Please use the API Group `traefik.io` instead.
## Docker & Docker Swarm ### Kubernetes Ingress API Group `networking.k8s.io/v1beta1`
In v3, the provider Docker has been split into 2 providers:
- Docker provider (without Swarm support)
- Swarm provider (Swarm support only)
## Kubernetes Ingress API Group `networking.k8s.io/v1beta1`
In v3, the Kubernetes Ingress API Group `networking.k8s.io/v1beta1` ([removed since Kubernetes v1.22](https://kubernetes.io/docs/reference/using-api/deprecation-guide/#ingress-v122)) support has been removed. In v3, the Kubernetes Ingress API Group `networking.k8s.io/v1beta1` ([removed since Kubernetes v1.22](https://kubernetes.io/docs/reference/using-api/deprecation-guide/#ingress-v122)) support has been removed.
Please use the API Group `networking.k8s.io/v1` instead. Please use the API Group `networking.k8s.io/v1` instead.
## Traefik CRD API Version `apiextensions.k8s.io/v1beta1` ### Traefik CRD API Version `apiextensions.k8s.io/v1beta1`
In v3, the Traefik CRD API Version `apiextensions.k8s.io/v1beta1` ([removed since Kubernetes v1.22](https://kubernetes.io/docs/reference/using-api/deprecation-guide/#customresourcedefinition-v122)) support has been removed. In v3, the Traefik CRD API Version `apiextensions.k8s.io/v1beta1` ([removed since Kubernetes v1.22](https://kubernetes.io/docs/reference/using-api/deprecation-guide/#customresourcedefinition-v122)) support has been removed.
Please use the CRD definition with the API Version `apiextensions.k8s.io/v1` instead. Please use the CRD definition with the API Version `apiextensions.k8s.io/v1` instead.
## Operations
### Traefik RBAC Update
In v3, the support of `TCPServersTransport` has been introduced.
When using the KubernetesCRD provider, it is therefore necessary to update [RBAC](../reference/dynamic-configuration/kubernetes-crd.md#rbac) and [CRD](../reference/dynamic-configuration/kubernetes-crd.md) manifests.
### Content-Type Auto-Detection
In v3, the `Content-Type` header is not auto-detected anymore when it is not set by the backend.
One should use the `ContentType` middleware to enable the `Content-Type` header value auto-detection.
### Observability
#### gRPC Metrics
In v3, the reported status code for gRPC requests is now the value of the `Grpc-Status` header.
#### Tracing
In v3, the tracing feature has been revamped and is now powered exclusively by [OpenTelemetry](https://opentelemetry.io/ "Link to website of OTel") (OTel).
!!! warning "Important"
Traefik v3 **no** longer supports direct output formats for specific vendors such as Instana, Jaeger, Zipkin, Haystack, Datadog, and Elastic.
Instead, it focuses on pure OpenTelemetry implementation, providing a unified and standardized approach for observability.
Here are two possible transition strategies:
1. OTLP Ingestion Endpoints:
Most vendors now offer OpenTelemetry Protocol (OTLP) ingestion endpoints.
You can seamlessly integrate Traefik v3 with these endpoints to continue leveraging tracing capabilities.
2. Legacy Stack Compatibility:
For legacy stacks that cannot immediately upgrade to the latest vendor agents supporting OTLP ingestion,
using OpenTelemetry (OTel) collectors with appropriate exporters configuration is a viable solution.
This allows continued compatibility with the existing infrastructure.

View file

@ -526,3 +526,13 @@ kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.10/docs/co
### Traefik Hub ### Traefik Hub
In `v2.10`, Traefik Hub configuration has been removed because Traefik Hub v2 doesn't require this configuration. In `v2.10`, Traefik Hub configuration has been removed because Traefik Hub v2 doesn't require this configuration.
## v2.11
### IPWhiteList (HTTP)
In `v2.11`, the `IPWhiteList` middleware is deprecated, please use the [IPAllowList](../middlewares/http/ipallowlist.md) middleware instead.
### IPWhiteList (TCP)
In `v2.11`, the `IPWhiteList` middleware is deprecated, please use the [IPAllowList](../middlewares/tcp/ipallowlist.md) middleware instead.

View file

@ -1,139 +0,0 @@
---
title: "Traefik Datadog Tracing Documentation"
description: "Traefik Proxy supports Datadog for tracing. Read the technical documentation to enable Datadog for observability."
---
# Datadog
To enable the Datadog tracer:
```yaml tab="File (YAML)"
tracing:
datadog: {}
```
```toml tab="File (TOML)"
[tracing]
[tracing.datadog]
```
```bash tab="CLI"
--tracing.datadog=true
```
#### `localAgentHostPort`
_Optional, Default="localhost:8126"_
Local Agent Host Port instructs the reporter to send spans to the Datadog Agent at this address (host:port).
```yaml tab="File (YAML)"
tracing:
datadog:
localAgentHostPort: localhost:8126
```
```toml tab="File (TOML)"
[tracing]
[tracing.datadog]
localAgentHostPort = "localhost:8126"
```
```bash tab="CLI"
--tracing.datadog.localAgentHostPort=localhost:8126
```
#### `localAgentSocket`
_Optional, Default=""_
Local Agent Socket instructs the reporter to send spans to the Datadog Agent at this UNIX socket.
```yaml tab="File (YAML)"
tracing:
datadog:
localAgentSocket: /var/run/datadog/apm.socket
```
```toml tab="File (TOML)"
[tracing]
[tracing.datadog]
localAgentSocket = "/var/run/datadog/apm.socket"
```
```bash tab="CLI"
--tracing.datadog.localAgentSocket=/var/run/datadog/apm.socket
```
#### `debug`
_Optional, Default=false_
Enables Datadog debug.
```yaml tab="File (YAML)"
tracing:
datadog:
debug: true
```
```toml tab="File (TOML)"
[tracing]
[tracing.datadog]
debug = true
```
```bash tab="CLI"
--tracing.datadog.debug=true
```
#### `globalTags`
_Optional, Default=empty_
Applies a list of shared key:value tags on all spans.
```yaml tab="File (YAML)"
tracing:
datadog:
globalTags:
tag1: foo
tag2: bar
```
```toml tab="File (TOML)"
[tracing]
[tracing.datadog]
[tracing.datadog.globalTags]
tag1 = "foo"
tag2 = "bar"
```
```bash tab="CLI"
--tracing.datadog.globalTags.tag1=foo
--tracing.datadog.globalTags.tag2=bar
```
#### `prioritySampling`
_Optional, Default=false_
Enables priority sampling.
When using distributed tracing,
this option must be enabled in order to get all the parts of a distributed trace sampled.
```yaml tab="File (YAML)"
tracing:
datadog:
prioritySampling: true
```
```toml tab="File (TOML)"
[tracing]
[tracing.datadog]
prioritySampling = true
```
```bash tab="CLI"
--tracing.datadog.prioritySampling=true
```

View file

@ -1,93 +0,0 @@
---
title: "Traefik Elastic Documentation"
description: "Traefik supports several tracing backends, including Elastic. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation."
---
# Elastic
To enable the Elastic tracer:
```yaml tab="File (YAML)"
tracing:
elastic: {}
```
```toml tab="File (TOML)"
[tracing]
[tracing.elastic]
```
```bash tab="CLI"
--tracing.elastic=true
```
#### `serverURL`
_Optional, Default="http://localhost:8200"_
URL of the Elastic APM server.
```yaml tab="File (YAML)"
tracing:
elastic:
serverURL: "http://apm:8200"
```
```toml tab="File (TOML)"
[tracing]
[tracing.elastic]
serverURL = "http://apm:8200"
```
```bash tab="CLI"
--tracing.elastic.serverurl="http://apm:8200"
```
#### `secretToken`
_Optional, Default=""_
Token used to connect to Elastic APM Server.
```yaml tab="File (YAML)"
tracing:
elastic:
secretToken: "mytoken"
```
```toml tab="File (TOML)"
[tracing]
[tracing.elastic]
secretToken = "mytoken"
```
```bash tab="CLI"
--tracing.elastic.secrettoken="mytoken"
```
#### `serviceEnvironment`
_Optional, Default=""_
Environment's name where Traefik is deployed in, e.g. `production` or `staging`.
```yaml tab="File (YAML)"
tracing:
elastic:
serviceEnvironment: "production"
```
```toml tab="File (TOML)"
[tracing]
[tracing.elastic]
serviceEnvironment = "production"
```
```bash tab="CLI"
--tracing.elastic.serviceenvironment="production"
```
### Further
Additional configuration of Elastic APM Go agent can be done using environment variables.
See [APM Go agent reference](https://www.elastic.co/guide/en/apm/agent/go/current/configuration.html).

View file

@ -1,176 +0,0 @@
---
title: "Traefik Haystack Documentation"
description: "Traefik supports several tracing backends, including Haystack. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation."
---
# Haystack
To enable the Haystack tracer:
```yaml tab="File (YAML)"
tracing:
haystack: {}
```
```toml tab="File (TOML)"
[tracing]
[tracing.haystack]
```
```bash tab="CLI"
--tracing.haystack=true
```
#### `localAgentHost`
_Required, Default="127.0.0.1"_
Local Agent Host instructs reporter to send spans to the Haystack Agent at this address.
```yaml tab="File (YAML)"
tracing:
haystack:
localAgentHost: 127.0.0.1
```
```toml tab="File (TOML)"
[tracing]
[tracing.haystack]
localAgentHost = "127.0.0.1"
```
```bash tab="CLI"
--tracing.haystack.localAgentHost=127.0.0.1
```
#### `localAgentPort`
_Required, Default=35000_
Local Agent Port instructs reporter to send spans to the Haystack Agent at this port.
```yaml tab="File (YAML)"
tracing:
haystack:
localAgentPort: 35000
```
```toml tab="File (TOML)"
[tracing]
[tracing.haystack]
localAgentPort = 35000
```
```bash tab="CLI"
--tracing.haystack.localAgentPort=35000
```
#### `globalTag`
_Optional, Default=empty_
Applies shared key:value tag on all spans.
```yaml tab="File (YAML)"
tracing:
haystack:
globalTag: sample:test
```
```toml tab="File (TOML)"
[tracing]
[tracing.haystack]
globalTag = "sample:test"
```
```bash tab="CLI"
--tracing.haystack.globalTag=sample:test
```
#### `traceIDHeaderName`
_Optional, Default=empty_
Sets the header name used to store the trace ID.
```yaml tab="File (YAML)"
tracing:
haystack:
traceIDHeaderName: Trace-ID
```
```toml tab="File (TOML)"
[tracing]
[tracing.haystack]
traceIDHeaderName = "Trace-ID"
```
```bash tab="CLI"
--tracing.haystack.traceIDHeaderName=Trace-ID
```
#### `parentIDHeaderName`
_Optional, Default=empty_
Sets the header name used to store the parent ID.
```yaml tab="File (YAML)"
tracing:
haystack:
parentIDHeaderName: Parent-Message-ID
```
```toml tab="File (TOML)"
[tracing]
[tracing.haystack]
parentIDHeaderName = "Parent-Message-ID"
```
```bash tab="CLI"
--tracing.haystack.parentIDHeaderName=Parent-Message-ID
```
#### `spanIDHeaderName`
_Optional, Default=empty_
Sets the header name used to store the span ID.
```yaml tab="File (YAML)"
tracing:
haystack:
spanIDHeaderName: Message-ID
```
```toml tab="File (TOML)"
[tracing]
[tracing.haystack]
spanIDHeaderName = "Message-ID"
```
```bash tab="CLI"
--tracing.haystack.spanIDHeaderName=Message-ID
```
#### `baggagePrefixHeaderName`
_Optional, Default=empty_
Sets the header name prefix used to store baggage items in a map.
```yaml tab="File (YAML)"
tracing:
haystack:
baggagePrefixHeaderName: "sample"
```
```toml tab="File (TOML)"
[tracing]
[tracing.haystack]
baggagePrefixHeaderName = "sample"
```
```bash tab="CLI"
--tracing.haystack.baggagePrefixHeaderName=sample
```

View file

@ -1,117 +0,0 @@
---
title: "Traefik Instana Documentation"
description: "Traefik supports several tracing backends, including Instana. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation."
---
# Instana
To enable the Instana tracer:
```yaml tab="File (YAML)"
tracing:
instana: {}
```
```toml tab="File (TOML)"
[tracing]
[tracing.instana]
```
```bash tab="CLI"
--tracing.instana=true
```
#### `localAgentHost`
_Required, Default="127.0.0.1"_
Local Agent Host instructs reporter to send spans to the Instana Agent at this address.
```yaml tab="File (YAML)"
tracing:
instana:
localAgentHost: 127.0.0.1
```
```toml tab="File (TOML)"
[tracing]
[tracing.instana]
localAgentHost = "127.0.0.1"
```
```bash tab="CLI"
--tracing.instana.localAgentHost=127.0.0.1
```
#### `localAgentPort`
_Required, Default=42699_
Local Agent port instructs reporter to send spans to the Instana Agent listening on this port.
```yaml tab="File (YAML)"
tracing:
instana:
localAgentPort: 42699
```
```toml tab="File (TOML)"
[tracing]
[tracing.instana]
localAgentPort = 42699
```
```bash tab="CLI"
--tracing.instana.localAgentPort=42699
```
#### `logLevel`
_Required, Default="info"_
Sets Instana tracer log level.
Valid values are:
- `error`
- `warn`
- `debug`
- `info`
```yaml tab="File (YAML)"
tracing:
instana:
logLevel: info
```
```toml tab="File (TOML)"
[tracing]
[tracing.instana]
logLevel = "info"
```
```bash tab="CLI"
--tracing.instana.logLevel=info
```
#### `enableAutoProfile`
_Required, Default=false_
Enables [automatic profiling](https://www.ibm.com/docs/en/obi/current?topic=instana-profile-processes) for the Traefik process.
```yaml tab="File (YAML)"
tracing:
instana:
enableAutoProfile: true
```
```toml tab="File (TOML)"
[tracing]
[tracing.instana]
enableAutoProfile = true
```
```bash tab="CLI"
--tracing.instana.enableAutoProfile=true
```

View file

@ -1,294 +0,0 @@
---
title: "Traefik Jaeger Documentation"
description: "Traefik supports several tracing backends, including Jaeger. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation."
---
# Jaeger
To enable the Jaeger tracer:
```yaml tab="File (YAML)"
tracing:
jaeger: {}
```
```toml tab="File (TOML)"
[tracing]
[tracing.jaeger]
```
```bash tab="CLI"
--tracing.jaeger=true
```
!!! warning
Traefik is able to send data over the compact thrift protocol to the [Jaeger agent](https://www.jaegertracing.io/docs/deployment/#agent)
or a [Jaeger collector](https://www.jaegertracing.io/docs/deployment/#collector).
!!! info
All Jaeger configuration can be overridden by [environment variables](https://github.com/jaegertracing/jaeger-client-go#environment-variables)
#### `samplingServerURL`
_Required, Default="http://localhost:5778/sampling"_
Address of the Jaeger Agent HTTP sampling server.
```yaml tab="File (YAML)"
tracing:
jaeger:
samplingServerURL: http://localhost:5778/sampling
```
```toml tab="File (TOML)"
[tracing]
[tracing.jaeger]
samplingServerURL = "http://localhost:5778/sampling"
```
```bash tab="CLI"
--tracing.jaeger.samplingServerURL=http://localhost:5778/sampling
```
#### `samplingType`
_Required, Default="const"_
Type of the sampler.
Valid values are:
- `const`
- `probabilistic`
- `rateLimiting`
```yaml tab="File (YAML)"
tracing:
jaeger:
samplingType: const
```
```toml tab="File (TOML)"
[tracing]
[tracing.jaeger]
samplingType = "const"
```
```bash tab="CLI"
--tracing.jaeger.samplingType=const
```
#### `samplingParam`
_Required, Default=1.0_
Value passed to the sampler.
Valid values are:
- for `const` sampler, 0 or 1 for always false/true respectively
- for `probabilistic` sampler, a probability between 0 and 1
- for `rateLimiting` sampler, the number of spans per second
```yaml tab="File (YAML)"
tracing:
jaeger:
samplingParam: 1.0
```
```toml tab="File (TOML)"
[tracing]
[tracing.jaeger]
samplingParam = 1.0
```
```bash tab="CLI"
--tracing.jaeger.samplingParam=1.0
```
#### `localAgentHostPort`
_Required, Default="127.0.0.1:6831"_
Local Agent Host Port instructs the reporter to send spans to the Jaeger Agent at this address (host:port).
```yaml tab="File (YAML)"
tracing:
jaeger:
localAgentHostPort: 127.0.0.1:6831
```
```toml tab="File (TOML)"
[tracing]
[tracing.jaeger]
localAgentHostPort = "127.0.0.1:6831"
```
```bash tab="CLI"
--tracing.jaeger.localAgentHostPort=127.0.0.1:6831
```
#### `gen128Bit`
_Optional, Default=false_
Generates 128 bits trace IDs, compatible with OpenCensus.
```yaml tab="File (YAML)"
tracing:
jaeger:
gen128Bit: true
```
```toml tab="File (TOML)"
[tracing]
[tracing.jaeger]
gen128Bit = true
```
```bash tab="CLI"
--tracing.jaeger.gen128Bit
```
#### `propagation`
_Required, Default="jaeger"_
Sets the propagation header type.
Valid values are:
- `jaeger`, jaeger's default trace header.
- `b3`, compatible with OpenZipkin
```yaml tab="File (YAML)"
tracing:
jaeger:
propagation: jaeger
```
```toml tab="File (TOML)"
[tracing]
[tracing.jaeger]
propagation = "jaeger"
```
```bash tab="CLI"
--tracing.jaeger.propagation=jaeger
```
#### `traceContextHeaderName`
_Required, Default="uber-trace-id"_
HTTP header name used to propagate tracing context.
This must be in lower-case to avoid mismatches when decoding incoming headers.
```yaml tab="File (YAML)"
tracing:
jaeger:
traceContextHeaderName: uber-trace-id
```
```toml tab="File (TOML)"
[tracing]
[tracing.jaeger]
traceContextHeaderName = "uber-trace-id"
```
```bash tab="CLI"
--tracing.jaeger.traceContextHeaderName=uber-trace-id
```
### disableAttemptReconnecting
_Optional, Default=true_
Disables the UDP connection helper that periodically re-resolves the agent's hostname and reconnects if there was a change.
Enabling the re-resolving of UDP address make the client more robust in Kubernetes deployments.
```yaml tab="File (YAML)"
tracing:
jaeger:
disableAttemptReconnecting: false
```
```toml tab="File (TOML)"
[tracing]
[tracing.jaeger]
disableAttemptReconnecting = false
```
```bash tab="CLI"
--tracing.jaeger.disableAttemptReconnecting=false
```
### `collector`
#### `endpoint`
_Optional, Default=""_
Collector Endpoint instructs the reporter to send spans to the Jaeger Collector at this URL.
```yaml tab="File (YAML)"
tracing:
jaeger:
collector:
endpoint: http://127.0.0.1:14268/api/traces?format=jaeger.thrift
```
```toml tab="File (TOML)"
[tracing]
[tracing.jaeger.collector]
endpoint = "http://127.0.0.1:14268/api/traces?format=jaeger.thrift"
```
```bash tab="CLI"
--tracing.jaeger.collector.endpoint=http://127.0.0.1:14268/api/traces?format=jaeger.thrift
```
#### `user`
_Optional, Default=""_
User instructs the reporter to include a user for basic HTTP authentication when sending spans to the Jaeger Collector.
```yaml tab="File (YAML)"
tracing:
jaeger:
collector:
user: my-user
```
```toml tab="File (TOML)"
[tracing]
[tracing.jaeger.collector]
user = "my-user"
```
```bash tab="CLI"
--tracing.jaeger.collector.user=my-user
```
#### `password`
_Optional, Default=""_
Password instructs the reporter to include a password for basic HTTP authentication when sending spans to the Jaeger Collector.
```yaml tab="File (YAML)"
tracing:
jaeger:
collector:
password: my-password
```
```toml tab="File (TOML)"
[tracing]
[tracing.jaeger.collector]
password = "my-password"
```
```bash tab="CLI"
--tracing.jaeger.collector.password=my-password
```

View file

@ -9,122 +9,75 @@ To enable the OpenTelemetry tracer:
```yaml tab="File (YAML)" ```yaml tab="File (YAML)"
tracing: tracing:
openTelemetry: {} otlp: {}
``` ```
```toml tab="File (TOML)" ```toml tab="File (TOML)"
[tracing] [tracing]
[tracing.openTelemetry] [tracing.otlp]
``` ```
```bash tab="CLI" ```bash tab="CLI"
--tracing.openTelemetry=true --tracing.otlp=true
``` ```
!!! info "The OpenTelemetry trace reporter will export traces to the collector using HTTP by default, see the [gRPC Section](#grpc-configuration) to use gRPC." !!! info "The OpenTelemetry trace reporter will export traces to the collector using HTTP by default (http://localhost:4318/v1/traces),
see the [gRPC Section](#grpc-configuration) to use gRPC."
!!! info "Trace sampling" !!! info "Trace sampling"
By default, the OpenTelemetry trace reporter will sample 100% of traces. By default, the OpenTelemetry trace reporter will sample 100% of traces.
See [OpenTelemetry's SDK configuration](https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/#general-sdk-configuration) to customize the sampling strategy. See [OpenTelemetry's SDK configuration](https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/#general-sdk-configuration) to customize the sampling strategy.
#### `address` ### HTTP configuration
_Required, Default="localhost:4318", Format="`<host>:<port>`"_ _Optional_
Address of the OpenTelemetry Collector to send spans to. This instructs the reporter to send spans to the OpenTelemetry Collector using HTTP.
```yaml tab="File (YAML)" ```yaml tab="File (YAML)"
tracing: tracing:
openTelemetry: otlp:
address: localhost:4318 http: {}
``` ```
```toml tab="File (TOML)" ```toml tab="File (TOML)"
[tracing] [tracing]
[tracing.openTelemetry] [tracing.otlp.http]
address = "localhost:4318"
``` ```
```bash tab="CLI" ```bash tab="CLI"
--tracing.openTelemetry.address=localhost:4318 --tracing.otlp.http=true
``` ```
#### `headers` #### `endpoint`
_Optional, Default={}_ _Required, Default="http://localhost:4318/v1/traces", Format="`<scheme>://<host>:<port><path>`"_
Additional headers sent with spans by the reporter to the OpenTelemetry Collector. URL of the OpenTelemetry Collector to send spans to.
```yaml tab="File (YAML)" ```yaml tab="File (YAML)"
tracing: tracing:
openTelemetry: otlp:
headers: http:
foo: bar endpoint: http://localhost:4318/v1/traces
baz: buz
``` ```
```toml tab="File (TOML)" ```toml tab="File (TOML)"
[tracing] [tracing]
[tracing.openTelemetry.headers] [tracing.otlp.http]
foo = "bar" endpoint = "http://localhost:4318/v1/traces"
baz = "buz"
``` ```
```bash tab="CLI" ```bash tab="CLI"
--tracing.openTelemetry.headers.foo=bar --tracing.openTelemetry.headers.baz=buz --tracing.otlp.http.endpoint=http://localhost:4318/v1/traces
```
#### `insecure`
_Optional, Default=false_
Allows reporter to send spans to the OpenTelemetry Collector without using a secured protocol.
```yaml tab="File (YAML)"
tracing:
openTelemetry:
insecure: true
```
```toml tab="File (TOML)"
[tracing]
[tracing.openTelemetry]
insecure = true
```
```bash tab="CLI"
--tracing.openTelemetry.insecure=true
```
#### `path`
_Required, Default="/v1/traces"_
Allows to override the default URL path used for sending traces.
This option has no effect when using gRPC transport.
```yaml tab="File (YAML)"
tracing:
openTelemetry:
path: /foo/v1/traces
```
```toml tab="File (TOML)"
[tracing]
[tracing.openTelemetry]
path = "/foo/v1/traces"
```
```bash tab="CLI"
--tracing.openTelemetry.path=/foo/v1/traces
``` ```
#### `tls` #### `tls`
_Optional_ _Optional_
Defines the TLS configuration used by the reporter to send spans to the OpenTelemetry Collector. Defines the Client TLS configuration used by the reporter to send spans to the OpenTelemetry Collector.
##### `ca` ##### `ca`
@ -135,18 +88,19 @@ it defaults to the system bundle.
```yaml tab="File (YAML)" ```yaml tab="File (YAML)"
tracing: tracing:
openTelemetry: otlp:
tls: http:
ca: path/to/ca.crt tls:
ca: path/to/ca.crt
``` ```
```toml tab="File (TOML)" ```toml tab="File (TOML)"
[tracing.openTelemetry.tls] [tracing.otlp.http.tls]
ca = "path/to/ca.crt" ca = "path/to/ca.crt"
``` ```
```bash tab="CLI" ```bash tab="CLI"
--tracing.openTelemetry.tls.ca=path/to/ca.crt --tracing.otlp.http.tls.ca=path/to/ca.crt
``` ```
##### `cert` ##### `cert`
@ -158,21 +112,22 @@ When using this option, setting the `key` option is required.
```yaml tab="File (YAML)" ```yaml tab="File (YAML)"
tracing: tracing:
openTelemetry: otlp:
tls: http:
cert: path/to/foo.cert tls:
key: path/to/foo.key cert: path/to/foo.cert
key: path/to/foo.key
``` ```
```toml tab="File (TOML)" ```toml tab="File (TOML)"
[tracing.openTelemetry.tls] [tracing.otlp.http.tls]
cert = "path/to/foo.cert" cert = "path/to/foo.cert"
key = "path/to/foo.key" key = "path/to/foo.key"
``` ```
```bash tab="CLI" ```bash tab="CLI"
--tracing.openTelemetry.tls.cert=path/to/foo.cert --tracing.otlp.http.tls.cert=path/to/foo.cert
--tracing.openTelemetry.tls.key=path/to/foo.key --tracing.otlp.http.tls.key=path/to/foo.key
``` ```
##### `key` ##### `key`
@ -184,21 +139,22 @@ When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)" ```yaml tab="File (YAML)"
tracing: tracing:
openTelemetry: otlp:
tls: http:
cert: path/to/foo.cert tls:
key: path/to/foo.key cert: path/to/foo.cert
key: path/to/foo.key
``` ```
```toml tab="File (TOML)" ```toml tab="File (TOML)"
[tracing.openTelemetry.tls] [tracing.otlp.http.tls]
cert = "path/to/foo.cert" cert = "path/to/foo.cert"
key = "path/to/foo.key" key = "path/to/foo.key"
``` ```
```bash tab="CLI" ```bash tab="CLI"
--tracing.openTelemetry.tls.cert=path/to/foo.cert --tracing.otlp.http.tls.cert=path/to/foo.cert
--tracing.openTelemetry.tls.key=path/to/foo.key --tracing.otlp.http.tls.key=path/to/foo.key
``` ```
##### `insecureSkipVerify` ##### `insecureSkipVerify`
@ -210,18 +166,19 @@ the TLS connection to the OpenTelemetry Collector accepts any certificate presen
```yaml tab="File (YAML)" ```yaml tab="File (YAML)"
tracing: tracing:
openTelemetry: otlp:
tls: http:
insecureSkipVerify: true tls:
insecureSkipVerify: true
``` ```
```toml tab="File (TOML)" ```toml tab="File (TOML)"
[tracing.openTelemetry.tls] [tracing.otlp.http.tls]
insecureSkipVerify = true insecureSkipVerify = true
``` ```
```bash tab="CLI" ```bash tab="CLI"
--tracing.openTelemetry.tls.insecureSkipVerify=true --tracing.otlp.http.tls.insecureSkipVerify=true
``` ```
#### gRPC configuration #### gRPC configuration
@ -232,15 +189,168 @@ This instructs the reporter to send spans to the OpenTelemetry Collector using g
```yaml tab="File (YAML)" ```yaml tab="File (YAML)"
tracing: tracing:
openTelemetry: otlp:
grpc: {} grpc: {}
``` ```
```toml tab="File (TOML)" ```toml tab="File (TOML)"
[tracing] [tracing]
[tracing.openTelemetry.grpc] [tracing.otlp.grpc]
``` ```
```bash tab="CLI" ```bash tab="CLI"
--tracing.openTelemetry.grpc=true --tracing.otlp.grpc=true
```
#### `endpoint`
_Required, Default="localhost:4317", Format="`<host>:<port>`"_
Address of the OpenTelemetry Collector to send spans to.
```yaml tab="File (YAML)"
tracing:
otlp:
grpc:
endpoint: localhost:4317
```
```toml tab="File (TOML)"
[tracing]
[tracing.otlp.grpc]
endpoint = "localhost:4317"
```
```bash tab="CLI"
--tracing.otlp.grpc.endpoint=localhost:4317
```
#### `insecure`
_Optional, Default=false_
Allows reporter to send spans to the OpenTelemetry Collector without using a secured protocol.
```yaml tab="File (YAML)"
tracing:
otlp:
grpc:
insecure: true
```
```toml tab="File (TOML)"
[tracing]
[tracing.otlp.grpc]
insecure = true
```
```bash tab="CLI"
--tracing.otlp.grpc.insecure=true
```
#### `tls`
_Optional_
Defines the Client TLS configuration used by the reporter to send spans to the OpenTelemetry Collector.
##### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to the OpenTelemetry Collector,
it defaults to the system bundle.
```yaml tab="File (YAML)"
tracing:
otlp:
grpc:
tls:
ca: path/to/ca.crt
```
```toml tab="File (TOML)"
[tracing.otlp.grpc.tls]
ca = "path/to/ca.crt"
```
```bash tab="CLI"
--tracing.otlp.grpc.tls.ca=path/to/ca.crt
```
##### `cert`
_Optional_
`cert` is the path to the public certificate used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
tracing:
otlp:
grpc:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[tracing.otlp.grpc.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--tracing.otlp.grpc.tls.cert=path/to/foo.cert
--tracing.otlp.grpc.tls.key=path/to/foo.key
```
##### `key`
_Optional_
`key` is the path to the private key used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
tracing:
otlp:
grpc:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[tracing.otlp.grpc.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--tracing.otlp.grpc.tls.cert=path/to/foo.cert
--tracing.otlp.grpc.tls.key=path/to/foo.key
```
##### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`,
the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers.
```yaml tab="File (YAML)"
tracing:
otlp:
grpc:
tls:
insecureSkipVerify: true
```
```toml tab="File (TOML)"
[tracing.otlp.grpc.tls]
insecureSkipVerify = true
```
```bash tab="CLI"
--tracing.otlp.grpc.tls.insecureSkipVerify=true
``` ```

View file

@ -10,21 +10,13 @@ Visualize the Requests Flow
The tracing system allows developers to visualize call flows in their infrastructure. The tracing system allows developers to visualize call flows in their infrastructure.
Traefik uses OpenTracing, an open standard designed for distributed tracing. Traefik uses [OpenTelemetry](https://opentelemetry.io/ "Link to website of OTel"), an open standard designed for distributed tracing.
Traefik supports seven tracing backends: Please check our dedicated [OTel docs](./opentelemetry.md) to learn more.
- [Jaeger](./jaeger.md)
- [Zipkin](./zipkin.md)
- [Datadog](./datadog.md)
- [Instana](./instana.md)
- [Haystack](./haystack.md)
- [Elastic](./elastic.md)
- [OpenTelemetry](./opentelemetry.md)
## Configuration ## Configuration
By default, Traefik uses Jaeger as tracing backend.
To enable the tracing: To enable the tracing:
@ -62,25 +54,71 @@ tracing:
--tracing.serviceName=traefik --tracing.serviceName=traefik
``` ```
#### `spanNameLimit` #### `sampleRate`
_Required, Default=0_ _Optional, Default=1.0_
Span name limit allows for name truncation in case of very long names. The proportion of requests to trace, specified between 0.0 and 1.0.
This can prevent certain tracing providers to drop traces that exceed their length limits.
`0` means no truncation will occur.
```yaml tab="File (YAML)" ```yaml tab="File (YAML)"
tracing: tracing:
spanNameLimit: 150 sampleRate: 0.2
``` ```
```toml tab="File (TOML)" ```toml tab="File (TOML)"
[tracing] [tracing]
spanNameLimit = 150 sampleRate = 0.2
``` ```
```bash tab="CLI" ```bash tab="CLI"
--tracing.spanNameLimit=150 --tracing.sampleRate=0.2
```
#### `headers`
_Optional, Default={}_
Defines additional headers to be sent with the span's payload.
```yaml tab="File (YAML)"
tracing:
headers:
foo: bar
baz: buz
```
```toml tab="File (TOML)"
[tracing]
[tracing.headers]
foo = "bar"
baz = "buz"
```
```bash tab="CLI"
--tracing.headers.foo=bar --tracing.headers.baz=buz
```
#### `globalAttributes`
_Optional, Default=empty_
Applies a list of shared key:value attributes on all spans.
```yaml tab="File (YAML)"
tracing:
globalAttributes:
attr1: foo
attr2: bar
```
```toml tab="File (TOML)"
[tracing]
[tracing.globalAttributes]
attr1 = "foo"
attr2 = "bar"
```
```bash tab="CLI"
--tracing.globalAttributes.attr1=foo
--tracing.globalAttributes.attr2=bar
``` ```

View file

@ -1,110 +0,0 @@
---
title: "Traefik Zipkin Documentation"
description: "Traefik supports several tracing backends, including Zipkin. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation."
---
# Zipkin
To enable the Zipkin tracer:
```yaml tab="File (YAML)"
tracing:
zipkin: {}
```
```toml tab="File (TOML)"
[tracing]
[tracing.zipkin]
```
```bash tab="CLI"
--tracing.zipkin=true
```
#### `httpEndpoint`
_Required, Default="http://localhost:9411/api/v2/spans"_
HTTP endpoint used to send data.
```yaml tab="File (YAML)"
tracing:
zipkin:
httpEndpoint: http://localhost:9411/api/v2/spans
```
```toml tab="File (TOML)"
[tracing]
[tracing.zipkin]
httpEndpoint = "http://localhost:9411/api/v2/spans"
```
```bash tab="CLI"
--tracing.zipkin.httpEndpoint=http://localhost:9411/api/v2/spans
```
#### `sameSpan`
_Optional, Default=false_
Uses SameSpan RPC style traces.
```yaml tab="File (YAML)"
tracing:
zipkin:
sameSpan: true
```
```toml tab="File (TOML)"
[tracing]
[tracing.zipkin]
sameSpan = true
```
```bash tab="CLI"
--tracing.zipkin.sameSpan=true
```
#### `id128Bit`
_Optional, Default=true_
Uses 128 bits trace IDs.
```yaml tab="File (YAML)"
tracing:
zipkin:
id128Bit: false
```
```toml tab="File (TOML)"
[tracing]
[tracing.zipkin]
id128Bit = false
```
```bash tab="CLI"
--tracing.zipkin.id128Bit=false
```
#### `sampleRate`
_Required, Default=1.0_
The proportion of requests to trace, specified between 0.0 and 1.0.
```yaml tab="File (YAML)"
tracing:
zipkin:
sampleRate: 0.2
```
```toml tab="File (TOML)"
[tracing]
[tracing.zipkin]
sampleRate = 0.2
```
```bash tab="CLI"
--tracing.zipkin.sampleRate=0.2
```

View file

@ -71,11 +71,11 @@ with a router attached to the service `api@internal` in the
to allow defining: to allow defining:
- One or more security features through [middlewares](../middlewares/overview.md) - One or more security features through [middlewares](../middlewares/overview.md)
like authentication ([basicAuth](../middlewares/http/basicauth.md) , [digestAuth](../middlewares/http/digestauth.md), like authentication ([basicAuth](../middlewares/http/basicauth.md), [digestAuth](../middlewares/http/digestauth.md),
[forwardAuth](../middlewares/http/forwardauth.md)) or [allowlisting](../middlewares/http/ipallowlist.md). [forwardAuth](../middlewares/http/forwardauth.md)) or [allowlisting](../middlewares/http/ipallowlist.md).
- A [router rule](#dashboard-router-rule) for accessing the dashboard, - A [router rule](#dashboard-router-rule) for accessing the dashboard,
through Traefik itself (sometimes referred as "Traefik-ception"). through Traefik itself (sometimes referred to as "Traefik-ception").
### Dashboard Router Rule ### Dashboard Router Rule
@ -83,7 +83,7 @@ As underlined in the [documentation for the `api.dashboard` option](./api.md#das
the [router rule](../routing/routers/index.md#rule) defined for Traefik must match the [router rule](../routing/routers/index.md#rule) defined for Traefik must match
the path prefixes `/api` and `/dashboard`. the path prefixes `/api` and `/dashboard`.
We recommend to use a "Host Based rule" as ```Host(`traefik.example.com`)``` to match everything on the host domain, We recommend using a "Host Based rule" as ```Host(`traefik.example.com`)``` to match everything on the host domain,
or to make sure that the defined rule captures both prefixes: or to make sure that the defined rule captures both prefixes:
```bash tab="Host Rule" ```bash tab="Host Rule"

View file

@ -33,7 +33,7 @@ whose default value is `traefik` (port `8080`).
| Path | Method | Description | | Path | Method | Description |
|---------|---------------|-----------------------------------------------------------------------------------------------------| |---------|---------------|-----------------------------------------------------------------------------------------------------|
| `/ping` | `GET`, `HEAD` | A simple endpoint to check for Traefik process liveness. Return a code `200` with the content: `OK` | | `/ping` | `GET`, `HEAD` | An endpoint to check for Traefik process liveness. Return a code `200` with the content: `OK` |
!!! note !!! note
The `cli` comes with a [`healthcheck`](./cli.md#healthcheck) command which can be used for calling this endpoint. The `cli` comes with a [`healthcheck`](./cli.md#healthcheck) command which can be used for calling this endpoint.
@ -92,10 +92,11 @@ ping:
_Optional, Default=503_ _Optional, Default=503_
During the period in which Traefik is gracefully shutting down, the ping handler During the period in which Traefik is gracefully shutting down, the ping handler
returns a 503 status code by default. If Traefik is behind e.g. a load-balancer returns a `503` status code by default.
If Traefik is behind, for example a load-balancer
doing health checks (such as the Kubernetes LivenessProbe), another code might doing health checks (such as the Kubernetes LivenessProbe), another code might
be expected as the signal for graceful termination. In which case, the be expected as the signal for graceful termination.
terminatingStatusCode can be used to set the code returned by the ping In that case, the terminatingStatusCode can be used to set the code returned by the ping
handler during termination. handler during termination.
```yaml tab="File (YAML)" ```yaml tab="File (YAML)"

View file

@ -163,7 +163,7 @@ See the [Docker API Access](#docker-api-access) section for more information.
services: services:
traefik: traefik:
image: traefik:v3.0 # The official v2 Traefik docker image image: traefik:v3.0 # The official v3 Traefik docker image
ports: ports:
- "80:80" - "80:80"
volumes: volumes:

View file

@ -80,17 +80,13 @@ This provider is proposed as an experimental feature and partially supports the
The Kubernetes Gateway API project provides several guides on how to use the APIs. The Kubernetes Gateway API project provides several guides on how to use the APIs.
These guides can help you to go further than the example above. These guides can help you to go further than the example above.
The [getting started guide](https://gateway-api.sigs.k8s.io/v1alpha2/guides/) details how to install the CRDs from their repository. The [getting started guide](https://gateway-api.sigs.k8s.io/guides/) details how to install the CRDs from their repository.
!!! note ""
Keep in mind that the Traefik Gateway provider only supports the `v0.4.0` (v1alpha2).
For now, the Traefik Gateway Provider can be used while following the below guides: For now, the Traefik Gateway Provider can be used while following the below guides:
* [Simple Gateway](https://gateway-api.sigs.k8s.io/v1alpha2/guides/simple-gateway/) * [Simple Gateway](https://gateway-api.sigs.k8s.io/guides/simple-gateway/)
* [HTTP routing](https://gateway-api.sigs.k8s.io/v1alpha2/guides/http-routing/) * [HTTP routing](https://gateway-api.sigs.k8s.io/guides/http-routing/)
* [TLS](https://gateway-api.sigs.k8s.io/v1alpha2/guides/tls/) * [TLS](https://gateway-api.sigs.k8s.io/guides/tls/)
## Resource Configuration ## Resource Configuration

View file

@ -229,3 +229,166 @@ providers:
```bash tab="CLI" ```bash tab="CLI"
--providers.redis.tls.insecureSkipVerify=true --providers.redis.tls.insecureSkipVerify=true
``` ```
### `sentinel`
_Optional_
Defines the Sentinel configuration used to interact with Redis Sentinel.
#### `masterName`
_Required_
`masterName` is the name of the Sentinel master.
```yaml tab="File (YAML)"
providers:
redis:
sentinel:
masterName: my-master
```
```toml tab="File (TOML)"
[providers.redis.sentinel]
masterName = "my-master"
```
```bash tab="CLI"
--providers.redis.sentinel.masterName=my-master
```
#### `username`
_Optional_
`username` is the username for Sentinel authentication.
```yaml tab="File (YAML)"
providers:
redis:
sentinel:
username: user
```
```toml tab="File (TOML)"
[providers.redis.sentinel]
username = "user"
```
```bash tab="CLI"
--providers.redis.sentinel.username=user
```
#### `password`
_Optional_
`password` is the password for Sentinel authentication.
```yaml tab="File (YAML)"
providers:
redis:
sentinel:
password: password
```
```toml tab="File (TOML)"
[providers.redis.sentinel]
password = "password"
```
```bash tab="CLI"
--providers.redis.sentinel.password=password
```
#### `latencyStrategy`
_Optional, Default=false_
`latencyStrategy` defines whether to route commands to the closest master or replica nodes
(mutually exclusive with RandomStrategy and ReplicaStrategy).
```yaml tab="File (YAML)"
providers:
redis:
sentinel:
latencyStrategy: true
```
```toml tab="File (TOML)"
[providers.redis.sentinel]
latencyStrategy = true
```
```bash tab="CLI"
--providers.redis.sentinel.latencyStrategy=true
```
#### `randomStrategy`
_Optional, Default=false_
`randomStrategy` defines whether to route commands randomly to master or replica nodes
(mutually exclusive with LatencyStrategy and ReplicaStrategy).
```yaml tab="File (YAML)"
providers:
redis:
sentinel:
randomStrategy: true
```
```toml tab="File (TOML)"
[providers.redis.sentinel]
randomStrategy = true
```
```bash tab="CLI"
--providers.redis.sentinel.randomStrategy=true
```
#### `replicaStrategy`
_Optional, Default=false_
`replicaStrategy` Defines whether to route all commands to replica nodes
(mutually exclusive with LatencyStrategy and RandomStrategy).
```yaml tab="File (YAML)"
providers:
redis:
sentinel:
replicaStrategy: true
```
```toml tab="File (TOML)"
[providers.redis.sentinel]
replicaStrategy = true
```
```bash tab="CLI"
--providers.redis.sentinel.replicaStrategy=true
```
#### `useDisconnectedReplicas`
_Optional, Default=false_
`useDisconnectedReplicas` defines whether to use replicas disconnected with master when cannot get connected replicas.
```yaml tab="File (YAML)"
providers:
redis:
sentinel:
useDisconnectedReplicas: true
```
```toml tab="File (TOML)"
[providers.redis.sentinel]
useDisconnectedReplicas = true
```
```bash tab="CLI"
--providers.redis.sentinel.useDisconnectedReplicas=true
```

View file

@ -68,6 +68,7 @@
- "traefik.http.middlewares.middleware11.ipallowlist.ipstrategy.depth=42" - "traefik.http.middlewares.middleware11.ipallowlist.ipstrategy.depth=42"
- "traefik.http.middlewares.middleware11.ipallowlist.ipstrategy.excludedips=foobar, foobar" - "traefik.http.middlewares.middleware11.ipallowlist.ipstrategy.excludedips=foobar, foobar"
- "traefik.http.middlewares.middleware11.ipallowlist.sourcerange=foobar, foobar" - "traefik.http.middlewares.middleware11.ipallowlist.sourcerange=foobar, foobar"
- "traefik.http.middlewares.middleware11.ipallowlist.rejectstatuscode=404"
- "traefik.http.middlewares.middleware12.inflightreq.amount=42" - "traefik.http.middlewares.middleware12.inflightreq.amount=42"
- "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.depth=42" - "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.depth=42"
- "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.excludedips=foobar, foobar" - "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.excludedips=foobar, foobar"
@ -163,6 +164,7 @@
- "traefik.http.services.service01.loadbalancer.server.scheme=foobar" - "traefik.http.services.service01.loadbalancer.server.scheme=foobar"
- "traefik.tcp.middlewares.tcpmiddleware00.ipallowlist.sourcerange=foobar, foobar" - "traefik.tcp.middlewares.tcpmiddleware00.ipallowlist.sourcerange=foobar, foobar"
- "traefik.tcp.middlewares.tcpmiddleware01.inflightconn.amount=42" - "traefik.tcp.middlewares.tcpmiddleware01.inflightconn.amount=42"
- "traefik.tcp.middlewares.tcpmiddleware02.ipallowlist.sourcerange=foobar, foobar"
- "traefik.tcp.routers.tcprouter0.entrypoints=foobar, foobar" - "traefik.tcp.routers.tcprouter0.entrypoints=foobar, foobar"
- "traefik.tcp.routers.tcprouter0.middlewares=foobar, foobar" - "traefik.tcp.routers.tcprouter0.middlewares=foobar, foobar"
- "traefik.tcp.routers.tcprouter0.rule=foobar" - "traefik.tcp.routers.tcprouter0.rule=foobar"

View file

@ -199,6 +199,7 @@
[http.middlewares.Middleware11] [http.middlewares.Middleware11]
[http.middlewares.Middleware11.ipAllowList] [http.middlewares.Middleware11.ipAllowList]
sourceRange = ["foobar", "foobar"] sourceRange = ["foobar", "foobar"]
rejectStatusCode = 404
[http.middlewares.Middleware11.ipAllowList.ipStrategy] [http.middlewares.Middleware11.ipAllowList.ipStrategy]
depth = 42 depth = 42
excludedIPs = ["foobar", "foobar"] excludedIPs = ["foobar", "foobar"]

View file

@ -225,6 +225,7 @@ http:
isDevelopment: true isDevelopment: true
Middleware11: Middleware11:
ipAllowList: ipAllowList:
rejectStatusCode: 404
sourceRange: sourceRange:
- foobar - foobar
- foobar - foobar
@ -450,6 +451,11 @@ tcp:
TCPMiddleware01: TCPMiddleware01:
inFlightConn: inFlightConn:
amount: 42 amount: 42
TCPMiddleware02:
ipAllowList:
sourceRange:
- foobar
- foobar
serversTransports: serversTransports:
TCPServersTransport0: TCPServersTransport0:
dialTimeout: 42s dialTimeout: 42s

View file

@ -0,0 +1,281 @@
# Copyright 2023 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Gateway API Experimental channel install
#
#
# config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml
#
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466
gateway.networking.k8s.io/bundle-version: v1.0.0
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null
labels:
gateway.networking.k8s.io/policy: Direct
name: backendtlspolicies.gateway.networking.k8s.io
spec:
group: gateway.networking.k8s.io
names:
categories:
- gateway-api
kind: BackendTLSPolicy
listKind: BackendTLSPolicyList
plural: backendtlspolicies
shortNames:
- btlspolicy
singular: backendtlspolicy
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha2
schema:
openAPIV3Schema:
description: BackendTLSPolicy provides a way to configure how a Gateway connects to a Backend via TLS.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: Spec defines the desired state of BackendTLSPolicy.
properties:
targetRef:
description: "TargetRef identifies an API object to apply the policy to. Only Services have Extended support. Implementations MAY support additional objects, with Implementation Specific support. Note that this config applies to the entire referenced resource by default, but this default may change in the future to provide a more granular application of the policy. \n Support: Extended for Kubernetes Service \n Support: Implementation-specific for any other resource"
properties:
group:
description: Group is the group of the target resource.
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
description: Kind is kind of the target resource.
maxLength: 63
minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string
name:
description: Name is the name of the target resource.
maxLength: 253
minLength: 1
type: string
namespace:
description: Namespace is the namespace of the referent. When unspecified, the local namespace is inferred. Even when policy targets a resource in a different namespace, it MUST only apply to traffic originating from the same namespace as the policy.
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
sectionName:
description: "SectionName is the name of a section within the target resource. When unspecified, this targetRef targets the entire resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name * Service: Port Name \n If a SectionName is specified, but does not exist on the targeted object, the Policy must fail to attach, and the policy implementation should record a `ResolvedRefs` or similar Condition in the Policy's status."
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
required:
- group
- kind
- name
type: object
tls:
description: TLS contains backend TLS policy configuration.
properties:
caCertRefs:
description: "CACertRefs contains one or more references to Kubernetes objects that contain a PEM-encoded TLS CA certificate bundle, which is used to validate a TLS handshake between the Gateway and backend Pod. \n If CACertRefs is empty or unspecified, then WellKnownCACerts must be specified. Only one of CACertRefs or WellKnownCACerts may be specified, not both. If CACertRefs is empty or unspecified, the configuration for WellKnownCACerts MUST be honored instead. \n References to a resource in a different namespace are invalid for the moment, although we will revisit this in the future. \n A single CACertRef to a Kubernetes ConfigMap kind has \"Core\" support. Implementations MAY choose to support attaching multiple certificates to a backend, but this behavior is implementation-specific. \n Support: Core - An optional single reference to a Kubernetes ConfigMap, with the CA certificate in a key named `ca.crt`. \n Support: Implementation-specific (More than one reference, or other kinds of resources)."
items:
description: "LocalObjectReference identifies an API object within the namespace of the referrer. The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid. \n References to objects with invalid Group and Kind are not valid, and must be rejected by the implementation, with appropriate Conditions set on the containing object."
properties:
group:
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:
description: Kind is kind of the referent. For example "HTTPRoute" or "Service".
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
required:
- group
- kind
- name
type: object
maxItems: 8
type: array
hostname:
description: "Hostname is used for two purposes in the connection between Gateways and backends: \n 1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066). 2. Hostname MUST be used for authentication and MUST match the certificate served by the matching backend. \n Support: Core"
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
wellKnownCACerts:
description: "WellKnownCACerts specifies whether system CA certificates may be used in the TLS handshake between the gateway and backend pod. \n If WellKnownCACerts is unspecified or empty (\"\"), then CACertRefs must be specified with at least one entry for a valid configuration. Only one of CACertRefs or WellKnownCACerts may be specified, not both. \n Support: Core for \"System\""
enum:
- System
type: string
required:
- hostname
type: object
x-kubernetes-validations:
- message: must not contain both CACertRefs and WellKnownCACerts
rule: '!(has(self.caCertRefs) && size(self.caCertRefs) > 0 && has(self.wellKnownCACerts) && self.wellKnownCACerts != "")'
- message: must specify either CACertRefs or WellKnownCACerts
rule: (has(self.caCertRefs) && size(self.caCertRefs) > 0 || has(self.wellKnownCACerts) && self.wellKnownCACerts != "")
required:
- targetRef
- tls
type: object
status:
description: Status defines the current state of BackendTLSPolicy.
properties:
ancestors:
description: "Ancestors is a list of ancestor resources (usually Gateways) that are associated with the policy, and the status of the policy with respect to each ancestor. When this policy attaches to a parent, the controller that manages the parent and the ancestors MUST add an entry to this list when the controller first sees the policy and SHOULD update the entry as appropriate when the relevant ancestor is modified. \n Note that choosing the relevant ancestor is left to the Policy designers; an important part of Policy design is designing the right object level at which to namespace this status. \n Note also that implementations MUST ONLY populate ancestor status for the Ancestor resources they are responsible for. Implementations MUST use the ControllerName field to uniquely identify the entries in this list that they are responsible for. \n Note that to achieve this, the list of PolicyAncestorStatus structs MUST be treated as a map with a composite key, made up of the AncestorRef and ControllerName fields combined. \n A maximum of 16 ancestors will be represented in this list. An empty list means the Policy is not relevant for any ancestors. \n If this slice is full, implementations MUST NOT add further entries. Instead they MUST consider the policy unimplementable and signal that on any related resources such as the ancestor that would be referenced here. For example, if this list was full on BackendTLSPolicy, no additional Gateways would be able to reference the Service targeted by the BackendTLSPolicy."
items:
description: "PolicyAncestorStatus describes the status of a route with respect to an associated Ancestor. \n Ancestors refer to objects that are either the Target of a policy or above it in terms of object hierarchy. For example, if a policy targets a Service, the Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most useful object to place Policy status on, so we recommend that implementations SHOULD use Gateway as the PolicyAncestorStatus object unless the designers have a _very_ good reason otherwise. \n In the context of policy attachment, the Ancestor is used to distinguish which resource results in a distinct application of this policy. For example, if a policy targets a Service, it may have a distinct result per attached Gateway. \n Policies targeting the same resource may have different effects depending on the ancestors of those resources. For example, different Gateways targeting the same Service may have different capabilities, especially if they have different underlying implementations. \n For example, in BackendTLSPolicy, the Policy attaches to a Service that is used as a backend in a HTTPRoute that is itself attached to a Gateway. In this case, the relevant object for status is the Gateway, and that is the ancestor object referred to in this status. \n Note that a parent is also an ancestor, so for objects where the parent is the relevant object for status, this struct SHOULD still be used. \n This struct is intended to be used in a slice that's effectively a map, with a composite key made up of the AncestorRef and the ControllerName."
properties:
ancestorRef:
description: AncestorRef corresponds with a ParentRef in the spec that this PolicyAncestorStatus struct describes the status of.
properties:
group:
default: gateway.networking.k8s.io
description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core"
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
default: Gateway
description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific."
maxLength: 63
minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string
name:
description: "Name is the name of the referent. \n Support: Core"
maxLength: 253
minLength: 1
type: string
namespace:
description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core"
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
port:
description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n "
format: int32
maximum: 65535
minimum: 1
type: integer
sectionName:
description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core"
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
required:
- name
type: object
conditions:
description: Conditions describes the status of the Policy with respect to the given Ancestor.
items:
description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating details about the transition. This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
maxItems: 8
minItems: 1
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
controllerName:
description: "ControllerName is a domain/path string that indicates the name of the controller that wrote this status. This corresponds with the controllerName field on GatewayClass. \n Example: \"example.net/gateway-controller\". \n The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). \n Controllers MUST populate this field when writing status. Controllers should ensure that entries to status populated with their ControllerName are cleaned up when they are no longer necessary."
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
type: string
required:
- ancestorRef
- controllerName
type: object
maxItems: 16
type: array
required:
- ancestors
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: null
storedVersions: null

View file

@ -1,226 +1,381 @@
#
--- # config/crd/experimental/gateway.networking.k8s.io_gatewayclasses.yaml
#
apiVersion: apiextensions.k8s.io/v1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/891 api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466
gateway.networking.k8s.io/bundle-version: v1.0.0
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null creationTimestamp: null
name: gatewayclasses.gateway.networking.k8s.io name: gatewayclasses.gateway.networking.k8s.io
spec: spec:
group: gateway.networking.k8s.io group: gateway.networking.k8s.io
names: names:
categories: categories:
- gateway-api - gateway-api
kind: GatewayClass kind: GatewayClass
listKind: GatewayClassList listKind: GatewayClassList
plural: gatewayclasses plural: gatewayclasses
shortNames: shortNames:
- gc - gc
singular: gatewayclass singular: gatewayclass
scope: Cluster scope: Cluster
versions: versions:
- additionalPrinterColumns: - additionalPrinterColumns:
- jsonPath: .spec.controller - jsonPath: .spec.controllerName
name: Controller name: Controller
type: string type: string
- jsonPath: .metadata.creationTimestamp - jsonPath: .status.conditions[?(@.type=="Accepted")].status
name: Age name: Accepted
type: date type: string
- jsonPath: .spec.description - jsonPath: .metadata.creationTimestamp
name: Description name: Age
priority: 1 type: date
type: string - jsonPath: .spec.description
name: v1alpha2 name: Description
schema: priority: 1
openAPIV3Schema: type: string
description: "GatewayClass describes a class of Gateways available to the name: v1
user for creating Gateway resources. \n It is recommended that this resource schema:
be used as a template for Gateways. This means that a Gateway is based on openAPIV3Schema:
the state of the GatewayClass at the time it was created and changes to description: "GatewayClass describes a class of Gateways available to the user for creating Gateway resources. \n 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. This recommendation is intended to limit the blast radius of changes to GatewayClass or associated parameters. If implementations choose to propagate GatewayClass changes to existing Gateways, that MUST be clearly documented by the implementation. \n Whenever one or more Gateways are using a GatewayClass, implementations SHOULD add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the associated GatewayClass. This ensures that a GatewayClass associated with a Gateway is not deleted while in use. \n GatewayClass is a Cluster level resource."
the GatewayClass or associated parameters are not propagated down to existing properties:
Gateways. This recommendation is intended to limit the blast radius of changes apiVersion:
to GatewayClass or associated parameters. If implementations choose to propagate description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
GatewayClass changes to existing Gateways, that MUST be clearly documented type: string
by the implementation. \n Whenever one or more Gateways are using a GatewayClass, kind:
implementations MUST add the `gateway-exists-finalizer.gateway.networking.k8s.io` description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
finalizer on the associated GatewayClass. This ensures that a GatewayClass type: string
associated with a Gateway is not deleted while in use. \n GatewayClass is metadata:
a Cluster level resource." type: object
properties: spec:
apiVersion: description: Spec defines the desired state of GatewayClass.
description: 'APIVersion defines the versioned schema of this representation properties:
of an object. Servers should convert recognized schemas to the latest controllerName:
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' description: "ControllerName is the name of the controller that is managing Gateways of this class. The value of this field MUST be a domain prefixed path. \n Example: \"example.net/gateway-controller\". \n This field is not mutable and cannot be empty. \n Support: Core"
type: string maxLength: 253
kind: minLength: 1
description: 'Kind is a string value representing the REST resource this pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
object represents. Servers may infer this from the endpoint the client type: string
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' x-kubernetes-validations:
type: string - message: Value is immutable
metadata: rule: self == oldSelf
type: object description:
spec: description: Description helps describe a GatewayClass with more details.
description: Spec defines the desired state of GatewayClass. maxLength: 64
properties: type: string
controllerName: parametersRef:
description: "ControllerName is the name of the controller that is description: "ParametersRef is a reference to a resource that contains the configuration parameters corresponding to the GatewayClass. This is optional if the controller does not require any additional configuration. \n ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap, or an implementation-specific custom resource. The resource can be cluster-scoped or namespace-scoped. \n If the referent cannot be found, the GatewayClass's \"InvalidParameters\" status condition will be true. \n Support: Implementation-specific"
managing Gateways of this class. The value of this field MUST be
a domain prefixed path. \n Example: \"example.net/gateway-controller\".
\n This field is not mutable and cannot be empty. \n Support: Core"
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
type: string
description:
description: Description helps describe a GatewayClass with more details.
maxLength: 64
type: string
parametersRef:
description: "ParametersRef is a reference to a resource that contains
the configuration parameters corresponding to the GatewayClass.
This is optional if the controller does not require any additional
configuration. \n ParametersRef can reference a standard Kubernetes
resource, i.e. ConfigMap, or an implementation-specific custom resource.
The resource can be cluster-scoped or namespace-scoped. \n If the
referent cannot be found, the GatewayClass's \"InvalidParameters\"
status condition will be true. \n Support: Custom"
properties:
group:
description: Group is the group of the referent.
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
description: Kind is kind of the referent.
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 referent. This
field is required when referring to a Namespace-scoped resource
and MUST be unset when referring to a Cluster-scoped resource.
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
required:
- group
- kind
- name
type: object
required:
- controllerName
type: object
status:
default:
conditions:
- lastTransitionTime: "1970-01-01T00:00:00Z"
message: Waiting for controller
reason: Waiting
status: Unknown
type: Accepted
description: Status defines the current state of GatewayClass.
properties:
conditions:
default:
- lastTransitionTime: "1970-01-01T00:00:00Z"
message: Waiting for controller
reason: Waiting
status: Unknown
type: Accepted
description: "Conditions is the current status from the controller
for this GatewayClass. \n Controllers should prefer to publish conditions
using values of GatewayClassConditionType for the type of each Condition."
items:
description: "Condition contains details for one aspect of the current
state of this API Resource. --- This struct is intended for direct
use as an array at the field path .status.conditions. For example,
type FooStatus struct{ // Represents the observations of a
foo's current state. // Known .status.conditions.type are:
\"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type
\ // +patchStrategy=merge // +listType=map // +listMapKey=type
\ Conditions []metav1.Condition `json:\"conditions,omitempty\"
patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`
\n // other fields }"
properties: properties:
lastTransitionTime: group:
description: lastTransitionTime is the last time the condition description: Group is the group of the referent.
transitioned from one status to another. This should be when maxLength: 253
the underlying condition changed. If that is not known, then pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
using the time when the API field changed is acceptable.
format: date-time
type: string type: string
message: kind:
description: message is a human readable message indicating description: Kind is kind of the referent.
details about the transition. This may be an empty string. maxLength: 63
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon. For instance, if .metadata.generation
is currently 12, but the .status.conditions[x].observedGeneration
is 9, the condition is out of date with respect to the current
state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating
the reason for the condition's last transition. Producers
of specific condition types may define expected values and
meanings for this field, and whether the values are considered
a guaranteed API. The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1 minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string type: string
status: name:
description: status of the condition, one of True, False, Unknown. description: Name is the name of the referent.
enum: maxLength: 253
- "True" minLength: 1
- "False"
- Unknown
type: string type: string
type: namespace:
description: type of condition in CamelCase or in foo.example.com/CamelCase. description: Namespace is the namespace of the referent. This field is required when referring to a Namespace-scoped resource and MUST be unset when referring to a Cluster-scoped resource.
--- Many .condition.type values are consistent across resources maxLength: 63
like Available, but because arbitrary conditions can be useful minLength: 1
(see .node.status.conditions), the ability to deconflict is pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string type: string
required: required:
- lastTransitionTime - group
- message - kind
- reason - name
- status
- type
type: object type: object
maxItems: 8 required:
type: array - controllerName
x-kubernetes-list-map-keys: type: object
- type status:
x-kubernetes-list-type: map default:
type: object conditions:
required: - lastTransitionTime: "1970-01-01T00:00:00Z"
- spec message: Waiting for controller
type: object reason: Waiting
served: true status: Unknown
storage: true type: Accepted
subresources: description: "Status defines the current state of GatewayClass. \n Implementations MUST populate status on all GatewayClass resources which specify their controller name."
status: {} properties:
conditions:
default:
- lastTransitionTime: "1970-01-01T00:00:00Z"
message: Waiting for controller
reason: Pending
status: Unknown
type: Accepted
description: "Conditions is the current status from the controller for this GatewayClass. \n Controllers should prefer to publish conditions using values of GatewayClassConditionType for the type of each Condition."
items:
description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating details about the transition. This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
maxItems: 8
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
supportedFeatures:
description: 'SupportedFeatures is the set of features the GatewayClass support. It MUST be sorted in ascending alphabetical order. '
items:
description: SupportedFeature is used to describe distinct features that are covered by conformance tests.
enum:
- Gateway
- GatewayPort8080
- GatewayStaticAddresses
- HTTPRoute
- HTTPRouteDestinationPortMatching
- HTTPRouteHostRewrite
- HTTPRouteMethodMatching
- HTTPRoutePathRedirect
- HTTPRoutePathRewrite
- HTTPRoutePortRedirect
- HTTPRouteQueryParamMatching
- HTTPRouteRequestMirror
- HTTPRouteRequestMultipleMirrors
- HTTPRouteResponseHeaderModification
- HTTPRouteSchemeRedirect
- Mesh
- ReferenceGrant
- TLSRoute
type: string
maxItems: 64
type: array
x-kubernetes-list-type: set
type: object
required:
- spec
type: object
served: true
storage: false
subresources:
status: {}
- additionalPrinterColumns:
- jsonPath: .spec.controllerName
name: Controller
type: string
- jsonPath: .status.conditions[?(@.type=="Accepted")].status
name: Accepted
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .spec.description
name: Description
priority: 1
type: string
name: v1beta1
schema:
openAPIV3Schema:
description: "GatewayClass describes a class of Gateways available to the user for creating Gateway resources. \n 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. This recommendation is intended to limit the blast radius of changes to GatewayClass or associated parameters. If implementations choose to propagate GatewayClass changes to existing Gateways, that MUST be clearly documented by the implementation. \n Whenever one or more Gateways are using a GatewayClass, implementations SHOULD add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the associated GatewayClass. This ensures that a GatewayClass associated with a Gateway is not deleted while in use. \n GatewayClass is a Cluster level resource."
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: Spec defines the desired state of GatewayClass.
properties:
controllerName:
description: "ControllerName is the name of the controller that is managing Gateways of this class. The value of this field MUST be a domain prefixed path. \n Example: \"example.net/gateway-controller\". \n This field is not mutable and cannot be empty. \n Support: Core"
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
type: string
x-kubernetes-validations:
- message: Value is immutable
rule: self == oldSelf
description:
description: Description helps describe a GatewayClass with more details.
maxLength: 64
type: string
parametersRef:
description: "ParametersRef is a reference to a resource that contains the configuration parameters corresponding to the GatewayClass. This is optional if the controller does not require any additional configuration. \n ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap, or an implementation-specific custom resource. The resource can be cluster-scoped or namespace-scoped. \n If the referent cannot be found, the GatewayClass's \"InvalidParameters\" status condition will be true. \n Support: Implementation-specific"
properties:
group:
description: Group is the group of the referent.
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
description: Kind is kind of the referent.
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 referent. This field is required when referring to a Namespace-scoped resource and MUST be unset when referring to a Cluster-scoped resource.
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
required:
- group
- kind
- name
type: object
required:
- controllerName
type: object
status:
default:
conditions:
- lastTransitionTime: "1970-01-01T00:00:00Z"
message: Waiting for controller
reason: Waiting
status: Unknown
type: Accepted
description: "Status defines the current state of GatewayClass. \n Implementations MUST populate status on all GatewayClass resources which specify their controller name."
properties:
conditions:
default:
- lastTransitionTime: "1970-01-01T00:00:00Z"
message: Waiting for controller
reason: Pending
status: Unknown
type: Accepted
description: "Conditions is the current status from the controller for this GatewayClass. \n Controllers should prefer to publish conditions using values of GatewayClassConditionType for the type of each Condition."
items:
description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating details about the transition. This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
maxItems: 8
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
supportedFeatures:
description: 'SupportedFeatures is the set of features the GatewayClass support. It MUST be sorted in ascending alphabetical order. '
items:
description: SupportedFeature is used to describe distinct features that are covered by conformance tests.
enum:
- Gateway
- GatewayPort8080
- GatewayStaticAddresses
- HTTPRoute
- HTTPRouteDestinationPortMatching
- HTTPRouteHostRewrite
- HTTPRouteMethodMatching
- HTTPRoutePathRedirect
- HTTPRoutePathRewrite
- HTTPRoutePortRedirect
- HTTPRouteQueryParamMatching
- HTTPRouteRequestMirror
- HTTPRouteRequestMultipleMirrors
- HTTPRouteResponseHeaderModification
- HTTPRouteSchemeRedirect
- Mesh
- ReferenceGrant
- TLSRoute
type: string
maxItems: 64
type: array
x-kubernetes-list-type: set
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}
status: status:
acceptedNames: acceptedNames:
kind: "" kind: ""
plural: "" plural: ""
conditions: [] conditions: null
storedVersions: [] storedVersions: null

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,819 @@
#
# config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml
#
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466
gateway.networking.k8s.io/bundle-version: v1.0.0
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null
name: grpcroutes.gateway.networking.k8s.io
spec:
group: gateway.networking.k8s.io
names:
categories:
- gateway-api
kind: GRPCRoute
listKind: GRPCRouteList
plural: grpcroutes
singular: grpcroute
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .spec.hostnames
name: Hostnames
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha2
schema:
openAPIV3Schema:
description: "GRPCRoute provides a way to route gRPC requests. This includes the capability to match requests by hostname, gRPC service, gRPC method, or HTTP/2 header. Filters can be used to specify additional processing steps. Backends specify where matching requests will be routed. \n GRPCRoute falls under extended support within the Gateway API. Within the following specification, the word \"MUST\" indicates that an implementation supporting GRPCRoute must conform to the indicated requirement, but an implementation not supporting this route type need not follow the requirement unless explicitly indicated. \n Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` MUST accept HTTP/2 connections without an initial upgrade from HTTP/1.1, i.e. via ALPN. If the implementation does not support this, then it MUST set the \"Accepted\" condition to \"False\" for the affected listener with a reason of \"UnsupportedProtocol\". Implementations MAY also accept HTTP/2 connections with an upgrade from HTTP/1. \n Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` MUST support HTTP/2 over cleartext TCP (h2c, https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial upgrade from HTTP/1.1, i.e. with prior knowledge (https://www.rfc-editor.org/rfc/rfc7540#section-3.4). If the implementation does not support this, then it MUST set the \"Accepted\" condition to \"False\" for the affected listener with a reason of \"UnsupportedProtocol\". Implementations MAY also accept HTTP/2 connections with an upgrade from HTTP/1, i.e. without prior knowledge."
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: Spec defines the desired state of GRPCRoute.
properties:
hostnames:
description: "Hostnames defines a set of hostnames to match against the GRPC Host header to select a GRPCRoute to process the request. This matches the RFC 1123 definition of a hostname with 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label MUST appear by itself as the first label. \n If a hostname is specified by both the Listener and GRPCRoute, there MUST be at least one intersecting hostname for the GRPCRoute to be attached to the Listener. For example: \n * A Listener with `test.example.com` as the hostname matches GRPCRoutes that have either not specified any hostnames, or have specified at least one of `test.example.com` or `*.example.com`. * A Listener with `*.example.com` as the hostname matches GRPCRoutes that have either not specified any hostnames or have specified at least one hostname that matches the Listener hostname. For example, `test.example.com` and `*.example.com` would both match. On the other hand, `example.com` and `test.example.net` would not match. \n Hostnames that are prefixed with a wildcard label (`*.`) are interpreted as a suffix match. That means that a match for `*.example.com` would match both `test.example.com`, and `foo.test.example.com`, but not `example.com`. \n If both the Listener and GRPCRoute have specified hostnames, any GRPCRoute hostnames that do not match the Listener hostname MUST be ignored. For example, if a Listener specified `*.example.com`, and the GRPCRoute specified `test.example.com` and `test.example.net`, `test.example.net` MUST NOT be considered for a match. \n If both the Listener and GRPCRoute have specified hostnames, and none match with the criteria above, then the GRPCRoute MUST NOT be accepted by the implementation. The implementation MUST raise an 'Accepted' Condition with a status of `False` in the corresponding RouteParentStatus. \n If a Route (A) of type HTTPRoute or GRPCRoute is attached to a Listener and that listener already has another Route (B) of the other type attached and the intersection of the hostnames of A and B is non-empty, then the implementation MUST accept exactly one of these two routes, determined by the following criteria, in order: \n * The oldest Route based on creation timestamp. * The Route appearing first in alphabetical order by \"{namespace}/{name}\". \n The rejected Route MUST raise an 'Accepted' condition with a status of 'False' in the corresponding RouteParentStatus. \n Support: Core"
items:
description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 definition of a hostname with 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. \n Hostname can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. `*.example.com`). \n Note that as per RFC1035 and RFC1123, a *label* must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character. No other punctuation is allowed."
maxLength: 253
minLength: 1
pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
maxItems: 16
type: array
parentRefs:
description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) This API may be extended in the future to support additional kinds of parent resources. \n ParentRefs must be _distinct_. This means either that: \n * They select different objects. If this is the case, then parentRef entries are distinct. In terms of fields, this means that the multi-part key defined by `group`, `kind`, `namespace`, and `name` must be unique across all parentRef entries in the Route. * They do not select different objects, but for each optional field used, each ParentRef that selects the same object must set the same set of optional fields to different values. If one ParentRef sets a combination of optional fields, all must set the same combination. \n Some examples: \n * If one ParentRef sets `sectionName`, all ParentRefs referencing the same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same object must also set `port`. * If one ParentRef sets `sectionName` and `port`, all ParentRefs referencing the same object must also set `sectionName` and `port`. \n It is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged. \n Note that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n "
items:
description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n This API may be extended in the future to support additional kinds of parent resources. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid."
properties:
group:
default: gateway.networking.k8s.io
description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core"
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
default: Gateway
description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific."
maxLength: 63
minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string
name:
description: "Name is the name of the referent. \n Support: Core"
maxLength: 253
minLength: 1
type: string
namespace:
description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core"
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
port:
description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n "
format: int32
maximum: 65535
minimum: 1
type: integer
sectionName:
description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core"
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
required:
- name
type: object
maxItems: 32
type: array
x-kubernetes-validations:
- message: sectionName or port must be specified when parentRefs includes 2 or more references to the same parent
rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__ == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))'
- message: sectionName or port must be unique when parentRefs includes 2 or more references to the same parent
rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))
rules:
description: Rules are a list of GRPC matchers, filters and actions.
items:
description: GRPCRouteRule defines the semantics for matching a gRPC request based on conditions (matches), processing it (filters), and forwarding the request to an API object (backendRefs).
properties:
backendRefs:
description: "BackendRefs defines the backend(s) where matching requests should be sent. \n Failure behavior here depends on how many BackendRefs are specified and how many are invalid. \n If *all* entries in BackendRefs are invalid, and there are also no filters specified in this route rule, *all* traffic which matches this rule MUST receive an `UNAVAILABLE` status. \n See the GRPCBackendRef definition for the rules about what makes a single GRPCBackendRef invalid. \n When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for requests that would have otherwise been routed to an invalid backend. If multiple backends are specified, and some are invalid, the proportion of requests that would otherwise have been routed to an invalid backend MUST receive an `UNAVAILABLE` status. \n For example, if two backends are specified with equal weights, and one is invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status. Implementations may choose how that 50 percent is determined. \n Support: Core for Kubernetes Service \n Support: Implementation-specific for any other resource \n Support for weight: Core"
items:
description: "GRPCBackendRef defines how a GRPCRoute forwards a gRPC request. \n 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. \n <gateway:experimental:description> \n When the BackendRef points to a Kubernetes Service, implementations SHOULD honor the appProtocol field if it is set for the target Service Port. \n Implementations supporting appProtocol SHOULD recognize the Kubernetes Standard Application Protocols defined in KEP-3726. \n If a Service appProtocol isn't specified, an implementation MAY infer the backend protocol through its own means. Implementations MAY infer the protocol from the Route type referring to the backend Service. \n If a Route is not able to send traffic to the backend using the specified protocol then the backend is considered invalid. Implementations MUST set the \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason. \n </gateway:experimental:description>"
properties:
filters:
description: "Filters defined at this level MUST be executed if and only if the request is being forwarded to the backend defined here. \n Support: Implementation-specific (For broader support of filters, use the Filters field in GRPCRouteRule.)"
items:
description: GRPCRouteFilter defines processing steps that must be completed during the request or response lifecycle. GRPCRouteFilters are meant as an extension point to express processing that may be done in Gateway implementations. Some examples include request or response modification, implementing authentication strategies, rate-limiting, and traffic shaping. API guarantee/conformance is defined based on the type of the filter.
properties:
extensionRef:
description: "ExtensionRef is an optional, implementation-specific extension to the \"filter\" behavior. For example, resource \"myroutefilter\" in group \"networking.example.net\"). ExtensionRef MUST NOT be used for core and extended filters. \n Support: Implementation-specific \n This filter can be used multiple times within the same rule."
properties:
group:
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:
description: Kind is kind of the referent. For example "HTTPRoute" or "Service".
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
required:
- group
- kind
- name
type: object
requestHeaderModifier:
description: "RequestHeaderModifier defines a schema for a filter that modifies request headers. \n Support: Core"
properties:
add:
description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz"
items:
description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230.
properties:
name:
description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent."
maxLength: 256
minLength: 1
pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
type: string
value:
description: Value is the value of HTTP Header to be matched.
maxLength: 4096
minLength: 1
type: string
required:
- name
- value
type: object
maxItems: 16
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
remove:
description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar"
items:
type: string
maxItems: 16
type: array
x-kubernetes-list-type: set
set:
description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar"
items:
description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230.
properties:
name:
description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent."
maxLength: 256
minLength: 1
pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
type: string
value:
description: Value is the value of HTTP Header to be matched.
maxLength: 4096
minLength: 1
type: string
required:
- name
- value
type: object
maxItems: 16
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
type: object
requestMirror:
description: "RequestMirror defines a schema for a filter that mirrors requests. Requests are sent to the specified destination, but responses from that destination are ignored. \n This filter can be used multiple times within the same rule. Note that not all implementations will be able to support mirroring to multiple backends. \n Support: Extended"
properties:
backendRef:
description: "BackendRef references a resource where mirrored requests are sent. \n Mirrored requests must be sent only to a single destination endpoint within this BackendRef, irrespective of how many endpoints are present within this BackendRef. \n If the referent cannot be found, this BackendRef is invalid and must be dropped from the Gateway. The controller must ensure the \"ResolvedRefs\" condition on the Route status is set to `status: False` and not configure this backend in the underlying implementation. \n If there is a cross-namespace reference to an *existing* object that is not allowed by a ReferenceGrant, the controller must ensure the \"ResolvedRefs\" condition on the Route is set to `status: False`, with the \"RefNotPermitted\" reason and not configure this backend in the underlying implementation. \n In either error case, the Message of the `ResolvedRefs` Condition should be used to provide more detail about the problem. \n Support: Extended for Kubernetes Service \n Support: Implementation-specific for any other resource"
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\". \n Defaults to \"Service\" when not specified. \n 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. \n Support: Core (Services with a type other than ExternalName) \n 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. \n 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. \n 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'
required:
- backendRef
type: object
responseHeaderModifier:
description: "ResponseHeaderModifier defines a schema for a filter that modifies response headers. \n Support: Extended"
properties:
add:
description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz"
items:
description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230.
properties:
name:
description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent."
maxLength: 256
minLength: 1
pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
type: string
value:
description: Value is the value of HTTP Header to be matched.
maxLength: 4096
minLength: 1
type: string
required:
- name
- value
type: object
maxItems: 16
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
remove:
description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar"
items:
type: string
maxItems: 16
type: array
x-kubernetes-list-type: set
set:
description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar"
items:
description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230.
properties:
name:
description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent."
maxLength: 256
minLength: 1
pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
type: string
value:
description: Value is the value of HTTP Header to be matched.
maxLength: 4096
minLength: 1
type: string
required:
- name
- value
type: object
maxItems: 16
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
type: object
type:
description: "Type identifies the type of filter to apply. As with other API fields, types are classified into three conformance levels: \n - Core: Filter types and their corresponding configuration defined by \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All implementations supporting GRPCRoute MUST support core filters. \n - Extended: Filter types and their corresponding configuration defined by \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers are encouraged to support extended filters. \n - Implementation-specific: Filters that are defined and supported by specific vendors. In the future, filters showing convergence in behavior across multiple implementations will be considered for inclusion in extended or core conformance levels. Filter-specific configuration for such filters is specified using the ExtensionRef field. `Type` MUST be set to \"ExtensionRef\" for custom filters. \n Implementers are encouraged to define custom implementation types to extend the core API with implementation-specific behavior. \n If a reference to a custom filter type cannot be resolved, the filter MUST NOT be skipped. Instead, requests that would have been processed by that filter MUST receive a HTTP error response. \n "
enum:
- ResponseHeaderModifier
- RequestHeaderModifier
- RequestMirror
- ExtensionRef
type: string
required:
- type
type: object
x-kubernetes-validations:
- message: filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier
rule: '!(has(self.requestHeaderModifier) && self.type != ''RequestHeaderModifier'')'
- message: filter.requestHeaderModifier must be specified for RequestHeaderModifier filter.type
rule: '!(!has(self.requestHeaderModifier) && self.type == ''RequestHeaderModifier'')'
- message: filter.responseHeaderModifier must be nil if the filter.type is not ResponseHeaderModifier
rule: '!(has(self.responseHeaderModifier) && self.type != ''ResponseHeaderModifier'')'
- message: filter.responseHeaderModifier must be specified for ResponseHeaderModifier filter.type
rule: '!(!has(self.responseHeaderModifier) && self.type == ''ResponseHeaderModifier'')'
- message: filter.requestMirror must be nil if the filter.type is not RequestMirror
rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'
- message: filter.requestMirror must be specified for RequestMirror filter.type
rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')'
- message: filter.extensionRef must be nil if the filter.type is not ExtensionRef
rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'
- message: filter.extensionRef must be specified for ExtensionRef filter.type
rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'
maxItems: 16
type: array
x-kubernetes-validations:
- message: RequestHeaderModifier filter cannot be repeated
rule: self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1
- message: ResponseHeaderModifier filter cannot be repeated
rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() <= 1
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\". \n Defaults to \"Service\" when not specified. \n 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. \n Support: Core (Services with a type other than ExternalName) \n 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. \n 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. \n 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
weight:
default: 1
description: "Weight specifies the proportion of requests forwarded to the referenced backend. This is computed as weight/(sum of all weights in this BackendRefs list). For non-zero values, there may be some epsilon from the exact proportion defined here depending on the precision an implementation supports. Weight is not a percentage and the sum of weights does not need to equal 100. \n If only one backend is specified and it has a weight greater than 0, 100% of the traffic is forwarded to that backend. If weight is set to 0, no traffic should be forwarded for this entry. If unspecified, weight defaults to 1. \n Support for this field varies based on the context where used."
format: int32
maximum: 1000000
minimum: 0
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: 16
type: array
filters:
description: "Filters define the filters that are applied to requests that match this rule. \n The effects of ordering of multiple behaviors are currently unspecified. This can change in the future based on feedback during the alpha stage. \n Conformance-levels at this level are defined based on the type of filter: \n - ALL core filters MUST be supported by all implementations that support GRPCRoute. - Implementers are encouraged to support extended filters. - Implementation-specific custom filters have no API guarantees across implementations. \n Specifying the same filter multiple times is not supported unless explicitly indicated in the filter. \n If an implementation can not support a combination of filters, it must clearly document that limitation. In cases where incompatible or unsupported filters are specified and cause the `Accepted` condition to be set to status `False`, implementations may use the `IncompatibleFilters` reason to specify this configuration error. \n Support: Core"
items:
description: GRPCRouteFilter defines processing steps that must be completed during the request or response lifecycle. GRPCRouteFilters are meant as an extension point to express processing that may be done in Gateway implementations. Some examples include request or response modification, implementing authentication strategies, rate-limiting, and traffic shaping. API guarantee/conformance is defined based on the type of the filter.
properties:
extensionRef:
description: "ExtensionRef is an optional, implementation-specific extension to the \"filter\" behavior. For example, resource \"myroutefilter\" in group \"networking.example.net\"). ExtensionRef MUST NOT be used for core and extended filters. \n Support: Implementation-specific \n This filter can be used multiple times within the same rule."
properties:
group:
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:
description: Kind is kind of the referent. For example "HTTPRoute" or "Service".
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
required:
- group
- kind
- name
type: object
requestHeaderModifier:
description: "RequestHeaderModifier defines a schema for a filter that modifies request headers. \n Support: Core"
properties:
add:
description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz"
items:
description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230.
properties:
name:
description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent."
maxLength: 256
minLength: 1
pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
type: string
value:
description: Value is the value of HTTP Header to be matched.
maxLength: 4096
minLength: 1
type: string
required:
- name
- value
type: object
maxItems: 16
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
remove:
description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar"
items:
type: string
maxItems: 16
type: array
x-kubernetes-list-type: set
set:
description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar"
items:
description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230.
properties:
name:
description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent."
maxLength: 256
minLength: 1
pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
type: string
value:
description: Value is the value of HTTP Header to be matched.
maxLength: 4096
minLength: 1
type: string
required:
- name
- value
type: object
maxItems: 16
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
type: object
requestMirror:
description: "RequestMirror defines a schema for a filter that mirrors requests. Requests are sent to the specified destination, but responses from that destination are ignored. \n This filter can be used multiple times within the same rule. Note that not all implementations will be able to support mirroring to multiple backends. \n Support: Extended"
properties:
backendRef:
description: "BackendRef references a resource where mirrored requests are sent. \n Mirrored requests must be sent only to a single destination endpoint within this BackendRef, irrespective of how many endpoints are present within this BackendRef. \n If the referent cannot be found, this BackendRef is invalid and must be dropped from the Gateway. The controller must ensure the \"ResolvedRefs\" condition on the Route status is set to `status: False` and not configure this backend in the underlying implementation. \n If there is a cross-namespace reference to an *existing* object that is not allowed by a ReferenceGrant, the controller must ensure the \"ResolvedRefs\" condition on the Route is set to `status: False`, with the \"RefNotPermitted\" reason and not configure this backend in the underlying implementation. \n In either error case, the Message of the `ResolvedRefs` Condition should be used to provide more detail about the problem. \n Support: Extended for Kubernetes Service \n Support: Implementation-specific for any other resource"
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\". \n Defaults to \"Service\" when not specified. \n 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. \n Support: Core (Services with a type other than ExternalName) \n 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. \n 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. \n 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'
required:
- backendRef
type: object
responseHeaderModifier:
description: "ResponseHeaderModifier defines a schema for a filter that modifies response headers. \n Support: Extended"
properties:
add:
description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz"
items:
description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230.
properties:
name:
description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent."
maxLength: 256
minLength: 1
pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
type: string
value:
description: Value is the value of HTTP Header to be matched.
maxLength: 4096
minLength: 1
type: string
required:
- name
- value
type: object
maxItems: 16
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
remove:
description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar"
items:
type: string
maxItems: 16
type: array
x-kubernetes-list-type: set
set:
description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar"
items:
description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230.
properties:
name:
description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent."
maxLength: 256
minLength: 1
pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
type: string
value:
description: Value is the value of HTTP Header to be matched.
maxLength: 4096
minLength: 1
type: string
required:
- name
- value
type: object
maxItems: 16
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
type: object
type:
description: "Type identifies the type of filter to apply. As with other API fields, types are classified into three conformance levels: \n - Core: Filter types and their corresponding configuration defined by \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All implementations supporting GRPCRoute MUST support core filters. \n - Extended: Filter types and their corresponding configuration defined by \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers are encouraged to support extended filters. \n - Implementation-specific: Filters that are defined and supported by specific vendors. In the future, filters showing convergence in behavior across multiple implementations will be considered for inclusion in extended or core conformance levels. Filter-specific configuration for such filters is specified using the ExtensionRef field. `Type` MUST be set to \"ExtensionRef\" for custom filters. \n Implementers are encouraged to define custom implementation types to extend the core API with implementation-specific behavior. \n If a reference to a custom filter type cannot be resolved, the filter MUST NOT be skipped. Instead, requests that would have been processed by that filter MUST receive a HTTP error response. \n "
enum:
- ResponseHeaderModifier
- RequestHeaderModifier
- RequestMirror
- ExtensionRef
type: string
required:
- type
type: object
x-kubernetes-validations:
- message: filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier
rule: '!(has(self.requestHeaderModifier) && self.type != ''RequestHeaderModifier'')'
- message: filter.requestHeaderModifier must be specified for RequestHeaderModifier filter.type
rule: '!(!has(self.requestHeaderModifier) && self.type == ''RequestHeaderModifier'')'
- message: filter.responseHeaderModifier must be nil if the filter.type is not ResponseHeaderModifier
rule: '!(has(self.responseHeaderModifier) && self.type != ''ResponseHeaderModifier'')'
- message: filter.responseHeaderModifier must be specified for ResponseHeaderModifier filter.type
rule: '!(!has(self.responseHeaderModifier) && self.type == ''ResponseHeaderModifier'')'
- message: filter.requestMirror must be nil if the filter.type is not RequestMirror
rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')'
- message: filter.requestMirror must be specified for RequestMirror filter.type
rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')'
- message: filter.extensionRef must be nil if the filter.type is not ExtensionRef
rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')'
- message: filter.extensionRef must be specified for ExtensionRef filter.type
rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'
maxItems: 16
type: array
x-kubernetes-validations:
- message: RequestHeaderModifier filter cannot be repeated
rule: self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1
- message: ResponseHeaderModifier filter cannot be repeated
rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() <= 1
matches:
description: "Matches define conditions used for matching the rule against incoming gRPC requests. Each match is independent, i.e. this rule will be matched if **any** one of the matches is satisfied. \n For example, take the following matches configuration: \n ``` matches: - method: service: foo.bar headers: values: version: 2 - method: service: foo.bar.v2 ``` \n For a request to match against this rule, it MUST satisfy EITHER of the two conditions: \n - service of foo.bar AND contains the header `version: 2` - service of foo.bar.v2 \n See the documentation for GRPCRouteMatch on how to specify multiple match conditions to be ANDed together. \n If no matches are specified, the implementation MUST match every gRPC request. \n Proxy or Load Balancer routing configuration generated from GRPCRoutes MUST prioritize rules based on the following criteria, continuing on ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes. Precedence MUST be given to the rule with the largest number of: \n * Characters in a matching non-wildcard hostname. * Characters in a matching hostname. * Characters in a matching service. * Characters in a matching method. * Header matches. \n If ties still exist across multiple Routes, matching precedence MUST be determined in order of the following criteria, continuing on ties: \n * The oldest Route based on creation timestamp. * The Route appearing first in alphabetical order by \"{namespace}/{name}\". \n If ties still exist within the Route that has been given precedence, matching precedence MUST be granted to the first matching rule meeting the above criteria."
items:
description: "GRPCRouteMatch defines the predicate used to match requests to a given action. Multiple match types are ANDed together, i.e. the match will evaluate to true only if all conditions are satisfied. \n For example, the match below will match a gRPC request only if its service is `foo` AND it contains the `version: v1` header: \n ``` matches: - method: type: Exact service: \"foo\" headers: - name: \"version\" value \"v1\" \n ```"
properties:
headers:
description: Headers specifies gRPC request header matchers. Multiple match values are ANDed together, meaning, a request MUST match all the specified headers to select the route.
items:
description: GRPCHeaderMatch describes how to select a gRPC route by matching gRPC request headers.
properties:
name:
description: "Name is the name of the gRPC Header to be matched. \n If multiple entries specify equivalent header names, only the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent."
maxLength: 256
minLength: 1
pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
type: string
type:
default: Exact
description: Type specifies how to match against the value of the header.
enum:
- Exact
- RegularExpression
type: string
value:
description: Value is the value of the gRPC Header to be matched.
maxLength: 4096
minLength: 1
type: string
required:
- name
- value
type: object
maxItems: 16
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
method:
description: Method specifies a gRPC request service/method matcher. If this field is not specified, all services and methods will match.
properties:
method:
description: "Value of the method to match against. If left empty or omitted, will match all services. \n At least one of Service and Method MUST be a non-empty string."
maxLength: 1024
type: string
service:
description: "Value of the service to match against. If left empty or omitted, will match any service. \n At least one of Service and Method MUST be a non-empty string."
maxLength: 1024
type: string
type:
default: Exact
description: "Type specifies how to match against the service and/or method. Support: Core (Exact with service and method specified) \n Support: Implementation-specific (Exact with method specified but no service specified) \n Support: Implementation-specific (RegularExpression)"
enum:
- Exact
- RegularExpression
type: string
type: object
x-kubernetes-validations:
- message: One or both of 'service' or 'method' must be specified
rule: 'has(self.type) ? has(self.service) || has(self.method) : true'
- message: service must only contain valid characters (matching ^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$)
rule: '(!has(self.type) || self.type == ''Exact'') && has(self.service) ? self.service.matches(r"""^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$"""): true'
- message: method must only contain valid characters (matching ^[A-Za-z_][A-Za-z_0-9]*$)
rule: '(!has(self.type) || self.type == ''Exact'') && has(self.method) ? self.method.matches(r"""^[A-Za-z_][A-Za-z_0-9]*$"""): true'
type: object
maxItems: 8
type: array
type: object
maxItems: 16
type: array
type: object
status:
description: Status defines the current state of GRPCRoute.
properties:
parents:
description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified. \n Note that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for. \n A maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway."
items:
description: RouteParentStatus describes the status of a route with respect to an associated Parent.
properties:
conditions:
description: "Conditions describes the status of the route with respect to the Gateway. Note that the route's availability is also subject to the Gateway's own status conditions and listener status. \n If the Route's ParentRef specifies an existing Gateway that supports Routes of this kind AND that Gateway's controller has sufficient access, then that Gateway's controller MUST set the \"Accepted\" condition on the Route, to indicate whether the route has been accepted or rejected by the Gateway, and why. \n A Route MUST be considered \"Accepted\" if at least one of the Route's rules is implemented by the Gateway. \n There are a number of cases where the \"Accepted\" condition may not be set due to lack of controller visibility, that includes when: \n * The Route refers to a non-existent parent. * The Route is of a type that the controller does not support. * The Route is in a namespace the controller does not have access to."
items:
description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating details about the transition. This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
maxItems: 8
minItems: 1
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
controllerName:
description: "ControllerName is a domain/path string that indicates the name of the controller that wrote this status. This corresponds with the controllerName field on GatewayClass. \n Example: \"example.net/gateway-controller\". \n The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). \n Controllers MUST populate this field when writing status. Controllers should ensure that entries to status populated with their ControllerName are cleaned up when they are no longer necessary."
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
type: string
parentRef:
description: ParentRef corresponds with a ParentRef in the spec that this RouteParentStatus struct describes the status of.
properties:
group:
default: gateway.networking.k8s.io
description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core"
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
default: Gateway
description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific."
maxLength: 63
minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string
name:
description: "Name is the name of the referent. \n Support: Core"
maxLength: 253
minLength: 1
type: string
namespace:
description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core"
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
port:
description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n "
format: int32
maximum: 65535
minimum: 1
type: integer
sectionName:
description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core"
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
required:
- name
type: object
required:
- controllerName
- parentRef
type: object
maxItems: 32
type: array
required:
- parents
type: object
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: null
storedVersions: null

View file

@ -0,0 +1,205 @@
#
# config/crd/experimental/gateway.networking.k8s.io_referencegrants.yaml
#
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466
gateway.networking.k8s.io/bundle-version: v1.0.0
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null
name: referencegrants.gateway.networking.k8s.io
spec:
group: gateway.networking.k8s.io
names:
categories:
- gateway-api
kind: ReferenceGrant
listKind: ReferenceGrantList
plural: referencegrants
shortNames:
- refgrant
singular: referencegrant
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
deprecated: true
deprecationWarning: The v1alpha2 version of ReferenceGrant has been deprecated and will be removed in a future release of the API. Please upgrade to v1beta1.
name: v1alpha2
schema:
openAPIV3Schema:
description: "ReferenceGrant identifies kinds of resources in other namespaces that are trusted to reference the specified kinds of resources in the same namespace as the policy. \n Each ReferenceGrant can be used to represent a unique trust relationship. Additional Reference Grants can be used to add to the set of trusted sources of inbound references for the namespace they are defined within. \n A ReferenceGrant is required for all cross-namespace references in Gateway API (with the exception of cross-namespace Route-Gateway attachment, which is governed by the AllowedRoutes configuration on the Gateway, and cross-namespace Service ParentRefs on a \"consumer\" mesh Route, which defines routing rules applicable only to workloads in the Route namespace). ReferenceGrants allowing a reference from a Route to a Service are only applicable to BackendRefs. \n ReferenceGrant is a form of runtime verification allowing users to assert which cross-namespace object references are permitted. Implementations that support ReferenceGrant MUST NOT permit cross-namespace references which have no grant, and MUST respond to the removal of a grant by revoking the access that the grant allowed."
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: Spec defines the desired state of ReferenceGrant.
properties:
from:
description: "From describes the trusted namespaces and kinds that can reference the resources described in \"To\". Each entry in this list MUST be considered to be an additional place that references can be valid from, or to put this another way, entries MUST be combined using OR. \n Support: Core"
items:
description: ReferenceGrantFrom describes trusted namespaces and kinds.
properties:
group:
description: "Group is the group of the referent. When empty, the Kubernetes core API group is inferred. \n Support: Core"
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
description: "Kind is the kind of the referent. Although implementations may support additional resources, the following types are part of the \"Core\" support level for this field. \n When used to permit a SecretObjectReference: \n * Gateway \n When used to permit a BackendObjectReference: \n * GRPCRoute * HTTPRoute * TCPRoute * TLSRoute * UDPRoute"
maxLength: 63
minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string
namespace:
description: "Namespace is the namespace of the referent. \n Support: Core"
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
required:
- group
- kind
- namespace
type: object
maxItems: 16
minItems: 1
type: array
to:
description: "To describes the resources that may be referenced by the resources described in \"From\". Each entry in this list MUST be considered to be an additional place that references can be valid to, or to put this another way, entries MUST be combined using OR. \n Support: Core"
items:
description: ReferenceGrantTo describes what Kinds are allowed as targets of the references.
properties:
group:
description: "Group is the group of the referent. When empty, the Kubernetes core API group is inferred. \n Support: Core"
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
description: "Kind is the kind of the referent. Although implementations may support additional resources, the following types are part of the \"Core\" support level for this field: \n * Secret when used to permit a SecretObjectReference * Service when used to permit a BackendObjectReference"
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. When unspecified, this policy refers to all resources of the specified Group and Kind in the local namespace.
maxLength: 253
minLength: 1
type: string
required:
- group
- kind
type: object
maxItems: 16
minItems: 1
type: array
required:
- from
- to
type: object
type: object
served: true
storage: false
subresources: {}
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: "ReferenceGrant identifies kinds of resources in other namespaces that are trusted to reference the specified kinds of resources in the same namespace as the policy. \n Each ReferenceGrant can be used to represent a unique trust relationship. Additional Reference Grants can be used to add to the set of trusted sources of inbound references for the namespace they are defined within. \n All cross-namespace references in Gateway API (with the exception of cross-namespace Gateway-route attachment) require a ReferenceGrant. \n ReferenceGrant is a form of runtime verification allowing users to assert which cross-namespace object references are permitted. Implementations that support ReferenceGrant MUST NOT permit cross-namespace references which have no grant, and MUST respond to the removal of a grant by revoking the access that the grant allowed."
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: Spec defines the desired state of ReferenceGrant.
properties:
from:
description: "From describes the trusted namespaces and kinds that can reference the resources described in \"To\". Each entry in this list MUST be considered to be an additional place that references can be valid from, or to put this another way, entries MUST be combined using OR. \n Support: Core"
items:
description: ReferenceGrantFrom describes trusted namespaces and kinds.
properties:
group:
description: "Group is the group of the referent. When empty, the Kubernetes core API group is inferred. \n Support: Core"
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
description: "Kind is the kind of the referent. Although implementations may support additional resources, the following types are part of the \"Core\" support level for this field. \n When used to permit a SecretObjectReference: \n * Gateway \n When used to permit a BackendObjectReference: \n * GRPCRoute * HTTPRoute * TCPRoute * TLSRoute * UDPRoute"
maxLength: 63
minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string
namespace:
description: "Namespace is the namespace of the referent. \n Support: Core"
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
required:
- group
- kind
- namespace
type: object
maxItems: 16
minItems: 1
type: array
to:
description: "To describes the resources that may be referenced by the resources described in \"From\". Each entry in this list MUST be considered to be an additional place that references can be valid to, or to put this another way, entries MUST be combined using OR. \n Support: Core"
items:
description: ReferenceGrantTo describes what Kinds are allowed as targets of the references.
properties:
group:
description: "Group is the group of the referent. When empty, the Kubernetes core API group is inferred. \n Support: Core"
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
description: "Kind is the kind of the referent. Although implementations may support additional resources, the following types are part of the \"Core\" support level for this field: \n * Secret when used to permit a SecretObjectReference * Service when used to permit a BackendObjectReference"
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. When unspecified, this policy refers to all resources of the specified Group and Kind in the local namespace.
maxLength: 253
minLength: 1
type: string
required:
- group
- kind
type: object
maxItems: 16
minItems: 1
type: array
required:
- from
- to
type: object
type: object
served: true
storage: true
subresources: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: null
storedVersions: null

View file

@ -1,431 +1,284 @@
#
--- # config/crd/experimental/gateway.networking.k8s.io_tcproutes.yaml
#
apiVersion: apiextensions.k8s.io/v1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/891 api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466
gateway.networking.k8s.io/bundle-version: v1.0.0
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null creationTimestamp: null
name: tcproutes.gateway.networking.k8s.io name: tcproutes.gateway.networking.k8s.io
spec: spec:
group: gateway.networking.k8s.io group: gateway.networking.k8s.io
names: names:
categories: categories:
- gateway-api - gateway-api
kind: TCPRoute kind: TCPRoute
listKind: TCPRouteList listKind: TCPRouteList
plural: tcproutes plural: tcproutes
singular: tcproute singular: tcproute
scope: Namespaced scope: Namespaced
versions: versions:
- additionalPrinterColumns: - additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp - jsonPath: .metadata.creationTimestamp
name: Age name: Age
type: date type: date
name: v1alpha2 name: v1alpha2
schema: schema:
openAPIV3Schema: openAPIV3Schema:
description: TCPRoute provides a way to route TCP requests. When combined description: TCPRoute provides a way to route TCP requests. When combined with a Gateway listener, it can be used to forward connections on the port specified by the listener to a set of backends specified by the TCPRoute.
with a Gateway listener, it can be used to forward connections on the port properties:
specified by the listener to a set of backends specified by the TCPRoute. apiVersion:
properties: description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
apiVersion: type: string
description: 'APIVersion defines the versioned schema of this representation kind:
of an object. Servers should convert recognized schemas to the latest description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string
type: string metadata:
kind: type: object
description: 'Kind is a string value representing the REST resource this spec:
object represents. Servers may infer this from the endpoint the client description: Spec defines the desired state of TCPRoute.
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' properties:
type: string parentRefs:
metadata: description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) This API may be extended in the future to support additional kinds of parent resources. \n ParentRefs must be _distinct_. This means either that: \n * They select different objects. If this is the case, then parentRef entries are distinct. In terms of fields, this means that the multi-part key defined by `group`, `kind`, `namespace`, and `name` must be unique across all parentRef entries in the Route. * They do not select different objects, but for each optional field used, each ParentRef that selects the same object must set the same set of optional fields to different values. If one ParentRef sets a combination of optional fields, all must set the same combination. \n Some examples: \n * If one ParentRef sets `sectionName`, all ParentRefs referencing the same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same object must also set `port`. * If one ParentRef sets `sectionName` and `port`, all ParentRefs referencing the same object must also set `sectionName` and `port`. \n It is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged. \n Note that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n "
type: object items:
spec: description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n This API may be extended in the future to support additional kinds of parent resources. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid."
description: Spec defines the desired state of TCPRoute. properties:
properties: group:
parentRefs: default: gateway.networking.k8s.io
description: "ParentRefs references the resources (usually Gateways) description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core"
that a Route wants to be attached to. Note that the referenced parent maxLength: 253
resource needs to allow this for the attachment to be complete. pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
For Gateways, that means the Gateway needs to allow attachment from type: string
Routes of this kind and namespace. \n The only kind of parent resource kind:
with \"Core\" support is Gateway. This API may be extended in the default: Gateway
future to support additional kinds of parent resources such as one description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific."
of the route kinds. \n It is invalid to reference an identical parent maxLength: 63
more than once. It is valid to reference multiple distinct sections minLength: 1
within the same parent resource, such as 2 Listeners within a Gateway. pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
\n It is possible to separately reference multiple distinct objects type: string
that may be collapsed by an implementation. For example, some implementations name:
may choose to merge compatible Gateway Listeners together. If that description: "Name is the name of the referent. \n Support: Core"
is the case, the list of routes attached to those resources should maxLength: 253
also be merged." minLength: 1
items: type: string
description: "ParentRef identifies an API object (usually a Gateway) namespace:
that can be considered a parent of this resource (usually a route). description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core"
The only kind of parent resource with \"Core\" support is Gateway. maxLength: 63
This API may be extended in the future to support additional kinds minLength: 1
of parent resources, such as HTTPRoute. \n The API object must pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
be valid in the cluster; the Group and Kind must be registered type: string
in the cluster for this reference to be valid. \n References to port:
objects with invalid Group and Kind are not valid, and must be description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n "
rejected by the implementation, with appropriate Conditions set format: int32
on the containing object." maximum: 65535
properties: minimum: 1
group: type: integer
default: gateway.networking.k8s.io sectionName:
description: "Group is the group of the referent. \n Support: description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core"
Core" maxLength: 253
maxLength: 253 minLength: 1
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string type: string
kind: required:
default: Gateway - name
description: "Kind is kind of the referent. \n Support: Core type: object
(Gateway) Support: Custom (Other Resources)" maxItems: 32
maxLength: 63 type: array
minLength: 1 x-kubernetes-validations:
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - message: sectionName or port must be specified when parentRefs includes 2 or more references to the same parent
type: string rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__ == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))'
name: - message: sectionName or port must be unique when parentRefs includes 2 or more references to the same parent
description: "Name is the name of the referent. \n Support: rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))
Core" rules:
maxLength: 253 description: Rules are a list of TCP matchers and actions.
minLength: 1 items:
type: string description: TCPRouteRule is the configuration for a given rule.
namespace: properties:
description: "Namespace is the namespace of the referent. When backendRefs:
unspecified (or empty string), this refers to the local namespace description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a non-existent resource or a Service with no endpoints), the underlying implementation MUST actively reject connection attempts to this backend. Connection rejections must respect weight; if an invalid backend is requested to have 80% of connections, then 80% of connections must be rejected instead. \n Support: Core for Kubernetes Service \n Support: Extended for Kubernetes ServiceImport \n Support: Implementation-specific for any other resource \n Support for weight: Extended"
of the Route. \n Support: Core" items:
maxLength: 63 description: "BackendRef defines how a Route should forward a request to a Kubernetes resource. \n 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. \n <gateway:experimental:description> \n When the BackendRef points to a Kubernetes Service, implementations SHOULD honor the appProtocol field if it is set for the target Service Port. \n Implementations supporting appProtocol SHOULD recognize the Kubernetes Standard Application Protocols defined in KEP-3726. \n If a Service appProtocol isn't specified, an implementation MAY infer the backend protocol through its own means. Implementations MAY infer the protocol from the Route type referring to the backend Service. \n If a Route is not able to send traffic to the backend using the specified protocol then the backend is considered invalid. Implementations MUST set the \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason. \n </gateway:experimental:description> \n Note that when the BackendTLSPolicy object is enabled by the implementation, there are some extra rules about validity to consider here. See the fields where this struct is used for more information about the exact behavior."
minLength: 1 properties:
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ group:
type: string default: ""
sectionName: description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred.
description: "SectionName is the name of a section within the maxLength: 253
target resource. In the following resources, SectionName is pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
interpreted as the following: \n * Gateway: Listener Name type: string
\n Implementations MAY choose to support attaching Routes kind:
to other resources. If that is the case, they MUST clearly default: Service
document how SectionName is interpreted. \n When unspecified description: "Kind is the Kubernetes resource kind of the referent. For example \"Service\". \n Defaults to \"Service\" when not specified. \n 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. \n Support: Core (Services with a type other than ExternalName) \n Support: Implementation-specific (Services with type ExternalName)"
(empty string), this will reference the entire resource. For maxLength: 63
the purpose of status, an attachment is considered successful minLength: 1
if at least one section in the parent resource accepts it. pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
For example, Gateway listeners can restrict which Routes can type: string
attach to them by Route kind, namespace, or hostname. If 1 name:
of 2 Gateway listeners accept attachment from the referencing description: Name is the name of the referent.
Route, the Route MUST be considered successfully attached. maxLength: 253
If no Gateway listeners accept attachment from this Route, minLength: 1
the Route MUST be considered detached from the Gateway. \n type: string
Support: Core" namespace:
maxLength: 253 description: "Namespace is the namespace of the backend. When unspecified, the local namespace is inferred. \n 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. \n Support: Core"
minLength: 1 maxLength: 63
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ minLength: 1
type: string pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
required: type: string
- name port:
type: object 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.
maxItems: 32 format: int32
type: array maximum: 65535
rules: minimum: 1
description: Rules are a list of TCP matchers and actions. type: integer
items: weight:
description: TCPRouteRule is the configuration for a given rule. default: 1
properties: description: "Weight specifies the proportion of requests forwarded to the referenced backend. This is computed as weight/(sum of all weights in this BackendRefs list). For non-zero values, there may be some epsilon from the exact proportion defined here depending on the precision an implementation supports. Weight is not a percentage and the sum of weights does not need to equal 100. \n If only one backend is specified and it has a weight greater than 0, 100% of the traffic is forwarded to that backend. If weight is set to 0, no traffic should be forwarded for this entry. If unspecified, weight defaults to 1. \n Support for this field varies based on the context where used."
backendRefs: format: int32
description: "BackendRefs defines the backend(s) where matching maximum: 1000000
requests should be sent. If unspecified or invalid (refers minimum: 0
to a non-existent resource or a Service with no endpoints), type: integer
the underlying implementation MUST actively reject connection required:
attempts to this backend. Connection rejections must respect - name
weight; if an invalid backend is requested to have 80% of type: object
connections, then 80% of connections must be rejected instead. x-kubernetes-validations:
\n Support: Core for Kubernetes Service Support: Custom for - message: Must have port for Service reference
any other resource \n Support for weight: Extended" rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true'
items: maxItems: 16
description: "BackendRef defines how a Route should forward minItems: 1
a request to a Kubernetes resource. \n Note that when a type: array
namespace is specified, a ReferencePolicy object is required type: object
in the referent namespace to allow that namespace's owner maxItems: 16
to accept the reference. See the ReferencePolicy documentation minItems: 1
for details." type: array
required:
- rules
type: object
status:
description: Status defines the current state of TCPRoute.
properties:
parents:
description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified. \n Note that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for. \n A maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway."
items:
description: RouteParentStatus describes the status of a route with respect to an associated Parent.
properties:
conditions:
description: "Conditions describes the status of the route with respect to the Gateway. Note that the route's availability is also subject to the Gateway's own status conditions and listener status. \n If the Route's ParentRef specifies an existing Gateway that supports Routes of this kind AND that Gateway's controller has sufficient access, then that Gateway's controller MUST set the \"Accepted\" condition on the Route, to indicate whether the route has been accepted or rejected by the Gateway, and why. \n A Route MUST be considered \"Accepted\" if at least one of the Route's rules is implemented by the Gateway. \n There are a number of cases where the \"Accepted\" condition may not be set due to lack of controller visibility, that includes when: \n * The Route refers to a non-existent parent. * The Route is of a type that the controller does not support. * The Route is in a namespace the controller does not have access to."
items:
description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating details about the transition. This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
maxItems: 8
minItems: 1
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
controllerName:
description: "ControllerName is a domain/path string that indicates the name of the controller that wrote this status. This corresponds with the controllerName field on GatewayClass. \n Example: \"example.net/gateway-controller\". \n The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). \n Controllers MUST populate this field when writing status. Controllers should ensure that entries to status populated with their ControllerName are cleaned up when they are no longer necessary."
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
type: string
parentRef:
description: ParentRef corresponds with a ParentRef in the spec that this RouteParentStatus struct describes the status of.
properties: properties:
group: group:
default: "" default: gateway.networking.k8s.io
description: Group is the group of the referent. For example, description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core"
"networking.k8s.io". When unspecified (empty string),
core API group is inferred.
maxLength: 253 maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string type: string
kind: kind:
default: Service default: Gateway
description: Kind is kind of the referent. For example description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific."
"HTTPRoute" or "Service".
maxLength: 63 maxLength: 63
minLength: 1 minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string type: string
name: name:
description: Name is the name of the referent. description: "Name is the name of the referent. \n Support: Core"
maxLength: 253 maxLength: 253
minLength: 1 minLength: 1
type: string type: string
namespace: namespace:
description: "Namespace is the namespace of the backend. description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core"
When unspecified, the local namespace is inferred. \n
Note that when a namespace is specified, a ReferencePolicy
object is required in the referent namespace to allow
that namespace's owner to accept the reference. See
the ReferencePolicy documentation for details. \n Support:
Core"
maxLength: 63 maxLength: 63
minLength: 1 minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string type: string
port: port:
description: Port specifies the destination port number description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n "
to use for this resource. Port is required when the
referent is a Kubernetes Service. For other resources,
destination port might be derived from the referent
resource or this field.
format: int32 format: int32
maximum: 65535 maximum: 65535
minimum: 1 minimum: 1
type: integer type: integer
weight: sectionName:
default: 1 description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core"
description: "Weight specifies the proportion of requests maxLength: 253
forwarded to the referenced backend. This is computed
as weight/(sum of all weights in this BackendRefs list).
For non-zero values, there may be some epsilon from
the exact proportion defined here depending on the precision
an implementation supports. Weight is not a percentage
and the sum of weights does not need to equal 100. \n
If only one backend is specified and it has a weight
greater than 0, 100% of the traffic is forwarded to
that backend. If weight is set to 0, no traffic should
be forwarded for this entry. If unspecified, weight
defaults to 1. \n Support for this field varies based
on the context where used."
format: int32
maximum: 1000000
minimum: 0
type: integer
required:
- name
type: object
maxItems: 16
minItems: 1
type: array
type: object
maxItems: 16
minItems: 1
type: array
required:
- rules
type: object
status:
description: Status defines the current state of TCPRoute.
properties:
parents:
description: "Parents is a list of parent resources (usually Gateways)
that are associated with the route, and the status of the route
with respect to each parent. When this route attaches to a parent,
the controller that manages the parent must add an entry to this
list when the controller first sees the route and should update
the entry as appropriate when the route or gateway is modified.
\n Note that parent references that cannot be resolved by an implementation
of this API will not be added to this list. Implementations of this
API can only populate Route status for the Gateways/parent resources
they are responsible for. \n A maximum of 32 Gateways will be represented
in this list. An empty list means the route has not been attached
to any Gateway."
items:
description: RouteParentStatus describes the status of a route with
respect to an associated Parent.
properties:
conditions:
description: "Conditions describes the status of the route with
respect to the Gateway. Note that the route's availability
is also subject to the Gateway's own status conditions and
listener status. \n If the Route's ParentRef specifies an
existing Gateway that supports Routes of this kind AND that
Gateway's controller has sufficient access, then that Gateway's
controller MUST set the \"Accepted\" condition on the Route,
to indicate whether the route has been accepted or rejected
by the Gateway, and why. \n A Route MUST be considered \"Accepted\"
if at least one of the Route's rules is implemented by the
Gateway. \n There are a number of cases where the \"Accepted\"
condition may not be set due to lack of controller visibility,
that includes when: \n * The Route refers to a non-existent
parent. * The Route is of a type that the controller does
not support. * The Route is in a namespace the the controller
does not have access to."
items:
description: "Condition contains details for one aspect of
the current state of this API Resource. --- This struct
is intended for direct use as an array at the field path
.status.conditions. For example, type FooStatus struct{
\ // Represents the observations of a foo's current state.
\ // Known .status.conditions.type are: \"Available\",
\"Progressing\", and \"Degraded\" // +patchMergeKey=type
\ // +patchStrategy=merge // +listType=map //
+listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\"
patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`
\n // other fields }"
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition
transitioned from one status to another. This should
be when the underlying condition changed. If that is
not known, then using the time when the API field changed
is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating
details about the transition. This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon. For instance,
if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration
is 9, the condition is out of date with respect to the
current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier
indicating the reason for the condition's last transition.
Producers of specific condition types may define expected
values and meanings for this field, and whether the
values are considered a guaranteed API. The value should
be a CamelCase string. This field may not be empty.
maxLength: 1024
minLength: 1 minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
status:
description: status of the condition, one of True, False,
Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
--- Many .condition.type values are consistent across
resources like Available, but because arbitrary conditions
can be useful (see .node.status.conditions), the ability
to deconflict is important. The regex it matches is
(dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string type: string
required: required:
- lastTransitionTime - name
- message
- reason
- status
- type
type: object type: object
maxItems: 8 required:
minItems: 1 - controllerName
type: array - parentRef
x-kubernetes-list-map-keys: type: object
- type maxItems: 32
x-kubernetes-list-type: map type: array
controllerName: required:
description: "ControllerName is a domain/path string that indicates - parents
the name of the controller that wrote this status. This corresponds type: object
with the controllerName field on GatewayClass. \n Example: required:
\"example.net/gateway-controller\". \n The format of this - spec
field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid type: object
Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names)." served: true
maxLength: 253 storage: true
minLength: 1 subresources:
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ status: {}
type: string
parentRef:
description: ParentRef corresponds with a ParentRef in the spec
that this RouteParentStatus struct describes the status of.
properties:
group:
default: gateway.networking.k8s.io
description: "Group is the group of the referent. \n Support:
Core"
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
default: Gateway
description: "Kind is kind of the referent. \n Support:
Core (Gateway) Support: Custom (Other Resources)"
maxLength: 63
minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string
name:
description: "Name is the name of the referent. \n Support:
Core"
maxLength: 253
minLength: 1
type: string
namespace:
description: "Namespace is the namespace of the referent.
When unspecified (or empty string), this refers to the
local namespace of the Route. \n Support: Core"
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
sectionName:
description: "SectionName is the name of a section within
the target resource. In the following resources, SectionName
is interpreted as the following: \n * Gateway: Listener
Name \n Implementations MAY choose to support attaching
Routes to other resources. If that is the case, they MUST
clearly document how SectionName is interpreted. \n When
unspecified (empty string), this will reference the entire
resource. For the purpose of status, an attachment is
considered successful if at least one section in the parent
resource accepts it. For example, Gateway listeners can
restrict which Routes can attach to them by Route kind,
namespace, or hostname. If 1 of 2 Gateway listeners accept
attachment from the referencing Route, the Route MUST
be considered successfully attached. If no Gateway listeners
accept attachment from this Route, the Route MUST be considered
detached from the Gateway. \n Support: Core"
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
required:
- name
type: object
required:
- controllerName
- parentRef
type: object
maxItems: 32
type: array
required:
- parents
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}
status: status:
acceptedNames: acceptedNames:
kind: "" kind: ""
plural: "" plural: ""
conditions: [] conditions: null
storedVersions: [] storedVersions: null

View file

@ -1,480 +1,294 @@
#
--- # config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml
#
apiVersion: apiextensions.k8s.io/v1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/891 api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466
gateway.networking.k8s.io/bundle-version: v1.0.0
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null creationTimestamp: null
name: tlsroutes.gateway.networking.k8s.io name: tlsroutes.gateway.networking.k8s.io
spec: spec:
group: gateway.networking.k8s.io group: gateway.networking.k8s.io
names: names:
categories: categories:
- gateway-api - gateway-api
kind: TLSRoute kind: TLSRoute
listKind: TLSRouteList listKind: TLSRouteList
plural: tlsroutes plural: tlsroutes
singular: tlsroute singular: tlsroute
scope: Namespaced scope: Namespaced
versions: versions:
- additionalPrinterColumns: - additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp - jsonPath: .metadata.creationTimestamp
name: Age name: Age
type: date type: date
name: v1alpha2 name: v1alpha2
schema: schema:
openAPIV3Schema: openAPIV3Schema:
description: "The TLSRoute resource is similar to TCPRoute, but can be configured description: "The TLSRoute resource is similar to TCPRoute, but can be configured to match against TLS-specific metadata. This allows more flexibility in matching streams for a given TLS listener. \n If you need to forward traffic to a single target for a TLS listener, you could choose to use a TCPRoute with a TLS listener."
to match against TLS-specific metadata. This allows more flexibility in properties:
matching streams for a given TLS listener. \n If you need to forward traffic apiVersion:
to a single target for a TLS listener, you could choose to use a TCPRoute description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
with a TLS listener." type: string
properties: kind:
apiVersion: description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: 'APIVersion defines the versioned schema of this representation type: string
of an object. Servers should convert recognized schemas to the latest metadata:
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: object
type: string spec:
kind: description: Spec defines the desired state of TLSRoute.
description: 'Kind is a string value representing the REST resource this properties:
object represents. Servers may infer this from the endpoint the client hostnames:
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' description: "Hostnames defines a set of SNI names that should match against the SNI attribute of TLS ClientHello message in TLS handshake. This matches the RFC 1123 definition of a hostname with 2 notable exceptions: \n 1. IPs are not allowed in SNI names per RFC 6066. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. \n If a hostname is specified by both the Listener and TLSRoute, there must be at least one intersecting hostname for the TLSRoute to be attached to the Listener. For example: \n * A Listener with `test.example.com` as the hostname matches TLSRoutes that have either not specified any hostnames, or have specified at least one of `test.example.com` or `*.example.com`. * A Listener with `*.example.com` as the hostname matches TLSRoutes that have either not specified any hostnames or have specified at least one hostname that matches the Listener hostname. For example, `test.example.com` and `*.example.com` would both match. On the other hand, `example.com` and `test.example.net` would not match. \n If both the Listener and TLSRoute have specified hostnames, any TLSRoute hostnames that do not match the Listener hostname MUST be ignored. For example, if a Listener specified `*.example.com`, and the TLSRoute specified `test.example.com` and `test.example.net`, `test.example.net` must not be considered for a match. \n If both the Listener and TLSRoute have specified hostnames, and none match with the criteria above, then the TLSRoute is not accepted. The implementation must raise an 'Accepted' Condition with a status of `False` in the corresponding RouteParentStatus. \n Support: Core"
type: string items:
metadata: description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 definition of a hostname with 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. \n Hostname can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. `*.example.com`). \n Note that as per RFC1035 and RFC1123, a *label* must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character. No other punctuation is allowed."
type: object maxLength: 253
spec: minLength: 1
description: Spec defines the desired state of TLSRoute. pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
properties: type: string
hostnames: maxItems: 16
description: "Hostnames defines a set of SNI names that should match type: array
against the SNI attribute of TLS ClientHello message in TLS handshake. parentRefs:
This matches the RFC 1123 definition of a hostname with 2 notable description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) This API may be extended in the future to support additional kinds of parent resources. \n ParentRefs must be _distinct_. This means either that: \n * They select different objects. If this is the case, then parentRef entries are distinct. In terms of fields, this means that the multi-part key defined by `group`, `kind`, `namespace`, and `name` must be unique across all parentRef entries in the Route. * They do not select different objects, but for each optional field used, each ParentRef that selects the same object must set the same set of optional fields to different values. If one ParentRef sets a combination of optional fields, all must set the same combination. \n Some examples: \n * If one ParentRef sets `sectionName`, all ParentRefs referencing the same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same object must also set `port`. * If one ParentRef sets `sectionName` and `port`, all ParentRefs referencing the same object must also set `sectionName` and `port`. \n It is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged. \n Note that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n "
exceptions: \n 1. IPs are not allowed in SNI names per RFC 6066. items:
2. A hostname may be prefixed with a wildcard label (`*.`). The description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n This API may be extended in the future to support additional kinds of parent resources. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid."
wildcard label must appear by itself as the first label. \n If properties:
a hostname is specified by both the Listener and TLSRoute, there group:
must be at least one intersecting hostname for the TLSRoute to be default: gateway.networking.k8s.io
attached to the Listener. For example: \n * A Listener with `test.example.com` description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core"
as the hostname matches TLSRoutes that have either not specified maxLength: 253
any hostnames, or have specified at least one of `test.example.com` pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
or `*.example.com`. * A Listener with `*.example.com` as the hostname type: string
matches TLSRoutes that have either not specified any hostnames kind:
or have specified at least one hostname that matches the Listener default: Gateway
hostname. For example, `test.example.com` and `*.example.com` description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific."
would both match. On the other hand, `example.com` and `test.example.net` maxLength: 63
would not match. \n If both the Listener and TLSRoute have specified minLength: 1
hostnames, any TLSRoute hostnames that do not match the Listener pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
hostname MUST be ignored. For example, if a Listener specified `*.example.com`, type: string
and the TLSRoute specified `test.example.com` and `test.example.net`, name:
`test.example.net` must not be considered for a match. \n If both description: "Name is the name of the referent. \n Support: Core"
the Listener and TLSRoute have specified hostnames, and none match maxLength: 253
with the criteria above, then the TLSRoute is not accepted. The minLength: 1
implementation must raise an 'Accepted' Condition with a status type: string
of `False` in the corresponding RouteParentStatus. \n Support: Core" namespace:
items: description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core"
description: "Hostname is the fully qualified domain name of a network maxLength: 63
host. This matches the RFC 1123 definition of a hostname with minLength: 1
2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
may be prefixed with a wildcard label (`*.`). The wildcard label type: string
must appear by itself as the first label. \n Hostname can be \"precise\" port:
which is a domain name without the terminating dot of a network description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n "
host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain format: int32
name prefixed with a single wildcard label (e.g. `*.example.com`). maximum: 65535
\n Note that as per RFC1035 and RFC1123, a *label* must consist minimum: 1
of lower case alphanumeric characters or '-', and must start and type: integer
end with an alphanumeric character. No other punctuation is allowed." sectionName:
maxLength: 253 description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core"
minLength: 1 maxLength: 253
pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ minLength: 1
type: string pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
maxItems: 16 type: string
type: array required:
parentRefs: - name
description: "ParentRefs references the resources (usually Gateways) type: object
that a Route wants to be attached to. Note that the referenced parent maxItems: 32
resource needs to allow this for the attachment to be complete. type: array
For Gateways, that means the Gateway needs to allow attachment from x-kubernetes-validations:
Routes of this kind and namespace. \n The only kind of parent resource - message: sectionName or port must be specified when parentRefs includes 2 or more references to the same parent
with \"Core\" support is Gateway. This API may be extended in the rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__ == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))'
future to support additional kinds of parent resources such as one - message: sectionName or port must be unique when parentRefs includes 2 or more references to the same parent
of the route kinds. \n It is invalid to reference an identical parent rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))
more than once. It is valid to reference multiple distinct sections rules:
within the same parent resource, such as 2 Listeners within a Gateway. description: Rules are a list of TLS matchers and actions.
\n It is possible to separately reference multiple distinct objects items:
that may be collapsed by an implementation. For example, some implementations description: TLSRouteRule is the configuration for a given rule.
may choose to merge compatible Gateway Listeners together. If that properties:
is the case, the list of routes attached to those resources should backendRefs:
also be merged." description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a non-existent resource or a Service with no endpoints), the rule performs no forwarding; if no filters are specified that would result in a response being sent, the underlying implementation must actively reject request attempts to this backend, by rejecting the connection or returning a 500 status code. Request rejections must respect weight; if an invalid backend is requested to have 80% of requests, then 80% of requests must be rejected instead. \n Support: Core for Kubernetes Service \n Support: Extended for Kubernetes ServiceImport \n Support: Implementation-specific for any other resource \n Support for weight: Extended"
items: items:
description: "ParentRef identifies an API object (usually a Gateway) description: "BackendRef defines how a Route should forward a request to a Kubernetes resource. \n 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. \n <gateway:experimental:description> \n When the BackendRef points to a Kubernetes Service, implementations SHOULD honor the appProtocol field if it is set for the target Service Port. \n Implementations supporting appProtocol SHOULD recognize the Kubernetes Standard Application Protocols defined in KEP-3726. \n If a Service appProtocol isn't specified, an implementation MAY infer the backend protocol through its own means. Implementations MAY infer the protocol from the Route type referring to the backend Service. \n If a Route is not able to send traffic to the backend using the specified protocol then the backend is considered invalid. Implementations MUST set the \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason. \n </gateway:experimental:description> \n Note that when the BackendTLSPolicy object is enabled by the implementation, there are some extra rules about validity to consider here. See the fields where this struct is used for more information about the exact behavior."
that can be considered a parent of this resource (usually a route). properties:
The only kind of parent resource with \"Core\" support is Gateway. group:
This API may be extended in the future to support additional kinds default: ""
of parent resources, such as HTTPRoute. \n The API object must description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred.
be valid in the cluster; the Group and Kind must be registered maxLength: 253
in the cluster for this reference to be valid. \n References to pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
objects with invalid Group and Kind are not valid, and must be type: string
rejected by the implementation, with appropriate Conditions set kind:
on the containing object." default: Service
properties: description: "Kind is the Kubernetes resource kind of the referent. For example \"Service\". \n Defaults to \"Service\" when not specified. \n 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. \n Support: Core (Services with a type other than ExternalName) \n Support: Implementation-specific (Services with type ExternalName)"
group: maxLength: 63
default: gateway.networking.k8s.io minLength: 1
description: "Group is the group of the referent. \n Support: pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
Core" type: string
maxLength: 253 name:
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ description: Name is the name of the referent.
type: string maxLength: 253
kind: minLength: 1
default: Gateway type: string
description: "Kind is kind of the referent. \n Support: Core namespace:
(Gateway) Support: Custom (Other Resources)" description: "Namespace is the namespace of the backend. When unspecified, the local namespace is inferred. \n 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. \n Support: Core"
maxLength: 63 maxLength: 63
minLength: 1 minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string type: string
name: port:
description: "Name is the name of the referent. \n Support: 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.
Core" format: int32
maxLength: 253 maximum: 65535
minLength: 1 minimum: 1
type: string type: integer
namespace: weight:
description: "Namespace is the namespace of the referent. When default: 1
unspecified (or empty string), this refers to the local namespace description: "Weight specifies the proportion of requests forwarded to the referenced backend. This is computed as weight/(sum of all weights in this BackendRefs list). For non-zero values, there may be some epsilon from the exact proportion defined here depending on the precision an implementation supports. Weight is not a percentage and the sum of weights does not need to equal 100. \n If only one backend is specified and it has a weight greater than 0, 100% of the traffic is forwarded to that backend. If weight is set to 0, no traffic should be forwarded for this entry. If unspecified, weight defaults to 1. \n Support for this field varies based on the context where used."
of the Route. \n Support: Core" format: int32
maxLength: 63 maximum: 1000000
minLength: 1 minimum: 0
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: integer
type: string required:
sectionName: - name
description: "SectionName is the name of a section within the type: object
target resource. In the following resources, SectionName is x-kubernetes-validations:
interpreted as the following: \n * Gateway: Listener Name - message: Must have port for Service reference
\n Implementations MAY choose to support attaching Routes rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true'
to other resources. If that is the case, they MUST clearly maxItems: 16
document how SectionName is interpreted. \n When unspecified minItems: 1
(empty string), this will reference the entire resource. For type: array
the purpose of status, an attachment is considered successful type: object
if at least one section in the parent resource accepts it. maxItems: 16
For example, Gateway listeners can restrict which Routes can minItems: 1
attach to them by Route kind, namespace, or hostname. If 1 type: array
of 2 Gateway listeners accept attachment from the referencing required:
Route, the Route MUST be considered successfully attached. - rules
If no Gateway listeners accept attachment from this Route, type: object
the Route MUST be considered detached from the Gateway. \n status:
Support: Core" description: Status defines the current state of TLSRoute.
maxLength: 253 properties:
minLength: 1 parents:
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified. \n Note that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for. \n A maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway."
type: string items:
required: description: RouteParentStatus describes the status of a route with respect to an associated Parent.
- name properties:
type: object conditions:
maxItems: 32 description: "Conditions describes the status of the route with respect to the Gateway. Note that the route's availability is also subject to the Gateway's own status conditions and listener status. \n If the Route's ParentRef specifies an existing Gateway that supports Routes of this kind AND that Gateway's controller has sufficient access, then that Gateway's controller MUST set the \"Accepted\" condition on the Route, to indicate whether the route has been accepted or rejected by the Gateway, and why. \n A Route MUST be considered \"Accepted\" if at least one of the Route's rules is implemented by the Gateway. \n There are a number of cases where the \"Accepted\" condition may not be set due to lack of controller visibility, that includes when: \n * The Route refers to a non-existent parent. * The Route is of a type that the controller does not support. * The Route is in a namespace the controller does not have access to."
type: array items:
rules: description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
description: Rules are a list of TLS matchers and actions. properties:
items: lastTransitionTime:
description: TLSRouteRule is the configuration for a given rule. description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
properties: format: date-time
backendRefs: type: string
description: "BackendRefs defines the backend(s) where matching message:
requests should be sent. If unspecified or invalid (refers description: message is a human readable message indicating details about the transition. This may be an empty string.
to a non-existent resource or a Service with no endpoints), maxLength: 32768
the rule performs no forwarding; if no filters are specified type: string
that would result in a response being sent, the underlying observedGeneration:
implementation must actively reject request attempts to this description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
backend, by rejecting the connection or returning a 503 status format: int64
code. Request rejections must respect weight; if an invalid minimum: 0
backend is requested to have 80% of requests, then 80% of type: integer
requests must be rejected instead. \n Support: Core for Kubernetes reason:
Service Support: Custom for any other resource \n Support description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
for weight: Extended" maxLength: 1024
items: minLength: 1
description: "BackendRef defines how a Route should forward pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
a request to a Kubernetes resource. \n Note that when a type: string
namespace is specified, a ReferencePolicy object is required status:
in the referent namespace to allow that namespace's owner description: status of the condition, one of True, False, Unknown.
to accept the reference. See the ReferencePolicy documentation enum:
for details." - "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
maxItems: 8
minItems: 1
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
controllerName:
description: "ControllerName is a domain/path string that indicates the name of the controller that wrote this status. This corresponds with the controllerName field on GatewayClass. \n Example: \"example.net/gateway-controller\". \n The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). \n Controllers MUST populate this field when writing status. Controllers should ensure that entries to status populated with their ControllerName are cleaned up when they are no longer necessary."
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
type: string
parentRef:
description: ParentRef corresponds with a ParentRef in the spec that this RouteParentStatus struct describes the status of.
properties: properties:
group: group:
default: "" default: gateway.networking.k8s.io
description: Group is the group of the referent. For example, description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core"
"networking.k8s.io". When unspecified (empty string),
core API group is inferred.
maxLength: 253 maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string type: string
kind: kind:
default: Service default: Gateway
description: Kind is kind of the referent. For example description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific."
"HTTPRoute" or "Service".
maxLength: 63 maxLength: 63
minLength: 1 minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string type: string
name: name:
description: Name is the name of the referent. description: "Name is the name of the referent. \n Support: Core"
maxLength: 253 maxLength: 253
minLength: 1 minLength: 1
type: string type: string
namespace: namespace:
description: "Namespace is the namespace of the backend. description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core"
When unspecified, the local namespace is inferred. \n
Note that when a namespace is specified, a ReferencePolicy
object is required in the referent namespace to allow
that namespace's owner to accept the reference. See
the ReferencePolicy documentation for details. \n Support:
Core"
maxLength: 63 maxLength: 63
minLength: 1 minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string type: string
port: port:
description: Port specifies the destination port number description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n "
to use for this resource. Port is required when the
referent is a Kubernetes Service. For other resources,
destination port might be derived from the referent
resource or this field.
format: int32 format: int32
maximum: 65535 maximum: 65535
minimum: 1 minimum: 1
type: integer type: integer
weight: sectionName:
default: 1 description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core"
description: "Weight specifies the proportion of requests maxLength: 253
forwarded to the referenced backend. This is computed
as weight/(sum of all weights in this BackendRefs list).
For non-zero values, there may be some epsilon from
the exact proportion defined here depending on the precision
an implementation supports. Weight is not a percentage
and the sum of weights does not need to equal 100. \n
If only one backend is specified and it has a weight
greater than 0, 100% of the traffic is forwarded to
that backend. If weight is set to 0, no traffic should
be forwarded for this entry. If unspecified, weight
defaults to 1. \n Support for this field varies based
on the context where used."
format: int32
maximum: 1000000
minimum: 0
type: integer
required:
- name
type: object
maxItems: 16
minItems: 1
type: array
type: object
maxItems: 16
minItems: 1
type: array
required:
- rules
type: object
status:
description: Status defines the current state of TLSRoute.
properties:
parents:
description: "Parents is a list of parent resources (usually Gateways)
that are associated with the route, and the status of the route
with respect to each parent. When this route attaches to a parent,
the controller that manages the parent must add an entry to this
list when the controller first sees the route and should update
the entry as appropriate when the route or gateway is modified.
\n Note that parent references that cannot be resolved by an implementation
of this API will not be added to this list. Implementations of this
API can only populate Route status for the Gateways/parent resources
they are responsible for. \n A maximum of 32 Gateways will be represented
in this list. An empty list means the route has not been attached
to any Gateway."
items:
description: RouteParentStatus describes the status of a route with
respect to an associated Parent.
properties:
conditions:
description: "Conditions describes the status of the route with
respect to the Gateway. Note that the route's availability
is also subject to the Gateway's own status conditions and
listener status. \n If the Route's ParentRef specifies an
existing Gateway that supports Routes of this kind AND that
Gateway's controller has sufficient access, then that Gateway's
controller MUST set the \"Accepted\" condition on the Route,
to indicate whether the route has been accepted or rejected
by the Gateway, and why. \n A Route MUST be considered \"Accepted\"
if at least one of the Route's rules is implemented by the
Gateway. \n There are a number of cases where the \"Accepted\"
condition may not be set due to lack of controller visibility,
that includes when: \n * The Route refers to a non-existent
parent. * The Route is of a type that the controller does
not support. * The Route is in a namespace the the controller
does not have access to."
items:
description: "Condition contains details for one aspect of
the current state of this API Resource. --- This struct
is intended for direct use as an array at the field path
.status.conditions. For example, type FooStatus struct{
\ // Represents the observations of a foo's current state.
\ // Known .status.conditions.type are: \"Available\",
\"Progressing\", and \"Degraded\" // +patchMergeKey=type
\ // +patchStrategy=merge // +listType=map //
+listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\"
patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`
\n // other fields }"
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition
transitioned from one status to another. This should
be when the underlying condition changed. If that is
not known, then using the time when the API field changed
is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating
details about the transition. This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon. For instance,
if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration
is 9, the condition is out of date with respect to the
current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier
indicating the reason for the condition's last transition.
Producers of specific condition types may define expected
values and meanings for this field, and whether the
values are considered a guaranteed API. The value should
be a CamelCase string. This field may not be empty.
maxLength: 1024
minLength: 1 minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
status:
description: status of the condition, one of True, False,
Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
--- Many .condition.type values are consistent across
resources like Available, but because arbitrary conditions
can be useful (see .node.status.conditions), the ability
to deconflict is important. The regex it matches is
(dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string type: string
required: required:
- lastTransitionTime - name
- message
- reason
- status
- type
type: object type: object
maxItems: 8 required:
minItems: 1 - controllerName
type: array - parentRef
x-kubernetes-list-map-keys: type: object
- type maxItems: 32
x-kubernetes-list-type: map type: array
controllerName: required:
description: "ControllerName is a domain/path string that indicates - parents
the name of the controller that wrote this status. This corresponds type: object
with the controllerName field on GatewayClass. \n Example: required:
\"example.net/gateway-controller\". \n The format of this - spec
field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid type: object
Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names)." served: true
maxLength: 253 storage: true
minLength: 1 subresources:
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ status: {}
type: string
parentRef:
description: ParentRef corresponds with a ParentRef in the spec
that this RouteParentStatus struct describes the status of.
properties:
group:
default: gateway.networking.k8s.io
description: "Group is the group of the referent. \n Support:
Core"
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
default: Gateway
description: "Kind is kind of the referent. \n Support:
Core (Gateway) Support: Custom (Other Resources)"
maxLength: 63
minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string
name:
description: "Name is the name of the referent. \n Support:
Core"
maxLength: 253
minLength: 1
type: string
namespace:
description: "Namespace is the namespace of the referent.
When unspecified (or empty string), this refers to the
local namespace of the Route. \n Support: Core"
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
sectionName:
description: "SectionName is the name of a section within
the target resource. In the following resources, SectionName
is interpreted as the following: \n * Gateway: Listener
Name \n Implementations MAY choose to support attaching
Routes to other resources. If that is the case, they MUST
clearly document how SectionName is interpreted. \n When
unspecified (empty string), this will reference the entire
resource. For the purpose of status, an attachment is
considered successful if at least one section in the parent
resource accepts it. For example, Gateway listeners can
restrict which Routes can attach to them by Route kind,
namespace, or hostname. If 1 of 2 Gateway listeners accept
attachment from the referencing Route, the Route MUST
be considered successfully attached. If no Gateway listeners
accept attachment from this Route, the Route MUST be considered
detached from the Gateway. \n Support: Core"
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
required:
- name
type: object
required:
- controllerName
- parentRef
type: object
maxItems: 32
type: array
required:
- parents
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}
status: status:
acceptedNames: acceptedNames:
kind: "" kind: ""
plural: "" plural: ""
conditions: [] conditions: null
storedVersions: [] storedVersions: null

View file

@ -0,0 +1,284 @@
#
# config/crd/experimental/gateway.networking.k8s.io_udproutes.yaml
#
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466
gateway.networking.k8s.io/bundle-version: v1.0.0
gateway.networking.k8s.io/channel: experimental
creationTimestamp: null
name: udproutes.gateway.networking.k8s.io
spec:
group: gateway.networking.k8s.io
names:
categories:
- gateway-api
kind: UDPRoute
listKind: UDPRouteList
plural: udproutes
singular: udproute
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha2
schema:
openAPIV3Schema:
description: UDPRoute provides a way to route UDP traffic. When combined with a Gateway listener, it can be used to forward traffic on the port specified by the listener to a set of backends specified by the UDPRoute.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: Spec defines the desired state of UDPRoute.
properties:
parentRefs:
description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) This API may be extended in the future to support additional kinds of parent resources. \n ParentRefs must be _distinct_. This means either that: \n * They select different objects. If this is the case, then parentRef entries are distinct. In terms of fields, this means that the multi-part key defined by `group`, `kind`, `namespace`, and `name` must be unique across all parentRef entries in the Route. * They do not select different objects, but for each optional field used, each ParentRef that selects the same object must set the same set of optional fields to different values. If one ParentRef sets a combination of optional fields, all must set the same combination. \n Some examples: \n * If one ParentRef sets `sectionName`, all ParentRefs referencing the same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same object must also set `port`. * If one ParentRef sets `sectionName` and `port`, all ParentRefs referencing the same object must also set `sectionName` and `port`. \n It is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged. \n Note that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n "
items:
description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n This API may be extended in the future to support additional kinds of parent resources. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid."
properties:
group:
default: gateway.networking.k8s.io
description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core"
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
default: Gateway
description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific."
maxLength: 63
minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string
name:
description: "Name is the name of the referent. \n Support: Core"
maxLength: 253
minLength: 1
type: string
namespace:
description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core"
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
port:
description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n "
format: int32
maximum: 65535
minimum: 1
type: integer
sectionName:
description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core"
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
required:
- name
type: object
maxItems: 32
type: array
x-kubernetes-validations:
- message: sectionName or port must be specified when parentRefs includes 2 or more references to the same parent
rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__ == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))'
- message: sectionName or port must be unique when parentRefs includes 2 or more references to the same parent
rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))
rules:
description: Rules are a list of UDP matchers and actions.
items:
description: UDPRouteRule is the configuration for a given rule.
properties:
backendRefs:
description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a non-existent resource or a Service with no endpoints), the underlying implementation MUST actively reject connection attempts to this backend. Packet drops must respect weight; if an invalid backend is requested to have 80% of the packets, then 80% of packets must be dropped instead. \n Support: Core for Kubernetes Service \n Support: Extended for Kubernetes ServiceImport \n Support: Implementation-specific for any other resource \n Support for weight: Extended"
items:
description: "BackendRef defines how a Route should forward a request to a Kubernetes resource. \n 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. \n <gateway:experimental:description> \n When the BackendRef points to a Kubernetes Service, implementations SHOULD honor the appProtocol field if it is set for the target Service Port. \n Implementations supporting appProtocol SHOULD recognize the Kubernetes Standard Application Protocols defined in KEP-3726. \n If a Service appProtocol isn't specified, an implementation MAY infer the backend protocol through its own means. Implementations MAY infer the protocol from the Route type referring to the backend Service. \n If a Route is not able to send traffic to the backend using the specified protocol then the backend is considered invalid. Implementations MUST set the \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason. \n </gateway:experimental:description> \n Note that when the BackendTLSPolicy object is enabled by the implementation, there are some extra rules about validity to consider here. See the fields where this struct is used for more information about the exact behavior."
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\". \n Defaults to \"Service\" when not specified. \n 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. \n Support: Core (Services with a type other than ExternalName) \n 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. \n 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. \n 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
weight:
default: 1
description: "Weight specifies the proportion of requests forwarded to the referenced backend. This is computed as weight/(sum of all weights in this BackendRefs list). For non-zero values, there may be some epsilon from the exact proportion defined here depending on the precision an implementation supports. Weight is not a percentage and the sum of weights does not need to equal 100. \n If only one backend is specified and it has a weight greater than 0, 100% of the traffic is forwarded to that backend. If weight is set to 0, no traffic should be forwarded for this entry. If unspecified, weight defaults to 1. \n Support for this field varies based on the context where used."
format: int32
maximum: 1000000
minimum: 0
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: 16
minItems: 1
type: array
type: object
maxItems: 16
minItems: 1
type: array
required:
- rules
type: object
status:
description: Status defines the current state of UDPRoute.
properties:
parents:
description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified. \n Note that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for. \n A maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway."
items:
description: RouteParentStatus describes the status of a route with respect to an associated Parent.
properties:
conditions:
description: "Conditions describes the status of the route with respect to the Gateway. Note that the route's availability is also subject to the Gateway's own status conditions and listener status. \n If the Route's ParentRef specifies an existing Gateway that supports Routes of this kind AND that Gateway's controller has sufficient access, then that Gateway's controller MUST set the \"Accepted\" condition on the Route, to indicate whether the route has been accepted or rejected by the Gateway, and why. \n A Route MUST be considered \"Accepted\" if at least one of the Route's rules is implemented by the Gateway. \n There are a number of cases where the \"Accepted\" condition may not be set due to lack of controller visibility, that includes when: \n * The Route refers to a non-existent parent. * The Route is of a type that the controller does not support. * The Route is in a namespace the controller does not have access to."
items:
description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating details about the transition. This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
maxItems: 8
minItems: 1
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
controllerName:
description: "ControllerName is a domain/path string that indicates the name of the controller that wrote this status. This corresponds with the controllerName field on GatewayClass. \n Example: \"example.net/gateway-controller\". \n The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). \n Controllers MUST populate this field when writing status. Controllers should ensure that entries to status populated with their ControllerName are cleaned up when they are no longer necessary."
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
type: string
parentRef:
description: ParentRef corresponds with a ParentRef in the spec that this RouteParentStatus struct describes the status of.
properties:
group:
default: gateway.networking.k8s.io
description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core"
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
default: Gateway
description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific."
maxLength: 63
minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string
name:
description: "Name is the name of the referent. \n Support: Core"
maxLength: 253
minLength: 1
type: string
namespace:
description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core"
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
port:
description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n "
format: int32
maximum: 65535
minimum: 1
type: integer
sectionName:
description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core"
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
required:
- name
type: object
required:
- controllerName
- parentRef
type: object
maxItems: 32
type: array
required:
- parents
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: null
storedVersions: null

View file

@ -1181,6 +1181,10 @@ spec:
type: string type: string
type: array type: array
type: object type: object
rejectStatusCode:
description: RejectStatusCode defines the HTTP status code used
for refused requests. If not set, the default is 403 (Forbidden).
type: integer
sourceRange: sourceRange:
description: SourceRange defines the set of allowed IPs (or ranges description: SourceRange defines the set of allowed IPs (or ranges
of allowed IPs by using CIDR notation). of allowed IPs by using CIDR notation).

View file

@ -1,5 +1,5 @@
--- ---
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass kind: GatewayClass
metadata: metadata:
name: my-gateway-class name: my-gateway-class
@ -7,7 +7,7 @@ spec:
controllerName: traefik.io/gateway-controller controllerName: traefik.io/gateway-controller
--- ---
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
kind: Gateway kind: Gateway
metadata: metadata:
name: my-gateway name: my-gateway
@ -44,7 +44,7 @@ spec:
name: mysecret name: mysecret
--- ---
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute kind: HTTPRoute
metadata: metadata:
name: http-app name: http-app

View file

@ -1,5 +1,5 @@
--- ---
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass kind: GatewayClass
metadata: metadata:
name: my-gateway-class name: my-gateway-class
@ -8,7 +8,7 @@ spec:
controllerName: traefik.io/gateway-controller controllerName: traefik.io/gateway-controller
--- ---
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
kind: Gateway kind: Gateway
metadata: metadata:
name: my-gateway name: my-gateway
@ -25,7 +25,7 @@ spec:
name: mysecret name: mysecret
--- ---
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute kind: HTTPRoute
metadata: metadata:
name: http-app name: http-app

View file

@ -11,11 +11,15 @@ Dynamic configuration with Kubernetes Gateway provider.
## Definitions ## Definitions
```yaml ```yaml
--8<-- "content/reference/dynamic-configuration/gateway.networking.k8s.io_backendtlspolicies.yaml"
--8<-- "content/reference/dynamic-configuration/gateway.networking.k8s.io_gatewayclasses.yaml" --8<-- "content/reference/dynamic-configuration/gateway.networking.k8s.io_gatewayclasses.yaml"
--8<-- "content/reference/dynamic-configuration/gateway.networking.k8s.io_gateways.yaml" --8<-- "content/reference/dynamic-configuration/gateway.networking.k8s.io_gateways.yaml"
--8<-- "content/reference/dynamic-configuration/gateway.networking.k8s.io_grpcroutes.yaml"
--8<-- "content/reference/dynamic-configuration/gateway.networking.k8s.io_httproutes.yaml" --8<-- "content/reference/dynamic-configuration/gateway.networking.k8s.io_httproutes.yaml"
--8<-- "content/reference/dynamic-configuration/gateway.networking.k8s.io_referencegrants.yaml"
--8<-- "content/reference/dynamic-configuration/gateway.networking.k8s.io_tcproutes.yaml" --8<-- "content/reference/dynamic-configuration/gateway.networking.k8s.io_tcproutes.yaml"
--8<-- "content/reference/dynamic-configuration/gateway.networking.k8s.io_tlsroutes.yaml" --8<-- "content/reference/dynamic-configuration/gateway.networking.k8s.io_tlsroutes.yaml"
--8<-- "content/reference/dynamic-configuration/gateway.networking.k8s.io_udproutes.yaml"
``` ```
## Resources ## Resources

View file

@ -81,6 +81,7 @@
| `traefik/http/middlewares/Middleware11/ipAllowList/ipStrategy/depth` | `42` | | `traefik/http/middlewares/Middleware11/ipAllowList/ipStrategy/depth` | `42` |
| `traefik/http/middlewares/Middleware11/ipAllowList/ipStrategy/excludedIPs/0` | `foobar` | | `traefik/http/middlewares/Middleware11/ipAllowList/ipStrategy/excludedIPs/0` | `foobar` |
| `traefik/http/middlewares/Middleware11/ipAllowList/ipStrategy/excludedIPs/1` | `foobar` | | `traefik/http/middlewares/Middleware11/ipAllowList/ipStrategy/excludedIPs/1` | `foobar` |
| `traefik/http/middlewares/Middleware11/ipAllowList/rejectStatusCode` | `404` |
| `traefik/http/middlewares/Middleware11/ipAllowList/sourceRange/0` | `foobar` | | `traefik/http/middlewares/Middleware11/ipAllowList/sourceRange/0` | `foobar` |
| `traefik/http/middlewares/Middleware11/ipAllowList/sourceRange/1` | `foobar` | | `traefik/http/middlewares/Middleware11/ipAllowList/sourceRange/1` | `foobar` |
| `traefik/http/middlewares/Middleware12/inFlightReq/amount` | `42` | | `traefik/http/middlewares/Middleware12/inFlightReq/amount` | `42` |

View file

@ -606,6 +606,10 @@ spec:
type: string type: string
type: array type: array
type: object type: object
rejectStatusCode:
description: RejectStatusCode defines the HTTP status code used
for refused requests. If not set, the default is 403 (Forbidden).
type: integer
sourceRange: sourceRange:
description: SourceRange defines the set of allowed IPs (or ranges description: SourceRange defines the set of allowed IPs (or ranges
of allowed IPs by using CIDR notation). of allowed IPs by using CIDR notation).

View file

@ -177,6 +177,12 @@ Trust all. (Default: ```false```)
`--entrypoints.<name>.proxyprotocol.trustedips`: `--entrypoints.<name>.proxyprotocol.trustedips`:
Trust only selected IPs. Trust only selected IPs.
`--entrypoints.<name>.transport.keepalivemaxrequests`:
Maximum number of requests before closing a keep-alive connection. (Default: ```0```)
`--entrypoints.<name>.transport.keepalivemaxtime`:
Maximum duration before closing a keep-alive connection. (Default: ```0```)
`--entrypoints.<name>.transport.lifecycle.gracetimeout`: `--entrypoints.<name>.transport.lifecycle.gracetimeout`:
Duration to give active requests a chance to finish before Traefik stops. (Default: ```10```) Duration to give active requests a chance to finish before Traefik stops. (Default: ```10```)
@ -195,9 +201,6 @@ WriteTimeout is the maximum duration before timing out writes of the response. I
`--entrypoints.<name>.udp.timeout`: `--entrypoints.<name>.udp.timeout`:
Timeout defines how long to wait on an idle session before releasing the related resources. (Default: ```3```) Timeout defines how long to wait on an idle session before releasing the related resources. (Default: ```3```)
`--experimental.http3`:
Enable HTTP3. (Default: ```false```)
`--experimental.kubernetesgateway`: `--experimental.kubernetesgateway`:
Allow the Kubernetes gateway api provider usage. (Default: ```false```) Allow the Kubernetes gateway api provider usage. (Default: ```false```)
@ -217,7 +220,7 @@ plugin's version.
Periodically check if a new version has been released. (Default: ```true```) Periodically check if a new version has been released. (Default: ```true```)
`--global.sendanonymoususage`: `--global.sendanonymoususage`:
Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default. (Default: ```false```) Periodically send anonymous usage statistics. If the option is not specified, it will be disabled by default. (Default: ```false```)
`--hostresolver`: `--hostresolver`:
Enable CNAME Flattening. (Default: ```false```) Enable CNAME Flattening. (Default: ```false```)
@ -822,6 +825,27 @@ Password for authentication.
`--providers.redis.rootkey`: `--providers.redis.rootkey`:
Root key used for KV store. (Default: ```traefik```) Root key used for KV store. (Default: ```traefik```)
`--providers.redis.sentinel.latencystrategy`:
Defines whether to route commands to the closest master or replica nodes (mutually exclusive with RandomStrategy and ReplicaStrategy). (Default: ```false```)
`--providers.redis.sentinel.mastername`:
Name of the master.
`--providers.redis.sentinel.password`:
Password for Sentinel authentication.
`--providers.redis.sentinel.randomstrategy`:
Defines whether to route commands randomly to master or replica nodes (mutually exclusive with LatencyStrategy and ReplicaStrategy). (Default: ```false```)
`--providers.redis.sentinel.replicastrategy`:
Defines whether to route all commands to replica nodes (mutually exclusive with LatencyStrategy and RandomStrategy). (Default: ```false```)
`--providers.redis.sentinel.usedisconnectedreplicas`:
Use replicas disconnected with master when cannot get connected replicas. (Default: ```false```)
`--providers.redis.sentinel.username`:
Username for Sentinel authentication.
`--providers.redis.tls.ca`: `--providers.redis.tls.ca`:
TLS CA TLS CA
@ -963,170 +987,50 @@ Defines the allowed SPIFFE trust domain.
`--tracing`: `--tracing`:
OpenTracing configuration. (Default: ```false```) OpenTracing configuration. (Default: ```false```)
`--tracing.datadog`: `--tracing.globalattributes.<name>`:
Settings for Datadog. (Default: ```false```) Defines additional attributes (key:value) on all spans.
`--tracing.datadog.bagageprefixheadername`: `--tracing.headers.<name>`:
Sets the header name prefix used to store baggage items in a map.
`--tracing.datadog.debug`:
Enables Datadog debug. (Default: ```false```)
`--tracing.datadog.globaltags.<name>`:
Sets a list of key:value tags on all spans.
`--tracing.datadog.localagenthostport`:
Sets the Datadog Agent host:port. (Default: ```localhost:8126```)
`--tracing.datadog.localagentsocket`:
Sets the socket for the Datadog Agent.
`--tracing.datadog.parentidheadername`:
Sets the header name used to store the parent ID.
`--tracing.datadog.prioritysampling`:
Enables priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled. (Default: ```false```)
`--tracing.datadog.samplingpriorityheadername`:
Sets the header name used to store the sampling priority.
`--tracing.datadog.traceidheadername`:
Sets the header name used to store the trace ID.
`--tracing.elastic`:
Settings for Elastic. (Default: ```false```)
`--tracing.elastic.secrettoken`:
Sets the token used to connect to Elastic APM Server.
`--tracing.elastic.serverurl`:
Sets the URL of the Elastic APM server.
`--tracing.elastic.serviceenvironment`:
Sets the name of the environment Traefik is deployed in, e.g. 'production' or 'staging'.
`--tracing.haystack`:
Settings for Haystack. (Default: ```false```)
`--tracing.haystack.baggageprefixheadername`:
Sets the header name prefix used to store baggage items in a map.
`--tracing.haystack.globaltag`:
Sets a key:value tag on all spans.
`--tracing.haystack.localagenthost`:
Sets the Haystack Agent host. (Default: ```127.0.0.1```)
`--tracing.haystack.localagentport`:
Sets the Haystack Agent port. (Default: ```35000```)
`--tracing.haystack.parentidheadername`:
Sets the header name used to store the parent ID.
`--tracing.haystack.spanidheadername`:
Sets the header name used to store the span ID.
`--tracing.haystack.traceidheadername`:
Sets the header name used to store the trace ID.
`--tracing.instana`:
Settings for Instana. (Default: ```false```)
`--tracing.instana.enableautoprofile`:
Enables automatic profiling for the Traefik process. (Default: ```false```)
`--tracing.instana.localagenthost`:
Sets the Instana Agent host.
`--tracing.instana.localagentport`:
Sets the Instana Agent port. (Default: ```42699```)
`--tracing.instana.loglevel`:
Sets the log level for the Instana tracer. ('error','warn','info','debug') (Default: ```info```)
`--tracing.jaeger`:
Settings for Jaeger. (Default: ```false```)
`--tracing.jaeger.collector.endpoint`:
Instructs reporter to send spans to jaeger-collector at this URL.
`--tracing.jaeger.collector.password`:
Password for basic http authentication when sending spans to jaeger-collector.
`--tracing.jaeger.collector.user`:
User for basic http authentication when sending spans to jaeger-collector.
`--tracing.jaeger.disableattemptreconnecting`:
Disables the periodic re-resolution of the agent's hostname and reconnection if there was a change. (Default: ```true```)
`--tracing.jaeger.gen128bit`:
Generates 128 bits span IDs. (Default: ```false```)
`--tracing.jaeger.localagenthostport`:
Sets the Jaeger Agent host:port. (Default: ```127.0.0.1:6831```)
`--tracing.jaeger.propagation`:
Sets the propagation format (jaeger/b3). (Default: ```jaeger```)
`--tracing.jaeger.samplingparam`:
Sets the sampling parameter. (Default: ```1.000000```)
`--tracing.jaeger.samplingserverurl`:
Sets the sampling server URL. (Default: ```http://localhost:5778/sampling```)
`--tracing.jaeger.samplingtype`:
Sets the sampling type. (Default: ```const```)
`--tracing.jaeger.tracecontextheadername`:
Sets the header name used to store the trace ID. (Default: ```uber-trace-id```)
`--tracing.opentelemetry`:
Settings for OpenTelemetry. (Default: ```false```)
`--tracing.opentelemetry.address`:
Sets the address (host:port) of the collector endpoint. (Default: ```localhost:4318```)
`--tracing.opentelemetry.grpc`:
gRPC specific configuration for the OpenTelemetry collector. (Default: ```true```)
`--tracing.opentelemetry.headers.<name>`:
Defines additional headers to be sent with the payloads. Defines additional headers to be sent with the payloads.
`--tracing.opentelemetry.insecure`: `--tracing.otlp`:
Settings for OpenTelemetry. (Default: ```false```)
`--tracing.otlp.grpc.endpoint`:
Sets the gRPC endpoint (host:port) of the collector. (Default: ```localhost:4317```)
`--tracing.otlp.grpc.insecure`:
Disables client transport security for the exporter. (Default: ```false```) Disables client transport security for the exporter. (Default: ```false```)
`--tracing.opentelemetry.path`: `--tracing.otlp.grpc.tls.ca`:
Sets the URL path of the collector endpoint.
`--tracing.opentelemetry.tls.ca`:
TLS CA TLS CA
`--tracing.opentelemetry.tls.cert`: `--tracing.otlp.grpc.tls.cert`:
TLS cert TLS cert
`--tracing.opentelemetry.tls.insecureskipverify`: `--tracing.otlp.grpc.tls.insecureskipverify`:
TLS insecure skip verify (Default: ```false```) TLS insecure skip verify (Default: ```false```)
`--tracing.opentelemetry.tls.key`: `--tracing.otlp.grpc.tls.key`:
TLS key TLS key
`--tracing.otlp.http.endpoint`:
Sets the HTTP endpoint (scheme://host:port/v1/traces) of the collector. (Default: ```localhost:4318```)
`--tracing.otlp.http.tls.ca`:
TLS CA
`--tracing.otlp.http.tls.cert`:
TLS cert
`--tracing.otlp.http.tls.insecureskipverify`:
TLS insecure skip verify (Default: ```false```)
`--tracing.otlp.http.tls.key`:
TLS key
`--tracing.samplerate`:
Sets the rate between 0.0 and 1.0 of requests to trace. (Default: ```1.000000```)
`--tracing.servicename`: `--tracing.servicename`:
Set the name for this service. (Default: ```traefik```) Set the name for this service. (Default: ```traefik```)
`--tracing.spannamelimit`:
Set the maximum character limit for Span names (default 0 = no limit). (Default: ```0```)
`--tracing.zipkin`:
Settings for Zipkin. (Default: ```false```)
`--tracing.zipkin.httpendpoint`:
Sets the HTTP Endpoint to report traces to. (Default: ```http://localhost:9411/api/v2/spans```)
`--tracing.zipkin.id128bit`:
Uses 128 bits root span IDs. (Default: ```true```)
`--tracing.zipkin.samespan`:
Uses SameSpan RPC style traces. (Default: ```false```)
`--tracing.zipkin.samplerate`:
Sets the rate between 0.0 and 1.0 of requests to trace. (Default: ```1.000000```)

View file

@ -177,6 +177,12 @@ Trust all. (Default: ```false```)
`TRAEFIK_ENTRYPOINTS_<NAME>_PROXYPROTOCOL_TRUSTEDIPS`: `TRAEFIK_ENTRYPOINTS_<NAME>_PROXYPROTOCOL_TRUSTEDIPS`:
Trust only selected IPs. Trust only selected IPs.
`TRAEFIK_ENTRYPOINTS_<NAME>_TRANSPORT_KEEPALIVEMAXREQUESTS`:
Maximum number of requests before closing a keep-alive connection. (Default: ```0```)
`TRAEFIK_ENTRYPOINTS_<NAME>_TRANSPORT_KEEPALIVEMAXTIME`:
Maximum duration before closing a keep-alive connection. (Default: ```0```)
`TRAEFIK_ENTRYPOINTS_<NAME>_TRANSPORT_LIFECYCLE_GRACETIMEOUT`: `TRAEFIK_ENTRYPOINTS_<NAME>_TRANSPORT_LIFECYCLE_GRACETIMEOUT`:
Duration to give active requests a chance to finish before Traefik stops. (Default: ```10```) Duration to give active requests a chance to finish before Traefik stops. (Default: ```10```)
@ -195,9 +201,6 @@ WriteTimeout is the maximum duration before timing out writes of the response. I
`TRAEFIK_ENTRYPOINTS_<NAME>_UDP_TIMEOUT`: `TRAEFIK_ENTRYPOINTS_<NAME>_UDP_TIMEOUT`:
Timeout defines how long to wait on an idle session before releasing the related resources. (Default: ```3```) Timeout defines how long to wait on an idle session before releasing the related resources. (Default: ```3```)
`TRAEFIK_EXPERIMENTAL_HTTP3`:
Enable HTTP3. (Default: ```false```)
`TRAEFIK_EXPERIMENTAL_KUBERNETESGATEWAY`: `TRAEFIK_EXPERIMENTAL_KUBERNETESGATEWAY`:
Allow the Kubernetes gateway api provider usage. (Default: ```false```) Allow the Kubernetes gateway api provider usage. (Default: ```false```)
@ -217,7 +220,7 @@ plugin's version.
Periodically check if a new version has been released. (Default: ```true```) Periodically check if a new version has been released. (Default: ```true```)
`TRAEFIK_GLOBAL_SENDANONYMOUSUSAGE`: `TRAEFIK_GLOBAL_SENDANONYMOUSUSAGE`:
Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default. (Default: ```false```) Periodically send anonymous usage statistics. If the option is not specified, it will be disabled by default. (Default: ```false```)
`TRAEFIK_HOSTRESOLVER`: `TRAEFIK_HOSTRESOLVER`:
Enable CNAME Flattening. (Default: ```false```) Enable CNAME Flattening. (Default: ```false```)
@ -822,6 +825,27 @@ Password for authentication.
`TRAEFIK_PROVIDERS_REDIS_ROOTKEY`: `TRAEFIK_PROVIDERS_REDIS_ROOTKEY`:
Root key used for KV store. (Default: ```traefik```) Root key used for KV store. (Default: ```traefik```)
`TRAEFIK_PROVIDERS_REDIS_SENTINEL_LATENCYSTRATEGY`:
Defines whether to route commands to the closest master or replica nodes (mutually exclusive with RandomStrategy and ReplicaStrategy). (Default: ```false```)
`TRAEFIK_PROVIDERS_REDIS_SENTINEL_MASTERNAME`:
Name of the master.
`TRAEFIK_PROVIDERS_REDIS_SENTINEL_PASSWORD`:
Password for Sentinel authentication.
`TRAEFIK_PROVIDERS_REDIS_SENTINEL_RANDOMSTRATEGY`:
Defines whether to route commands randomly to master or replica nodes (mutually exclusive with LatencyStrategy and ReplicaStrategy). (Default: ```false```)
`TRAEFIK_PROVIDERS_REDIS_SENTINEL_REPLICASTRATEGY`:
Defines whether to route all commands to replica nodes (mutually exclusive with LatencyStrategy and RandomStrategy). (Default: ```false```)
`TRAEFIK_PROVIDERS_REDIS_SENTINEL_USEDISCONNECTEDREPLICAS`:
Use replicas disconnected with master when cannot get connected replicas. (Default: ```false```)
`TRAEFIK_PROVIDERS_REDIS_SENTINEL_USERNAME`:
Username for Sentinel authentication.
`TRAEFIK_PROVIDERS_REDIS_TLS_CA`: `TRAEFIK_PROVIDERS_REDIS_TLS_CA`:
TLS CA TLS CA
@ -963,170 +987,50 @@ Defines the allowed SPIFFE trust domain.
`TRAEFIK_TRACING`: `TRAEFIK_TRACING`:
OpenTracing configuration. (Default: ```false```) OpenTracing configuration. (Default: ```false```)
`TRAEFIK_TRACING_DATADOG`: `TRAEFIK_TRACING_GLOBALATTRIBUTES_<NAME>`:
Settings for Datadog. (Default: ```false```) Defines additional attributes (key:value) on all spans.
`TRAEFIK_TRACING_DATADOG_BAGAGEPREFIXHEADERNAME`: `TRAEFIK_TRACING_HEADERS_<NAME>`:
Sets the header name prefix used to store baggage items in a map.
`TRAEFIK_TRACING_DATADOG_DEBUG`:
Enables Datadog debug. (Default: ```false```)
`TRAEFIK_TRACING_DATADOG_GLOBALTAGS_<NAME>`:
Sets a list of key:value tags on all spans.
`TRAEFIK_TRACING_DATADOG_LOCALAGENTHOSTPORT`:
Sets the Datadog Agent host:port. (Default: ```localhost:8126```)
`TRAEFIK_TRACING_DATADOG_LOCALAGENTSOCKET`:
Sets the socket for the Datadog Agent.
`TRAEFIK_TRACING_DATADOG_PARENTIDHEADERNAME`:
Sets the header name used to store the parent ID.
`TRAEFIK_TRACING_DATADOG_PRIORITYSAMPLING`:
Enables priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled. (Default: ```false```)
`TRAEFIK_TRACING_DATADOG_SAMPLINGPRIORITYHEADERNAME`:
Sets the header name used to store the sampling priority.
`TRAEFIK_TRACING_DATADOG_TRACEIDHEADERNAME`:
Sets the header name used to store the trace ID.
`TRAEFIK_TRACING_ELASTIC`:
Settings for Elastic. (Default: ```false```)
`TRAEFIK_TRACING_ELASTIC_SECRETTOKEN`:
Sets the token used to connect to Elastic APM Server.
`TRAEFIK_TRACING_ELASTIC_SERVERURL`:
Sets the URL of the Elastic APM server.
`TRAEFIK_TRACING_ELASTIC_SERVICEENVIRONMENT`:
Sets the name of the environment Traefik is deployed in, e.g. 'production' or 'staging'.
`TRAEFIK_TRACING_HAYSTACK`:
Settings for Haystack. (Default: ```false```)
`TRAEFIK_TRACING_HAYSTACK_BAGGAGEPREFIXHEADERNAME`:
Sets the header name prefix used to store baggage items in a map.
`TRAEFIK_TRACING_HAYSTACK_GLOBALTAG`:
Sets a key:value tag on all spans.
`TRAEFIK_TRACING_HAYSTACK_LOCALAGENTHOST`:
Sets the Haystack Agent host. (Default: ```127.0.0.1```)
`TRAEFIK_TRACING_HAYSTACK_LOCALAGENTPORT`:
Sets the Haystack Agent port. (Default: ```35000```)
`TRAEFIK_TRACING_HAYSTACK_PARENTIDHEADERNAME`:
Sets the header name used to store the parent ID.
`TRAEFIK_TRACING_HAYSTACK_SPANIDHEADERNAME`:
Sets the header name used to store the span ID.
`TRAEFIK_TRACING_HAYSTACK_TRACEIDHEADERNAME`:
Sets the header name used to store the trace ID.
`TRAEFIK_TRACING_INSTANA`:
Settings for Instana. (Default: ```false```)
`TRAEFIK_TRACING_INSTANA_ENABLEAUTOPROFILE`:
Enables automatic profiling for the Traefik process. (Default: ```false```)
`TRAEFIK_TRACING_INSTANA_LOCALAGENTHOST`:
Sets the Instana Agent host.
`TRAEFIK_TRACING_INSTANA_LOCALAGENTPORT`:
Sets the Instana Agent port. (Default: ```42699```)
`TRAEFIK_TRACING_INSTANA_LOGLEVEL`:
Sets the log level for the Instana tracer. ('error','warn','info','debug') (Default: ```info```)
`TRAEFIK_TRACING_JAEGER`:
Settings for Jaeger. (Default: ```false```)
`TRAEFIK_TRACING_JAEGER_COLLECTOR_ENDPOINT`:
Instructs reporter to send spans to jaeger-collector at this URL.
`TRAEFIK_TRACING_JAEGER_COLLECTOR_PASSWORD`:
Password for basic http authentication when sending spans to jaeger-collector.
`TRAEFIK_TRACING_JAEGER_COLLECTOR_USER`:
User for basic http authentication when sending spans to jaeger-collector.
`TRAEFIK_TRACING_JAEGER_DISABLEATTEMPTRECONNECTING`:
Disables the periodic re-resolution of the agent's hostname and reconnection if there was a change. (Default: ```true```)
`TRAEFIK_TRACING_JAEGER_GEN128BIT`:
Generates 128 bits span IDs. (Default: ```false```)
`TRAEFIK_TRACING_JAEGER_LOCALAGENTHOSTPORT`:
Sets the Jaeger Agent host:port. (Default: ```127.0.0.1:6831```)
`TRAEFIK_TRACING_JAEGER_PROPAGATION`:
Sets the propagation format (jaeger/b3). (Default: ```jaeger```)
`TRAEFIK_TRACING_JAEGER_SAMPLINGPARAM`:
Sets the sampling parameter. (Default: ```1.000000```)
`TRAEFIK_TRACING_JAEGER_SAMPLINGSERVERURL`:
Sets the sampling server URL. (Default: ```http://localhost:5778/sampling```)
`TRAEFIK_TRACING_JAEGER_SAMPLINGTYPE`:
Sets the sampling type. (Default: ```const```)
`TRAEFIK_TRACING_JAEGER_TRACECONTEXTHEADERNAME`:
Sets the header name used to store the trace ID. (Default: ```uber-trace-id```)
`TRAEFIK_TRACING_OPENTELEMETRY`:
Settings for OpenTelemetry. (Default: ```false```)
`TRAEFIK_TRACING_OPENTELEMETRY_ADDRESS`:
Sets the address (host:port) of the collector endpoint. (Default: ```localhost:4318```)
`TRAEFIK_TRACING_OPENTELEMETRY_GRPC`:
gRPC specific configuration for the OpenTelemetry collector. (Default: ```true```)
`TRAEFIK_TRACING_OPENTELEMETRY_HEADERS_<NAME>`:
Defines additional headers to be sent with the payloads. Defines additional headers to be sent with the payloads.
`TRAEFIK_TRACING_OPENTELEMETRY_INSECURE`: `TRAEFIK_TRACING_OTLP`:
Settings for OpenTelemetry. (Default: ```false```)
`TRAEFIK_TRACING_OTLP_GRPC_ENDPOINT`:
Sets the gRPC endpoint (host:port) of the collector. (Default: ```localhost:4317```)
`TRAEFIK_TRACING_OTLP_GRPC_INSECURE`:
Disables client transport security for the exporter. (Default: ```false```) Disables client transport security for the exporter. (Default: ```false```)
`TRAEFIK_TRACING_OPENTELEMETRY_PATH`: `TRAEFIK_TRACING_OTLP_GRPC_TLS_CA`:
Sets the URL path of the collector endpoint.
`TRAEFIK_TRACING_OPENTELEMETRY_TLS_CA`:
TLS CA TLS CA
`TRAEFIK_TRACING_OPENTELEMETRY_TLS_CERT`: `TRAEFIK_TRACING_OTLP_GRPC_TLS_CERT`:
TLS cert TLS cert
`TRAEFIK_TRACING_OPENTELEMETRY_TLS_INSECURESKIPVERIFY`: `TRAEFIK_TRACING_OTLP_GRPC_TLS_INSECURESKIPVERIFY`:
TLS insecure skip verify (Default: ```false```) TLS insecure skip verify (Default: ```false```)
`TRAEFIK_TRACING_OPENTELEMETRY_TLS_KEY`: `TRAEFIK_TRACING_OTLP_GRPC_TLS_KEY`:
TLS key TLS key
`TRAEFIK_TRACING_OTLP_HTTP_ENDPOINT`:
Sets the HTTP endpoint (scheme://host:port/v1/traces) of the collector. (Default: ```localhost:4318```)
`TRAEFIK_TRACING_OTLP_HTTP_TLS_CA`:
TLS CA
`TRAEFIK_TRACING_OTLP_HTTP_TLS_CERT`:
TLS cert
`TRAEFIK_TRACING_OTLP_HTTP_TLS_INSECURESKIPVERIFY`:
TLS insecure skip verify (Default: ```false```)
`TRAEFIK_TRACING_OTLP_HTTP_TLS_KEY`:
TLS key
`TRAEFIK_TRACING_SAMPLERATE`:
Sets the rate between 0.0 and 1.0 of requests to trace. (Default: ```1.000000```)
`TRAEFIK_TRACING_SERVICENAME`: `TRAEFIK_TRACING_SERVICENAME`:
Set the name for this service. (Default: ```traefik```) Set the name for this service. (Default: ```traefik```)
`TRAEFIK_TRACING_SPANNAMELIMIT`:
Set the maximum character limit for Span names (default 0 = no limit). (Default: ```0```)
`TRAEFIK_TRACING_ZIPKIN`:
Settings for Zipkin. (Default: ```false```)
`TRAEFIK_TRACING_ZIPKIN_HTTPENDPOINT`:
Sets the HTTP Endpoint to report traces to. (Default: ```http://localhost:9411/api/v2/spans```)
`TRAEFIK_TRACING_ZIPKIN_ID128BIT`:
Uses 128 bits root span IDs. (Default: ```true```)
`TRAEFIK_TRACING_ZIPKIN_SAMESPAN`:
Uses SameSpan RPC style traces. (Default: ```false```)
`TRAEFIK_TRACING_ZIPKIN_SAMPLERATE`:
Sets the rate between 0.0 and 1.0 of requests to trace. (Default: ```1.000000```)

View file

@ -35,6 +35,8 @@
address = "foobar" address = "foobar"
asDefault = true asDefault = true
[entryPoints.EntryPoint0.transport] [entryPoints.EntryPoint0.transport]
keepAliveMaxRequests = 42
keepAliveMaxTime = "42s"
[entryPoints.EntryPoint0.transport.lifeCycle] [entryPoints.EntryPoint0.transport.lifeCycle]
requestAcceptGraceTimeout = "42s" requestAcceptGraceTimeout = "42s"
graceTimeOut = "42s" graceTimeOut = "42s"
@ -242,6 +244,14 @@
cert = "foobar" cert = "foobar"
key = "foobar" key = "foobar"
insecureSkipVerify = true insecureSkipVerify = true
[providers.redis.sentinel]
masterName = "foobar"
username = "foobar"
password = "foobar"
latencyStrategy = true
randomStrategy = true
replicaStrategy = true
useDisconnectedReplicas = true
[providers.http] [providers.http]
endpoint = "foobar" endpoint = "foobar"
pollInterval = "42s" pollInterval = "42s"
@ -357,68 +367,28 @@
[tracing] [tracing]
serviceName = "foobar" serviceName = "foobar"
spanNameLimit = 42 sampleRate = 42
[tracing.jaeger] [tracing.headers]
samplingServerURL = "foobar" header1 = "foobar"
samplingType = "foobar" header2 = "foobar"
samplingParam = 42.0 [tracing.globalAttributes]
localAgentHostPort = "foobar" attr1 = "foobar"
gen128Bit = true attr2 = "foobar"
propagation = "foobar" [tracing.otlp.grpc]
traceContextHeaderName = "foobar" endpoint = "foobar"
disableAttemptReconnecting = true
[tracing.jaeger.collector]
endpoint = "foobar"
user = "foobar"
password = "foobar"
[tracing.zipkin]
httpEndpoint = "foobar"
sameSpan = true
id128Bit = true
sampleRate = 42.0
[tracing.datadog]
localAgentHostPort = "foobar"
localAgentSocket = "foobar"
[tracing.datadog.globalTags]
tag1 = "foobar"
tag2 = "foobar"
debug = true
prioritySampling = true
traceIDHeaderName = "foobar"
parentIDHeaderName = "foobar"
samplingPriorityHeaderName = "foobar"
bagagePrefixHeaderName = "foobar"
[tracing.instana]
localAgentHost = "foobar"
localAgentPort = 42
logLevel = "foobar"
enableAutoProfile = true
[tracing.haystack]
localAgentHost = "foobar"
localAgentPort = 42
globalTag = "foobar"
traceIDHeaderName = "foobar"
parentIDHeaderName = "foobar"
spanIDHeaderName = "foobar"
baggagePrefixHeaderName = "foobar"
[tracing.elastic]
serverURL = "foobar"
secretToken = "foobar"
serviceEnvironment = "foobar"
[tracing.openTelemetry]
address = "foobar"
insecure = true insecure = true
path = "foobar" [tracing.otlp.grpc.tls]
[tracing.openTelemetry.headers]
name0 = "foobar"
name1 = "foobar"
[tracing.openTelemetry.tls]
ca = "foobar" ca = "foobar"
caOptional = true
cert = "foobar" cert = "foobar"
key = "foobar" key = "foobar"
insecureSkipVerify = true insecureSkipVerify = true
[tracing.openTelemetry.grpc] [tracing.otlp.http]
endpoint = "foobar"
[tracing.otlp.http.tls]
ca = "foobar"
cert = "foobar"
key = "foobar"
insecureSkipVerify = true
[hostResolver] [hostResolver]
cnameFlattening = true cnameFlattening = true
@ -449,7 +419,6 @@
[experimental] [experimental]
kubernetesGateway = true kubernetesGateway = true
http3 = true
[experimental.plugins] [experimental.plugins]
[experimental.plugins.Descriptor0] [experimental.plugins.Descriptor0]
moduleName = "foobar" moduleName = "foobar"

View file

@ -36,6 +36,8 @@ entryPoints:
address: foobar address: foobar
asDefault: true asDefault: true
transport: transport:
keepAliveMaxRequests: 42
keepAliveMaxTime: 42s
lifeCycle: lifeCycle:
requestAcceptGraceTimeout: 42s requestAcceptGraceTimeout: 42s
graceTimeOut: 42s graceTimeOut: 42s
@ -271,6 +273,14 @@ providers:
cert: foobar cert: foobar
key: foobar key: foobar
insecureSkipVerify: true insecureSkipVerify: true
sentinel:
masterName: foobar
username: foobar
password: foobar
latencyStrategy: true
randomStrategy: true
replicaStrategy: true
useDisconnectedReplicas: true
http: http:
endpoint: foobar endpoint: foobar
pollInterval: 42s pollInterval: 42s
@ -387,68 +397,29 @@ accessLog:
bufferingSize: 42 bufferingSize: 42
tracing: tracing:
serviceName: foobar serviceName: foobar
spanNameLimit: 42 sampleRate: 42
jaeger: headers:
samplingServerURL: foobar header1: foobar
samplingType: foobar header2: foobar
samplingParam: 42 globalAttributes:
localAgentHostPort: foobar attr1: foobar
gen128Bit: true attr2: foobar
propagation: foobar otlp:
traceContextHeaderName: foobar grpc:
disableAttemptReconnecting: true
collector:
endpoint: foobar endpoint: foobar
user: foobar insecure: true
password: foobar tls:
zipkin: ca: foobar
httpEndpoint: foobar cert: foobar
sameSpan: true key: foobar
id128Bit: true insecureSkipVerify: true
sampleRate: 42 http:
datadog: endpoint: foobar
localAgentHostPort: foobar tls:
localAgentSocket: foobar ca: foobar
globalTags: cert: foobar
tag1: foobar key: foobar
tag2: foobar insecureSkipVerify: true
debug: true
prioritySampling: true
traceIDHeaderName: foobar
parentIDHeaderName: foobar
samplingPriorityHeaderName: foobar
bagagePrefixHeaderName: foobar
instana:
localAgentHost: foobar
localAgentPort: 42
logLevel: foobar
enableAutoProfile: true
haystack:
localAgentHost: foobar
localAgentPort: 42
globalTag: foobar
traceIDHeaderName: foobar
parentIDHeaderName: foobar
spanIDHeaderName: foobar
baggagePrefixHeaderName: foobar
elastic:
serverURL: foobar
secretToken: foobar
serviceEnvironment: foobar
openTelemetry:
address: foobar
headers:
name0: foobar
name1: foobar
insecure: true
path: foobar
tls:
ca: foobar
caOptional: true
cert: foobar
key: foobar
insecureSkipVerify: true
grpc: {}
hostResolver: hostResolver:
cnameFlattening: true cnameFlattening: true
resolvConfig: foobar resolvConfig: foobar
@ -479,7 +450,6 @@ certificatesResolvers:
tailscale: {} tailscale: {}
experimental: experimental:
kubernetesGateway: true kubernetesGateway: true
http3: true
plugins: plugins:
Descriptor0: Descriptor0:
moduleName: foobar moduleName: foobar

View file

@ -623,17 +623,77 @@ Controls the behavior of Traefik during the shutdown phase.
--entryPoints.name.transport.lifeCycle.graceTimeOut=42 --entryPoints.name.transport.lifeCycle.graceTimeOut=42
``` ```
#### `keepAliveMaxRequests`
_Optional, Default=0_
The maximum number of requests Traefik can handle before sending a `Connection: Close` header to the client (for HTTP2, Traefik sends a GOAWAY). Zero means no limit.
```yaml tab="File (YAML)"
## Static configuration
entryPoints:
name:
address: ":8888"
transport:
keepAliveMaxRequests: 42
```
```toml tab="File (TOML)"
## Static configuration
[entryPoints]
[entryPoints.name]
address = ":8888"
[entryPoints.name.transport]
keepAliveMaxRequests = 42
```
```bash tab="CLI"
## Static configuration
--entryPoints.name.address=:8888
--entryPoints.name.transport.keepAliveRequests=42
```
#### `keepAliveMaxTime`
_Optional, Default=0s_
The maximum duration Traefik can handle requests before sending a `Connection: Close` header to the client (for HTTP2, Traefik sends a GOAWAY). Zero means no limit.
```yaml tab="File (YAML)"
## Static configuration
entryPoints:
name:
address: ":8888"
transport:
keepAliveMaxTime: 42s
```
```toml tab="File (TOML)"
## Static configuration
[entryPoints]
[entryPoints.name]
address = ":8888"
[entryPoints.name.transport]
keepAliveMaxTime = 42s
```
```bash tab="CLI"
## Static configuration
--entryPoints.name.address=:8888
--entryPoints.name.transport.keepAliveTime=42s
```
### ProxyProtocol ### ProxyProtocol
Traefik supports [ProxyProtocol](https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt) version 1 and 2. Traefik supports [PROXY protocol](https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt) version 1 and 2.
If Proxy Protocol header parsing is enabled for the entry point, this entry point can accept connections with or without Proxy Protocol headers. If PROXY protocol header parsing is enabled for the entry point, this entry point can accept connections with or without PROXY protocol headers.
If the Proxy Protocol header is passed, then the version is determined automatically. If the PROXY protocol header is passed, then the version is determined automatically.
??? info "`proxyProtocol.trustedIPs`" ??? info "`proxyProtocol.trustedIPs`"
Enabling Proxy Protocol with Trusted IPs. Enabling PROXY protocol with Trusted IPs.
```yaml tab="File (YAML)" ```yaml tab="File (YAML)"
## Static configuration ## Static configuration
@ -696,7 +756,7 @@ If the Proxy Protocol header is passed, then the version is determined automatic
!!! warning "Queuing Traefik behind Another Load Balancer" !!! warning "Queuing Traefik behind Another Load Balancer"
When queuing Traefik behind another load-balancer, make sure to configure Proxy Protocol on both sides. When queuing Traefik behind another load-balancer, make sure to configure PROXY protocol on both sides.
Not doing so could introduce a security risk in your system (enabling request forgery). Not doing so could introduce a security risk in your system (enabling request forgery).
## HTTP Options ## HTTP Options

View file

@ -39,19 +39,19 @@ The Kubernetes Gateway API, The Experimental Way. {: .subtitle }
You can find an excerpt of the supported Kubernetes Gateway API resources in the table below: You can find an excerpt of the supported Kubernetes Gateway API resources in the table below:
| Kind | Purpose | Concept Behind | | Kind | Purpose | Concept Behind |
|------------------------------------|---------------------------------------------------------------------------|---------------------------------------------------------------------------------| |------------------------------------|---------------------------------------------------------------------------|------------------------------------------------------------------------|
| [GatewayClass](#kind-gatewayclass) | Defines a set of Gateways that share a common configuration and behaviour | [GatewayClass](https://gateway-api.sigs.k8s.io/v1alpha2/api-types/gatewayclass) | | [GatewayClass](#kind-gatewayclass) | Defines a set of Gateways that share a common configuration and behaviour | [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass) |
| [Gateway](#kind-gateway) | Describes how traffic can be translated to Services within the cluster | [Gateway](https://gateway-api.sigs.k8s.io/v1alpha2/api-types/gateway) | | [Gateway](#kind-gateway) | Describes how traffic can be translated to Services within the cluster | [Gateway](https://gateway-api.sigs.k8s.io/api-types/gateway) |
| [HTTPRoute](#kind-httproute) | HTTP rules for mapping requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/v1alpha2/api-types/httproute) | | [HTTPRoute](#kind-httproute) | HTTP rules for mapping requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/api-types/httproute) |
| [TCPRoute](#kind-tcproute) | Allows mapping TCP requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/v1alpha2/guides/tcp/) | | [TCPRoute](#kind-tcproute) | Allows mapping TCP requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/guides/tcp/) |
| [TLSRoute](#kind-tlsroute) | Allows mapping TLS requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/v1alpha2/guides/tls/) | | [TLSRoute](#kind-tlsroute) | Allows mapping TLS requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/guides/tls/) |
### Kind: `GatewayClass` ### Kind: `GatewayClass`
`GatewayClass` is cluster-scoped resource defined by the infrastructure provider. This resource represents a class of `GatewayClass` is cluster-scoped resource defined by the infrastructure provider. This resource represents a class of
Gateways that can be instantiated. More details on the Gateways that can be instantiated. More details on the
GatewayClass [official documentation](https://gateway-api.sigs.k8s.io/v1alpha2/api-types/gatewayclass/). GatewayClass [official documentation](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/).
The `GatewayClass` should be declared by the infrastructure provider, otherwise please register the `GatewayClass` The `GatewayClass` should be declared by the infrastructure provider, otherwise please register the `GatewayClass`
[definition](../../reference/dynamic-configuration/kubernetes-gateway.md#definitions) in the Kubernetes cluster before [definition](../../reference/dynamic-configuration/kubernetes-gateway.md#definitions) in the Kubernetes cluster before
@ -60,7 +60,7 @@ creating `GatewayClass` objects.
!!! info "Declaring GatewayClass" !!! info "Declaring GatewayClass"
```yaml ```yaml
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass kind: GatewayClass
metadata: metadata:
name: my-gateway-class name: my-gateway-class
@ -92,7 +92,7 @@ Depending on the Listener Protocol, different modes and Route types are supporte
!!! info "Declaring Gateway" !!! info "Declaring Gateway"
```yaml tab="HTTP Listener" ```yaml tab="HTTP Listener"
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
kind: Gateway kind: Gateway
metadata: metadata:
name: my-http-gateway name: my-http-gateway
@ -114,7 +114,7 @@ Depending on the Listener Protocol, different modes and Route types are supporte
``` ```
```yaml tab="HTTPS Listener" ```yaml tab="HTTPS Listener"
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
kind: Gateway kind: Gateway
metadata: metadata:
name: my-https-gateway name: my-https-gateway
@ -140,7 +140,7 @@ Depending on the Listener Protocol, different modes and Route types are supporte
``` ```
```yaml tab="TCP Listener" ```yaml tab="TCP Listener"
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
kind: Gateway kind: Gateway
metadata: metadata:
name: my-tcp-gateway name: my-tcp-gateway
@ -162,7 +162,7 @@ Depending on the Listener Protocol, different modes and Route types are supporte
``` ```
```yaml tab="TLS Listener" ```yaml tab="TLS Listener"
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
kind: Gateway kind: Gateway
metadata: metadata:
name: my-tls-gateway name: my-tls-gateway
@ -213,7 +213,7 @@ Kubernetes cluster before creating `HTTPRoute` objects.
!!! info "Declaring HTTPRoute" !!! info "Declaring HTTPRoute"
```yaml ```yaml
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute kind: HTTPRoute
metadata: metadata:
name: http-app name: http-app
@ -274,7 +274,7 @@ Kubernetes cluster before creating `TCPRoute` objects.
!!! info "Declaring TCPRoute" !!! info "Declaring TCPRoute"
```yaml ```yaml
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
kind: TCPRoute kind: TCPRoute
metadata: metadata:
name: tcp-app name: tcp-app
@ -318,7 +318,7 @@ Kubernetes cluster before creating `TLSRoute` objects.
!!! info "Declaring TLSRoute" !!! info "Declaring TLSRoute"
```yaml ```yaml
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
kind: TLSRoute kind: TLSRoute
metadata: metadata:
name: tls-app name: tls-app

View file

@ -3,9 +3,9 @@ title: "Traefik Docker DNS Challenge Documentation"
description: "Learn how to create a certificate with the Let's Encrypt DNS challenge to use HTTPS on a Service exposed with Traefik Proxy. Read the tehnical documentation." description: "Learn how to create a certificate with the Let's Encrypt DNS challenge to use HTTPS on a Service exposed with Traefik Proxy. Read the tehnical documentation."
--- ---
# Docker-compose with let's encrypt: DNS Challenge # Docker-compose with Let's Encrypt: DNS Challenge
This guide aim to demonstrate how to create a certificate with the let's encrypt DNS challenge to use https on a simple service exposed with Traefik. This guide aim to demonstrate how to create a certificate with the Let's Encrypt DNS challenge to use https on a simple service exposed with Traefik.
Please also read the [basic example](../basic-example) for details on how to expose such a service. Please also read the [basic example](../basic-example) for details on how to expose such a service.
## Prerequisite ## Prerequisite
@ -52,7 +52,7 @@ For the DNS challenge, you'll need:
!!! Note !!! Note
If you uncommented the `acme.caserver` line, you will get an SSL error, but if you display the certificate and see it was emitted by `Fake LE Intermediate X1` then it means all is good. If you uncommented the `acme.caserver` line, you will get an SSL error, but if you display the certificate and see it was emitted by `Fake LE Intermediate X1` then it means all is good.
(It is the staging environment intermediate certificate used by let's encrypt). (It is the staging environment intermediate certificate used by Let's Encrypt).
You can now safely comment the `acme.caserver` line, remove the `letsencrypt/acme.json` file and restart Traefik to issue a valid certificate. You can now safely comment the `acme.caserver` line, remove the `letsencrypt/acme.json` file and restart Traefik to issue a valid certificate.
## Explanation ## Explanation
@ -69,7 +69,7 @@ ports:
- "443:443" - "443:443"
``` ```
- We configure the DNS let's encrypt challenge: - We configure the DNS Let's Encrypt challenge:
```yaml ```yaml
command: command:
@ -77,7 +77,7 @@ command:
- "--certificatesresolvers.myresolver.acme.dnschallenge=true" - "--certificatesresolvers.myresolver.acme.dnschallenge=true"
# Tell which provider to use # Tell which provider to use
- "--certificatesresolvers.myresolver.acme.dnschallenge.provider=ovh" - "--certificatesresolvers.myresolver.acme.dnschallenge.provider=ovh"
# The email to provide to let's encrypt # The email to provide to Let's Encrypt
- "--certificatesresolvers.myresolver.acme.email=postmaster@example.com" - "--certificatesresolvers.myresolver.acme.email=postmaster@example.com"
``` ```
@ -175,7 +175,7 @@ services:
- "ovh_consumer_key" - "ovh_consumer_key"
``` ```
- The environment variable within our `whoami` service are suffixed by `_FILE` which allow us to point to files containing the value, instead of exposing the value itself. - The environment variable within our `traefik` service are suffixed by `_FILE` which allow us to point to files containing the value, instead of exposing the value itself.
The acme client will read the content of those file to get the required configuration values. The acme client will read the content of those file to get the required configuration values.
```yaml ```yaml

View file

@ -3,9 +3,9 @@ title: "Traefik Docker HTTP Challenge Documentation"
description: "Learn how to create a certificate with the Let's Encrypt HTTP challenge to use HTTPS on a Service exposed with Traefik Proxy. Read the technical documentation." description: "Learn how to create a certificate with the Let's Encrypt HTTP challenge to use HTTPS on a Service exposed with Traefik Proxy. Read the technical documentation."
--- ---
# Docker-compose with let's encrypt : HTTP Challenge # Docker-compose with Let's Encrypt : HTTP Challenge
This guide aim to demonstrate how to create a certificate with the let's encrypt HTTP challenge to use https on a simple service exposed with Traefik. This guide aim to demonstrate how to create a certificate with the Let's Encrypt HTTP challenge to use https on a simple service exposed with Traefik.
Please also read the [basic example](../basic-example) for details on how to expose such a service. Please also read the [basic example](../basic-example) for details on how to expose such a service.
## Prerequisite ## Prerequisite
@ -38,7 +38,7 @@ For the HTTP challenge you will need:
!!! Note !!! Note
If you uncommented the `acme.caserver` line, you will get an SSL error, but if you display the certificate and see it was emitted by `Fake LE Intermediate X1` then it means all is good. If you uncommented the `acme.caserver` line, you will get an SSL error, but if you display the certificate and see it was emitted by `Fake LE Intermediate X1` then it means all is good.
(It is the staging environment intermediate certificate used by let's encrypt). (It is the staging environment intermediate certificate used by Let's Encrypt).
You can now safely comment the `acme.caserver` line, remove the `letsencrypt/acme.json` file and restart Traefik to issue a valid certificate. You can now safely comment the `acme.caserver` line, remove the `letsencrypt/acme.json` file and restart Traefik to issue a valid certificate.
## Explanation ## Explanation
@ -55,7 +55,7 @@ ports:
- "443:443" - "443:443"
``` ```
- We configure the HTTPS let's encrypt challenge: - We configure the HTTPS Let's Encrypt challenge:
```yaml ```yaml
command: command:
@ -63,7 +63,7 @@ command:
- "--certificatesresolvers.myresolver.acme.httpchallenge=true" - "--certificatesresolvers.myresolver.acme.httpchallenge=true"
# Tell it to use our predefined entrypoint named "web" # Tell it to use our predefined entrypoint named "web"
- "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web" - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
# The email to provide to let's encrypt # The email to provide to Let's Encrypt
- "--certificatesresolvers.myresolver.acme.email=postmaster@example.com" - "--certificatesresolvers.myresolver.acme.email=postmaster@example.com"
``` ```

View file

@ -3,9 +3,9 @@ title: "Traefik Docker TLS Challenge Documentation"
description: "Learn how to create a certificate with the Let's Encrypt TLS challenge to use HTTPS on a service exposed with Traefik Proxy. Read the technical documentation." description: "Learn how to create a certificate with the Let's Encrypt TLS challenge to use HTTPS on a service exposed with Traefik Proxy. Read the technical documentation."
--- ---
# Docker-compose with let's encrypt: TLS Challenge # Docker-compose with Let's Encrypt: TLS Challenge
This guide aim to demonstrate how to create a certificate with the let's encrypt TLS challenge to use https on a simple service exposed with Traefik. This guide aim to demonstrate how to create a certificate with the Let's Encrypt TLS challenge to use https on a simple service exposed with Traefik.
Please also read the [basic example](../basic-example) for details on how to expose such a service. Please also read the [basic example](../basic-example) for details on how to expose such a service.
## Prerequisite ## Prerequisite
@ -38,7 +38,7 @@ For the TLS challenge you will need:
!!! Note !!! Note
If you uncommented the `acme.caserver` line, you will get an SSL error, but if you display the certificate and see it was emitted by `Fake LE Intermediate X1` then it means all is good. If you uncommented the `acme.caserver` line, you will get an SSL error, but if you display the certificate and see it was emitted by `Fake LE Intermediate X1` then it means all is good.
(It is the staging environment intermediate certificate used by let's encrypt). (It is the staging environment intermediate certificate used by Let's Encrypt).
You can now safely comment the `acme.caserver` line, remove the `letsencrypt/acme.json` file and restart Traefik to issue a valid certificate. You can now safely comment the `acme.caserver` line, remove the `letsencrypt/acme.json` file and restart Traefik to issue a valid certificate.
## Explanation ## Explanation
@ -55,7 +55,7 @@ ports:
- "443:443" - "443:443"
``` ```
- We configure the Https let's encrypt challenge: - We configure the TLS Let's Encrypt challenge:
```yaml ```yaml
command: command:

View file

@ -1,16 +1,15 @@
--- ---
title: "Traefik Docker Documentation" title: "Traefik Docker Documentation"
description: "This guide covers a Docker Compose file exposing a service using the Docker provider in Traefik Proxy. Read the technical documentation." description: "Learn how to use Docker Compose to expose a service with Traefik Proxy."
--- ---
# Docker Compose example # Docker Compose example
In this section, we quickly go over a Docker Compose file exposing a service using the Docker provider. In this section, you will learn how to use [Docker Compose](https://docs.docker.com/compose/ "Link to Docker Compose") to expose a service using the Docker provider.
This will also be used as a starting point for the other Docker Compose guides.
## Setup ## Setup
- Edit a `docker-compose.yml` file with the following content: Create a `docker-compose.yml` file with the following content:
```yaml ```yaml
--8<-- "content/user-guides/docker-compose/basic-example/docker-compose.yml" --8<-- "content/user-guides/docker-compose/basic-example/docker-compose.yml"
@ -45,33 +44,44 @@ This will also be used as a starting point for the other Docker Compose guides.
``` ```
- Replace `whoami.localhost` by your **own domain** within the `traefik.http.routers.whoami.rule` label of the `whoami` service. Replace `whoami.localhost` by your **own domain** within the `traefik.http.routers.whoami.rule` label of the `whoami` service.
- Run `docker-compose up -d` within the folder where you created the previous file.
- Wait a bit and visit `http://your_own_domain` to confirm everything went fine.
You should see the output of the whoami service. Something similar to:
```text Now run `docker-compose up -d` within the folder where you created the previous file.
Hostname: d7f919e54651 This will start Docker Compose in background mode.
IP: 127.0.0.1
IP: 192.168.64.2 !!! info "This can take a moment"
GET / HTTP/1.1
Host: whoami.localhost Docker Compose will now create and start the services declared in the `docker-compose.yml`.
User-Agent: curl/7.52.1
Accept: */* Wait a bit and visit `http://your_own_domain` to confirm everything went fine.
Accept-Encoding: gzip
X-Forwarded-For: 192.168.64.1 You should see the output of the whoami service.
X-Forwarded-Host: whoami.localhost It should be similar to the following example:
X-Forwarded-Port: 80
X-Forwarded-Proto: http ```text
X-Forwarded-Server: 7f0c797dbc51 Hostname: d7f919e54651
X-Real-Ip: 192.168.64.1 IP: 127.0.0.1
``` IP: 192.168.64.2
GET / HTTP/1.1
Host: whoami.localhost
User-Agent: curl/7.52.1
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 192.168.64.1
X-Forwarded-Host: whoami.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 7f0c797dbc51
X-Real-Ip: 192.168.64.1
```
## Details ## Details
- As an example, we use [whoami](https://github.com/traefik/whoami "Link to the GitHub repo of whoami") (a tiny Go server that prints OS information and HTTP request to output) which was used to define our `simple-service` container. Let's break it down and go through it, step-by-step.
- We define an entry point, along with the exposure of the matching port within Docker Compose, which allow us to "open and accept" HTTP traffic: You use [whoami](https://github.com/traefik/whoami "Link to the GitHub repo of whoami"), a tiny Go server that prints OS information and HTTP request to output as service container.
Second, you define an entry point, along with the exposure of the matching port within Docker Compose, which allows to "open and accept" HTTP traffic:
```yaml ```yaml
command: command:
@ -82,7 +92,7 @@ ports:
- "80:80" - "80:80"
``` ```
- We expose the Traefik API to be able to check the configuration if needed: Third, you expose the Traefik API to be able to check the configuration if needed:
```yaml ```yaml
command: command:
@ -101,7 +111,7 @@ ports:
curl -s 127.0.0.1:8080/api/rawdata | jq . curl -s 127.0.0.1:8080/api/rawdata | jq .
``` ```
- We allow Traefik to gather configuration from Docker: Fourth, you allow Traefik to gather configuration from Docker:
```yaml ```yaml
traefik: traefik:

View file

@ -27,7 +27,7 @@ theme:
prev: 'Previous' prev: 'Previous'
next: 'Next' next: 'Next'
copyright: 'Traefik Labs • Copyright &copy; 2016-2023' copyright: 'Traefik Labs • Copyright &copy; 2016-2024'
extra_javascript: extra_javascript:
- assets/js/hljs/highlight.pack.js # Download from https://highlightjs.org/download/ and enable YAML, TOML and Dockerfile - assets/js/hljs/highlight.pack.js # Download from https://highlightjs.org/download/ and enable YAML, TOML and Dockerfile
@ -125,7 +125,8 @@ nav:
- 'ForwardAuth': 'middlewares/http/forwardauth.md' - 'ForwardAuth': 'middlewares/http/forwardauth.md'
- 'GrpcWeb': 'middlewares/http/grpcweb.md' - 'GrpcWeb': 'middlewares/http/grpcweb.md'
- 'Headers': 'middlewares/http/headers.md' - 'Headers': 'middlewares/http/headers.md'
- 'IpAllowList': 'middlewares/http/ipallowlist.md' - 'IPWhiteList': 'middlewares/http/ipwhitelist.md'
- 'IPAllowList': 'middlewares/http/ipallowlist.md'
- 'InFlightReq': 'middlewares/http/inflightreq.md' - 'InFlightReq': 'middlewares/http/inflightreq.md'
- 'PassTLSClientCert': 'middlewares/http/passtlsclientcert.md' - 'PassTLSClientCert': 'middlewares/http/passtlsclientcert.md'
- 'RateLimit': 'middlewares/http/ratelimit.md' - 'RateLimit': 'middlewares/http/ratelimit.md'
@ -139,7 +140,8 @@ nav:
- 'TCP': - 'TCP':
- 'Overview': 'middlewares/tcp/overview.md' - 'Overview': 'middlewares/tcp/overview.md'
- 'InFlightConn': 'middlewares/tcp/inflightconn.md' - 'InFlightConn': 'middlewares/tcp/inflightconn.md'
- 'IpAllowList': 'middlewares/tcp/ipallowlist.md' - 'IPWhiteList': 'middlewares/tcp/ipwhitelist.md'
- 'IPAllowList': 'middlewares/tcp/ipallowlist.md'
- 'Plugins & Plugin Catalog': 'plugins/index.md' - 'Plugins & Plugin Catalog': 'plugins/index.md'
- 'Operations': - 'Operations':
- 'CLI': 'operations/cli.md' - 'CLI': 'operations/cli.md'
@ -151,19 +153,9 @@ nav:
- 'Access Logs': 'observability/access-logs.md' - 'Access Logs': 'observability/access-logs.md'
- 'Metrics': - 'Metrics':
- 'Overview': 'observability/metrics/overview.md' - 'Overview': 'observability/metrics/overview.md'
- 'Datadog': 'observability/metrics/datadog.md'
- 'InfluxDB2': 'observability/metrics/influxdb2.md'
- 'OpenTelemetry': 'observability/metrics/opentelemetry.md' - 'OpenTelemetry': 'observability/metrics/opentelemetry.md'
- 'Prometheus': 'observability/metrics/prometheus.md'
- 'StatsD': 'observability/metrics/statsd.md'
- 'Tracing': - 'Tracing':
- 'Overview': 'observability/tracing/overview.md' - 'Overview': 'observability/tracing/overview.md'
- 'Jaeger': 'observability/tracing/jaeger.md'
- 'Zipkin': 'observability/tracing/zipkin.md'
- 'Datadog': 'observability/tracing/datadog.md'
- 'Instana': 'observability/tracing/instana.md'
- 'Haystack': 'observability/tracing/haystack.md'
- 'Elastic': 'observability/tracing/elastic.md'
- 'OpenTelemetry': 'observability/tracing/opentelemetry.md' - 'OpenTelemetry': 'observability/tracing/opentelemetry.md'
- 'User Guides': - 'User Guides':
- 'Kubernetes and Let''s Encrypt': 'user-guides/crd-acme/index.md' - 'Kubernetes and Let''s Encrypt': 'user-guides/crd-acme/index.md'

178
go.mod
View file

@ -4,7 +4,6 @@ go 1.21
require ( require (
github.com/BurntSushi/toml v1.3.2 github.com/BurntSushi/toml v1.3.2
github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61
github.com/Masterminds/sprig/v3 v3.2.3 github.com/Masterminds/sprig/v3 v3.2.3
github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000 github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000
github.com/andybalholm/brotli v1.0.6 github.com/andybalholm/brotli v1.0.6
@ -19,6 +18,7 @@ require (
github.com/docker/docker v20.10.21+incompatible github.com/docker/docker v20.10.21+incompatible
github.com/docker/go-connections v0.4.0 github.com/docker/go-connections v0.4.0
github.com/fatih/structs v1.1.0 github.com/fatih/structs v1.1.0
github.com/fsnotify/fsnotify v1.7.0
github.com/go-acme/lego/v4 v4.14.0 github.com/go-acme/lego/v4 v4.14.0
github.com/go-check/check v0.0.0-00010101000000-000000000000 github.com/go-check/check v0.0.0-00010101000000-000000000000
github.com/go-kit/kit v0.10.1-0.20200915143503-439c4d2ed3ea github.com/go-kit/kit v0.10.1-0.20200915143503-439c4d2ed3ea
@ -35,11 +35,10 @@ require (
github.com/http-wasm/http-wasm-host-go v0.5.2 github.com/http-wasm/http-wasm-host-go v0.5.2
github.com/influxdata/influxdb-client-go/v2 v2.7.0 github.com/influxdata/influxdb-client-go/v2 v2.7.0
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d
github.com/instana/go-sensor v1.38.3
github.com/klauspost/compress v1.17.1 github.com/klauspost/compress v1.17.1
github.com/kvtools/consul v1.0.2 github.com/kvtools/consul v1.0.2
github.com/kvtools/etcdv3 v1.0.2 github.com/kvtools/etcdv3 v1.0.2
github.com/kvtools/redis v1.0.2 github.com/kvtools/redis v1.1.0
github.com/kvtools/valkeyrie v1.0.0 github.com/kvtools/valkeyrie v1.0.0
github.com/kvtools/zookeeper v1.0.2 github.com/kvtools/zookeeper v1.0.2
github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f
@ -48,63 +47,54 @@ require (
github.com/mitchellh/hashstructure v1.0.0 github.com/mitchellh/hashstructure v1.0.0
github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/mapstructure v1.5.0
github.com/natefinch/lumberjack v0.0.0-20201021141957-47ffae23317c github.com/natefinch/lumberjack v0.0.0-20201021141957-47ffae23317c
github.com/opentracing/opentracing-go v1.2.0
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5
github.com/openzipkin/zipkin-go v0.2.2
github.com/patrickmn/go-cache v2.1.0+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pires/go-proxyproto v0.6.1 github.com/pires/go-proxyproto v0.6.1
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
github.com/prometheus/client_golang v1.14.0 github.com/prometheus/client_golang v1.17.0
github.com/prometheus/client_model v0.3.0 github.com/prometheus/client_model v0.5.0
github.com/quic-go/quic-go v0.39.1 github.com/quic-go/quic-go v0.40.1
github.com/rs/zerolog v1.28.0 github.com/rs/zerolog v1.29.0
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
github.com/spiffe/go-spiffe/v2 v2.1.1 github.com/spiffe/go-spiffe/v2 v2.1.1
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154
github.com/tailscale/tscert v0.0.0-20220316030059-54bbcb9f74e2 github.com/tailscale/tscert v0.0.0-20220316030059-54bbcb9f74e2
github.com/tetratelabs/wazero v1.5.0 github.com/tetratelabs/wazero v1.5.0
github.com/tidwall/gjson v1.17.0
github.com/traefik/grpc-web v0.16.0 github.com/traefik/grpc-web v0.16.0
github.com/traefik/paerser v0.2.0 github.com/traefik/paerser v0.2.0
github.com/traefik/yaegi v0.15.1 github.com/traefik/yaegi v0.15.1
github.com/uber/jaeger-client-go v2.30.0+incompatible
github.com/uber/jaeger-lib v2.2.0+incompatible
github.com/unrolled/render v1.0.2 github.com/unrolled/render v1.0.2
github.com/unrolled/secure v1.0.9 github.com/unrolled/secure v1.0.9
github.com/vdemeester/shakers v0.1.0 github.com/vdemeester/shakers v0.1.0
github.com/vulcand/oxy/v2 v2.0.0-20230427132221-be5cf38f3c1c github.com/vulcand/oxy/v2 v2.0.0-20230427132221-be5cf38f3c1c
github.com/vulcand/predicate v1.2.0 github.com/vulcand/predicate v1.2.0
go.elastic.co/apm v1.13.1
go.elastic.co/apm/module/apmot v1.13.1
go.opentelemetry.io/collector/pdata v0.66.0 go.opentelemetry.io/collector/pdata v0.66.0
go.opentelemetry.io/otel v1.19.0 go.opentelemetry.io/otel v1.21.0
go.opentelemetry.io/otel/bridge/opentracing v1.19.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.42.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 go.opentelemetry.io/otel/metric v1.21.0
go.opentelemetry.io/otel/metric v1.19.0 go.opentelemetry.io/otel/sdk v1.21.0
go.opentelemetry.io/otel/sdk v1.19.0 go.opentelemetry.io/otel/sdk/metric v1.21.0
go.opentelemetry.io/otel/sdk/metric v1.19.0 go.opentelemetry.io/otel/trace v1.21.0
go.opentelemetry.io/otel/trace v1.19.0 golang.org/x/exp v0.0.0-20231006140011-7918f672742d
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 golang.org/x/mod v0.13.0
golang.org/x/mod v0.12.0
golang.org/x/net v0.17.0 golang.org/x/net v0.17.0
golang.org/x/text v0.13.0 golang.org/x/text v0.13.0
golang.org/x/time v0.3.0 golang.org/x/time v0.3.0
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 golang.org/x/tools v0.14.0
google.golang.org/grpc v1.58.3 google.golang.org/grpc v1.59.0
gopkg.in/DataDog/dd-trace-go.v1 v1.56.1
gopkg.in/fsnotify.v1 v1.4.7
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.26.3 k8s.io/api v0.28.3
k8s.io/apiextensions-apiserver v0.26.3 k8s.io/apiextensions-apiserver v0.28.3
k8s.io/apimachinery v0.26.3 k8s.io/apimachinery v0.28.3
k8s.io/client-go v0.26.3 k8s.io/client-go v0.28.3
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 k8s.io/utils v0.0.0-20230726121419-3b25d923346b
mvdan.cc/xurls/v2 v2.5.0 mvdan.cc/xurls/v2 v2.5.0
sigs.k8s.io/gateway-api v0.4.0 sigs.k8s.io/gateway-api v1.0.0
) )
require ( require (
@ -129,13 +119,6 @@ require (
github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect
github.com/DataDog/appsec-internal-go v1.0.0 // indirect
github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.0 // indirect
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.0-devel.0.20230725154044-2549ba9058df // indirect
github.com/DataDog/datadog-go/v5 v5.3.0 // indirect
github.com/DataDog/go-libddwaf v1.5.0 // indirect
github.com/DataDog/go-tuf v1.0.2-0.5.2 // indirect
github.com/DataDog/sketches-go v1.4.2 // indirect
github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.0 // indirect github.com/Masterminds/semver/v3 v3.2.0 // indirect
@ -148,7 +131,6 @@ require (
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1755 // indirect github.com/aliyun/alibaba-cloud-sdk-go v1.61.1755 // indirect
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
github.com/armon/go-metrics v0.4.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/aws/aws-sdk-go-v2 v1.20.3 // indirect github.com/aws/aws-sdk-go-v2 v1.20.3 // indirect
github.com/aws/aws-sdk-go-v2/config v1.18.28 // indirect github.com/aws/aws-sdk-go-v2/config v1.18.28 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.13.27 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.13.27 // indirect
@ -175,8 +157,8 @@ require (
github.com/containerd/containerd v1.5.17 // indirect github.com/containerd/containerd v1.5.17 // indirect
github.com/containerd/continuity v0.3.0 // indirect github.com/containerd/continuity v0.3.0 // indirect
github.com/containerd/typeurl v1.0.2 // indirect github.com/containerd/typeurl v1.0.2 // indirect
github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cpu/goacmedns v0.1.1 // indirect github.com/cpu/goacmedns v0.1.1 // indirect
github.com/deepmap/oapi-codegen v1.9.1 // indirect github.com/deepmap/oapi-codegen v1.9.1 // indirect
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
@ -190,28 +172,23 @@ require (
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-metrics v0.0.1 // indirect
github.com/docker/go-units v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/ebitengine/purego v0.5.0-alpha.1 // indirect
github.com/elastic/go-licenser v0.3.1 // indirect
github.com/elastic/go-sysinfo v1.1.1 // indirect
github.com/elastic/go-windows v1.0.0 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/evanphx/json-patch v5.7.0+incompatible // indirect
github.com/exoscale/egoscale v0.100.1 // indirect github.com/exoscale/egoscale v0.100.1 // indirect
github.com/fatih/color v1.15.0 // indirect github.com/fatih/color v1.15.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/fvbommel/sortorder v1.0.1 // indirect github.com/fvbommel/sortorder v1.0.1 // indirect
github.com/ghodss/yaml v1.0.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect
github.com/gin-gonic/gin v1.7.7 // indirect
github.com/go-errors/errors v1.0.1 // indirect github.com/go-errors/errors v1.0.1 // indirect
github.com/go-jose/go-jose/v3 v3.0.0 // indirect github.com/go-jose/go-jose/v3 v3.0.0 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.19.14 // indirect github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/go-resty/resty/v2 v2.7.0 // indirect github.com/go-resty/resty/v2 v2.7.0 // indirect
github.com/go-sql-driver/mysql v1.6.0 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/go-zookeeper/zk v1.0.3 // indirect github.com/go-zookeeper/zk v1.0.3 // indirect
github.com/gofrs/flock v0.8.0 // indirect github.com/gofrs/flock v0.8.0 // indirect
@ -220,8 +197,8 @@ require (
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.6.0 // indirect github.com/golang/mock v1.6.0 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-cmp v0.6.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect
@ -245,14 +222,12 @@ require (
github.com/hashicorp/serf v0.10.1 // indirect github.com/hashicorp/serf v0.10.1 // indirect
github.com/huandu/xstrings v1.4.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df // indirect github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df // indirect
github.com/imdario/mergo v0.3.12 // indirect github.com/imdario/mergo v0.3.16 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect
github.com/infobloxopen/infoblox-go-client v1.1.1 // indirect github.com/infobloxopen/infoblox-go-client v1.1.1 // indirect
github.com/jaguilar/vt100 v0.0.0-20150826170717-2703a27b14ea // indirect github.com/jaguilar/vt100 v0.0.0-20150826170717-2703a27b14ea // indirect
github.com/jcchavezs/porto v0.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect
github.com/jonboulle/clockwork v0.2.2 // indirect github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
@ -266,7 +241,6 @@ require (
github.com/liquidweb/go-lwApi v0.0.5 // indirect github.com/liquidweb/go-lwApi v0.0.5 // indirect
github.com/liquidweb/liquidweb-cli v0.6.9 // indirect github.com/liquidweb/liquidweb-cli v0.6.9 // indirect
github.com/liquidweb/liquidweb-go v1.6.3 // indirect github.com/liquidweb/liquidweb-go v1.6.3 // indirect
github.com/looplab/fsm v0.1.0 // indirect
github.com/magiconair/properties v1.8.6 // indirect github.com/magiconair/properties v1.8.6 // indirect
github.com/mailgun/minheap v0.0.0-20170619185613-3dbe6c6bf55f // indirect github.com/mailgun/minheap v0.0.0-20170619185613-3dbe6c6bf55f // indirect
github.com/mailgun/multibuf v0.1.2 // indirect github.com/mailgun/multibuf v0.1.2 // indirect
@ -275,7 +249,7 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/miekg/pkcs11 v1.0.3 // indirect github.com/miekg/pkcs11 v1.0.3 // indirect
github.com/mimuret/golang-iij-dpf v0.9.1 // indirect github.com/mimuret/golang-iij-dpf v0.9.1 // indirect
@ -301,44 +275,44 @@ require (
github.com/nrdcg/nodion v0.1.0 // indirect github.com/nrdcg/nodion v0.1.0 // indirect
github.com/nrdcg/porkbun v0.2.0 // indirect github.com/nrdcg/porkbun v0.2.0 // indirect
github.com/nzdjb/go-metaname v1.0.0 // indirect github.com/nzdjb/go-metaname v1.0.0 // indirect
github.com/onsi/ginkgo/v2 v2.9.5 // indirect github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/ginkgo/v2 v2.11.0 // indirect
github.com/onsi/gomega v1.27.10 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect
github.com/opencontainers/runc v1.1.5 // indirect github.com/opencontainers/runc v1.1.5 // indirect
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect
github.com/outcaste-io/ristretto v0.2.3 // indirect
github.com/ovh/go-ovh v1.4.1 // indirect github.com/ovh/go-ovh v1.4.1 // indirect
github.com/philhofer/fwd v1.1.2 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/pquerna/otp v1.4.0 // indirect github.com/pquerna/otp v1.4.0 // indirect
github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-20 v0.3.4 // indirect github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
github.com/redis/go-redis/v9 v9.2.1 // indirect
github.com/rs/cors v1.7.0 // indirect github.com/rs/cors v1.7.0 // indirect
github.com/sacloud/api-client-go v0.2.8 // indirect github.com/sacloud/api-client-go v0.2.8 // indirect
github.com/sacloud/go-http v0.1.6 // indirect github.com/sacloud/go-http v0.1.6 // indirect
github.com/sacloud/iaas-api-go v1.11.1 // indirect github.com/sacloud/iaas-api-go v1.11.1 // indirect
github.com/sacloud/packages-go v0.0.9 // indirect github.com/sacloud/packages-go v0.0.9 // indirect
github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b // indirect github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b // indirect
github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17 // indirect github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.7.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect github.com/shopspring/decimal v1.2.0 // indirect
github.com/simplesurance/bunny-go v0.0.0-20221115111006-e11d9dc91f04 // indirect github.com/simplesurance/bunny-go v0.0.0-20221115111006-e11d9dc91f04 // indirect
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect
github.com/softlayer/softlayer-go v1.1.2 // indirect github.com/softlayer/softlayer-go v1.1.2 // indirect
github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect
github.com/spf13/cast v1.3.1 // indirect github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/cobra v1.6.0 // indirect github.com/spf13/cobra v1.7.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.5.1 // indirect github.com/stretchr/objx v0.5.1 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490 // indirect github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.490 // indirect github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.490 // indirect
github.com/theupdateframework/notary v0.6.1 // indirect github.com/theupdateframework/notary v0.6.1 // indirect
github.com/tinylib/msgp v1.1.8 // indirect github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/tonistiigi/fsutil v0.0.0-20201103201449-0834f99b7b85 // indirect github.com/tonistiigi/fsutil v0.0.0-20201103201449-0834f99b7b85 // indirect
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
github.com/transip/gotransip/v6 v6.20.0 // indirect github.com/transip/gotransip/v6 v6.20.0 // indirect
@ -351,47 +325,39 @@ require (
github.com/yandex-cloud/go-genproto v0.0.0-20220805142335-27b56ddae16f // indirect github.com/yandex-cloud/go-genproto v0.0.0-20220805142335-27b56ddae16f // indirect
github.com/yandex-cloud/go-sdk v0.0.0-20220805164847-cf028e604997 // indirect github.com/yandex-cloud/go-sdk v0.0.0-20220805164847-cf028e604997 // indirect
github.com/zeebo/errs v1.2.2 // indirect github.com/zeebo/errs v1.2.2 // indirect
go.elastic.co/apm/module/apmhttp v1.13.1 // indirect go.etcd.io/etcd/api/v3 v3.5.9 // indirect
go.elastic.co/fastjson v1.1.0 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect
go.etcd.io/etcd/api/v3 v3.5.5 // indirect go.etcd.io/etcd/client/v3 v3.5.9 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect
go.etcd.io/etcd/client/v3 v3.5.5 // indirect
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect
go.uber.org/atomic v1.11.0 // indirect go.uber.org/atomic v1.11.0 // indirect
go.uber.org/mock v0.3.0 // indirect go.uber.org/mock v0.3.0 // indirect
go.uber.org/multierr v1.8.0 // indirect go.uber.org/multierr v1.11.0 // indirect
go.uber.org/ratelimit v0.2.0 // indirect go.uber.org/ratelimit v0.2.0 // indirect
go.uber.org/zap v1.21.0 // indirect go.uber.org/zap v1.26.0 // indirect
go4.org/intern v0.0.0-20230525184215-6c62f75575cb // indirect
go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 // indirect
golang.org/x/crypto v0.14.0 // indirect golang.org/x/crypto v0.14.0 // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect golang.org/x/oauth2 v0.13.0 // indirect
golang.org/x/oauth2 v0.10.0 // indirect golang.org/x/sync v0.4.0 // indirect
golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.14.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/term v0.13.0 // indirect golang.org/x/term v0.13.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.128.0 // indirect google.golang.org/api v0.128.0 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/protobuf v1.31.0 // indirect google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/h2non/gock.v1 v1.0.16 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/ns1/ns1-go.v2 v2.7.6 // indirect gopkg.in/ns1/ns1-go.v2 v2.7.6 // indirect
gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect k8s.io/klog/v2 v2.100.1 // indirect
inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a // indirect k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
k8s.io/klog/v2 v2.80.1 // indirect
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
nhooyr.io/websocket v1.8.7 // indirect nhooyr.io/websocket v1.8.7 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect sigs.k8s.io/yaml v1.4.0 // indirect
) )
// Containous forks // Containous forks

523
go.sum

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1181,6 +1181,10 @@ spec:
type: string type: string
type: array type: array
type: object type: object
rejectStatusCode:
description: RejectStatusCode defines the HTTP status code used
for refused requests. If not set, the default is 403 (Forbidden).
type: integer
sourceRange: sourceRange:
description: SourceRange defines the set of allowed IPs (or ranges description: SourceRange defines the set of allowed IPs (or ranges
of allowed IPs by using CIDR notation). of allowed IPs by using CIDR notation).

View file

@ -1,6 +1,6 @@
--- ---
kind: GatewayClass kind: GatewayClass
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
metadata: metadata:
name: my-gateway-class name: my-gateway-class
spec: spec:
@ -8,7 +8,7 @@ spec:
--- ---
kind: Gateway kind: Gateway
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
metadata: metadata:
name: my-gateway name: my-gateway
namespace: default namespace: default
@ -24,7 +24,7 @@ spec:
--- ---
kind: Gateway kind: Gateway
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
metadata: metadata:
name: my-tcp-gateway name: my-tcp-gateway
namespace: default namespace: default
@ -51,7 +51,7 @@ data:
--- ---
kind: Gateway kind: Gateway
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
metadata: metadata:
name: my-tls-gateway name: my-tls-gateway
namespace: default namespace: default
@ -83,7 +83,7 @@ spec:
--- ---
kind: Gateway kind: Gateway
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
metadata: metadata:
name: my-https-gateway name: my-https-gateway
namespace: default namespace: default
@ -104,7 +104,7 @@ spec:
--- ---
kind: HTTPRoute kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1alpha2 apiVersion: gateway.networking.k8s.io/v1
metadata: metadata:
name: http-app-1 name: http-app-1
namespace: default namespace: default

View file

@ -0,0 +1,19 @@
[global]
checkNewVersion = false
sendAnonymousUsage = false
[log]
level = "DEBUG"
[entryPoints.web]
address = ":8000"
[api]
insecure = true
[providers.redis]
rootKey = "traefik"
endpoints = ["{{ .RedisAddress }}"]
[providers.redis.sentinel]
masterName = "mymaster"

View file

@ -0,0 +1,21 @@
receivers:
otlp:
protocols:
grpc:
http:
exporters:
otlp/tempo:
endpoint: http://tempo:4317
tls:
insecure: true
service:
telemetry:
logs:
level: "error"
extensions: [ health_check ]
pipelines:
traces:
receivers: [otlp]
exporters: [otlp/tempo]
extensions:
health_check:

View file

@ -1,70 +0,0 @@
[global]
checkNewVersion = false
sendAnonymousUsage = false
[log]
level = "DEBUG"
noColor = true
[api]
insecure = true
[entryPoints]
[entryPoints.web]
address = ":8000"
[tracing]
servicename = "tracing"
[tracing.jaeger]
samplingType = "const"
samplingParam = 1.0
samplingServerURL = "http://{{.IP}}:5778/sampling"
localAgentHostPort = "{{.IP}}:6831"
traceContextHeaderName = "{{.TraceContextHeaderName}}"
[providers.file]
filename = "{{ .SelfFilename }}"
## dynamic configuration ##
[http.routers]
[http.routers.router1]
Service = "service1"
Middlewares = ["retry", "ratelimit-1"]
Rule = "Path(`/ratelimit`)"
[http.routers.router2]
Service = "service2"
Middlewares = ["retry"]
Rule = "Path(`/retry`)"
[http.routers.router3]
Service = "service3"
Middlewares = ["retry", "basic-auth"]
Rule = "Path(`/auth`)"
[http.middlewares]
[http.middlewares.retry.retry]
attempts = 3
[http.middlewares.basic-auth.basicAuth]
users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"]
[http.middlewares.ratelimit-1.rateLimit]
average = 1
burst = 2
[http.services]
[http.services.service1]
[http.services.service1.loadBalancer]
passHostHeader = true
[[http.services.service1.loadBalancer.servers]]
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
[http.services.service2]
[http.services.service2.loadBalancer]
passHostHeader = true
[[http.services.service2.loadBalancer.servers]]
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
[http.services.service3]
[http.services.service3.loadBalancer]
passHostHeader = true
[[http.services.service3.loadBalancer.servers]]
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"

View file

@ -15,12 +15,15 @@
[tracing] [tracing]
servicename = "tracing" servicename = "tracing"
[tracing.jaeger] sampleRate = 1.0
samplingType = "const" {{if .IsHTTP}}
samplingParam = 1.0 [tracing.otlp.http]
samplingServerURL = "http://{{.IP}}:5778/sampling" endpoint = "http://{{.IP}}:4318"
[tracing.jaeger.collector] {{else}}
endpoint = "http://{{.IP}}:14268/api/traces?format=jaeger.thrift" [tracing.otlp.grpc]
endpoint = "{{.IP}}:4317"
insecure = true
{{end}}
[providers.file] [providers.file]
filename = "{{ .SelfFilename }}" filename = "{{ .SelfFilename }}"
@ -28,6 +31,10 @@
## dynamic configuration ## ## dynamic configuration ##
[http.routers] [http.routers]
[http.routers.router0]
Service = "service0"
Middlewares = []
Rule = "Path(`/basic`)"
[http.routers.router1] [http.routers.router1]
Service = "service1" Service = "service1"
Middlewares = ["retry", "ratelimit-1"] Middlewares = ["retry", "ratelimit-1"]
@ -50,8 +57,13 @@
average = 1 average = 1
burst = 2 burst = 2
[http.services] [http.services]
[http.services.service0]
[http.services.service0.loadBalancer]
passHostHeader = true
[[http.services.service0.loadBalancer.servers]]
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
[http.services.service1] [http.services.service1]
[http.services.service1.loadBalancer] [http.services.service1.loadBalancer]
passHostHeader = true passHostHeader = true

View file

@ -1,66 +0,0 @@
[global]
checkNewVersion = false
sendAnonymousUsage = false
[log]
level = "DEBUG"
noColor = true
[api]
insecure = true
[entryPoints]
[entryPoints.web]
address = ":8000"
[tracing]
servicename = "tracing"
[tracing.zipkin]
httpEndpoint = "http://{{.IP}}:9411/api/v2/spans"
[providers.file]
filename = "{{ .SelfFilename }}"
## dynamic configuration ##
[http.routers]
[http.routers.router1]
service = "service1"
middlewares = ["retry", "ratelimit-1"]
rule = "Path(`/ratelimit`)"
[http.routers.router2]
service = "service2"
middlewares = ["retry"]
rule = "Path(`/retry`)"
[http.routers.router3]
service = "service3"
middlewares = ["retry", "basic-auth"]
rule = "Path(`/auth`)"
[http.middlewares]
[http.middlewares.retry.retry]
attempts = 3
[http.middlewares.basic-auth.basicAuth]
users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"]
[http.middlewares.ratelimit-1.rateLimit]
average = 1
burst = 2
[http.services]
[http.services.service1]
[http.services.service1.loadBalancer]
passHostHeader = true
[[http.services.service1.loadBalancer.servers]]
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
[http.services.service2]
[http.services.service2.loadBalancer]
passHostHeader = true
[[http.services.service2.loadBalancer.servers]]
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
[http.services.service3]
[http.services.service3.loadBalancer]
passHostHeader = true
[[http.services.service3.loadBalancer.servers]]
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"

View file

@ -0,0 +1,56 @@
server:
http_listen_port: 3200
query_frontend:
search:
duration_slo: 5s
throughput_bytes_slo: 1.073741824e+09
trace_by_id:
duration_slo: 5s
distributor:
receivers:
otlp:
protocols:
grpc:
ingester:
lifecycler:
address: 127.0.0.1
ring:
kvstore:
store: inmemory
replication_factor: 1
final_sleep: 0s
trace_idle_period: 1s
max_block_duration: 1m
complete_block_timeout: 5s
flush_check_period: 1s
compactor:
compaction:
block_retention: 1h
metrics_generator:
registry:
external_labels:
source: tempo
cluster: docker-compose
storage:
path: /tmp/tempo/generator/wal
remote_write:
- url: http://prometheus:9090/api/v1/write
send_exemplars: true
storage:
trace:
backend: local # backend configuration to use
wal:
path: /tmp/tempo/wal # where to store the wal locally
local:
path: /tmp/tempo/blocks
overrides:
defaults:
metrics_generator:
processors: [service-graphs, span-metrics] # enables metrics generator

View file

@ -4,12 +4,18 @@ import (
"bytes" "bytes"
"context" "context"
"encoding/json" "encoding/json"
"errors"
"fmt"
"io/fs"
"net" "net"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"text/template"
"time" "time"
"github.com/fatih/structs"
"github.com/go-check/check" "github.com/go-check/check"
"github.com/kvtools/redis" "github.com/kvtools/redis"
"github.com/kvtools/valkeyrie" "github.com/kvtools/valkeyrie"
@ -23,24 +29,36 @@ import (
// Redis test suites. // Redis test suites.
type RedisSuite struct { type RedisSuite struct {
BaseSuite BaseSuite
kvClient store.Store kvClient store.Store
redisAddr string redisEndpoints []string
}
func (s *RedisSuite) TearDownSuite(c *check.C) {
s.composeDown(c)
for _, filename := range []string{"sentinel1.conf", "sentinel2.conf", "sentinel3.conf"} {
err := os.Remove(filepath.Join(".", "resources", "compose", "config", filename))
if err != nil && !errors.Is(err, fs.ErrNotExist) {
c.Fatal("unable to clean configuration file for sentinel: ", err)
}
}
} }
func (s *RedisSuite) setupStore(c *check.C) { func (s *RedisSuite) setupStore(c *check.C) {
s.createComposeProject(c, "redis") s.createComposeProject(c, "redis")
s.composeUp(c) s.composeUp(c)
s.redisAddr = net.JoinHostPort(s.getComposeServiceIP(c, "redis"), "6379") s.redisEndpoints = []string{}
s.redisEndpoints = append(s.redisEndpoints, net.JoinHostPort(s.getComposeServiceIP(c, "redis"), "6379"))
kv, err := valkeyrie.NewStore( kv, err := valkeyrie.NewStore(
context.Background(), context.Background(),
redis.StoreName, redis.StoreName,
[]string{s.redisAddr}, s.redisEndpoints,
&redis.Config{}, &redis.Config{},
) )
if err != nil { if err != nil {
c.Fatal("Cannot create store redis") c.Fatal("Cannot create store redis: ", err)
} }
s.kvClient = kv s.kvClient = kv
@ -52,7 +70,172 @@ func (s *RedisSuite) setupStore(c *check.C) {
func (s *RedisSuite) TestSimpleConfiguration(c *check.C) { func (s *RedisSuite) TestSimpleConfiguration(c *check.C) {
s.setupStore(c) s.setupStore(c)
file := s.adaptFile(c, "fixtures/redis/simple.toml", struct{ RedisAddress string }{s.redisAddr}) file := s.adaptFile(c, "fixtures/redis/simple.toml", struct{ RedisAddress string }{
RedisAddress: strings.Join(s.redisEndpoints, ","),
})
defer os.Remove(file)
data := map[string]string{
"traefik/http/routers/Router0/entryPoints/0": "web",
"traefik/http/routers/Router0/middlewares/0": "compressor",
"traefik/http/routers/Router0/middlewares/1": "striper",
"traefik/http/routers/Router0/service": "simplesvc",
"traefik/http/routers/Router0/rule": "Host(`kv1.localhost`)",
"traefik/http/routers/Router0/priority": "42",
"traefik/http/routers/Router0/tls": "true",
"traefik/http/routers/Router1/rule": "Host(`kv2.localhost`)",
"traefik/http/routers/Router1/priority": "42",
"traefik/http/routers/Router1/tls/domains/0/main": "aaa.localhost",
"traefik/http/routers/Router1/tls/domains/0/sans/0": "aaa.aaa.localhost",
"traefik/http/routers/Router1/tls/domains/0/sans/1": "bbb.aaa.localhost",
"traefik/http/routers/Router1/tls/domains/1/main": "bbb.localhost",
"traefik/http/routers/Router1/tls/domains/1/sans/0": "aaa.bbb.localhost",
"traefik/http/routers/Router1/tls/domains/1/sans/1": "bbb.bbb.localhost",
"traefik/http/routers/Router1/entryPoints/0": "web",
"traefik/http/routers/Router1/service": "simplesvc",
"traefik/http/services/simplesvc/loadBalancer/servers/0/url": "http://10.0.1.1:8888",
"traefik/http/services/simplesvc/loadBalancer/servers/1/url": "http://10.0.1.1:8889",
"traefik/http/services/srvcA/loadBalancer/servers/0/url": "http://10.0.1.2:8888",
"traefik/http/services/srvcA/loadBalancer/servers/1/url": "http://10.0.1.2:8889",
"traefik/http/services/srvcB/loadBalancer/servers/0/url": "http://10.0.1.3:8888",
"traefik/http/services/srvcB/loadBalancer/servers/1/url": "http://10.0.1.3:8889",
"traefik/http/services/mirror/mirroring/service": "simplesvc",
"traefik/http/services/mirror/mirroring/mirrors/0/name": "srvcA",
"traefik/http/services/mirror/mirroring/mirrors/0/percent": "42",
"traefik/http/services/mirror/mirroring/mirrors/1/name": "srvcB",
"traefik/http/services/mirror/mirroring/mirrors/1/percent": "42",
"traefik/http/services/Service03/weighted/services/0/name": "srvcA",
"traefik/http/services/Service03/weighted/services/0/weight": "42",
"traefik/http/services/Service03/weighted/services/1/name": "srvcB",
"traefik/http/services/Service03/weighted/services/1/weight": "42",
"traefik/http/middlewares/compressor/compress": "true",
"traefik/http/middlewares/striper/stripPrefix/prefixes/0": "foo",
"traefik/http/middlewares/striper/stripPrefix/prefixes/1": "bar",
}
for k, v := range data {
err := s.kvClient.Put(context.Background(), k, []byte(v), nil)
c.Assert(err, checker.IsNil)
}
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second,
try.BodyContains(`"striper@redis":`, `"compressor@redis":`, `"srvcA@redis":`, `"srvcB@redis":`),
)
c.Assert(err, checker.IsNil)
resp, err := http.Get("http://127.0.0.1:8080/api/rawdata")
c.Assert(err, checker.IsNil)
var obtained api.RunTimeRepresentation
err = json.NewDecoder(resp.Body).Decode(&obtained)
c.Assert(err, checker.IsNil)
got, err := json.MarshalIndent(obtained, "", " ")
c.Assert(err, checker.IsNil)
expectedJSON := filepath.FromSlash("testdata/rawdata-redis.json")
if *updateExpected {
err = os.WriteFile(expectedJSON, got, 0o666)
c.Assert(err, checker.IsNil)
}
expected, err := os.ReadFile(expectedJSON)
c.Assert(err, checker.IsNil)
if !bytes.Equal(expected, got) {
diff := difflib.UnifiedDiff{
FromFile: "Expected",
A: difflib.SplitLines(string(expected)),
ToFile: "Got",
B: difflib.SplitLines(string(got)),
Context: 3,
}
text, err := difflib.GetUnifiedDiffString(diff)
c.Assert(err, checker.IsNil)
c.Error(text)
}
}
func (s *RedisSuite) setupSentinelStore(c *check.C) {
s.setupSentinelConfiguration(c, []string{"26379", "36379", "46379"})
s.createComposeProject(c, "redis_sentinel")
s.composeUp(c)
s.redisEndpoints = []string{
net.JoinHostPort(s.getComposeServiceIP(c, "sentinel1"), "26379"),
net.JoinHostPort(s.getComposeServiceIP(c, "sentinel2"), "36379"),
net.JoinHostPort(s.getComposeServiceIP(c, "sentinel3"), "46379"),
}
kv, err := valkeyrie.NewStore(
context.Background(),
redis.StoreName,
s.redisEndpoints,
&redis.Config{
Sentinel: &redis.Sentinel{
MasterName: "mymaster",
},
},
)
if err != nil {
c.Fatal("Cannot create store redis sentinel")
}
s.kvClient = kv
// wait for redis
err = try.Do(60*time.Second, try.KVExists(kv, "test"))
c.Assert(err, checker.IsNil)
}
func (s *RedisSuite) setupSentinelConfiguration(c *check.C, ports []string) {
for i, port := range ports {
templateValue := struct{ SentinelPort string }{SentinelPort: port}
// Load file
templateFile := "resources/compose/config/sentinel_template.conf"
tmpl, err := template.ParseFiles(templateFile)
c.Assert(err, checker.IsNil)
folder, prefix := filepath.Split(templateFile)
fileName := fmt.Sprintf("%s/sentinel%d.conf", folder, i+1)
tmpFile, err := os.Create(fileName)
c.Assert(err, checker.IsNil)
defer tmpFile.Close()
model := structs.Map(templateValue)
model["SelfFilename"] = tmpFile.Name()
err = tmpl.ExecuteTemplate(tmpFile, prefix, model)
c.Assert(err, checker.IsNil)
err = tmpFile.Sync()
c.Assert(err, checker.IsNil)
}
}
func (s *RedisSuite) TestSentinelConfiguration(c *check.C) {
s.setupSentinelStore(c)
file := s.adaptFile(c, "fixtures/redis/sentinel.toml", struct{ RedisAddress string }{
RedisAddress: strings.Join(s.redisEndpoints, `","`),
})
defer os.Remove(file) defer os.Remove(file)
data := map[string]string{ data := map[string]string{

View file

@ -6,7 +6,7 @@ services:
traefik.enable: true traefik.enable: true
traefik.http.routers.rt1.rule: Host(`no.override.allowlist.docker.local`) traefik.http.routers.rt1.rule: Host(`no.override.allowlist.docker.local`)
traefik.http.routers.rt1.middlewares: wl1 traefik.http.routers.rt1.middlewares: wl1
traefik.http.middlewares.wl1.ipallowList.sourceRange: 8.8.8.8 traefik.http.middlewares.wl1.ipallowlist.sourceRange: 8.8.8.8
overrideIPStrategyRemoteAddrAllowlist: overrideIPStrategyRemoteAddrAllowlist:
image: traefik/whoami image: traefik/whoami

View file

@ -0,0 +1,5 @@
port {{ .SentinelPort }}
dir "/tmp"
sentinel resolve-hostnames yes
sentinel monitor mymaster master 6380 2
sentinel deny-scripts-reconfig yes

View file

@ -0,0 +1,61 @@
version: "3.8"
services:
master:
image: redis
container_name: redis-master
command: redis-server --port 6380
ports:
- 6380:6380
healthcheck:
test: redis-cli -p 6380 ping
node1:
image: redis
container_name: redis-node-1
ports:
- 6381:6381
command: redis-server --port 6381 --slaveof redis-master 6380
healthcheck:
test: redis-cli -p 6381 ping
node2:
image: redis
container_name: redis-node-2
ports:
- 6382:6382
command: redis-server --port 6382 --slaveof redis-master 6380
healthcheck:
test: redis-cli -p 6382 ping
sentinel1:
image: redis
container_name: redis-sentinel-1
ports:
- 26379:26379
command: redis-sentinel /usr/local/etc/redis/conf/sentinel1.conf
healthcheck:
test: redis-cli -p 26379 ping
volumes:
- ./resources/compose/config:/usr/local/etc/redis/conf
sentinel2:
image: redis
container_name: redis-sentinel-2
ports:
- 36379:26379
command: redis-sentinel /usr/local/etc/redis/conf/sentinel2.conf
healthcheck:
test: redis-cli -p 36379 ping
volumes:
- ./resources/compose/config:/usr/local/etc/redis/conf
sentinel3:
image: redis
container_name: redis-sentinel-3
ports:
- 46379:26379
command: redis-sentinel /usr/local/etc/redis/conf/sentinel3.conf
healthcheck:
test: redis-cli -p 46379 ping
volumes:
- ./resources/compose/config:/usr/local/etc/redis/conf
networks:
default:
name: traefik-test-network
external: true

View file

@ -1,16 +1,15 @@
version: "3.8" version: "3.8"
services: services:
zipkin: tempo:
image: openzipkin/zipkin:2.16.2 hostname: tempo
environment: image: grafana/tempo:latest
STORAGE_TYPE: mem command: [ "-config.file=/etc/tempo.yaml" ]
JAVA_OPTS: -Dlogging.level.zipkin=DEBUG volumes:
- ./fixtures/tracing/tempo.yaml:/etc/tempo.yaml
jaeger: otel-collector:
image: jaegertracing/all-in-one:1.14 image: otel/opentelemetry-collector-contrib:0.89.0
environment: volumes:
COLLECTOR_ZIPKIN_HTTP_PORT: 9411 - ./fixtures/tracing/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
whoami: whoami:
image: traefik/whoami image: traefik/whoami

View file

@ -1,20 +1,26 @@
package integration package integration
import ( import (
"encoding/json"
"io"
"net/http" "net/http"
"net/url"
"os" "os"
"strings"
"time" "time"
"github.com/go-check/check" "github.com/go-check/check"
"github.com/tidwall/gjson"
"github.com/traefik/traefik/v3/integration/try" "github.com/traefik/traefik/v3/integration/try"
checker "github.com/vdemeester/shakers" checker "github.com/vdemeester/shakers"
) )
type TracingSuite struct { type TracingSuite struct {
BaseSuite BaseSuite
whoamiIP string whoamiIP string
whoamiPort int whoamiPort int
tracerIP string tempoIP string
otelCollectorIP string
} }
type TracingTemplate struct { type TracingTemplate struct {
@ -22,39 +28,157 @@ type TracingTemplate struct {
WhoamiPort int WhoamiPort int
IP string IP string
TraceContextHeaderName string TraceContextHeaderName string
IsHTTP bool
} }
func (s *TracingSuite) SetUpSuite(c *check.C) { func (s *TracingSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "tracing") s.createComposeProject(c, "tracing")
s.composeUp(c) s.composeUp(c)
}
func (s *TracingSuite) SetUpTest(c *check.C) {
s.composeUp(c, "tempo", "otel-collector", "whoami")
s.whoamiIP = s.getComposeServiceIP(c, "whoami") s.whoamiIP = s.getComposeServiceIP(c, "whoami")
s.whoamiPort = 80 s.whoamiPort = 80
}
func (s *TracingSuite) startZipkin(c *check.C) { // Wait for whoami to turn ready.
s.composeUp(c, "zipkin") err := try.GetRequest("http://"+s.whoamiIP+":80", 30*time.Second, try.StatusCodeIs(http.StatusOK))
s.tracerIP = s.getComposeServiceIP(c, "zipkin") c.Assert(err, checker.IsNil)
// Wait for Zipkin to turn ready. s.tempoIP = s.getComposeServiceIP(c, "tempo")
err := try.GetRequest("http://"+s.tracerIP+":9411/api/v2/services", 20*time.Second, try.StatusCodeIs(http.StatusOK))
// Wait for tempo to turn ready.
err = try.GetRequest("http://"+s.tempoIP+":3200/ready", 30*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
s.otelCollectorIP = s.getComposeServiceIP(c, "otel-collector")
// Wait for otel collector to turn ready.
err = try.GetRequest("http://"+s.otelCollectorIP+":13133/", 30*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
} }
func (s *TracingSuite) TestZipkinRateLimit(c *check.C) { func (s *TracingSuite) TearDownTest(c *check.C) {
s.startZipkin(c) s.composeStop(c, "tempo")
// defer s.composeStop(c, "zipkin") }
file := s.adaptFile(c, "fixtures/tracing/simple-zipkin.toml", TracingTemplate{ func (s *TracingSuite) TestOpentelemetryBasic_HTTP(c *check.C) {
file := s.adaptFile(c, "fixtures/tracing/simple-opentelemetry.toml", TracingTemplate{
WhoamiIP: s.whoamiIP, WhoamiIP: s.whoamiIP,
WhoamiPort: s.whoamiPort, WhoamiPort: s.whoamiPort,
IP: s.tracerIP, IP: s.otelCollectorIP,
IsHTTP: true,
}) })
defer os.Remove(file) defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file)) cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c) defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/basic", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
contains := []map[string]string{
{
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
"batches.0.scopeSpans.0.spans.0.name": "EntryPoint",
"batches.0.scopeSpans.0.spans.0.kind": "SPAN_KIND_SERVER",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"entry_point\").value.stringValue": "web",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue": "/basic",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
"batches.0.scopeSpans.0.spans.1.name": "Router",
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "router0@file",
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
"batches.0.scopeSpans.0.spans.2.name": "Service",
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
"batches.0.scopeSpans.0.spans.3.name": "ReverseProxy",
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_CLIENT",
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"url.scheme\").value.stringValue": "http",
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
},
}
checkTraceContent(c, s.tempoIP, contains)
}
func (s *TracingSuite) TestOpentelemetryBasic_gRPC(c *check.C) {
file := s.adaptFile(c, "fixtures/tracing/simple-opentelemetry.toml", TracingTemplate{
WhoamiIP: s.whoamiIP,
WhoamiPort: s.whoamiPort,
IP: s.otelCollectorIP,
IsHTTP: false,
})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/basic", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
contains := []map[string]string{
{
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
"batches.0.scopeSpans.0.spans.0.name": "EntryPoint",
"batches.0.scopeSpans.0.spans.0.kind": "SPAN_KIND_SERVER",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"entry_point\").value.stringValue": "web",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue": "/basic",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
"batches.0.scopeSpans.0.spans.1.name": "Router",
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "router0@file",
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
"batches.0.scopeSpans.0.spans.2.name": "Service",
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.service.name\").value.stringValue": "service0@file",
"batches.0.scopeSpans.0.spans.3.name": "ReverseProxy",
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_CLIENT",
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"url.scheme\").value.stringValue": "http",
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
},
}
checkTraceContent(c, s.tempoIP, contains)
}
func (s *TracingSuite) TestOpentelemetryRateLimit(c *check.C) {
file := s.adaptFile(c, "fixtures/tracing/simple-opentelemetry.toml", TracingTemplate{
WhoamiIP: s.whoamiIP,
WhoamiPort: s.whoamiPort,
IP: s.otelCollectorIP,
})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start() err := cmd.Start()
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
defer s.killCmd(cmd) defer s.killCmd(cmd)
@ -85,22 +209,94 @@ func (s *TracingSuite) TestZipkinRateLimit(c *check.C) {
err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK)) err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
time.Sleep(3 * time.Second)
err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests)) err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests))
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
err = try.GetRequest("http://"+s.tracerIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("forward service1/router1@file", "ratelimit-1@file")) contains := []map[string]string{
c.Assert(err, checker.IsNil) {
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
"batches.0.scopeSpans.0.spans.0.name": "EntryPoint",
"batches.0.scopeSpans.0.spans.0.kind": "SPAN_KIND_SERVER",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"entry_point\").value.stringValue": "web",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue": "/ratelimit",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
"batches.0.scopeSpans.0.spans.1.name": "Router",
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "router1@file",
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service1@file",
"batches.0.scopeSpans.0.spans.2.name": "Retry",
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
"batches.0.scopeSpans.0.spans.3.name": "RateLimiter",
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "ratelimit-1@file",
"batches.0.scopeSpans.0.spans.4.name": "Service",
"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.service.name\").value.stringValue": "service1@file",
"batches.0.scopeSpans.0.spans.5.name": "ReverseProxy",
"batches.0.scopeSpans.0.spans.5.kind": "SPAN_KIND_CLIENT",
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"url.scheme\").value.stringValue": "http",
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"http.response.status_code\").value.intValue": "200",
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
},
{
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
"batches.0.scopeSpans.0.spans.0.name": "EntryPoint",
"batches.0.scopeSpans.0.spans.0.kind": "SPAN_KIND_SERVER",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"entry_point\").value.stringValue": "web",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue": "/ratelimit",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "429",
"batches.0.scopeSpans.0.spans.1.name": "Router",
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "router1@file",
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service1@file",
"batches.0.scopeSpans.0.spans.2.name": "Retry",
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
"batches.0.scopeSpans.0.spans.3.name": "RateLimiter",
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "ratelimit-1@file",
"batches.0.scopeSpans.0.spans.4.name": "Retry",
"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"http.resend_count\").value.intValue": "1",
"batches.0.scopeSpans.0.spans.5.name": "RateLimiter",
"batches.0.scopeSpans.0.spans.5.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "ratelimit-1@file",
"batches.0.scopeSpans.0.spans.6.name": "Retry",
"batches.0.scopeSpans.0.spans.6.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"http.resend_count\").value.intValue": "2",
"batches.0.scopeSpans.0.spans.7.name": "RateLimiter",
"batches.0.scopeSpans.0.spans.7.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "ratelimit-1@file",
},
}
checkTraceContent(c, s.tempoIP, contains)
} }
func (s *TracingSuite) TestZipkinRetry(c *check.C) { func (s *TracingSuite) TestOpentelemetryRetry(c *check.C) {
s.startZipkin(c) file := s.adaptFile(c, "fixtures/tracing/simple-opentelemetry.toml", TracingTemplate{
defer s.composeStop(c, "zipkin")
file := s.adaptFile(c, "fixtures/tracing/simple-zipkin.toml", TracingTemplate{
WhoamiIP: s.whoamiIP, WhoamiIP: s.whoamiIP,
WhoamiPort: 81, WhoamiPort: 81,
IP: s.tracerIP, IP: s.otelCollectorIP,
}) })
defer os.Remove(file) defer os.Remove(file)
@ -117,18 +313,75 @@ func (s *TracingSuite) TestZipkinRetry(c *check.C) {
err = try.GetRequest("http://127.0.0.1:8000/retry", 500*time.Millisecond, try.StatusCodeIs(http.StatusBadGateway)) err = try.GetRequest("http://127.0.0.1:8000/retry", 500*time.Millisecond, try.StatusCodeIs(http.StatusBadGateway))
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
err = try.GetRequest("http://"+s.tracerIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("forward service2/router2@file", "retry@file")) contains := []map[string]string{
c.Assert(err, checker.IsNil) {
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
"batches.0.scopeSpans.0.spans.0.name": "EntryPoint",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue": "/retry",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
"batches.0.scopeSpans.0.spans.0.status.code": "STATUS_CODE_ERROR",
"batches.0.scopeSpans.0.spans.1.name": "Router",
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "router2@file",
"batches.0.scopeSpans.0.spans.2.name": "Retry",
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
"batches.0.scopeSpans.0.spans.3.name": "Service",
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
"batches.0.scopeSpans.0.spans.4.name": "ReverseProxy",
"batches.0.scopeSpans.0.spans.4.kind": "SPAN_KIND_CLIENT",
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"url.scheme\").value.stringValue": "http",
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
"batches.0.scopeSpans.0.spans.4.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
"batches.0.scopeSpans.0.spans.5.name": "Retry",
"batches.0.scopeSpans.0.spans.5.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
"batches.0.scopeSpans.0.spans.5.attributes.#(key=\"http.resend_count\").value.intValue": "1",
"batches.0.scopeSpans.0.spans.6.name": "Service",
"batches.0.scopeSpans.0.spans.6.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.6.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
"batches.0.scopeSpans.0.spans.7.name": "ReverseProxy",
"batches.0.scopeSpans.0.spans.7.kind": "SPAN_KIND_CLIENT",
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"url.scheme\").value.stringValue": "http",
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
"batches.0.scopeSpans.0.spans.7.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
"batches.0.scopeSpans.0.spans.8.name": "Retry",
"batches.0.scopeSpans.0.spans.8.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
"batches.0.scopeSpans.0.spans.8.attributes.#(key=\"http.resend_count\").value.intValue": "2",
"batches.0.scopeSpans.0.spans.9.name": "Service",
"batches.0.scopeSpans.0.spans.9.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.9.attributes.#(key=\"traefik.service.name\").value.stringValue": "service2@file",
"batches.0.scopeSpans.0.spans.10.name": "ReverseProxy",
"batches.0.scopeSpans.0.spans.10.kind": "SPAN_KIND_CLIENT",
"batches.0.scopeSpans.0.spans.10.attributes.#(key=\"url.scheme\").value.stringValue": "http",
"batches.0.scopeSpans.0.spans.10.attributes.#(key=\"http.response.status_code\").value.intValue": "502",
"batches.0.scopeSpans.0.spans.10.attributes.#(key=\"user_agent.original\").value.stringValue": "Go-http-client/1.1",
},
}
checkTraceContent(c, s.tempoIP, contains)
} }
func (s *TracingSuite) TestZipkinAuth(c *check.C) { func (s *TracingSuite) TestOpentelemetryAuth(c *check.C) {
s.startZipkin(c) file := s.adaptFile(c, "fixtures/tracing/simple-opentelemetry.toml", TracingTemplate{
defer s.composeStop(c, "zipkin")
file := s.adaptFile(c, "fixtures/tracing/simple-zipkin.toml", TracingTemplate{
WhoamiIP: s.whoamiIP, WhoamiIP: s.whoamiIP,
WhoamiPort: s.whoamiPort, WhoamiPort: s.whoamiPort,
IP: s.tracerIP, IP: s.otelCollectorIP,
}) })
defer os.Remove(file) defer os.Remove(file)
@ -145,181 +398,101 @@ func (s *TracingSuite) TestZipkinAuth(c *check.C) {
err = try.GetRequest("http://127.0.0.1:8000/auth", 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized)) err = try.GetRequest("http://127.0.0.1:8000/auth", 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized))
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
err = try.GetRequest("http://"+s.tracerIP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("entrypoint web", "basic-auth@file")) contains := []map[string]string{
c.Assert(err, checker.IsNil) {
"batches.0.scopeSpans.0.scope.name": "github.com/traefik/traefik",
"batches.0.scopeSpans.0.spans.0.name": "EntryPoint",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.request.method\").value.stringValue": "GET",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"url.path\").value.stringValue": "/auth",
"batches.0.scopeSpans.0.spans.0.attributes.#(key=\"http.response.status_code\").value.intValue": "401",
"batches.0.scopeSpans.0.spans.1.name": "Router",
"batches.0.scopeSpans.0.spans.1.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.router.name\").value.stringValue": "router3@file",
"batches.0.scopeSpans.0.spans.1.attributes.#(key=\"traefik.service.name\").value.stringValue": "service3@file",
"batches.0.scopeSpans.0.spans.2.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.2.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "retry@file",
"batches.0.scopeSpans.0.spans.3.kind": "SPAN_KIND_INTERNAL",
"batches.0.scopeSpans.0.spans.3.attributes.#(key=\"traefik.middleware.name\").value.stringValue": "basic-auth@file",
},
}
checkTraceContent(c, s.tempoIP, contains)
} }
func (s *TracingSuite) startJaeger(c *check.C) { func checkTraceContent(c *check.C, tempoIP string, expectedJSON []map[string]string) {
s.composeUp(c, "jaeger", "whoami") baseURL, err := url.Parse("http://" + tempoIP + ":3200/api/search")
s.tracerIP = s.getComposeServiceIP(c, "jaeger")
// Wait for Jaeger to turn ready.
err := try.GetRequest("http://"+s.tracerIP+":16686/api/services", 20*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
req := &http.Request{
Method: http.MethodGet,
URL: baseURL,
}
// Wait for traces to be available.
time.Sleep(10 * time.Second)
resp, err := try.Response(req, 5*time.Second)
c.Assert(err, checker.IsNil)
out := &TraceResponse{}
content, err := io.ReadAll(resp.Body)
c.Assert(err, checker.IsNil)
err = json.Unmarshal(content, &out)
c.Assert(err, checker.IsNil)
if len(out.Traces) == 0 {
c.Fatalf("expected at least one trace, got %d (%s)", len(out.Traces), string(content))
}
var contents []string
for _, t := range out.Traces {
baseURL, err := url.Parse("http://" + tempoIP + ":3200/api/traces/" + t.TraceID)
c.Assert(err, checker.IsNil)
req := &http.Request{
Method: http.MethodGet,
URL: baseURL,
}
resp, err := try.Response(req, 5*time.Second)
c.Assert(err, checker.IsNil)
content, err := io.ReadAll(resp.Body)
c.Assert(err, checker.IsNil)
contents = append(contents, string(content))
}
for _, expected := range expectedJSON {
containsAll(c, expected, contents)
}
} }
func (s *TracingSuite) TestJaegerRateLimit(c *check.C) { func containsAll(c *check.C, expectedJSON map[string]string, contents []string) {
s.startJaeger(c) for k, v := range expectedJSON {
defer s.composeStop(c, "jaeger") found := false
for _, content := range contents {
if gjson.Get(content, k).String() == v {
found = true
break
}
}
file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{ if !found {
WhoamiIP: s.whoamiIP, c.Log("[" + strings.Join(contents, ",") + "]")
WhoamiPort: s.whoamiPort, c.Errorf("missing element: \nKey: %q\nValue: %q ", k, v)
IP: s.tracerIP, }
TraceContextHeaderName: "uber-trace-id", }
})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests))
c.Assert(err, checker.IsNil)
// sleep for 4 seconds to be certain the configured time period has elapsed
// then test another request and verify a 200 status code
time.Sleep(4 * time.Second)
err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
// continue requests at 3 second intervals to test the other rate limit time period
time.Sleep(3 * time.Second)
err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
time.Sleep(3 * time.Second)
err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/ratelimit", 500*time.Millisecond, try.StatusCodeIs(http.StatusTooManyRequests))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://"+s.tracerIP+":16686/api/traces?service=tracing", 20*time.Second, try.BodyContains("forward service1/router1@file", "ratelimit-1@file"))
c.Assert(err, checker.IsNil)
} }
func (s *TracingSuite) TestJaegerRetry(c *check.C) { // TraceResponse contains a list of traces.
s.startJaeger(c) type TraceResponse struct {
defer s.composeStop(c, "jaeger") Traces []Trace `json:"traces"`
file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{
WhoamiIP: s.whoamiIP,
WhoamiPort: 81,
IP: s.tracerIP,
TraceContextHeaderName: "uber-trace-id",
})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/retry", 500*time.Millisecond, try.StatusCodeIs(http.StatusBadGateway))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://"+s.tracerIP+":16686/api/traces?service=tracing", 20*time.Second, try.BodyContains("forward service2/router2@file", "retry@file"))
c.Assert(err, checker.IsNil)
} }
func (s *TracingSuite) TestJaegerAuth(c *check.C) { // Trace represents a simplified grafana tempo trace.
s.startJaeger(c) type Trace struct {
defer s.composeStop(c, "jaeger") TraceID string `json:"traceID"`
file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{
WhoamiIP: s.whoamiIP,
WhoamiPort: s.whoamiPort,
IP: s.tracerIP,
TraceContextHeaderName: "uber-trace-id",
})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/auth", 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://"+s.tracerIP+":16686/api/traces?service=tracing", 20*time.Second, try.BodyContains("EntryPoint web", "basic-auth@file"))
c.Assert(err, checker.IsNil)
}
func (s *TracingSuite) TestJaegerCustomHeader(c *check.C) {
s.startJaeger(c)
defer s.composeStop(c, "jaeger")
file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{
WhoamiIP: s.whoamiIP,
WhoamiPort: s.whoamiPort,
IP: s.tracerIP,
TraceContextHeaderName: "powpow",
})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/auth", 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://"+s.tracerIP+":16686/api/traces?service=tracing", 20*time.Second, try.BodyContains("EntryPoint web", "basic-auth@file"))
c.Assert(err, checker.IsNil)
}
func (s *TracingSuite) TestJaegerAuthCollector(c *check.C) {
s.startJaeger(c)
defer s.composeStop(c, "jaeger")
file := s.adaptFile(c, "fixtures/tracing/simple-jaeger-collector.toml", TracingTemplate{
WhoamiIP: s.whoamiIP,
WhoamiPort: s.whoamiPort,
IP: s.tracerIP,
})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/auth", 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://"+s.tracerIP+":16686/api/traces?service=tracing", 20*time.Second, try.BodyContains("EntryPoint web", "basic-auth@file"))
c.Assert(err, checker.IsNil)
} }

View file

@ -18,7 +18,6 @@ import (
"github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd" "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd"
"github.com/traefik/traefik/v3/pkg/provider/kubernetes/ingress" "github.com/traefik/traefik/v3/pkg/provider/kubernetes/ingress"
"github.com/traefik/traefik/v3/pkg/provider/rest" "github.com/traefik/traefik/v3/pkg/provider/rest"
"github.com/traefik/traefik/v3/pkg/tracing/jaeger"
"github.com/traefik/traefik/v3/pkg/types" "github.com/traefik/traefik/v3/pkg/types"
) )
@ -259,9 +258,7 @@ func TestHandler_Overview(t *testing.T) {
Metrics: &types.Metrics{ Metrics: &types.Metrics{
Prometheus: &types.Prometheus{}, Prometheus: &types.Prometheus{},
}, },
Tracing: &static.Tracing{ Tracing: &static.Tracing{},
Jaeger: &jaeger.Config{},
},
}, },
confDyn: runtime.Configuration{}, confDyn: runtime.Configuration{},
expected: expected{ expected: expected{

View file

@ -2,7 +2,7 @@
"features": { "features": {
"accessLog": false, "accessLog": false,
"metrics": "Prometheus", "metrics": "Prometheus",
"tracing": "Jaeger" "tracing": ""
}, },
"http": { "http": {
"middlewares": { "middlewares": {

View file

@ -122,41 +122,29 @@
[tracing] [tracing]
serviceName = "foobar" serviceName = "foobar"
spanNameLimit = 42 sampleRate = 42
[tracing.jaeger] [tracing.headers]
samplingServerURL = "foobar" header1 = "foobar"
samplingType = "foobar" header2 = "foobar"
samplingParam = 42.0 [tracing.globalAttributes]
localAgentHostPort = "foobar" attr1 = "foobar"
gen128Bit = true attr2 = "foobar"
propagation = "foobar" [tracing.otlp.grpc]
traceContextHeaderName = "foobar" endpoint = "foobar"
[tracing.zipkin] insecure = true
httpEndpoint = "foobar" [tracing.otlp.grpc.tls]
sameSpan = true ca = "foobar"
id128Bit = true cert = "foobar"
debug = true key = "foobar"
sampleRate = 42.0 insecureSkipVerify = true
[tracing.datadog] [tracing.otlp.http]
localAgentHostPort = "foobar" endpoint = "foobar"
localAgentSocket = "foobar" insecure = true
debug = true [tracing.otlp.http.tls]
prioritySampling = true ca = "foobar"
traceIDHeaderName = "foobar" cert = "foobar"
parentIDHeaderName = "foobar" key = "foobar"
samplingPriorityHeaderName = "foobar" insecureSkipVerify = true
bagagePrefixHeaderName = "foobar"
[tracing.instana]
localAgentHost = "foobar"
localAgentPort = 42
logLevel = "foobar"
[tracing.haystack]
localAgentHost = "foobar"
localAgentPort = 42
globalTag = "foobar"
traceIDHeaderName = "foobar"
parentIDHeaderName = "foobar"
spanIDHeaderName = "foobar"
[hostResolver] [hostResolver]
cnameFlattening = true cnameFlattening = true

View file

@ -383,6 +383,9 @@ type IPAllowList struct {
// SourceRange defines the set of allowed IPs (or ranges of allowed IPs by using CIDR notation). // SourceRange defines the set of allowed IPs (or ranges of allowed IPs by using CIDR notation).
SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"` SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"`
IPStrategy *IPStrategy `json:"ipStrategy,omitempty" toml:"ipStrategy,omitempty" yaml:"ipStrategy,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"` IPStrategy *IPStrategy `json:"ipStrategy,omitempty" toml:"ipStrategy,omitempty" yaml:"ipStrategy,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"`
// RejectStatusCode defines the HTTP status code used for refused requests.
// If not set, the default is 403 (Forbidden).
RejectStatusCode int `json:"rejectStatusCode,omitempty" toml:"rejectStatusCode,omitempty" yaml:"rejectStatusCode,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"`
} }
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true

View file

@ -23,7 +23,6 @@ type TCPInFlightConn struct {
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true
// TCPIPAllowList holds the TCP IPAllowList middleware configuration. // TCPIPAllowList holds the TCP IPAllowList middleware configuration.
// This middleware accepts/refuses connections based on the client IP.
type TCPIPAllowList struct { type TCPIPAllowList struct {
// SourceRange defines the allowed IPs (or ranges of allowed IPs by using CIDR notation). // SourceRange defines the allowed IPs (or ranges of allowed IPs by using CIDR notation).
SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"` SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"`

View file

@ -4,7 +4,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Copyright (c) 2016-2020 Containous SAS; 2020-2024 Traefik Labs
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1254,6 +1254,7 @@ func TestEncodeConfiguration(t *testing.T) {
"traefik.HTTP.Middlewares.Middleware8.Headers.STSSeconds": "42", "traefik.HTTP.Middlewares.Middleware8.Headers.STSSeconds": "42",
"traefik.HTTP.Middlewares.Middleware9.IPAllowList.IPStrategy.Depth": "42", "traefik.HTTP.Middlewares.Middleware9.IPAllowList.IPStrategy.Depth": "42",
"traefik.HTTP.Middlewares.Middleware9.IPAllowList.IPStrategy.ExcludedIPs": "foobar, fiibar", "traefik.HTTP.Middlewares.Middleware9.IPAllowList.IPStrategy.ExcludedIPs": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware9.IPAllowList.RejectStatusCode": "0",
"traefik.HTTP.Middlewares.Middleware9.IPAllowList.SourceRange": "foobar, fiibar", "traefik.HTTP.Middlewares.Middleware9.IPAllowList.SourceRange": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware10.InFlightReq.Amount": "42", "traefik.HTTP.Middlewares.Middleware10.InFlightReq.Amount": "42",
"traefik.HTTP.Middlewares.Middleware10.InFlightReq.SourceCriterion.IPStrategy.Depth": "42", "traefik.HTTP.Middlewares.Middleware10.InFlightReq.SourceCriterion.IPStrategy.Depth": "42",

View file

@ -123,8 +123,10 @@ type EntryPoints map[string]*EntryPoint
// EntryPointsTransport configures communication between clients and Traefik. // EntryPointsTransport configures communication between clients and Traefik.
type EntryPointsTransport struct { type EntryPointsTransport struct {
LifeCycle *LifeCycle `description:"Timeouts influencing the server life cycle." json:"lifeCycle,omitempty" toml:"lifeCycle,omitempty" yaml:"lifeCycle,omitempty" export:"true"` LifeCycle *LifeCycle `description:"Timeouts influencing the server life cycle." json:"lifeCycle,omitempty" toml:"lifeCycle,omitempty" yaml:"lifeCycle,omitempty" export:"true"`
RespondingTimeouts *RespondingTimeouts `description:"Timeouts for incoming requests to the Traefik instance." json:"respondingTimeouts,omitempty" toml:"respondingTimeouts,omitempty" yaml:"respondingTimeouts,omitempty" export:"true"` RespondingTimeouts *RespondingTimeouts `description:"Timeouts for incoming requests to the Traefik instance." json:"respondingTimeouts,omitempty" toml:"respondingTimeouts,omitempty" yaml:"respondingTimeouts,omitempty" export:"true"`
KeepAliveMaxTime ptypes.Duration `description:"Maximum duration before closing a keep-alive connection." json:"keepAliveMaxTime,omitempty" toml:"keepAliveMaxTime,omitempty" yaml:"keepAliveMaxTime,omitempty" export:"true"`
KeepAliveMaxRequests int `description:"Maximum number of requests before closing a keep-alive connection." json:"keepAliveMaxRequests,omitempty" toml:"keepAliveMaxRequests,omitempty" yaml:"keepAliveMaxRequests,omitempty" export:"true"`
} }
// SetDefaults sets the default values. // SetDefaults sets the default values.

View file

@ -8,5 +8,4 @@ type Experimental struct {
LocalPlugins map[string]plugins.LocalDescriptor `description:"Local plugins configuration." json:"localPlugins,omitempty" toml:"localPlugins,omitempty" yaml:"localPlugins,omitempty" export:"true"` LocalPlugins map[string]plugins.LocalDescriptor `description:"Local plugins configuration." json:"localPlugins,omitempty" toml:"localPlugins,omitempty" yaml:"localPlugins,omitempty" export:"true"`
KubernetesGateway bool `description:"Allow the Kubernetes gateway api provider usage." json:"kubernetesGateway,omitempty" toml:"kubernetesGateway,omitempty" yaml:"kubernetesGateway,omitempty" export:"true"` KubernetesGateway bool `description:"Allow the Kubernetes gateway api provider usage." json:"kubernetesGateway,omitempty" toml:"kubernetesGateway,omitempty" yaml:"kubernetesGateway,omitempty" export:"true"`
HTTP3 bool `description:"Enable HTTP3." json:"http3,omitempty" toml:"http3,omitempty" yaml:"http3,omitempty" export:"true"`
} }

View file

@ -1,6 +1,7 @@
package static package static
import ( import (
"errors"
"fmt" "fmt"
"strings" "strings"
"time" "time"
@ -27,13 +28,7 @@ import (
"github.com/traefik/traefik/v3/pkg/provider/nomad" "github.com/traefik/traefik/v3/pkg/provider/nomad"
"github.com/traefik/traefik/v3/pkg/provider/rest" "github.com/traefik/traefik/v3/pkg/provider/rest"
"github.com/traefik/traefik/v3/pkg/tls" "github.com/traefik/traefik/v3/pkg/tls"
"github.com/traefik/traefik/v3/pkg/tracing/datadog"
"github.com/traefik/traefik/v3/pkg/tracing/elastic"
"github.com/traefik/traefik/v3/pkg/tracing/haystack"
"github.com/traefik/traefik/v3/pkg/tracing/instana"
"github.com/traefik/traefik/v3/pkg/tracing/jaeger"
"github.com/traefik/traefik/v3/pkg/tracing/opentelemetry" "github.com/traefik/traefik/v3/pkg/tracing/opentelemetry"
"github.com/traefik/traefik/v3/pkg/tracing/zipkin"
"github.com/traefik/traefik/v3/pkg/types" "github.com/traefik/traefik/v3/pkg/types"
) )
@ -96,7 +91,7 @@ type CertificateResolver struct {
// Global holds the global configuration. // Global holds the global configuration.
type Global struct { type Global struct {
CheckNewVersion bool `description:"Periodically check if a new version has been released." json:"checkNewVersion,omitempty" toml:"checkNewVersion,omitempty" yaml:"checkNewVersion,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` CheckNewVersion bool `description:"Periodically check if a new version has been released." json:"checkNewVersion,omitempty" toml:"checkNewVersion,omitempty" yaml:"checkNewVersion,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
SendAnonymousUsage bool `description:"Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default." json:"sendAnonymousUsage,omitempty" toml:"sendAnonymousUsage,omitempty" yaml:"sendAnonymousUsage,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` SendAnonymousUsage bool `description:"Periodically send anonymous usage statistics. If the option is not specified, it will be disabled by default." json:"sendAnonymousUsage,omitempty" toml:"sendAnonymousUsage,omitempty" yaml:"sendAnonymousUsage,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
} }
// ServersTransport options to configure communication between Traefik and the servers. // ServersTransport options to configure communication between Traefik and the servers.
@ -187,21 +182,18 @@ func (a *LifeCycle) SetDefaults() {
// Tracing holds the tracing configuration. // Tracing holds the tracing configuration.
type Tracing struct { type Tracing struct {
ServiceName string `description:"Set the name for this service." json:"serviceName,omitempty" toml:"serviceName,omitempty" yaml:"serviceName,omitempty" export:"true"` ServiceName string `description:"Set the name for this service." json:"serviceName,omitempty" toml:"serviceName,omitempty" yaml:"serviceName,omitempty" export:"true"`
SpanNameLimit int `description:"Set the maximum character limit for Span names (default 0 = no limit)." json:"spanNameLimit,omitempty" toml:"spanNameLimit,omitempty" yaml:"spanNameLimit,omitempty" export:"true"` Headers map[string]string `description:"Defines additional headers to be sent with the payloads." json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty" export:"true"`
Jaeger *jaeger.Config `description:"Settings for Jaeger." json:"jaeger,omitempty" toml:"jaeger,omitempty" yaml:"jaeger,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` GlobalAttributes map[string]string `description:"Defines additional attributes (key:value) on all spans." json:"globalAttributes,omitempty" toml:"globalAttributes,omitempty" yaml:"globalAttributes,omitempty" export:"true"`
Zipkin *zipkin.Config `description:"Settings for Zipkin." json:"zipkin,omitempty" toml:"zipkin,omitempty" yaml:"zipkin,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` SampleRate float64 `description:"Sets the rate between 0.0 and 1.0 of requests to trace." json:"sampleRate,omitempty" toml:"sampleRate,omitempty" yaml:"sampleRate,omitempty" export:"true"`
Datadog *datadog.Config `description:"Settings for Datadog." json:"datadog,omitempty" toml:"datadog,omitempty" yaml:"datadog,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
Instana *instana.Config `description:"Settings for Instana." json:"instana,omitempty" toml:"instana,omitempty" yaml:"instana,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` OTLP *opentelemetry.Config `description:"Settings for OpenTelemetry." json:"otlp,omitempty" toml:"otlp,omitempty" yaml:"otlp,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
Haystack *haystack.Config `description:"Settings for Haystack." json:"haystack,omitempty" toml:"haystack,omitempty" yaml:"haystack,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
Elastic *elastic.Config `description:"Settings for Elastic." json:"elastic,omitempty" toml:"elastic,omitempty" yaml:"elastic,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
OpenTelemetry *opentelemetry.Config `description:"Settings for OpenTelemetry." json:"openTelemetry,omitempty" toml:"openTelemetry,omitempty" yaml:"openTelemetry,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
} }
// SetDefaults sets the default values. // SetDefaults sets the default values.
func (t *Tracing) SetDefaults() { func (t *Tracing) SetDefaults() {
t.ServiceName = "traefik" t.ServiceName = "traefik"
t.SpanNameLimit = 0 t.SampleRate = 1.0
} }
// Providers contains providers configuration. // Providers contains providers configuration.
@ -326,6 +318,20 @@ func (c *Configuration) ValidateConfiguration() error {
acmeEmail = resolver.ACME.Email acmeEmail = resolver.ACME.Email
} }
if c.Tracing != nil && c.Tracing.OTLP != nil {
if c.Tracing.OTLP.HTTP == nil && c.Tracing.OTLP.GRPC == nil {
return errors.New("tracing OTLP: at least one of HTTP and gRPC options should be defined")
}
if c.Tracing.OTLP.HTTP != nil && c.Tracing.OTLP.GRPC != nil {
return errors.New("tracing OTLP: HTTP and gRPC options are mutually exclusive")
}
if c.Tracing.OTLP.GRPC != nil && c.Tracing.OTLP.GRPC.TLS != nil && c.Tracing.OTLP.GRPC.Insecure {
return errors.New("tracing OTLP GRPC: TLS and Insecure options are mutually exclusive")
}
}
return nil return nil
} }

View file

@ -1,28 +0,0 @@
package logs
import (
"github.com/rs/zerolog"
)
type HaystackLogger struct {
logger zerolog.Logger
}
func NewHaystackLogger(logger zerolog.Logger) *HaystackLogger {
return &HaystackLogger{logger: logger}
}
// Error prints the error message.
func (l HaystackLogger) Error(format string, v ...interface{}) {
l.logger.Error().CallerSkipFrame(1).Msgf(format, v...)
}
// Info prints the info message.
func (l HaystackLogger) Info(format string, v ...interface{}) {
l.logger.Info().CallerSkipFrame(1).Msgf(format, v...)
}
// Debug prints the info message.
func (l HaystackLogger) Debug(format string, v ...interface{}) {
l.logger.Debug().CallerSkipFrame(1).Msgf(format, v...)
}

View file

@ -1,24 +0,0 @@
package logs
import (
"bytes"
"os"
"testing"
"time"
"github.com/rs/zerolog"
"github.com/stretchr/testify/assert"
)
func TestNewHaystackLogger(t *testing.T) {
buf := bytes.NewBuffer(nil)
cwb := zerolog.ConsoleWriter{Out: buf, TimeFormat: time.RFC3339, NoColor: true}
out := zerolog.MultiLevelWriter(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}, cwb)
logger := NewHaystackLogger(zerolog.New(out).With().Caller().Logger())
logger.Info("foo")
assert.Equal(t, "<nil> INF haystack_test.go:21 > foo\n", buf.String())
}

View file

@ -1,23 +0,0 @@
package logs
import (
"github.com/rs/zerolog"
)
// JaegerLogger is an implementation of the Logger interface that delegates to traefik log.
type JaegerLogger struct {
logger zerolog.Logger
}
func NewJaegerLogger(logger zerolog.Logger) *JaegerLogger {
return &JaegerLogger{logger: logger}
}
func (l *JaegerLogger) Error(msg string) {
l.logger.Error().CallerSkipFrame(1).Msg(msg)
}
// Infof logs a message at debug priority.
func (l *JaegerLogger) Infof(msg string, args ...interface{}) {
l.logger.Debug().CallerSkipFrame(1).Msgf(msg, args...)
}

View file

@ -1,24 +0,0 @@
package logs
import (
"bytes"
"os"
"testing"
"time"
"github.com/rs/zerolog"
"github.com/stretchr/testify/assert"
)
func TestNewJaegerLogger(t *testing.T) {
buf := bytes.NewBuffer(nil)
cwb := zerolog.ConsoleWriter{Out: buf, TimeFormat: time.RFC3339, NoColor: true}
out := zerolog.MultiLevelWriter(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}, cwb)
logger := NewJaegerLogger(zerolog.New(out).With().Caller().Logger())
logger.Infof("foo")
assert.Equal(t, "<nil> DBG jaeger_test.go:21 > foo\n", buf.String())
}

View file

@ -19,7 +19,7 @@ import (
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
sdkmetric "go.opentelemetry.io/otel/sdk/metric" sdkmetric "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.12.0" semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"google.golang.org/grpc/encoding/gzip" "google.golang.org/grpc/encoding/gzip"
) )

View file

@ -5,10 +5,9 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"github.com/opentracing/opentracing-go/ext"
"github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/middlewares" "github.com/traefik/traefik/v3/pkg/middlewares"
"github.com/traefik/traefik/v3/pkg/tracing" "go.opentelemetry.io/otel/trace"
) )
const ( const (
@ -40,8 +39,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.AddPrefix, name
return result, nil return result, nil
} }
func (a *addPrefix) GetTracingInformation() (string, ext.SpanKindEnum) { func (a *addPrefix) GetTracingInformation() (string, string, trace.SpanKind) {
return a.name, tracing.SpanKindNoneEnum return a.name, typeName, trace.SpanKindInternal
} }
func (a *addPrefix) ServeHTTP(rw http.ResponseWriter, req *http.Request) { func (a *addPrefix) ServeHTTP(rw http.ResponseWriter, req *http.Request) {

View file

@ -8,15 +8,15 @@ import (
"strings" "strings"
goauth "github.com/abbot/go-http-auth" goauth "github.com/abbot/go-http-auth"
"github.com/opentracing/opentracing-go/ext"
"github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/middlewares" "github.com/traefik/traefik/v3/pkg/middlewares"
"github.com/traefik/traefik/v3/pkg/middlewares/accesslog" "github.com/traefik/traefik/v3/pkg/middlewares/accesslog"
"github.com/traefik/traefik/v3/pkg/tracing" "github.com/traefik/traefik/v3/pkg/tracing"
"go.opentelemetry.io/otel/trace"
) )
const ( const (
basicTypeName = "BasicAuth" typeNameBasic = "BasicAuth"
) )
type basicAuth struct { type basicAuth struct {
@ -30,7 +30,7 @@ type basicAuth struct {
// NewBasic creates a basicAuth middleware. // NewBasic creates a basicAuth middleware.
func NewBasic(ctx context.Context, next http.Handler, authConfig dynamic.BasicAuth, name string) (http.Handler, error) { func NewBasic(ctx context.Context, next http.Handler, authConfig dynamic.BasicAuth, name string) (http.Handler, error) {
middlewares.GetLogger(ctx, name, basicTypeName).Debug().Msg("Creating middleware") middlewares.GetLogger(ctx, name, typeNameBasic).Debug().Msg("Creating middleware")
users, err := getUsers(authConfig.UsersFile, authConfig.Users, basicUserParser) users, err := getUsers(authConfig.UsersFile, authConfig.Users, basicUserParser)
if err != nil { if err != nil {
@ -55,12 +55,12 @@ func NewBasic(ctx context.Context, next http.Handler, authConfig dynamic.BasicAu
return ba, nil return ba, nil
} }
func (b *basicAuth) GetTracingInformation() (string, ext.SpanKindEnum) { func (b *basicAuth) GetTracingInformation() (string, string, trace.SpanKind) {
return b.name, tracing.SpanKindNoneEnum return b.name, typeNameBasic, trace.SpanKindInternal
} }
func (b *basicAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) { func (b *basicAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
logger := middlewares.GetLogger(req.Context(), b.name, basicTypeName) logger := middlewares.GetLogger(req.Context(), b.name, typeNameBasic)
user, password, ok := req.BasicAuth() user, password, ok := req.BasicAuth()
if ok { if ok {
@ -77,7 +77,7 @@ func (b *basicAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if !ok { if !ok {
logger.Debug().Msg("Authentication failed") logger.Debug().Msg("Authentication failed")
tracing.SetErrorWithEvent(req, "Authentication failed") tracing.SetStatusErrorf(req.Context(), "Authentication failed")
b.auth.RequireAuth(rw, req) b.auth.RequireAuth(rw, req)
return return

View file

@ -8,15 +8,15 @@ import (
"strings" "strings"
goauth "github.com/abbot/go-http-auth" goauth "github.com/abbot/go-http-auth"
"github.com/opentracing/opentracing-go/ext"
"github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/middlewares" "github.com/traefik/traefik/v3/pkg/middlewares"
"github.com/traefik/traefik/v3/pkg/middlewares/accesslog" "github.com/traefik/traefik/v3/pkg/middlewares/accesslog"
"github.com/traefik/traefik/v3/pkg/tracing" "github.com/traefik/traefik/v3/pkg/tracing"
"go.opentelemetry.io/otel/trace"
) )
const ( const (
digestTypeName = "digestAuth" typeNameDigest = "digestAuth"
) )
type digestAuth struct { type digestAuth struct {
@ -30,7 +30,7 @@ type digestAuth struct {
// NewDigest creates a digest auth middleware. // NewDigest creates a digest auth middleware.
func NewDigest(ctx context.Context, next http.Handler, authConfig dynamic.DigestAuth, name string) (http.Handler, error) { func NewDigest(ctx context.Context, next http.Handler, authConfig dynamic.DigestAuth, name string) (http.Handler, error) {
middlewares.GetLogger(ctx, name, digestTypeName).Debug().Msg("Creating middleware") middlewares.GetLogger(ctx, name, typeNameDigest).Debug().Msg("Creating middleware")
users, err := getUsers(authConfig.UsersFile, authConfig.Users, digestUserParser) users, err := getUsers(authConfig.UsersFile, authConfig.Users, digestUserParser)
if err != nil { if err != nil {
@ -54,12 +54,12 @@ func NewDigest(ctx context.Context, next http.Handler, authConfig dynamic.Digest
return da, nil return da, nil
} }
func (d *digestAuth) GetTracingInformation() (string, ext.SpanKindEnum) { func (d *digestAuth) GetTracingInformation() (string, string, trace.SpanKind) {
return d.name, tracing.SpanKindNoneEnum return d.name, typeNameDigest, trace.SpanKindInternal
} }
func (d *digestAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) { func (d *digestAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
logger := middlewares.GetLogger(req.Context(), d.name, digestTypeName) logger := middlewares.GetLogger(req.Context(), d.name, typeNameDigest)
username, authinfo := d.auth.CheckAuth(req) username, authinfo := d.auth.CheckAuth(req)
if username == "" { if username == "" {
@ -78,13 +78,13 @@ func (d *digestAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if authinfo != nil && *authinfo == "stale" { if authinfo != nil && *authinfo == "stale" {
logger.Debug().Msg("Digest authentication failed, possibly because out of order requests") logger.Debug().Msg("Digest authentication failed, possibly because out of order requests")
tracing.SetErrorWithEvent(req, "Digest authentication failed, possibly because out of order requests") tracing.SetStatusErrorf(req.Context(), "Digest authentication failed, possibly because out of order requests")
d.auth.RequireAuthStale(rw, req) d.auth.RequireAuthStale(rw, req)
return return
} }
logger.Debug().Msg("Digest authentication failed") logger.Debug().Msg("Digest authentication failed")
tracing.SetErrorWithEvent(req, "Digest authentication failed") tracing.SetStatusErrorf(req.Context(), "Digest authentication failed")
d.auth.RequireAuth(rw, req) d.auth.RequireAuth(rw, req)
return return
} }

View file

@ -11,21 +11,22 @@ import (
"strings" "strings"
"time" "time"
"github.com/opentracing/opentracing-go/ext"
"github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/middlewares" "github.com/traefik/traefik/v3/pkg/middlewares"
"github.com/traefik/traefik/v3/pkg/middlewares/connectionheader" "github.com/traefik/traefik/v3/pkg/middlewares/connectionheader"
"github.com/traefik/traefik/v3/pkg/tracing" "github.com/traefik/traefik/v3/pkg/tracing"
"github.com/vulcand/oxy/v2/forward" "github.com/vulcand/oxy/v2/forward"
"github.com/vulcand/oxy/v2/utils" "github.com/vulcand/oxy/v2/utils"
"go.opentelemetry.io/otel/trace"
) )
const ( const (
xForwardedURI = "X-Forwarded-Uri" xForwardedURI = "X-Forwarded-Uri"
xForwardedMethod = "X-Forwarded-Method" xForwardedMethod = "X-Forwarded-Method"
forwardedTypeName = "ForwardedAuthType"
) )
const typeNameForward = "ForwardAuth"
// hopHeaders Hop-by-hop headers to be removed in the authentication request. // hopHeaders Hop-by-hop headers to be removed in the authentication request.
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html // http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
// Proxy-Authorization header is forwarded to the authentication server (see https://tools.ietf.org/html/rfc7235#section-4.4). // Proxy-Authorization header is forwarded to the authentication server (see https://tools.ietf.org/html/rfc7235#section-4.4).
@ -51,7 +52,7 @@ type forwardAuth struct {
// NewForward creates a forward auth middleware. // NewForward creates a forward auth middleware.
func NewForward(ctx context.Context, next http.Handler, config dynamic.ForwardAuth, name string) (http.Handler, error) { func NewForward(ctx context.Context, next http.Handler, config dynamic.ForwardAuth, name string) (http.Handler, error) {
middlewares.GetLogger(ctx, name, forwardedTypeName).Debug().Msg("Creating middleware") middlewares.GetLogger(ctx, name, typeNameForward).Debug().Msg("Creating middleware")
fa := &forwardAuth{ fa := &forwardAuth{
address: config.Address, address: config.Address,
@ -89,30 +90,38 @@ func NewForward(ctx context.Context, next http.Handler, config dynamic.ForwardAu
fa.authResponseHeadersRegex = re fa.authResponseHeadersRegex = re
} }
return connectionheader.Remover(fa), nil return fa, nil
} }
func (fa *forwardAuth) GetTracingInformation() (string, ext.SpanKindEnum) { func (fa *forwardAuth) GetTracingInformation() (string, string, trace.SpanKind) {
return fa.name, ext.SpanKindRPCClientEnum return fa.name, typeNameForward, trace.SpanKindInternal
} }
func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) { func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
logger := middlewares.GetLogger(req.Context(), fa.name, forwardedTypeName) logger := middlewares.GetLogger(req.Context(), fa.name, typeNameForward)
forwardReq, err := http.NewRequest(http.MethodGet, fa.address, nil) req = connectionheader.Remove(req)
tracing.LogRequest(tracing.GetSpan(req), forwardReq)
forwardReq, err := http.NewRequestWithContext(req.Context(), http.MethodGet, fa.address, nil)
if err != nil { if err != nil {
logMessage := fmt.Sprintf("Error calling %s. Cause %s", fa.address, err) logMessage := fmt.Sprintf("Error calling %s. Cause %s", fa.address, err)
logger.Debug().Msg(logMessage) logger.Debug().Msg(logMessage)
tracing.SetErrorWithEvent(req, logMessage) tracing.SetStatusErrorf(req.Context(), logMessage)
rw.WriteHeader(http.StatusInternalServerError) rw.WriteHeader(http.StatusInternalServerError)
return return
} }
// Ensure tracing headers are in the request before we copy the headers to the var forwardSpan trace.Span
// forwardReq. if tracer := tracing.TracerFromContext(req.Context()); tracer != nil {
tracing.InjectRequestHeaders(req) var tracingCtx context.Context
tracingCtx, forwardSpan = tracer.Start(req.Context(), "AuthRequest", trace.WithSpanKind(trace.SpanKindClient))
defer forwardSpan.End()
forwardReq = forwardReq.WithContext(tracingCtx)
tracing.InjectContextIntoCarrier(forwardReq)
tracing.LogClientRequest(forwardSpan, forwardReq)
}
writeHeader(req, forwardReq, fa.trustForwardHeader, fa.authRequestHeaders) writeHeader(req, forwardReq, fa.trustForwardHeader, fa.authRequestHeaders)
@ -120,7 +129,7 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if forwardErr != nil { if forwardErr != nil {
logMessage := fmt.Sprintf("Error calling %s. Cause: %s", fa.address, forwardErr) logMessage := fmt.Sprintf("Error calling %s. Cause: %s", fa.address, forwardErr)
logger.Debug().Msg(logMessage) logger.Debug().Msg(logMessage)
tracing.SetErrorWithEvent(req, logMessage) tracing.SetStatusErrorf(forwardReq.Context(), logMessage)
rw.WriteHeader(http.StatusInternalServerError) rw.WriteHeader(http.StatusInternalServerError)
return return
@ -131,12 +140,18 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if readError != nil { if readError != nil {
logMessage := fmt.Sprintf("Error reading body %s. Cause: %s", fa.address, readError) logMessage := fmt.Sprintf("Error reading body %s. Cause: %s", fa.address, readError)
logger.Debug().Msg(logMessage) logger.Debug().Msg(logMessage)
tracing.SetErrorWithEvent(req, logMessage) tracing.SetStatusErrorf(forwardReq.Context(), logMessage)
rw.WriteHeader(http.StatusInternalServerError) rw.WriteHeader(http.StatusInternalServerError)
return return
} }
// Ending the forward request span as soon as the response is handled.
// If any errors happen earlier, this span will be close by the defer instruction.
if forwardSpan != nil {
forwardSpan.End()
}
// Pass the forward response's body and selected headers if it // Pass the forward response's body and selected headers if it
// didn't return a response within the range of [200, 300). // didn't return a response within the range of [200, 300).
if forwardResponse.StatusCode < http.StatusOK || forwardResponse.StatusCode >= http.StatusMultipleChoices { if forwardResponse.StatusCode < http.StatusOK || forwardResponse.StatusCode >= http.StatusMultipleChoices {
@ -152,7 +167,7 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if !errors.Is(err, http.ErrNoLocation) { if !errors.Is(err, http.ErrNoLocation) {
logMessage := fmt.Sprintf("Error reading response location header %s. Cause: %s", fa.address, err) logMessage := fmt.Sprintf("Error reading response location header %s. Cause: %s", fa.address, err)
logger.Debug().Msg(logMessage) logger.Debug().Msg(logMessage)
tracing.SetErrorWithEvent(req, logMessage) tracing.SetStatusErrorf(forwardReq.Context(), logMessage)
rw.WriteHeader(http.StatusInternalServerError) rw.WriteHeader(http.StatusInternalServerError)
return return
@ -162,7 +177,7 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("Location", redirectURL.String()) rw.Header().Set("Location", redirectURL.String())
} }
tracing.LogResponseCode(tracing.GetSpan(req), forwardResponse.StatusCode) tracing.LogResponseCode(forwardSpan, forwardResponse.StatusCode, trace.SpanKindClient)
rw.WriteHeader(forwardResponse.StatusCode) rw.WriteHeader(forwardResponse.StatusCode)
if _, err = rw.Write(body); err != nil { if _, err = rw.Write(body); err != nil {
@ -193,6 +208,8 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
} }
} }
tracing.LogResponseCode(forwardSpan, forwardResponse.StatusCode, trace.SpanKindClient)
req.RequestURI = req.URL.RequestURI() req.RequestURI = req.URL.RequestURI()
fa.next.ServeHTTP(rw, req) fa.next.ServeHTTP(rw, req)
} }

View file

@ -8,15 +8,22 @@ import (
"net/http/httptest" "net/http/httptest"
"testing" "testing"
"github.com/opentracing/opentracing-go" "github.com/containous/alice"
"github.com/opentracing/opentracing-go/mocktracer"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/config/static"
tracingMiddleware "github.com/traefik/traefik/v3/pkg/middlewares/tracing" tracingMiddleware "github.com/traefik/traefik/v3/pkg/middlewares/tracing"
"github.com/traefik/traefik/v3/pkg/testhelpers" "github.com/traefik/traefik/v3/pkg/testhelpers"
"github.com/traefik/traefik/v3/pkg/tracing" "github.com/traefik/traefik/v3/pkg/tracing"
"github.com/traefik/traefik/v3/pkg/tracing/opentelemetry"
"github.com/traefik/traefik/v3/pkg/version"
"github.com/vulcand/oxy/v2/forward" "github.com/vulcand/oxy/v2/forward"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/trace/tracetest"
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
) )
func TestForwardAuthFail(t *testing.T) { func TestForwardAuthFail(t *testing.T) {
@ -452,8 +459,8 @@ func Test_writeHeader(t *testing.T) {
func TestForwardAuthUsesTracing(t *testing.T) { func TestForwardAuthUsesTracing(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Mockpfx-Ids-Traceid") == "" { if r.Header.Get("Traceparent") == "" {
t.Errorf("expected Mockpfx-Ids-Traceid header to be present in request") t.Errorf("expected Traceparent header to be present in request")
} }
})) }))
t.Cleanup(server.Close) t.Cleanup(server.Close)
@ -464,15 +471,44 @@ func TestForwardAuthUsesTracing(t *testing.T) {
Address: server.URL, Address: server.URL,
} }
tracer := mocktracer.New() exporter := tracetest.NewInMemoryExporter()
opentracing.SetGlobalTracer(tracer)
tr, _ := tracing.NewTracing("testApp", 100, &mockBackend{tracer}) tres, err := resource.New(context.Background(),
resource.WithAttributes(semconv.ServiceNameKey.String("traefik")),
next, err := NewForward(context.Background(), next, auth, "authTest") resource.WithAttributes(semconv.ServiceVersionKey.String(version.Version)),
resource.WithFromEnv(),
resource.WithTelemetrySDK(),
)
require.NoError(t, err) require.NoError(t, err)
next = tracingMiddleware.NewEntryPoint(context.Background(), tr, "tracingTest", next) tracerProvider := sdktrace.NewTracerProvider(
sdktrace.WithSampler(sdktrace.AlwaysSample()),
sdktrace.WithResource(tres),
sdktrace.WithBatcher(exporter),
)
otel.SetTracerProvider(tracerProvider)
config := &static.Tracing{
ServiceName: "testApp",
SampleRate: 1,
OTLP: &opentelemetry.Config{
HTTP: &opentelemetry.HTTP{
Endpoint: "http://127.0.0.1:8080",
},
},
}
tr, closer, err := tracing.NewTracing(config)
require.NoError(t, err)
t.Cleanup(func() {
_ = closer.Close()
})
next, err = NewForward(context.Background(), next, auth, "authTest")
require.NoError(t, err)
chain := alice.New(tracingMiddleware.WrapEntryPointHandler(context.Background(), tr, "tracingTest"))
next, err = chain.Then(next)
require.NoError(t, err)
ts := httptest.NewServer(next) ts := httptest.NewServer(next)
t.Cleanup(ts.Close) t.Cleanup(ts.Close)
@ -482,11 +518,3 @@ func TestForwardAuthUsesTracing(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode) assert.Equal(t, http.StatusOK, res.StatusCode)
} }
type mockBackend struct {
opentracing.Tracer
}
func (b *mockBackend) Setup(componentName string) (opentracing.Tracer, io.Closer, error) {
return b.Tracer, io.NopCloser(nil), nil
}

View file

@ -4,13 +4,12 @@ import (
"context" "context"
"net/http" "net/http"
"github.com/opentracing/opentracing-go/ext"
"github.com/rs/zerolog" "github.com/rs/zerolog"
"github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/logs" "github.com/traefik/traefik/v3/pkg/logs"
"github.com/traefik/traefik/v3/pkg/middlewares" "github.com/traefik/traefik/v3/pkg/middlewares"
"github.com/traefik/traefik/v3/pkg/tracing"
oxybuffer "github.com/vulcand/oxy/v2/buffer" oxybuffer "github.com/vulcand/oxy/v2/buffer"
"go.opentelemetry.io/otel/trace"
) )
const ( const (
@ -49,8 +48,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.Buffering, name
}, nil }, nil
} }
func (b *buffer) GetTracingInformation() (string, ext.SpanKindEnum) { func (b *buffer) GetTracingInformation() (string, string, trace.SpanKind) {
return b.name, tracing.SpanKindNoneEnum return b.name, typeName, trace.SpanKindInternal
} }
func (b *buffer) ServeHTTP(rw http.ResponseWriter, req *http.Request) { func (b *buffer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {

View file

@ -5,7 +5,6 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/opentracing/opentracing-go/ext"
"github.com/rs/zerolog" "github.com/rs/zerolog"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/config/dynamic"
@ -13,6 +12,7 @@ import (
"github.com/traefik/traefik/v3/pkg/middlewares" "github.com/traefik/traefik/v3/pkg/middlewares"
"github.com/traefik/traefik/v3/pkg/tracing" "github.com/traefik/traefik/v3/pkg/tracing"
"github.com/vulcand/oxy/v2/cbreaker" "github.com/vulcand/oxy/v2/cbreaker"
"go.opentelemetry.io/otel/trace"
) )
const typeName = "CircuitBreaker" const typeName = "CircuitBreaker"
@ -32,7 +32,7 @@ func New(ctx context.Context, next http.Handler, confCircuitBreaker dynamic.Circ
cbOpts := []cbreaker.Option{ cbOpts := []cbreaker.Option{
cbreaker.Fallback(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { cbreaker.Fallback(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
tracing.SetErrorWithEvent(req, "blocked by circuit-breaker (%q)", expression) tracing.SetStatusErrorf(req.Context(), "blocked by circuit-breaker (%q)", expression)
rw.WriteHeader(http.StatusServiceUnavailable) rw.WriteHeader(http.StatusServiceUnavailable)
if _, err := rw.Write([]byte(http.StatusText(http.StatusServiceUnavailable))); err != nil { if _, err := rw.Write([]byte(http.StatusText(http.StatusServiceUnavailable))); err != nil {
@ -66,8 +66,8 @@ func New(ctx context.Context, next http.Handler, confCircuitBreaker dynamic.Circ
}, nil }, nil
} }
func (c *circuitBreaker) GetTracingInformation() (string, ext.SpanKindEnum) { func (c *circuitBreaker) GetTracingInformation() (string, string, trace.SpanKind) {
return c.name, tracing.SpanKindNoneEnum return c.name, typeName, trace.SpanKindInternal
} }
func (c *circuitBreaker) ServeHTTP(rw http.ResponseWriter, req *http.Request) { func (c *circuitBreaker) ServeHTTP(rw http.ResponseWriter, req *http.Request) {

View file

@ -9,11 +9,10 @@ import (
"strings" "strings"
"github.com/klauspost/compress/gzhttp" "github.com/klauspost/compress/gzhttp"
"github.com/opentracing/opentracing-go/ext"
"github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/middlewares" "github.com/traefik/traefik/v3/pkg/middlewares"
"github.com/traefik/traefik/v3/pkg/middlewares/compress/brotli" "github.com/traefik/traefik/v3/pkg/middlewares/compress/brotli"
"github.com/traefik/traefik/v3/pkg/tracing" "go.opentelemetry.io/otel/trace"
) )
const typeName = "Compress" const typeName = "Compress"
@ -114,8 +113,8 @@ func (c *compress) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
c.next.ServeHTTP(rw, req) c.next.ServeHTTP(rw, req)
} }
func (c *compress) GetTracingInformation() (string, ext.SpanKindEnum) { func (c *compress) GetTracingInformation() (string, string, trace.SpanKind) {
return c.name, tracing.SpanKindNoneEnum return c.name, typeName, trace.SpanKindInternal
} }
func (c *compress) newGzipHandler() (http.Handler, error) { func (c *compress) newGzipHandler() (http.Handler, error) {

View file

@ -17,24 +17,29 @@ const (
// See RFC 7230, section 6.1. // See RFC 7230, section 6.1.
func Remover(next http.Handler) http.HandlerFunc { func Remover(next http.Handler) http.HandlerFunc {
return func(rw http.ResponseWriter, req *http.Request) { return func(rw http.ResponseWriter, req *http.Request) {
var reqUpType string next.ServeHTTP(rw, Remove(req))
if httpguts.HeaderValuesContainsToken(req.Header[connectionHeader], upgradeHeader) {
reqUpType = req.Header.Get(upgradeHeader)
}
removeConnectionHeaders(req.Header)
if reqUpType != "" {
req.Header.Set(connectionHeader, upgradeHeader)
req.Header.Set(upgradeHeader, reqUpType)
} else {
req.Header.Del(connectionHeader)
}
next.ServeHTTP(rw, req)
} }
} }
// Remove removes hop-by-hop header on the request.
func Remove(req *http.Request) *http.Request {
var reqUpType string
if httpguts.HeaderValuesContainsToken(req.Header[connectionHeader], upgradeHeader) {
reqUpType = req.Header.Get(upgradeHeader)
}
removeConnectionHeaders(req.Header)
if reqUpType != "" {
req.Header.Set(connectionHeader, upgradeHeader)
req.Header.Set(upgradeHeader, reqUpType)
} else {
req.Header.Del(connectionHeader)
}
return req
}
func removeConnectionHeaders(h http.Header) { func removeConnectionHeaders(h http.Header) {
for _, f := range h[connectionHeader] { for _, f := range h[connectionHeader] {
for _, sf := range strings.Split(f, ",") { for _, sf := range strings.Split(f, ",") {

View file

@ -10,12 +10,12 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/opentracing/opentracing-go/ext"
"github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/middlewares" "github.com/traefik/traefik/v3/pkg/middlewares"
"github.com/traefik/traefik/v3/pkg/tracing" "github.com/traefik/traefik/v3/pkg/tracing"
"github.com/traefik/traefik/v3/pkg/types" "github.com/traefik/traefik/v3/pkg/types"
"github.com/vulcand/oxy/v2/utils" "github.com/vulcand/oxy/v2/utils"
"go.opentelemetry.io/otel/trace"
) )
// Compile time validation that the response recorder implements http interfaces correctly. // Compile time validation that the response recorder implements http interfaces correctly.
@ -24,7 +24,7 @@ var (
_ middlewares.Stateful = &codeCatcher{} _ middlewares.Stateful = &codeCatcher{}
) )
const typeName = "customError" const typeName = "CustomError"
type serviceBuilder interface { type serviceBuilder interface {
BuildHTTP(ctx context.Context, serviceName string) (http.Handler, error) BuildHTTP(ctx context.Context, serviceName string) (http.Handler, error)
@ -62,8 +62,8 @@ func New(ctx context.Context, next http.Handler, config dynamic.ErrorPage, servi
}, nil }, nil
} }
func (c *customErrors) GetTracingInformation() (string, ext.SpanKindEnum) { func (c *customErrors) GetTracingInformation() (string, string, trace.SpanKind) {
return c.name, tracing.SpanKindNoneEnum return c.name, typeName, trace.SpanKindInternal
} }
func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) { func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
@ -71,7 +71,7 @@ func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if c.backendHandler == nil { if c.backendHandler == nil {
logger.Error().Msg("Error pages: no backend handler.") logger.Error().Msg("Error pages: no backend handler.")
tracing.SetErrorWithEvent(req, "Error pages: no backend handler.") tracing.SetStatusErrorf(req.Context(), "Error pages: no backend handler.")
c.next.ServeHTTP(rw, req) c.next.ServeHTTP(rw, req)
return return
} }
@ -96,12 +96,12 @@ func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
pageReq, err := newRequest("http://" + req.Host + query) pageReq, err := newRequest("http://" + req.Host + query)
if err != nil { if err != nil {
logger.Error().Err(err).Send() logger.Error().Err(err).Send()
tracing.SetStatusErrorf(req.Context(), err.Error())
http.Error(rw, http.StatusText(code), code) http.Error(rw, http.StatusText(code), code)
return return
} }
utils.CopyHeaders(pageReq.Header, req.Header) utils.CopyHeaders(pageReq.Header, req.Header)
c.backendHandler.ServeHTTP(newCodeModifier(rw, code), c.backendHandler.ServeHTTP(newCodeModifier(rw, code),
pageReq.WithContext(req.Context())) pageReq.WithContext(req.Context()))
} }

View file

@ -9,7 +9,7 @@ import (
"github.com/traefik/traefik/v3/pkg/middlewares" "github.com/traefik/traefik/v3/pkg/middlewares"
) )
const typeName = "grpc-web" const typeName = "GRPCWeb"
// New builds a new gRPC web request converter. // New builds a new gRPC web request converter.
func New(ctx context.Context, next http.Handler, config dynamic.GrpcWeb, name string) http.Handler { func New(ctx context.Context, next http.Handler, config dynamic.GrpcWeb, name string) http.Handler {

Some files were not shown because too many files have changed in this diff Show more