Compare commits
No commits in common. "e467a8093bae9c4b0438eb1f577180799a166f96" and "dc5b82f6fd9a7911ee5478e823125d769d5c2010" have entirely different histories.
e467a8093b
...
dc5b82f6fd
|
@ -1,5 +1,8 @@
|
||||||
run:
|
run:
|
||||||
timeout: 10m
|
timeout: 10m
|
||||||
|
skip-files: []
|
||||||
|
skip-dirs:
|
||||||
|
- pkg/provider/kubernetes/crd/generated/
|
||||||
|
|
||||||
linters-settings:
|
linters-settings:
|
||||||
govet:
|
govet:
|
||||||
|
@ -206,16 +209,11 @@ linters:
|
||||||
- maintidx # kind of duplicate of gocyclo
|
- maintidx # kind of duplicate of gocyclo
|
||||||
- nonamedreturns # Too strict
|
- nonamedreturns # Too strict
|
||||||
- gosmopolitan # not relevant
|
- gosmopolitan # not relevant
|
||||||
- exportloopref # Useless with go1.22
|
|
||||||
- musttag
|
|
||||||
- intrange # bug (fixed in golangci-lint v1.58)
|
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
exclude-use-default: false
|
exclude-use-default: false
|
||||||
max-issues-per-linter: 0
|
max-issues-per-linter: 0
|
||||||
max-same-issues: 0
|
max-same-issues: 0
|
||||||
exclude-dirs:
|
|
||||||
- pkg/provider/kubernetes/crd/generated/
|
|
||||||
exclude:
|
exclude:
|
||||||
- 'Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked'
|
- 'Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked'
|
||||||
- "should have a package comment, unless it's in another file for this package"
|
- "should have a package comment, unless it's in another file for this package"
|
||||||
|
|
|
@ -25,7 +25,7 @@ global_job_config:
|
||||||
- export "PATH=${GOPATH}/bin:${PATH}"
|
- export "PATH=${GOPATH}/bin:${PATH}"
|
||||||
- mkdir -vp "${SEMAPHORE_GIT_DIR}" "${GOPATH}/bin"
|
- mkdir -vp "${SEMAPHORE_GIT_DIR}" "${GOPATH}/bin"
|
||||||
- export GOPROXY=https://proxy.golang.org,direct
|
- export GOPROXY=https://proxy.golang.org,direct
|
||||||
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "${GOPATH}/bin" v1.57.0
|
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "${GOPATH}/bin" v1.56.2
|
||||||
- curl -sSfL https://gist.githubusercontent.com/traefiker/6d7ac019c11d011e4f131bb2cca8900e/raw/goreleaser.sh | bash -s -- -b "${GOPATH}/bin"
|
- curl -sSfL https://gist.githubusercontent.com/traefiker/6d7ac019c11d011e4f131bb2cca8900e/raw/goreleaser.sh | bash -s -- -b "${GOPATH}/bin"
|
||||||
- checkout
|
- checkout
|
||||||
- cache restore traefik-$(checksum go.sum)
|
- cache restore traefik-$(checksum go.sum)
|
||||||
|
|
|
@ -95,6 +95,7 @@ func TestAppendCertMetric(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,6 @@ description: "Traefik Proxy is an open source software with a thriving community
|
||||||
* Harold Ozouf [@jspdown](https://github.com/jspdown)
|
* Harold Ozouf [@jspdown](https://github.com/jspdown)
|
||||||
* Tom Moulard [@tommoulard](https://github.com/tommoulard)
|
* Tom Moulard [@tommoulard](https://github.com/tommoulard)
|
||||||
* Landry Benguigui [@lbenguigui](https://github.com/lbenguigui)
|
* Landry Benguigui [@lbenguigui](https://github.com/lbenguigui)
|
||||||
* Simon Delicata [@sdelicata](https://github.com/sdelicata)
|
|
||||||
* Baptiste Mayelle [@youkoulayley](https://github.com/youkoulayley)
|
|
||||||
|
|
||||||
## Past Maintainers
|
## Past Maintainers
|
||||||
|
|
||||||
|
|
|
@ -92,34 +92,6 @@ Docker provider `tls.CAOptional` option has been removed in v3, as TLS client au
|
||||||
|
|
||||||
The `tls.caOptional` option should be removed from the Docker provider static configuration.
|
The `tls.caOptional` option should be removed from the Docker provider static configuration.
|
||||||
|
|
||||||
### Kubernetes Gateway API
|
|
||||||
|
|
||||||
#### Experimental Channel Resources (TLSRoute and TCPRoute)
|
|
||||||
|
|
||||||
In v3, the Kubernetes Gateway API provider does not enable support for the experimental channel API resources by default.
|
|
||||||
|
|
||||||
##### Remediation
|
|
||||||
|
|
||||||
The `experimentalChannel` option should be used to enable the support for the experimental channel API resources.
|
|
||||||
|
|
||||||
??? example "An example usage of the Kubernetes Gateway API provider with experimental channel support enabled"
|
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
|
||||||
providers:
|
|
||||||
kubernetesGateway:
|
|
||||||
experimentalChannel: true
|
|
||||||
```
|
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
|
||||||
[providers.kubernetesGateway]
|
|
||||||
experimentalChannel = true
|
|
||||||
# ...
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash tab="CLI"
|
|
||||||
--providers.kubernetesgateway.experimentalchannel=true
|
|
||||||
```
|
|
||||||
|
|
||||||
### Experimental Configuration
|
### Experimental Configuration
|
||||||
|
|
||||||
#### HTTP3
|
#### HTTP3
|
||||||
|
@ -724,7 +696,7 @@ Here are two possible transition strategies:
|
||||||
|
|
||||||
Please check the [OpenTelemetry Tracing provider documention](../observability/tracing/opentelemetry.md) for more information.
|
Please check the [OpenTelemetry Tracing provider documention](../observability/tracing/opentelemetry.md) for more information.
|
||||||
|
|
||||||
#### Internal Resources Observability
|
#### Internal Resources Observability (AccessLogs, Metrics and Tracing)
|
||||||
|
|
||||||
In v3, observability for internal routers or services (e.g.: `ping@internal`) is disabled by default.
|
In v3, observability for internal routers or services (e.g.: `ping@internal`) is disabled by default.
|
||||||
To enable it one should use the new `addInternals` option for AccessLogs, Metrics or Tracing.
|
To enable it one should use the new `addInternals` option for AccessLogs, Metrics or Tracing.
|
||||||
|
@ -732,4 +704,4 @@ Please take a look at the observability documentation for more information:
|
||||||
|
|
||||||
- [AccessLogs](../observability/access-logs.md#addinternals)
|
- [AccessLogs](../observability/access-logs.md#addinternals)
|
||||||
- [Metrics](../observability/metrics/overview.md#addinternals)
|
- [Metrics](../observability/metrics/overview.md#addinternals)
|
||||||
- [Tracing](../observability/tracing/overview.md#addinternals)
|
- [AccessLogs](../observability/tracing/overview.md#addinternals)
|
||||||
|
|
|
@ -563,20 +563,3 @@ To enable these ciphers, please set the option `CipherSuites` in your [TLS confi
|
||||||
> (https://go.dev/doc/go1.22#crypto/tls)
|
> (https://go.dev/doc/go1.22#crypto/tls)
|
||||||
|
|
||||||
To enable TLS 1.0, please set the option `MinVersion` to `VersionTLS10` in your [TLS configuration](https://doc.traefik.io/traefik/https/tls/#cipher-suites) or set the environment variable `GODEBUG=tls10server=1`.
|
To enable TLS 1.0, please set the option `MinVersion` to `VersionTLS10` in your [TLS configuration](https://doc.traefik.io/traefik/https/tls/#cipher-suites) or set the environment variable `GODEBUG=tls10server=1`.
|
||||||
|
|
||||||
## v2.11.1
|
|
||||||
|
|
||||||
### Maximum Router Priority Value
|
|
||||||
|
|
||||||
Before v2.11.1, the maximum user-defined router priority value is:
|
|
||||||
|
|
||||||
- `MaxInt32` for 32-bit platforms,
|
|
||||||
- `MaxInt64` for 64-bit platforms.
|
|
||||||
|
|
||||||
Please check out the [go documentation](https://pkg.go.dev/math#pkg-constants) for more information.
|
|
||||||
|
|
||||||
In v2.11.1, Traefik reserves a range of priorities for its internal routers and now,
|
|
||||||
the maximum user-defined router priority value is:
|
|
||||||
|
|
||||||
- `(MaxInt32 - 1000)` for 32-bit platforms,
|
|
||||||
- `(MaxInt64 - 1000)` for 64-bit platforms.
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ accessLog: {}
|
||||||
|
|
||||||
_Optional, Default="false"_
|
_Optional, Default="false"_
|
||||||
|
|
||||||
Enables accessLogs for internal resources (e.g.: `ping@internal`).
|
Enables accessLogs for internal resources.
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
accesslog:
|
accesslog:
|
||||||
|
|
|
@ -21,7 +21,7 @@ and [Kubernetes](https://grafana.com/grafana/dashboards/17347) deployments.
|
||||||
|
|
||||||
_Optional, Default="false"_
|
_Optional, Default="false"_
|
||||||
|
|
||||||
Enables metrics for internal resources (e.g.: `ping@internals`).
|
Enables metrics for internal resources.
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
metrics:
|
metrics:
|
||||||
|
|
|
@ -36,7 +36,7 @@ tracing: {}
|
||||||
|
|
||||||
_Optional, Default="false"_
|
_Optional, Default="false"_
|
||||||
|
|
||||||
Enables tracing for internal resources (e.g.: `ping@internal`).
|
Enables tracing for internal resources.
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
tracing:
|
tracing:
|
||||||
|
|
|
@ -212,29 +212,6 @@ providers:
|
||||||
--providers.kubernetesgateway.namespaces=default,production
|
--providers.kubernetesgateway.namespaces=default,production
|
||||||
```
|
```
|
||||||
|
|
||||||
### `experimentalChannel`
|
|
||||||
|
|
||||||
_Optional, Default: false_
|
|
||||||
|
|
||||||
Toggles support for the Experimental Channel resources ([Gateway API release channels documentation](https://gateway-api.sigs.k8s.io/concepts/versioning/#release-channels)).
|
|
||||||
This option currently enables support for `TCPRoute` and `TLSRoute`.
|
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
|
||||||
providers:
|
|
||||||
kubernetesGateway:
|
|
||||||
experimentalChannel: true
|
|
||||||
```
|
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
|
||||||
[providers.kubernetesGateway]
|
|
||||||
experimentalChannel = true
|
|
||||||
# ...
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash tab="CLI"
|
|
||||||
--providers.kubernetesgateway.experimentalchannel=true
|
|
||||||
```
|
|
||||||
|
|
||||||
### `labelselector`
|
### `labelselector`
|
||||||
|
|
||||||
_Optional, Default: ""_
|
_Optional, Default: ""_
|
||||||
|
|
|
@ -511,27 +511,3 @@ providers:
|
||||||
--providers.nomad.namespaces=ns1,ns2
|
--providers.nomad.namespaces=ns1,ns2
|
||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### `allowEmptyServices`
|
|
||||||
|
|
||||||
_Optional, Default: false_
|
|
||||||
|
|
||||||
If the parameter is set to `true`,
|
|
||||||
it allows the creation of an empty [servers load balancer](../routing/services/index.md#servers-load-balancer) if the targeted Nomad service has no endpoints available. This results in a `503` HTTP response instead of a `404`.
|
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
|
||||||
providers:
|
|
||||||
nomad:
|
|
||||||
allowEmptyServices: true
|
|
||||||
# ...
|
|
||||||
```
|
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
|
||||||
[providers.nomad]
|
|
||||||
allowEmptyServices = true
|
|
||||||
# ...
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash tab="CLI"
|
|
||||||
--providers.nomad.allowEmptyServices=true
|
|
||||||
```
|
|
||||||
|
|
|
@ -729,9 +729,6 @@ Kubernetes certificate authority file path (not needed for in-cluster client).
|
||||||
`--providers.kubernetesgateway.endpoint`:
|
`--providers.kubernetesgateway.endpoint`:
|
||||||
Kubernetes server endpoint (required for external cluster client).
|
Kubernetes server endpoint (required for external cluster client).
|
||||||
|
|
||||||
`--providers.kubernetesgateway.experimentalchannel`:
|
|
||||||
Toggles Experimental Channel resources support (TCPRoute, TLSRoute...). (Default: ```false```)
|
|
||||||
|
|
||||||
`--providers.kubernetesgateway.labelselector`:
|
`--providers.kubernetesgateway.labelselector`:
|
||||||
Kubernetes label selector to select specific GatewayClasses.
|
Kubernetes label selector to select specific GatewayClasses.
|
||||||
|
|
||||||
|
@ -789,9 +786,6 @@ Kubernetes bearer token (not needed for in-cluster client). It accepts either a
|
||||||
`--providers.nomad`:
|
`--providers.nomad`:
|
||||||
Enable Nomad backend with default settings. (Default: ```false```)
|
Enable Nomad backend with default settings. (Default: ```false```)
|
||||||
|
|
||||||
`--providers.nomad.allowemptyservices`:
|
|
||||||
Allow the creation of services without endpoints. (Default: ```false```)
|
|
||||||
|
|
||||||
`--providers.nomad.constraints`:
|
`--providers.nomad.constraints`:
|
||||||
Constraints is an expression that Traefik matches against the Nomad service's tags to determine whether to create route(s) for that service.
|
Constraints is an expression that Traefik matches against the Nomad service's tags to determine whether to create route(s) for that service.
|
||||||
|
|
||||||
|
|
|
@ -729,9 +729,6 @@ Kubernetes certificate authority file path (not needed for in-cluster client).
|
||||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_ENDPOINT`:
|
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_ENDPOINT`:
|
||||||
Kubernetes server endpoint (required for external cluster client).
|
Kubernetes server endpoint (required for external cluster client).
|
||||||
|
|
||||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_EXPERIMENTALCHANNEL`:
|
|
||||||
Toggles Experimental Channel resources support (TCPRoute, TLSRoute...). (Default: ```false```)
|
|
||||||
|
|
||||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_LABELSELECTOR`:
|
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_LABELSELECTOR`:
|
||||||
Kubernetes label selector to select specific GatewayClasses.
|
Kubernetes label selector to select specific GatewayClasses.
|
||||||
|
|
||||||
|
@ -789,9 +786,6 @@ Kubernetes bearer token (not needed for in-cluster client). It accepts either a
|
||||||
`TRAEFIK_PROVIDERS_NOMAD`:
|
`TRAEFIK_PROVIDERS_NOMAD`:
|
||||||
Enable Nomad backend with default settings. (Default: ```false```)
|
Enable Nomad backend with default settings. (Default: ```false```)
|
||||||
|
|
||||||
`TRAEFIK_PROVIDERS_NOMAD_ALLOWEMPTYSERVICES`:
|
|
||||||
Allow the creation of services without endpoints. (Default: ```false```)
|
|
||||||
|
|
||||||
`TRAEFIK_PROVIDERS_NOMAD_CONSTRAINTS`:
|
`TRAEFIK_PROVIDERS_NOMAD_CONSTRAINTS`:
|
||||||
Constraints is an expression that Traefik matches against the Nomad service's tags to determine whether to create route(s) for that service.
|
Constraints is an expression that Traefik matches against the Nomad service's tags to determine whether to create route(s) for that service.
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,6 @@
|
||||||
namespaces = ["foobar", "foobar"]
|
namespaces = ["foobar", "foobar"]
|
||||||
labelSelector = "foobar"
|
labelSelector = "foobar"
|
||||||
throttleDuration = "42s"
|
throttleDuration = "42s"
|
||||||
experimentalChannel = true
|
|
||||||
[providers.rest]
|
[providers.rest]
|
||||||
insecure = true
|
insecure = true
|
||||||
[providers.consulCatalog]
|
[providers.consulCatalog]
|
||||||
|
@ -185,7 +184,6 @@
|
||||||
stale = true
|
stale = true
|
||||||
exposedByDefault = true
|
exposedByDefault = true
|
||||||
refreshInterval = "42s"
|
refreshInterval = "42s"
|
||||||
allowEmptyServices = true
|
|
||||||
namespaces = ["foobar", "foobar"]
|
namespaces = ["foobar", "foobar"]
|
||||||
[providers.nomad.endpoint]
|
[providers.nomad.endpoint]
|
||||||
address = "foobar"
|
address = "foobar"
|
||||||
|
|
|
@ -163,7 +163,6 @@ providers:
|
||||||
- foobar
|
- foobar
|
||||||
labelSelector: foobar
|
labelSelector: foobar
|
||||||
throttleDuration: 42s
|
throttleDuration: 42s
|
||||||
experimentalChannel: true
|
|
||||||
rest:
|
rest:
|
||||||
insecure: true
|
insecure: true
|
||||||
consulCatalog:
|
consulCatalog:
|
||||||
|
@ -216,7 +215,6 @@ providers:
|
||||||
stale: true
|
stale: true
|
||||||
exposedByDefault: true
|
exposedByDefault: true
|
||||||
refreshInterval: 42s
|
refreshInterval: 42s
|
||||||
allowEmptyServices: true
|
|
||||||
namespaces:
|
namespaces:
|
||||||
- foobar
|
- foobar
|
||||||
- foobar
|
- foobar
|
||||||
|
|
|
@ -374,7 +374,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne
|
||||||
| [4] | `routes[n].priority` | Defines the [priority](../routers/index.md#priority) to disambiguate rules of the same length, for route matching |
|
| [4] | `routes[n].priority` | Defines the [priority](../routers/index.md#priority) to disambiguate rules of the same length, for route matching |
|
||||||
| [5] | `routes[n].middlewares` | List of reference to [Middleware](#kind-middleware) |
|
| [5] | `routes[n].middlewares` | List of reference to [Middleware](#kind-middleware) |
|
||||||
| [6] | `middlewares[n].name` | Defines the [Middleware](#kind-middleware) name |
|
| [6] | `middlewares[n].name` | Defines the [Middleware](#kind-middleware) name |
|
||||||
| [7] | `middlewares[n].namespace` | Defines the [Middleware](#kind-middleware) namespace. It can be omitted when the Middleware is in the IngressRoute namespace. |
|
| [7] | `middlewares[n].namespace` | Defines the [Middleware](#kind-middleware) namespace |
|
||||||
| [8] | `routes[n].services` | List of any combination of [TraefikService](#kind-traefikservice) and reference to a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) (See below for `ExternalName Service` setup) |
|
| [8] | `routes[n].services` | List of any combination of [TraefikService](#kind-traefikservice) and reference to a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) (See below for `ExternalName Service` setup) |
|
||||||
| [9] | `services[n].port` | Defines the port of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/). This can be a reference to a named port. |
|
| [9] | `services[n].port` | Defines the port of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/). This can be a reference to a named port. |
|
||||||
| [10] | `services[n].serversTransport` | Defines the reference to a [ServersTransport](#kind-serverstransport). The ServersTransport namespace is assumed to be the [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) namespace (see [ServersTransport reference](#serverstransport-reference)). |
|
| [10] | `services[n].serversTransport` | Defines the reference to a [ServersTransport](#kind-serverstransport). The ServersTransport namespace is assumed to be the [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) namespace (see [ServersTransport reference](#serverstransport-reference)). |
|
||||||
|
|
|
@ -241,20 +241,10 @@ Kubernetes cluster before creating `HTTPRoute` objects.
|
||||||
- name: api@internal
|
- name: api@internal
|
||||||
group: traefik.io # [18]
|
group: traefik.io # [18]
|
||||||
kind: TraefikService # [19]
|
kind: TraefikService # [19]
|
||||||
- filters: # [20]
|
|
||||||
- type: ExtensionRef # [21]
|
|
||||||
extensionRef: # [22]
|
|
||||||
group: traefik.io # [23]
|
|
||||||
kind: Middleware # [24]
|
|
||||||
name: my-middleware # [25]
|
|
||||||
- type: RequestRedirect # [26]
|
|
||||||
requestRedirect: # [27]
|
|
||||||
scheme: https # [28]
|
|
||||||
statusCode: 301 # [29]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
| Ref | Attribute | Description |
|
| Ref | Attribute | Description |
|
||||||
|------|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|------|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [1] | `parentRefs` | References the resources (usually Gateways) that a Route wants to be attached to. |
|
| [1] | `parentRefs` | References the resources (usually Gateways) that a Route wants to be attached to. |
|
||||||
| [2] | `name` | Name of the referent. |
|
| [2] | `name` | Name of the referent. |
|
||||||
| [3] | `namespace` | Namespace of the referent. When unspecified (or empty string), this refers to the local namespace of the Route. |
|
| [3] | `namespace` | Namespace of the referent. When unspecified (or empty string), this refers to the local namespace of the Route. |
|
||||||
|
@ -266,24 +256,14 @@ Kubernetes cluster before creating `HTTPRoute` objects.
|
||||||
| [9] | `type` | Type of match against the path Value (supported types: `Exact`, `Prefix`). |
|
| [9] | `type` | Type of match against the path Value (supported types: `Exact`, `Prefix`). |
|
||||||
| [10] | `value` | The value of the HTTP path to match against. |
|
| [10] | `value` | The value of the HTTP path to match against. |
|
||||||
| [11] | `headers` | Conditions to select a HTTP route by matching HTTP request headers. |
|
| [11] | `headers` | Conditions to select a HTTP route by matching HTTP request headers. |
|
||||||
| [12] | `name` | Name of the HTTP header to be matched. |
|
| [12] | `type` | Type of match for the HTTP request header match against the `values` (supported types: `Exact`). |
|
||||||
| [13] | `value` | Value of HTTP Header to be matched. |
|
| [13] | `value` | A map of HTTP Headers to be matched. It MUST contain at least one entry. |
|
||||||
| [14] | `backendRefs` | Defines the backend(s) where matching requests should be sent. |
|
| [14] | `backendRefs` | Defines the backend(s) where matching requests should be sent. |
|
||||||
| [15] | `name` | The name of the referent service. |
|
| [15] | `name` | The name of the referent service. |
|
||||||
| [16] | `weight` | The proportion of traffic forwarded to a targetRef, computed as weight/(sum of all weights in targetRefs). |
|
| [16] | `weight` | The proportion of traffic forwarded to a targetRef, computed as weight/(sum of all weights in targetRefs). |
|
||||||
| [17] | `port` | The port of the referent service. |
|
| [17] | `port` | The port of the referent service. |
|
||||||
| [18] | `group` | Group is the group of the referent. Only `traefik.io` and `gateway.networking.k8s.io` values are supported. |
|
| [18] | `group` | Group is the group of the referent. Only `traefik.io` and `gateway.networking.k8s.io` values are supported. |
|
||||||
| [19] | `kind` | Kind is kind of the referent. Only `TraefikService` and `Service` values are supported. |
|
| [19] | `kind` | Kind is kind of the referent. Only `TraefikService` and `Service` values are supported. |
|
||||||
| [20] | `filters` | Defines the filters (middlewares) applied to the route. |
|
|
||||||
| [21] | `type` | Defines the type of filter; ExtensionRef is used for configuring custom HTTP filters. |
|
|
||||||
| [22] | `extensionRef` | Configuration of the custom HTTP filter. |
|
|
||||||
| [23] | `group` | Group of the kubernetes object to reference. |
|
|
||||||
| [24] | `kind` | Kind of the kubernetes object to reference. |
|
|
||||||
| [25] | `name` | Name of the kubernetes object to reference. |
|
|
||||||
| [26] | `type` | Defines the type of filter; RequestRedirect redirects a request to another location. |
|
|
||||||
| [27] | `requestRedirect` | Configuration of redirect filter. |
|
|
||||||
| [28] | `scheme` | Scheme is the scheme to be used in the value of the Location header in the response. |
|
|
||||||
| [29] | `statusCode` | StatusCode is the HTTP status code to be used in response. |
|
|
||||||
|
|
||||||
### Kind: `TCPRoute`
|
### Kind: `TCPRoute`
|
||||||
|
|
||||||
|
|
|
@ -442,14 +442,6 @@ The priority is directly equal to the length of the rule, and so the longest len
|
||||||
|
|
||||||
A value of `0` for the priority is ignored: `priority = 0` means that the default rules length sorting is used.
|
A value of `0` for the priority is ignored: `priority = 0` means that the default rules length sorting is used.
|
||||||
|
|
||||||
??? warning "Maximum Value"
|
|
||||||
|
|
||||||
Traefik reserves a range of priorities for its internal routers,
|
|
||||||
the maximum user-defined router priority value is:
|
|
||||||
|
|
||||||
- `(MaxInt32 - 1000)` for 32-bit platforms,
|
|
||||||
- `(MaxInt64 - 1000)` for 64-bit platforms.
|
|
||||||
|
|
||||||
??? info "How default priorities are computed"
|
??? info "How default priorities are computed"
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
|
@ -1156,14 +1148,6 @@ The priority is directly equal to the length of the rule, and so the longest len
|
||||||
|
|
||||||
A value of `0` for the priority is ignored: `priority = 0` means that the default rules length sorting is used.
|
A value of `0` for the priority is ignored: `priority = 0` means that the default rules length sorting is used.
|
||||||
|
|
||||||
??? warning "Maximum Value"
|
|
||||||
|
|
||||||
Traefik reserves a range of priorities for its internal routers,
|
|
||||||
the maximum user-defined router priority value is:
|
|
||||||
|
|
||||||
- `(MaxInt32 - 1000)` for 32-bit platforms,
|
|
||||||
- `(MaxInt64 - 1000)` for 64-bit platforms.
|
|
||||||
|
|
||||||
??? info "How default priorities are computed"
|
??? info "How default priorities are computed"
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -61,7 +61,7 @@ require (
|
||||||
github.com/tidwall/gjson v1.17.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.16.1
|
github.com/traefik/yaegi v0.15.1
|
||||||
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/vulcand/oxy/v2 v2.0.0-20230427132221-be5cf38f3c1c
|
github.com/vulcand/oxy/v2 v2.0.0-20230427132221-be5cf38f3c1c
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -1097,8 +1097,8 @@ github.com/traefik/grpc-web v0.16.0 h1:eeUWZaFg6ZU0I9dWOYE2D5qkNzRBmXzzuRlxdltas
|
||||||
github.com/traefik/grpc-web v0.16.0/go.mod h1:2ttniSv7pTgBWIU2HZLokxRfFX3SA60c/DTmQQgVml4=
|
github.com/traefik/grpc-web v0.16.0/go.mod h1:2ttniSv7pTgBWIU2HZLokxRfFX3SA60c/DTmQQgVml4=
|
||||||
github.com/traefik/paerser v0.2.0 h1:zqCLGSXoNlcBd+mzqSCLjon/I6phqIjeJL2xFB2ysgQ=
|
github.com/traefik/paerser v0.2.0 h1:zqCLGSXoNlcBd+mzqSCLjon/I6phqIjeJL2xFB2ysgQ=
|
||||||
github.com/traefik/paerser v0.2.0/go.mod h1:afzaVcgF8A+MpTnPG4wBr4whjanCSYA6vK5RwaYVtRc=
|
github.com/traefik/paerser v0.2.0/go.mod h1:afzaVcgF8A+MpTnPG4wBr4whjanCSYA6vK5RwaYVtRc=
|
||||||
github.com/traefik/yaegi v0.16.1 h1:f1De3DVJqIDKmnasUF6MwmWv1dSEEat0wcpXhD2On3E=
|
github.com/traefik/yaegi v0.15.1 h1:YA5SbaL6HZA0Exh9T/oArRHqGN2HQ+zgmCY7dkoTXu4=
|
||||||
github.com/traefik/yaegi v0.16.1/go.mod h1:4eVhbPb3LnD2VigQjhYbEJ69vDRFdT2HQNrXx8eEwUY=
|
github.com/traefik/yaegi v0.15.1/go.mod h1:AVRxhaI2G+nUsaM1zyktzwXn69G3t/AuTDrCiTds9p0=
|
||||||
github.com/transip/gotransip/v6 v6.23.0 h1:PsTdjortrEZ8IFFifEryzjVjOy9SgK4ahlnhKBBIQgA=
|
github.com/transip/gotransip/v6 v6.23.0 h1:PsTdjortrEZ8IFFifEryzjVjOy9SgK4ahlnhKBBIQgA=
|
||||||
github.com/transip/gotransip/v6 v6.23.0/go.mod h1:nzv9eN2tdsUrm5nG5ZX6AugYIU4qgsMwIn2c0EZLk8c=
|
github.com/transip/gotransip/v6 v6.23.0/go.mod h1:nzv9eN2tdsUrm5nG5ZX6AugYIU4qgsMwIn2c0EZLk8c=
|
||||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||||
|
|
|
@ -27,4 +27,3 @@
|
||||||
address = ":8443"
|
address = ":8443"
|
||||||
|
|
||||||
[providers.kubernetesGateway]
|
[providers.kubernetesGateway]
|
||||||
experimentalChannel = true
|
|
||||||
|
|
|
@ -24,12 +24,10 @@
|
||||||
[tcp.routers.router1]
|
[tcp.routers.router1]
|
||||||
service = "service1"
|
service = "service1"
|
||||||
rule = "HostSNI(`snitest.net`)"
|
rule = "HostSNI(`snitest.net`)"
|
||||||
[tcp.routers.router1.tls]
|
|
||||||
|
|
||||||
[tcp.routers.router2]
|
[tcp.routers.router2]
|
||||||
service = "service2"
|
service = "service2"
|
||||||
rule = "HostSNI(`snitest.com`)"
|
rule = "HostSNI(`snitest.com`)"
|
||||||
[tcp.routers.router2.tls]
|
|
||||||
|
|
||||||
[tcp.services]
|
[tcp.services]
|
||||||
[tcp.services.service1]
|
[tcp.services.service1]
|
||||||
|
|
|
@ -1134,6 +1134,8 @@ func (s *HTTPSSuite) TestWithDomainFronting() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, "https://127.0.0.1:4443", nil)
|
req, err := http.NewRequest(http.MethodGet, "https://127.0.0.1:4443", nil)
|
||||||
require.NoError(s.T(), err)
|
require.NoError(s.T(), err)
|
||||||
req.Host = test.hostHeader
|
req.Host = test.hostHeader
|
||||||
|
@ -1177,6 +1179,8 @@ func (s *HTTPSSuite) TestWithInvalidTLSOption() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
tlsConfig := &tls.Config{
|
tlsConfig := &tls.Config{
|
||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ func Append(router *mux.Router, customAssets fs.FS) {
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
|
||||||
w.Header().Del("Content-Type")
|
w.Header().Del("Content-Type")
|
||||||
|
|
||||||
http.StripPrefix("/dashboard/", http.FileServerFS(assets)).ServeHTTP(w, r)
|
http.StripPrefix("/dashboard/", http.FileServer(http.FS(assets))).ServeHTTP(w, r)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ func (g Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
|
||||||
w.Header().Del("Content-Type")
|
w.Header().Del("Content-Type")
|
||||||
|
|
||||||
http.FileServerFS(assets).ServeHTTP(w, r)
|
http.FileServer(http.FS(assets)).ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func safePrefix(req *http.Request) string {
|
func safePrefix(req *http.Request) string {
|
||||||
|
|
|
@ -42,6 +42,7 @@ func Test_safePrefix(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -90,6 +91,7 @@ func Test_ContentSecurityPolicy(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,7 @@ func TestHandler_EntryPoints(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -998,6 +998,7 @@ func TestHandler_HTTP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -269,6 +269,7 @@ func TestHandler_Overview(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -874,6 +874,7 @@ func TestHandler_TCP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,7 @@ func TestHandler_RawData(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -251,6 +252,7 @@ func TestHandler_GetMiddleware(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -564,6 +564,7 @@ func TestHandler_UDP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -828,6 +828,7 @@ func TestSortRouters(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(fmt.Sprintf("%s-%s", test.direction, test.sortBy), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%s-%s", test.direction, test.sortBy), func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -1338,6 +1339,7 @@ func TestSortServices(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(fmt.Sprintf("%s-%s", test.direction, test.sortBy), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%s-%s", test.direction, test.sortBy), func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -1672,6 +1674,7 @@ func TestSortMiddlewares(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(fmt.Sprintf("%s-%s", test.direction, test.sortBy), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%s-%s", test.direction, test.sortBy), func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -267,6 +267,7 @@ func TestDeprecationNotice(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -384,6 +385,7 @@ func TestLoad(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
tconfig := cmd.NewTraefikConfiguration()
|
tconfig := cmd.NewTraefikConfiguration()
|
||||||
c := &cli.Command{Configuration: tconfig}
|
c := &cli.Command{Configuration: tconfig}
|
||||||
|
|
|
@ -65,7 +65,7 @@ func createBody(staticConfiguration *static.Configuration) (*bytes.Buffer, error
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err = json.NewEncoder(buf).Encode(data)
|
err = json.NewEncoder(buf).Encode(data) //nolint:musttag // cannot be changed for historical reasons.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,6 +244,7 @@ func TestDecodeToNode(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,7 @@ func TestDecode(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -208,6 +208,7 @@ func TestGetRoutersByEntryPoints(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
runtimeConfig := NewConfig(test.conf)
|
runtimeConfig := NewConfig(test.conf)
|
||||||
|
|
|
@ -208,6 +208,7 @@ func TestGetTCPRoutersByEntryPoints(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
runtimeConfig := NewConfig(test.conf)
|
runtimeConfig := NewConfig(test.conf)
|
||||||
|
|
|
@ -665,6 +665,8 @@ func TestPopulateUsedBy(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -189,6 +189,7 @@ func TestGetUDPRoutersByEntryPoints(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
runtimeConfig := NewConfig(test.conf)
|
runtimeConfig := NewConfig(test.conf)
|
||||||
|
|
|
@ -288,10 +288,6 @@ func (c *Configuration) SetEffectiveConfiguration() {
|
||||||
entryPoints[epName] = gateway.Entrypoint{Address: entryPoint.GetAddress(), HasHTTPTLSConf: entryPoint.HTTP.TLS != nil}
|
entryPoints[epName] = gateway.Entrypoint{Address: entryPoint.GetAddress(), HasHTTPTLSConf: entryPoint.HTTP.TLS != nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Providers.KubernetesCRD != nil {
|
|
||||||
c.Providers.KubernetesCRD.FillExtensionBuilderRegistry(c.Providers.KubernetesGateway)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Providers.KubernetesGateway.EntryPoints = entryPoints
|
c.Providers.KubernetesGateway.EntryPoints = entryPoints
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ func TestHasEntrypoint(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -243,6 +243,7 @@ func TestServiceHealthChecker_newRequest(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -404,6 +405,7 @@ func TestServiceHealthChecker_Launch(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ func TestIsAuthorized(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -116,6 +117,7 @@ func TestNew(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -287,6 +289,7 @@ func TestContainsIsAllowed(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ func TestRemoteAddrStrategy_GetIP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ func TestDepthStrategy_GetIP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -107,6 +109,7 @@ func TestTrustedIPsStrategy_GetIP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ func TestDatadog_parseDatadogAddress(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,8 @@ func TestOpenTelemetry_labels(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -179,6 +181,8 @@ func TestOpenTelemetry_GaugeCollectorAdd(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -271,6 +275,8 @@ func TestOpenTelemetry_GaugeCollectorSet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ func TestRegisterPromState(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
actualNbRegistries := 0
|
actualNbRegistries := 0
|
||||||
for _, prom := range test.prometheusSlice {
|
for _, prom := range test.prometheusSlice {
|
||||||
|
@ -380,6 +381,7 @@ func TestPrometheus(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
family := findMetricFamily(test.name, metricsFamilies)
|
family := findMetricFamily(test.name, metricsFamilies)
|
||||||
if family == nil {
|
if family == nil {
|
||||||
|
|
|
@ -86,6 +86,7 @@ func TestCommonLogFormatter_Format(t *testing.T) {
|
||||||
t.Setenv("TZ", "Etc/GMT+9")
|
t.Setenv("TZ", "Etc/GMT+9")
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -149,6 +150,7 @@ func Test_toLog(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -180,6 +180,7 @@ func TestLoggerHeaderFields(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
logFile, err := os.CreateTemp(t.TempDir(), "*.log")
|
logFile, err := os.CreateTemp(t.TempDir(), "*.log")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -468,6 +469,7 @@ func TestLoggerJSON(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -685,6 +687,7 @@ func TestNewLogHandlerOutputStdout(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
// NOTE: It is not possible to run these cases in parallel because we capture Stdout
|
// NOTE: It is not possible to run these cases in parallel because we capture Stdout
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ func TestParseAccessLog(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@ func TestSaveRetries(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(fmt.Sprintf("%d retries", test.requestAttempt), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%d retries", test.requestAttempt), func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
saveRetries := &SaveRetries{}
|
saveRetries := &SaveRetries{}
|
||||||
|
|
|
@ -29,6 +29,7 @@ func TestNewAddPrefix(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -74,6 +75,7 @@ func TestAddPrefix(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,7 @@ func TestBasicAuthUsersFromFile(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@ func TestDigestAuthUsersFromFile(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ func TestBuffering(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@ func Test_NoBody(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -346,6 +347,7 @@ func Test_ExcludedContentTypes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -450,6 +452,7 @@ func Test_IncludedContentTypes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -554,6 +557,7 @@ func Test_FlushExcludedContentTypes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -672,6 +676,7 @@ func Test_FlushIncludedContentTypes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -826,6 +831,8 @@ func TestParseContentType_equals(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,8 @@ func TestNegotiation(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -297,6 +299,7 @@ func TestShouldNotCompressWhenSpecificContentType(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -348,6 +351,7 @@ func TestShouldCompressWhenSpecificContentType(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -543,6 +547,8 @@ func TestMinResponseBodyBytes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ func TestRemover(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ func TestAutoDetection(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -157,6 +157,7 @@ func TestHandler(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -272,6 +272,7 @@ func TestServeHTTP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -368,6 +369,7 @@ func Test_isWebsocketRequest(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ func TestNewHeader_customRequestHeader(t *testing.T) {
|
||||||
emptyHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
emptyHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ func TestNew_allowedHosts(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ func Test_newSecure_modifyResponse(t *testing.T) {
|
||||||
emptyHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })
|
emptyHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ func TestNewIPAllowLister(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -101,6 +102,7 @@ func TestIPAllowLister_ServeHTTP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ func TestNewIPWhiteLister(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -75,6 +76,7 @@ func TestIPWhiteLister_ServeHTTP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,7 @@ func Test_getMethod(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.method, func(t *testing.T) {
|
t.Run(test.method, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -131,6 +132,7 @@ func Test_getRequestProtocol(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -173,6 +175,7 @@ func Test_grpcStatusCode(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,7 @@ func TestEntryPointMiddleware_metrics(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -310,6 +310,7 @@ func TestPassTLSClientCert_PEM(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -532,6 +533,7 @@ func TestPassTLSClientCert_certInfo(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -602,6 +604,7 @@ WqeUSNGYV//RunTeuRDAf5OxehERb1srzBXhRZ3cZdzXbgR/`,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -642,6 +645,7 @@ func Test_getSANs(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,7 @@ func TestNewRateLimiter(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -247,6 +248,7 @@ func TestRateLimit(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
if test.loadDuration >= time.Minute && testing.Short() {
|
if test.loadDuration >= time.Minute && testing.Short() {
|
||||||
t.Skip("skipping test in short mode.")
|
t.Skip("skipping test in short mode.")
|
||||||
|
|
|
@ -154,6 +154,7 @@ func TestRedirectRegexHandler(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -283,6 +283,8 @@ func TestRedirectSchemeHandler(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ func (rp *replacePathRegex) ServeHTTP(rw http.ResponseWriter, req *http.Request)
|
||||||
currentPath = req.URL.EscapedPath()
|
currentPath = req.URL.EscapedPath()
|
||||||
}
|
}
|
||||||
|
|
||||||
if rp.regexp != nil && rp.regexp.MatchString(currentPath) {
|
if rp.regexp != nil && len(rp.replacement) > 0 && rp.regexp.MatchString(currentPath) {
|
||||||
req.Header.Add(replacepath.ReplacedPathHeader, currentPath)
|
req.Header.Add(replacepath.ReplacedPathHeader, currentPath)
|
||||||
req.URL.RawPath = rp.regexp.ReplaceAllString(currentPath, rp.replacement)
|
req.URL.RawPath = rp.regexp.ReplaceAllString(currentPath, rp.replacement)
|
||||||
|
|
||||||
|
|
|
@ -44,28 +44,6 @@ func TestReplacePathRegex(t *testing.T) {
|
||||||
expectedRawPath: "/who-am-i/and/who-am-i",
|
expectedRawPath: "/who-am-i/and/who-am-i",
|
||||||
expectedHeader: "/whoami/and/whoami",
|
expectedHeader: "/whoami/and/whoami",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "empty replacement",
|
|
||||||
path: "/whoami/and/whoami",
|
|
||||||
config: dynamic.ReplacePathRegex{
|
|
||||||
Replacement: "",
|
|
||||||
Regex: `/whoami`,
|
|
||||||
},
|
|
||||||
expectedPath: "/and",
|
|
||||||
expectedRawPath: "/and",
|
|
||||||
expectedHeader: "/whoami/and/whoami",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "empty trimmed replacement",
|
|
||||||
path: "/whoami/and/whoami",
|
|
||||||
config: dynamic.ReplacePathRegex{
|
|
||||||
Replacement: " ",
|
|
||||||
Regex: `/whoami`,
|
|
||||||
},
|
|
||||||
expectedPath: "/and",
|
|
||||||
expectedRawPath: "/and",
|
|
||||||
expectedHeader: "/whoami/and/whoami",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
desc: "no match",
|
desc: "no match",
|
||||||
path: "/whoami/and/whoami",
|
path: "/whoami/and/whoami",
|
||||||
|
|
|
@ -35,6 +35,7 @@ func TestCNAMEFlatten(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ func TestRequestHost(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -79,6 +80,7 @@ func TestRequestFlattening(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -171,6 +173,7 @@ func Test_parseHost(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,7 @@ func TestRetry(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -271,6 +272,7 @@ func TestRetryWebsocket(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ func TestSNICheck_ServeHTTP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,7 @@ func TestStripPrefix(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,7 @@ func TestStripPrefixRegex(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.path, func(t *testing.T) {
|
t.Run(test.path, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ func TestNewIPAllowLister(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -80,6 +81,7 @@ func TestIPAllowLister_ServeHTTP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ func TestNewIPWhiteLister(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -80,6 +81,7 @@ func TestIPWhiteLister_ServeHTTP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ func TestClientIPMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -138,6 +139,7 @@ func TestMethodMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -255,6 +257,7 @@ func TestHostMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -354,6 +357,7 @@ func TestHostRegexpMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -427,6 +431,7 @@ func TestPathMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -519,6 +524,7 @@ func TestPathRegexpMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -590,6 +596,7 @@ func TestPathPrefixMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -676,6 +683,8 @@ func TestHeaderMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -783,6 +792,7 @@ func TestHeaderRegexpMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -871,6 +881,7 @@ func TestQueryMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -984,6 +995,7 @@ func TestQueryRegexpMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -25,21 +25,15 @@ var httpFuncsV2 = map[string]func(*matchersTree, ...string) error{
|
||||||
}
|
}
|
||||||
|
|
||||||
func pathV2(tree *matchersTree, paths ...string) error {
|
func pathV2(tree *matchersTree, paths ...string) error {
|
||||||
var routes []*mux.Route
|
|
||||||
|
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
route := mux.NewRouter().NewRoute()
|
if !strings.HasPrefix(path, "/") {
|
||||||
|
return fmt.Errorf("path %q does not start with a '/'", path)
|
||||||
if err := route.Path(path).GetError(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
routes = append(routes, route)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.matcher = func(req *http.Request) bool {
|
tree.matcher = func(req *http.Request) bool {
|
||||||
for _, route := range routes {
|
for _, path := range paths {
|
||||||
if route.Match(req, &mux.RouteMatch{}) {
|
if req.URL.Path == path {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,21 +45,15 @@ func pathV2(tree *matchersTree, paths ...string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func pathPrefixV2(tree *matchersTree, paths ...string) error {
|
func pathPrefixV2(tree *matchersTree, paths ...string) error {
|
||||||
var routes []*mux.Route
|
|
||||||
|
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
route := mux.NewRouter().NewRoute()
|
if !strings.HasPrefix(path, "/") {
|
||||||
|
return fmt.Errorf("path %q does not start with a '/'", path)
|
||||||
if err := route.PathPrefix(path).GetError(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
routes = append(routes, route)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.matcher = func(req *http.Request) bool {
|
tree.matcher = func(req *http.Request) bool {
|
||||||
for _, route := range routes {
|
for _, path := range paths {
|
||||||
if route.Match(req, &mux.RouteMatch{}) {
|
if strings.HasPrefix(req.URL.Path, path) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ func TestClientIPV2Matcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -145,6 +146,7 @@ func TestMethodV2Matcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -269,6 +271,7 @@ func TestHostV2Matcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -371,6 +374,7 @@ func TestHostRegexpV2Matcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -450,21 +454,10 @@ func TestPathV2Matcher(t *testing.T) {
|
||||||
"https://example.com/css/main.css": http.StatusNotFound,
|
"https://example.com/css/main.css": http.StatusNotFound,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "valid Path matcher with regexp",
|
|
||||||
rule: "Path(`/css{path:(/.*)?}`)",
|
|
||||||
expected: map[string]int{
|
|
||||||
"https://example.com": http.StatusNotFound,
|
|
||||||
"https://example.com/css/main.css": http.StatusOK,
|
|
||||||
"https://example.org/css/main.css": http.StatusOK,
|
|
||||||
"https://example.com/css/components/component.css": http.StatusOK,
|
|
||||||
"https://example.com/css.css": http.StatusNotFound,
|
|
||||||
"https://example.com/js/main.js": http.StatusNotFound,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -542,21 +535,10 @@ func TestPathPrefixV2Matcher(t *testing.T) {
|
||||||
"https://example.com/css/main.css": http.StatusOK,
|
"https://example.com/css/main.css": http.StatusOK,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "valid PathPrefix matcher with regexp",
|
|
||||||
rule: "PathPrefix(`/css-{name:[0-9]?}`)",
|
|
||||||
expected: map[string]int{
|
|
||||||
"https://example.com": http.StatusNotFound,
|
|
||||||
"https://example.com/css-1/main.css": http.StatusOK,
|
|
||||||
"https://example.org/css-222/main.css": http.StatusOK,
|
|
||||||
"https://example.com/css-333333/components/component.css": http.StatusOK,
|
|
||||||
"https://example.com/css.css": http.StatusNotFound,
|
|
||||||
"https://example.com/js/main.js": http.StatusNotFound,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -643,6 +625,8 @@ func TestHeadersMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -750,6 +734,7 @@ func TestHeaderRegexpV2Matcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -842,6 +827,7 @@ func TestHostRegexp(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -1509,6 +1495,8 @@ func Test_addRoute(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -222,6 +222,8 @@ func TestMuxer(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -376,12 +378,14 @@ func Test_addRoutePriority(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
muxer, err := NewMuxer()
|
muxer, err := NewMuxer()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
for _, route := range test.cases {
|
for _, route := range test.cases {
|
||||||
|
route := route
|
||||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("X-From", route.xFrom)
|
w.Header().Set("X-From", route.xFrom)
|
||||||
})
|
})
|
||||||
|
@ -442,6 +446,7 @@ func TestParseDomains(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.expression, func(t *testing.T) {
|
t.Run(test.expression, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -506,6 +511,7 @@ func TestEmptyHost(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -544,6 +550,7 @@ func TestGetRulePriority(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ func Test_HostSNICatchAll(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -136,6 +137,7 @@ func Test_HostSNI(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -218,6 +220,7 @@ func Test_HostSNIRegexp(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -289,6 +292,7 @@ func Test_ClientIP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -352,6 +356,7 @@ func Test_ALPN(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -461,6 +461,8 @@ func Test_addTCPRouteV2(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -559,6 +561,7 @@ func TestParseHostSNIV2(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.expression, func(t *testing.T) {
|
t.Run(test.expression, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -603,6 +606,8 @@ func Test_HostSNICatchAllV2(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -703,6 +708,8 @@ func Test_HostSNIV2(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -816,6 +823,8 @@ func Test_HostSNIRegexpV2(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -907,6 +916,8 @@ func Test_ClientIPV2(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -974,6 +985,8 @@ func Test_ALPNV2(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -263,6 +263,8 @@ func Test_addTCPRoute(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -371,6 +373,7 @@ func TestParseHostSNI(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -433,6 +436,8 @@ func Test_Priority(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -441,6 +446,7 @@ func Test_Priority(t *testing.T) {
|
||||||
|
|
||||||
matchedRule := ""
|
matchedRule := ""
|
||||||
for rule, priority := range test.rules {
|
for rule, priority := range test.rules {
|
||||||
|
rule := rule
|
||||||
err := muxer.AddRoute(rule, "", priority, tcp.HandlerFunc(func(conn tcp.WriteCloser) {
|
err := muxer.AddRoute(rule, "", priority, tcp.HandlerFunc(func(conn tcp.WriteCloser) {
|
||||||
matchedRule = rule
|
matchedRule = rule
|
||||||
}))
|
}))
|
||||||
|
@ -482,6 +488,7 @@ func TestGetRulePriority(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ func TestLocalStore_GetAccount(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
s := NewLocalStore(test.filename)
|
s := NewLocalStore(test.filename)
|
||||||
|
|
||||||
|
|
|
@ -166,6 +166,7 @@ func TestGetUncheckedCertificates(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -240,6 +241,7 @@ func TestProvider_sanitizeDomains(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -421,6 +423,7 @@ func TestDeleteUnnecessaryDomains(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -494,6 +497,7 @@ func TestIsAccountMatchingCaServer(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -569,6 +573,7 @@ func TestInitAccount(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -627,6 +632,7 @@ func Test_getCertificateRenewDurations(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -179,6 +179,7 @@ func (p ProviderAggregator) Provide(configurationChan chan<- dynamic.Message, po
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, prd := range p.providers {
|
for _, prd := range p.providers {
|
||||||
|
prd := prd
|
||||||
safe.Go(func() {
|
safe.Go(func() {
|
||||||
p.launchProvider(configurationChan, pool, prd)
|
p.launchProvider(configurationChan, pool, prd)
|
||||||
})
|
})
|
||||||
|
|
|
@ -161,6 +161,7 @@ func TestMatchLabels(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.expr, func(t *testing.T) {
|
t.Run(test.expr, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,7 @@ func TestMatchTags(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.expr, func(t *testing.T) {
|
t.Run(test.expr, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -298,6 +298,7 @@ func TestDefaultRule(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -3346,6 +3347,8 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -3411,6 +3414,8 @@ func TestNamespaces(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -3859,6 +3864,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ func Test_tagsToNeutralLabels(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -395,6 +395,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -3648,6 +3649,8 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -3834,6 +3837,7 @@ func TestDynConfBuilder_getIPPort_docker(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -3946,6 +3950,7 @@ func TestDynConfBuilder_getIPAddress_docker(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -4015,6 +4020,7 @@ func TestDynConfBuilder_getIPAddress_swarm(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for serviceID, test := range testCases {
|
for serviceID, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(strconv.Itoa(serviceID), func(t *testing.T) {
|
t.Run(strconv.Itoa(serviceID), func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,8 @@ func (p *SwarmProvider) listServices(ctx context.Context, dockerClient client.AP
|
||||||
|
|
||||||
networkMap := make(map[string]*dockertypes.NetworkResource)
|
networkMap := make(map[string]*dockertypes.NetworkResource)
|
||||||
for _, network := range networkList {
|
for _, network := range networkList {
|
||||||
networkMap[network.ID] = &network
|
networkToAdd := network
|
||||||
|
networkMap[network.ID] = &networkToAdd
|
||||||
}
|
}
|
||||||
|
|
||||||
var dockerDataList []dockerData
|
var dockerDataList []dockerData
|
||||||
|
|
|
@ -63,6 +63,7 @@ func TestListTasks(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for caseID, test := range testCases {
|
for caseID, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(strconv.Itoa(caseID), func(t *testing.T) {
|
t.Run(strconv.Itoa(caseID), func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -229,6 +230,7 @@ func TestSwarmProvider_listServices(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -349,6 +351,7 @@ func TestSwarmProvider_parseService_task(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for caseID, test := range testCases {
|
for caseID, test := range testCases {
|
||||||
|
test := test
|
||||||
t.Run(strconv.Itoa(caseID), func(t *testing.T) {
|
t.Run(strconv.Itoa(caseID), func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue