mirror of
https://github.com/traefik/traefik.git
synced 2026-05-04 12:01:15 +02:00
Merge branch v3.6 into master
This commit is contained in:
commit
efcc60fbdb
@ -1 +1 @@
|
||||
1.25.7
|
||||
1.25
|
||||
|
||||
32
CHANGELOG.md
32
CHANGELOG.md
@ -1,3 +1,35 @@
|
||||
## [v3.6.10](https://github.com/traefik/traefik/tree/v3.6.10) (2026-03-06)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v3.6.9...v3.6.10)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[docker]** Bump Docker and OpenTelemetry dependencies ([#12761](https://github.com/traefik/traefik/pull/12761) by [mmatur](https://github.com/mmatur))
|
||||
- **[fastproxy]** Bump github.com/valyala/fasthttp to v1.69.0 ([#12763](https://github.com/traefik/traefik/pull/12763) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[healthcheck, grpc]** Remove path parsing with grpc healthcheck ([#12760](https://github.com/traefik/traefik/pull/12760) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[k8s/gatewayapi]** Fix Gateway API router's rules ([#12753](https://github.com/traefik/traefik/pull/12753) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[middleware]** Fix HasSecureHeadersDefined returning false when stsSeconds is 0 ([#12684](https://github.com/traefik/traefik/pull/12684) by [veeceey](https://github.com/veeceey))
|
||||
- **[otel]** Bump go.opentelemetry.io/otel dependencies ([#12754](https://github.com/traefik/traefik/pull/12754) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[server]** Bump golang.org/x/net to v0.51.0 ([#12756](https://github.com/traefik/traefik/pull/12756) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[webui]** Fix priority display in dashboard and ACME bypass redirect ([#12740](https://github.com/traefik/traefik/pull/12740) by [mmatur](https://github.com/mmatur))
|
||||
- **[webui]** Fix basePath validation for dashboard template ([#12729](https://github.com/traefik/traefik/pull/12729) by [gndz07](https://github.com/gndz07))
|
||||
|
||||
**Documentation:**
|
||||
- **[middleware]** Correct documentation for Digest auth ([#12651](https://github.com/traefik/traefik/pull/12651) by [Zash](https://github.com/Zash))
|
||||
- Add missing `.http` to TOML table names ([#12713](https://github.com/traefik/traefik/pull/12713) by [Darsstar](https://github.com/Darsstar))
|
||||
- Fix incorrect TOML example in entrypoints docs ([#12711](https://github.com/traefik/traefik/pull/12711) by [mfmfuyu](https://github.com/mfmfuyu))
|
||||
- Fix API basepath option documentation ([#12744](https://github.com/traefik/traefik/pull/12744) by [nmengin](https://github.com/nmengin))
|
||||
|
||||
## [v2.11.40](https://github.com/traefik/traefik/tree/v2.11.40) (2026-03-06)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.38...v2.11.40)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[docker]** Bump Docker and OpenTelemetry dependencies ([#12761](https://github.com/traefik/traefik/pull/12761) by [mmatur](https://github.com/mmatur))
|
||||
- **[server]** Bump golang.org/x/net to v0.51.0 ([#12756](https://github.com/traefik/traefik/pull/12756) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
## [v2.11.39](https://github.com/traefik/traefik/tree/v2.11.39) (2026-03-06)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.38...v2.11.39)
|
||||
|
||||
Release canceled.
|
||||
|
||||
## [v3.6.9](https://github.com/traefik/traefik/tree/v3.6.9) (2026-02-23)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v3.6.8...v3.6.9)
|
||||
|
||||
|
||||
@ -170,11 +170,11 @@ enabling the dashboard [here](https://github.com/traefik/traefik-helm-chart/blob
|
||||
| Field | Description | Default | Required |
|
||||
|:-----------|:---------------------------------|:--------|:---------|
|
||||
| <a id="opt-api" href="#opt-api" title="#opt-api">`api`</a> | Enable api/dashboard. When set to `true`, its sub option `api.dashboard` is also set to true.| false | No |
|
||||
| <a id="opt-api-basepath" href="#opt-api-basepath" title="#opt-api-basepath">api.basepath</a> | Defines the base path where the API and Dashboard will be exposed. | / | No |
|
||||
| <a id="opt-api-basepath" href="#opt-api-basepath" title="#opt-api-basepath">api.basepath</a> | Defines the base path where the API and Dashboard will be exposed.<br/>Please note that this option is incompatible with the [insecure mode](#opt-api-insecure). | / | No |
|
||||
| <a id="opt-api-dashboard" href="#opt-api-dashboard" title="#opt-api-dashboard">`api.dashboard`</a> | Enable dashboard. | false | No |
|
||||
| <a id="opt-api-debug" href="#opt-api-debug" title="#opt-api-debug">`api.debug`</a> | Enable additional endpoints for debugging and profiling. | false | No |
|
||||
| <a id="opt-api-disabledashboardad" href="#opt-api-disabledashboardad" title="#opt-api-disabledashboardad">`api.disabledashboardad`</a> | Disable the advertisement from the dashboard. | false | No |
|
||||
| <a id="opt-api-insecure" href="#opt-api-insecure" title="#opt-api-insecure">`api.insecure`</a> | Enable the API and the dashboard on the entryPoint named traefik.| false | No |
|
||||
| <a id="opt-api-insecure" href="#opt-api-insecure" title="#opt-api-insecure">`api.insecure`</a> | Enable the API and the dashboard on the entryPoint named traefik.<br/>Please note that this mode is incompatible with the custom API [base path option](#opt-api-basepath).| false | No |
|
||||
|
||||
## Endpoints
|
||||
|
||||
|
||||
@ -37,8 +37,8 @@ entryPoints:
|
||||
[entryPoints.web]
|
||||
address = ":80"
|
||||
[entryPoints.web.http]
|
||||
[entryPoints.web.http.redirections]
|
||||
entryPoint = "websecure"
|
||||
[entryPoints.web.http.redirections.entryPoint]
|
||||
to = "websecure"
|
||||
scheme = "https"
|
||||
permanent = true
|
||||
[entryPoints.web.observability]
|
||||
@ -49,10 +49,8 @@ entryPoints:
|
||||
[entryPoints.websecure]
|
||||
address = ":443"
|
||||
[entryPoints.websecure.http]
|
||||
middlewares = ["auth@kubernetescrd", "strip@kubernetescrd"]
|
||||
[entryPoints.websecure.http.tls]
|
||||
[entryPoints.websecure.http.middlewares]
|
||||
- auth@kubernetescrd
|
||||
- strip@kubernetescrd
|
||||
```
|
||||
|
||||
```yaml tab="Helm Chart Values"
|
||||
@ -68,9 +66,9 @@ ports:
|
||||
- auth@kubernetescrd
|
||||
- strip@kubernetescrd
|
||||
additionalArguments:
|
||||
- --entryPoints.web.http.redirections.to=websecure
|
||||
- --entryPoints.web.http.redirections.scheme=https
|
||||
- --entryPoints.web.http.redirections.permanent=true
|
||||
- --entryPoints.web.http.redirections.entryPoint.to=websecure
|
||||
- --entryPoints.web.http.redirections.entryPoint.scheme=https
|
||||
- --entryPoints.web.http.redirections.entryPoint.permanent=true
|
||||
- --entryPoints.web.observability.accessLogs=false
|
||||
- --entryPoints.web.observability.metrics=false
|
||||
- --entryPoints.web.observability.tracing=false
|
||||
@ -89,13 +87,14 @@ additionalArguments:
|
||||
|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------|:---------|
|
||||
| <a id="opt-address" href="#opt-address" title="#opt-address">`address`</a> | Define the port, and optionally the hostname, on which to listen for incoming connections and packets.<br /> It also defines the protocol to use (TCP or UDP).<br /> If no protocol is specified, the default is TCP. The format is:`[host]:port[/tcp\|/udp] | - | Yes |
|
||||
| <a id="opt-asDefault" href="#opt-asDefault" title="#opt-asDefault">`asDefault`</a> | Mark the `entryPoint` to be in the list of default `entryPoints`.<br /> `entryPoints`in this list are used (by default) on HTTP and TCP routers that do not define their own `entryPoints` option.<br /> More information [here](#asdefault). | false | No |
|
||||
| <a id="opt-allowACMEByPass" href="#opt-allowACMEByPass" title="#opt-allowACMEByPass">`allowACMEByPass`</a> | Enables handling of ACME TLS and HTTP challenges with custom routers instead of the internal ACME router. | false | No |
|
||||
| <a id="opt-forwardedHeaders-trustedIPs" href="#opt-forwardedHeaders-trustedIPs" title="#opt-forwardedHeaders-trustedIPs">`forwardedHeaders.trustedIPs`</a> | Set the IPs or CIDR from where Traefik trusts the forwarded headers information (`X-Forwarded-*`). | - | No |
|
||||
| <a id="opt-forwardedHeaders-insecure" href="#opt-forwardedHeaders-insecure" title="#opt-forwardedHeaders-insecure">`forwardedHeaders.insecure`</a> | Set the insecure mode to always trust the forwarded headers information (`X-Forwarded-*`).<br />We recommend to use this option only for tests purposes, not in production. | false | No |
|
||||
| <a id="opt-forwardedHeaders-notAppendXForwardedFor" href="#opt-forwardedHeaders-notAppendXForwardedFor" title="#opt-forwardedHeaders-notAppendXForwardedFor">`forwardedHeaders.`<br />`notAppendXForwardedFor`</a> | When set to `true`, Traefik will not append the client's `RemoteAddr` to the `X-Forwarded-For` header. The existing header is preserved as-is. If no `X-Forwarded-For` header exists, none will be added. | false | No |
|
||||
| <a id="opt-http-redirections-entryPoint-to" href="#opt-http-redirections-entryPoint-to" title="#opt-http-redirections-entryPoint-to">`http.redirections.`<br />`entryPoint.to`</a> | The target element to enable (permanent) redirecting of all incoming requests on an entry point to another one. <br /> The target element can be an entry point name (ex: `websecure`), or a port (`:443`). | - | Yes |
|
||||
| <a id="opt-http-redirections-entryPoint-scheme" href="#opt-http-redirections-entryPoint-scheme" title="#opt-http-redirections-entryPoint-scheme">`http.redirections.`<br />`entryPoint.scheme`</a> | The target scheme to use for (permanent) redirection of all incoming requests. | https | No |
|
||||
| <a id="opt-http-redirections-entryPoint-permanent" href="#opt-http-redirections-entryPoint-permanent" title="#opt-http-redirections-entryPoint-permanent">`http.redirections.`<br />`entryPoint.permanent`</a> | Enable permanent redirecting of all incoming requests on an entry point to another one changing the scheme. <br /> The target element, it can be an entry point name (ex: `websecure`), or a port (`:443`). | false | No |
|
||||
| <a id="opt-http-redirections-entryPoint-priority" href="#opt-http-redirections-entryPoint-priority" title="#opt-http-redirections-entryPoint-priority">`http.redirections.`<br />`entryPoint.priority`</a> | Default priority applied to the routers attached to the `entryPoint`. | MaxInt32-1 (2147483646) | No |
|
||||
| <a id="opt-http-redirections-entryPoint-priority" href="#opt-http-redirections-entryPoint-priority" title="#opt-http-redirections-entryPoint-priority">`http.redirections.`<br />`entryPoint.priority`</a> | Default priority applied to the routers attached to the `entryPoint`. | MaxInt-1 (`2147483646` on 32-bit, `9223372036854775806` on 64-bit) | No |
|
||||
| <a id="opt-http-encodedCharacters" href="#opt-http-encodedCharacters" title="#opt-http-encodedCharacters">`http.encodedCharacters`</a> | Defines which encoded characters are allowed in the request path. More information [here](#encoded-characters). | false | No |
|
||||
| <a id="opt-http-encodedCharacters-allowEncodedSlash" href="#opt-http-encodedCharacters-allowEncodedSlash" title="#opt-http-encodedCharacters-allowEncodedSlash">`http.encodedCharacters.`<br />`allowEncodedSlash`</a> | Defines whether requests with encoded slash characters in the path are allowed. | true | No |
|
||||
| <a id="opt-http-encodedCharacters-allowEncodedBackSlash" href="#opt-http-encodedCharacters-allowEncodedBackSlash" title="#opt-http-encodedCharacters-allowEncodedBackSlash">`http.encodedCharacters.`<br />`allowEncodedBackSlash`</a> | Defines whether requests with encoded back slash characters in the path are allowed. | true | No |
|
||||
@ -147,6 +146,53 @@ The `asDefault` option has no effect on UDP entryPoints.
|
||||
When a UDP router does not define the entryPoints option, it is attached to all
|
||||
available UDP entryPoints.
|
||||
|
||||
### allowACMEByPass
|
||||
|
||||
By default, Traefik creates an internal router with the highest possible priority (`MaxInt`) to handle
|
||||
ACME HTTP and TLS challenges. This ensures that certificate challenges always succeed,
|
||||
but it also prevents any user-defined router from intercepting challenge requests on the same entrypoint.
|
||||
|
||||
When `allowACMEByPass` is set to `true` on an entrypoint:
|
||||
|
||||
- The internal ACME HTTP challenge router is created **without** an explicit high priority,
|
||||
allowing user-defined routers to handle challenge requests instead.
|
||||
- The TLS-ALPN challenge passthrough is enabled on the entrypoint,
|
||||
allowing user-defined TLS routers to handle TLS challenges.
|
||||
|
||||
This is useful when you need custom handling of ACME challenges,
|
||||
for example when using a dedicated service to solve HTTP-01 or TLS-ALPN-01 challenges.
|
||||
|
||||
!!! note
|
||||
|
||||
When no TLS challenge resolver is configured, `allowACMEByPass` is implicitly enabled
|
||||
for TLS passthrough on all entrypoints.
|
||||
|
||||
!!! note
|
||||
|
||||
When `allowACMEByPass` is enabled and the entrypoint has an HTTP redirect configured
|
||||
(via `http.redirections.entryPoint`), the redirect router automatically excludes
|
||||
the ACME challenge path (`/.well-known/acme-challenge/`).
|
||||
This allows user-defined ACME challenge routers to handle challenge requests
|
||||
without being overridden by the redirect.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
allowACMEByPass: true
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[entryPoints.web]
|
||||
address = ":80"
|
||||
allowACMEByPass = true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.web.allowACMEByPass=true
|
||||
```
|
||||
|
||||
### http.middlewares
|
||||
|
||||
- You can attach a list of [middlewares](../../middlewares/http/overview.md)
|
||||
|
||||
@ -67,8 +67,7 @@ spec:
|
||||
|
||||
### Passwords format
|
||||
|
||||
Passwords must be hashed using MD5, SHA1, or BCrypt.
|
||||
Use `htpasswd` to generate the passwords.
|
||||
Use `htdigest` to generate the passwords.
|
||||
|
||||
### users & usersFile
|
||||
|
||||
|
||||
@ -229,8 +229,8 @@ Negative priority values are supported.
|
||||
|
||||
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.
|
||||
- `(MaxInt32 - 1000)` = `2147482647` for 32-bit platforms,
|
||||
- `(MaxInt64 - 1000)` = `9223372036854774807` for 64-bit platforms.
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
75
go.mod
75
go.mod
@ -6,7 +6,7 @@ require (
|
||||
github.com/BurntSushi/toml v1.6.0
|
||||
github.com/Masterminds/sprig/v3 v3.2.3
|
||||
github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000 // No tag on the repo.
|
||||
github.com/andybalholm/brotli v1.1.1
|
||||
github.com/andybalholm/brotli v1.2.0
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.1
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.8
|
||||
@ -18,9 +18,9 @@ require (
|
||||
github.com/cenkalti/backoff/v4 v4.3.0
|
||||
github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd // No tag on the repo.
|
||||
github.com/coreos/go-systemd/v22 v22.5.0
|
||||
github.com/docker/cli v28.3.3+incompatible
|
||||
github.com/docker/docker v28.3.3+incompatible
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/docker/cli v29.2.1+incompatible
|
||||
github.com/docker/docker v28.5.2+incompatible
|
||||
github.com/docker/go-connections v0.6.0
|
||||
github.com/fatih/structs v1.1.0
|
||||
github.com/fsnotify/fsnotify v1.9.0
|
||||
github.com/go-acme/lego/v4 v4.32.0
|
||||
@ -32,7 +32,6 @@ require (
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674
|
||||
github.com/hashicorp/consul/api v1.26.1
|
||||
github.com/hashicorp/go-hclog v1.6.3
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8
|
||||
github.com/hashicorp/go-version v1.8.0
|
||||
github.com/hashicorp/nomad/api v0.0.0-20231213195942-64e3dca9274b // No tag on the repo.
|
||||
@ -40,7 +39,7 @@ require (
|
||||
github.com/huandu/xstrings v1.5.0
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.7.0
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab // No tag on the repo.
|
||||
github.com/klauspost/compress v1.18.0
|
||||
github.com/klauspost/compress v1.18.2
|
||||
github.com/kvtools/consul v1.0.2
|
||||
github.com/kvtools/etcdv3 v1.0.3
|
||||
github.com/kvtools/redis v1.2.0
|
||||
@ -66,8 +65,8 @@ require (
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807 // No tag on the repo.
|
||||
github.com/tailscale/tscert v0.0.0-20230806124524-28a91b69a046 // No tag on the repo.
|
||||
github.com/testcontainers/testcontainers-go v0.32.0
|
||||
github.com/testcontainers/testcontainers-go/modules/k3s v0.32.0
|
||||
github.com/testcontainers/testcontainers-go v0.40.0
|
||||
github.com/testcontainers/testcontainers-go/modules/k3s v0.40.0
|
||||
github.com/tetratelabs/wazero v1.8.0
|
||||
github.com/tidwall/gjson v1.17.0
|
||||
github.com/traefik/grpc-web v0.16.0
|
||||
@ -77,36 +76,36 @@ require (
|
||||
github.com/tufanbarisyildirim/gonginx v0.0.0-20250620092546-c3e307e36701 // latest tag is too old.
|
||||
github.com/unrolled/render v1.0.2
|
||||
github.com/unrolled/secure v1.0.9
|
||||
github.com/valyala/fasthttp v1.58.0
|
||||
github.com/valyala/fasthttp v1.69.0
|
||||
github.com/vulcand/oxy/v2 v2.0.3
|
||||
github.com/vulcand/predicate v1.3.0
|
||||
github.com/yuin/gopher-lua v1.1.1
|
||||
go.opentelemetry.io/collector/pdata v1.41.0
|
||||
go.opentelemetry.io/contrib/bridges/otellogrus v0.13.0
|
||||
go.opentelemetry.io/contrib/propagators/autoprop v0.63.0
|
||||
go.opentelemetry.io/otel v1.39.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0
|
||||
go.opentelemetry.io/otel/log v0.14.0
|
||||
go.opentelemetry.io/otel/metric v1.39.0
|
||||
go.opentelemetry.io/otel/sdk v1.39.0
|
||||
go.opentelemetry.io/otel/sdk/log v0.14.0
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0
|
||||
go.opentelemetry.io/otel/trace v1.39.0
|
||||
go.opentelemetry.io/otel v1.41.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.17.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.17.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.41.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.41.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0
|
||||
go.opentelemetry.io/otel/log v0.17.0
|
||||
go.opentelemetry.io/otel/metric v1.41.0
|
||||
go.opentelemetry.io/otel/sdk v1.41.0
|
||||
go.opentelemetry.io/otel/sdk/log v0.17.0
|
||||
go.opentelemetry.io/otel/sdk/metric v1.41.0
|
||||
go.opentelemetry.io/otel/trace v1.41.0
|
||||
golang.org/x/crypto v0.48.0
|
||||
golang.org/x/mod v0.32.0
|
||||
golang.org/x/net v0.50.0
|
||||
golang.org/x/net v0.51.0
|
||||
golang.org/x/sync v0.19.0
|
||||
golang.org/x/sys v0.41.0
|
||||
golang.org/x/text v0.34.0
|
||||
golang.org/x/time v0.14.0
|
||||
golang.org/x/tools v0.41.0
|
||||
google.golang.org/grpc v1.78.0
|
||||
google.golang.org/grpc v1.79.1
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/api v0.34.3
|
||||
@ -127,7 +126,7 @@ require (
|
||||
cloud.google.com/go/auth v0.18.1 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
dario.cat/mergo v1.0.2 // indirect
|
||||
github.com/AdamSLevy/jsonrpc2/v14 v14.1.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 // indirect
|
||||
@ -151,7 +150,6 @@ require (
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.3.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.13.0 // indirect
|
||||
github.com/VividCortex/gohistogram v1.0.0 // indirect
|
||||
github.com/akamai/AkamaiOPEN-edgegrid-golang/v11 v11.1.0 // indirect
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
|
||||
@ -179,17 +177,16 @@ require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blendle/zapdriver v1.3.1 // indirect
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||
github.com/bytedance/sonic v1.10.0 // indirect
|
||||
github.com/bytedance/sonic v1.12.0 // indirect
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||
github.com/containerd/containerd v1.7.29 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/platforms v1.0.0-rc.1 // indirect
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/cpuguy83/dockercfg v0.3.1 // indirect
|
||||
github.com/cpuguy83/dockercfg v0.3.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/deepmap/oapi-codegen v1.9.1 // indirect
|
||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
|
||||
@ -198,6 +195,7 @@ require (
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/dnsimple/dnsimple-go/v4 v4.0.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/ebitengine/purego v0.8.4 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
|
||||
github.com/exoscale/egoscale/v3 v3.1.33 // indirect
|
||||
@ -239,6 +237,7 @@ require (
|
||||
github.com/google/gnostic-models v0.7.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/go-querystring v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect
|
||||
@ -246,12 +245,14 @@ require (
|
||||
github.com/gophercloud/gophercloud v1.14.1 // indirect
|
||||
github.com/gophercloud/utils v0.0.0-20231010081019-80377eca5d56 // indirect
|
||||
github.com/gravitational/trace v1.5.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect
|
||||
github.com/hashicorp/cronexpr v1.1.2 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||
github.com/hashicorp/go-sockaddr v1.0.7 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
|
||||
@ -274,7 +275,7 @@ require (
|
||||
github.com/liquidweb/liquidweb-cli v0.6.9 // indirect
|
||||
github.com/liquidweb/liquidweb-go v1.6.4 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/magiconair/properties v1.8.10 // indirect
|
||||
github.com/mailgun/minheap v0.0.0-20170619185613-3dbe6c6bf55f // indirect
|
||||
github.com/mailgun/multibuf v0.1.2 // indirect
|
||||
github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51 // indirect
|
||||
@ -289,7 +290,6 @@ require (
|
||||
github.com/moby/go-archive v0.1.0 // indirect
|
||||
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||
github.com/moby/spdystream v0.5.0 // indirect
|
||||
github.com/moby/sys/atomicwriter v0.1.0 // indirect
|
||||
github.com/moby/sys/sequential v0.6.0 // indirect
|
||||
github.com/moby/sys/user v0.4.0 // indirect
|
||||
github.com/moby/sys/userns v0.1.0 // indirect
|
||||
@ -341,8 +341,7 @@ require (
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36 // indirect
|
||||
github.com/selectel/domains-go v1.1.0 // indirect
|
||||
github.com/selectel/go-selvpcclient/v4 v4.1.0 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.24.4 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.25.6 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/softlayer/softlayer-go v1.2.1 // indirect
|
||||
github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect
|
||||
@ -384,7 +383,7 @@ require (
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.38.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/ot v1.38.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/ratelimit v0.3.1 // indirect
|
||||
@ -397,8 +396,8 @@ require (
|
||||
golang.org/x/term v0.40.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/api v0.267.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
|
||||
179
go.sum
179
go.sum
@ -41,8 +41,8 @@ contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d h
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d/go.mod h1:IshRmMJBhDfFj5Y67nVhMYTTIze91RUeT73ipWKs/GY=
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg=
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.2/go.mod h1:dvEHbiKmgvbr5pjaF9fpw1KeYcjrnC1J8B+JKjsZyRQ=
|
||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
|
||||
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
@ -116,8 +116,6 @@ github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBa
|
||||
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/Microsoft/hcsshim v0.13.0 h1:/BcXOiS6Qi7N9XqUcv27vkIuVOkBEcWstd2pMlWSeaA=
|
||||
github.com/Microsoft/hcsshim v0.13.0/go.mod h1:9KWJ/8DgU+QzYGupX4tzMhRQE8h6w90lH6HAaclpEok=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/sarama v1.30.1/go.mod h1:hGgx05L/DiW8XYBXeJdKIN6V2QUy2H6JqME5VT1NLRw=
|
||||
@ -182,8 +180,8 @@ github.com/aliyun/credentials-go v1.3.6/go.mod h1:1LxUuX7L5YrZUWzBrRyk0SwSdH4OmP
|
||||
github.com/aliyun/credentials-go v1.4.5/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
|
||||
github.com/aliyun/credentials-go v1.4.7 h1:T17dLqEtPUFvjDRRb5giVvLh6dFT8IcNFJJb7MeyCxw=
|
||||
github.com/aliyun/credentials-go v1.4.7/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
|
||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
|
||||
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
@ -261,10 +259,10 @@ github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
|
||||
github.com/bytedance/sonic v1.10.0 h1:qtNZduETEIWJVIyDl01BeNxur2rW9OwTQ/yBqFRkKEk=
|
||||
github.com/bytedance/sonic v1.10.0/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
|
||||
github.com/bytedance/sonic v1.12.0 h1:YGPgxF9xzaCNvd/ZKdQ28yRovhfMFZQjuk6fKBzZ3ls=
|
||||
github.com/bytedance/sonic v1.12.0/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||
github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM=
|
||||
github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw=
|
||||
github.com/casbin/casbin/v2 v2.37.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
|
||||
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
@ -281,12 +279,6 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
|
||||
github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo=
|
||||
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
@ -296,11 +288,13 @@ github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5P
|
||||
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
|
||||
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/containerd/containerd v1.7.29 h1:90fWABQsaN9mJhGkoVnuzEY+o1XDPbg9BTC9QTAHnuE=
|
||||
github.com/containerd/containerd v1.7.29/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs=
|
||||
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
||||
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
|
||||
@ -327,8 +321,8 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
|
||||
github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
|
||||
github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
|
||||
github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
@ -356,12 +350,12 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/dnsimple/dnsimple-go/v4 v4.0.0 h1:nUCICZSyZDiiqimAAL+E8XL+0sKGks5VRki5S8XotRo=
|
||||
github.com/dnsimple/dnsimple-go/v4 v4.0.0/go.mod h1:AXT2yfAFOntJx6iMeo1J/zKBw0ggXFYBt4e97dqqPnc=
|
||||
github.com/docker/cli v28.3.3+incompatible h1:fp9ZHAr1WWPGdIWBM1b3zLtgCF+83gRdVMTJsUeiyAo=
|
||||
github.com/docker/cli v28.3.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI=
|
||||
github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/cli v29.2.1+incompatible h1:n3Jt0QVCN65eiVBoUTZQM9mcQICCJt3akW4pKAbKdJg=
|
||||
github.com/docker/cli v29.2.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM=
|
||||
github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
|
||||
github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
@ -369,6 +363,8 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m
|
||||
github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
|
||||
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
|
||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
||||
@ -595,7 +591,6 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
@ -617,8 +612,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
|
||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
||||
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
||||
@ -653,8 +648,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmg
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
|
||||
github.com/hashicorp/consul/api v1.26.1 h1:5oSXOO5fboPZeW5SN+TdGFP/BILDgBm19OrPZ/pICIM=
|
||||
@ -693,8 +688,8 @@ github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
|
||||
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
|
||||
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
|
||||
github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw=
|
||||
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
@ -794,12 +789,10 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
|
||||
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
|
||||
github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00=
|
||||
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
@ -854,13 +847,12 @@ github.com/liquidweb/liquidweb-cli v0.6.9 h1:acbIvdRauiwbxIsOCEMXGwF75aSJDbDiyAW
|
||||
github.com/liquidweb/liquidweb-cli v0.6.9/go.mod h1:cE1uvQ+x24NGUL75D0QagOFCG8Wdvmwu8aL9TLmA/eQ=
|
||||
github.com/liquidweb/liquidweb-go v1.6.4 h1:6S0m3hHSpiLqGD7AFSb7lH/W/qr1wx+tKil9fgIbjMc=
|
||||
github.com/liquidweb/liquidweb-go v1.6.4/go.mod h1:B934JPIIcdA+uTq2Nz5PgOtG6CuCaEvQKe/Ge/5GgZ4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 h1:PpXWgLPs+Fqr325bN2FD2ISlRRztXibcX6e8f5FR5Dc=
|
||||
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
|
||||
github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mailgun/multibuf v0.1.2 h1:QE9kE27lK6LFZB4aYNVtUPlWVHVCT0zpgUr2uoq/+jk=
|
||||
github.com/mailgun/multibuf v0.1.2/go.mod h1:E+sUhIy69qgT6EM57kCPdUTlHnjTuxQBO/yf6af9Hes=
|
||||
github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51 h1:Kg/NPZLLC3aAFr1YToMs98dbCdhootQ1hZIvZU28hAQ=
|
||||
@ -1079,7 +1071,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/pquerna/otp v1.5.0 h1:NMMR+WrmaqXU4EzdGJEE1aUUI0AMRzsp96fFFWNPwxs=
|
||||
@ -1170,11 +1161,8 @@ github.com/selectel/domains-go v1.1.0 h1:futG50J43ALLKQAnZk9H9yOtLGnSUh7c5hSvuC5
|
||||
github.com/selectel/domains-go v1.1.0/go.mod h1:SugRKfq4sTpnOHquslCpzda72wV8u0cMBHx0C0l+bzA=
|
||||
github.com/selectel/go-selvpcclient/v4 v4.1.0 h1:22lBp+rzg9g2MP4iiGhpVAcCt0kMv7I7uV1W3taLSvQ=
|
||||
github.com/selectel/go-selvpcclient/v4 v4.1.0/go.mod h1:eFhL1KUW159KOJVeGO7k/Uxl0TYd/sBkWXjuF5WxmYk=
|
||||
github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU=
|
||||
github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/shirou/gopsutil/v4 v4.25.6 h1:kLysI2JsKorfaFPcYmcJqbzROzsBWEOAtw6A7dIfqXs=
|
||||
github.com/shirou/gopsutil/v4 v4.25.6/go.mod h1:PfybzyydfZcN+JMMjkF6Zb8Mq1A/VcogFFg7hj50W9c=
|
||||
github.com/shoenig/test v1.7.0 h1:eWcHtTXa6QLnBvm0jgEabMRN/uJ4DMV3M8xUGgRkZmk=
|
||||
github.com/shoenig/test v1.7.0/go.mod h1:UxJ6u/x2v/TNs/LoLxBNJRV9DiwBBKYxXSyczsBHFoI=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
@ -1249,7 +1237,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807 h1:LUsDduamlucuNnWcaTbXQ6aLILFcLXADpOzeEH3U+OI=
|
||||
@ -1263,10 +1250,10 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.24/go.mod h
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.38/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.48 h1:bCs+z6dxRaHWm/C1D/XkSOcCZ0+W2+/6HmIXjpAj+fY=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.48/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
|
||||
github.com/testcontainers/testcontainers-go v0.32.0 h1:ug1aK08L3gCHdhknlTTwWjPHPS+/alvLJU/DRxTD/ME=
|
||||
github.com/testcontainers/testcontainers-go v0.32.0/go.mod h1:CRHrzHLQhlXUsa5gXjTOfqIEJcrK5+xMDmBr/WMI88E=
|
||||
github.com/testcontainers/testcontainers-go/modules/k3s v0.32.0 h1:Z3DTMveNUqeGJZ+CXZhpvI7OF1BS71Ywi3SwoXLZ4Lc=
|
||||
github.com/testcontainers/testcontainers-go/modules/k3s v0.32.0/go.mod h1:SYp1WtvNc3n/cg5atO6LvaOd2aqkQYMSDCcWPOUdaZg=
|
||||
github.com/testcontainers/testcontainers-go v0.40.0 h1:pSdJYLOVgLE8YdUY2FHQ1Fxu+aMnb6JfVz1mxk7OeMU=
|
||||
github.com/testcontainers/testcontainers-go v0.40.0/go.mod h1:FSXV5KQtX2HAMlm7U3APNyLkkap35zNLxukw9oBi/MY=
|
||||
github.com/testcontainers/testcontainers-go/modules/k3s v0.40.0 h1:3w6SjtIp/+FdpjWJCyPqaGWknG2iU6MacEWA7hl0IqQ=
|
||||
github.com/testcontainers/testcontainers-go/modules/k3s v0.40.0/go.mod h1:1xJwmfO2g+XKox9LiJXKGCm1vWp7LozX+78UjXVRbF0=
|
||||
github.com/tetratelabs/wazero v1.8.0 h1:iEKu0d4c2Pd+QSRieYbnQC9yiFlMS9D+Jr0LsRmcF4g=
|
||||
github.com/tetratelabs/wazero v1.8.0/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
|
||||
github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM=
|
||||
@ -1283,10 +1270,8 @@ github.com/timtadh/lexmachine v0.2.2/go.mod h1:GBJvD5OAfRn/gnp92zb9KTgHLB7akKyxm
|
||||
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
|
||||
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
|
||||
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
|
||||
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
|
||||
github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
@ -1323,8 +1308,8 @@ github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
|
||||
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.58.0 h1:GGB2dWxSbEprU9j0iMJHgdKYJVDyjrOwF9RE59PbRuE=
|
||||
github.com/valyala/fasthttp v1.58.0/go.mod h1:SYXvHHaFp7QZHGKSHmoMipInhrI5StHrhDTYVEjK/Kw=
|
||||
github.com/valyala/fasthttp v1.69.0 h1:fNLLESD2SooWeh2cidsuFtOcrEi4uB4m1mPrkJMZyVI=
|
||||
github.com/valyala/fasthttp v1.69.0/go.mod h1:4wA4PfAraPlAsJ5jMSqCE2ug5tqUPwKXxVj8oNECGcw=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/vinyldns/go-vinyldns v0.9.17 h1:hfPZfCaxcRBX6Gsgl42rLCeoal58/BH8kkvJShzjjdI=
|
||||
@ -1408,41 +1393,41 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 h1:nXGeLvT1QtCAhkASkP/ksj
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.38.0/go.mod h1:oMvOXk78ZR3KEuPMBgp/ThAMDy9ku/eyUVztr+3G6Wo=
|
||||
go.opentelemetry.io/contrib/propagators/ot v1.38.0 h1:k4gSyyohaDXI8F9BDXYC3uO2vr5sRNeQFMsN9Zn0EoI=
|
||||
go.opentelemetry.io/contrib/propagators/ot v1.38.0/go.mod h1:2hDsuiHRO39SRUMhYGqmj64z/IuMRoxE4bBSFR82Lo8=
|
||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 h1:OMqPldHt79PqWKOMYIAQs3CxAi7RLgPxwfFSwr4ZxtM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0/go.mod h1:1biG4qiqTxKiUCtoWDPpL3fB3KxVwCiGw81j3nKMuHE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 h1:QQqYw3lkrzwVsoEX0w//EhH/TCnpRdEenKBOOEIMjWc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0/go.mod h1:gSVQcr17jk2ig4jqJ2DX30IdWH251JcNAecvrqTxH1s=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4=
|
||||
go.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM=
|
||||
go.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno=
|
||||
go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c=
|
||||
go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.17.0 h1:6SRrIZrFLFVkktXaO0OUTweDdxNveqxczTsk3XUVQX8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.17.0/go.mod h1:Nx2rIwEusIh/KFV8UrjjB87BfVn+daJ/lWCA0CkxAtY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.17.0 h1:GcSx2UgcMuQEu0vHq823xR5LCN3WqEx5yKhqDkv1pwY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.17.0/go.mod h1:ctNT8t8Vzx9sb1oWAozighT3guWorr8xdCboBvkT5yg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.41.0 h1:VO3BL6OZXRQ1yQc8W6EVfJzINeJ35BkiHx4MYfoQf44=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.41.0/go.mod h1:qRDnJ2nv3CQXMK2HUd9K9VtvedsPAce3S+/4LZHjX/s=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.41.0 h1:MMrOAN8H1FrvDyq9UJ4lu5/+ss49Qgfgb7Zpm0m8ABo=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.41.0/go.mod h1:Na+2NNASJtF+uT4NxDe0G+NQb+bUgdPDfwxY/6JmS/c=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 h1:ao6Oe+wSebTlQ1OEht7jlYTzQKE+pnx/iNywFvTbuuI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0/go.mod h1:u3T6vz0gh/NVzgDgiwkgLxpsSF6PaPmo2il0apGJbls=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 h1:mq/Qcf28TWz719lE3/hMB4KkyDuLJIvgJnFGcd0kEUI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0/go.mod h1:yk5LXEYhsL2htyDNJbEq7fWzNEigeEdV5xBF/Y+kAv0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 h1:inYW9ZhgqiDqh6BioM7DVHHzEGVq76Db5897WLGZ5Go=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0/go.mod h1:Izur+Wt8gClgMJqO/cZ8wdeeMryJ/xxiOVgFSSfpDTY=
|
||||
go.opentelemetry.io/otel/log v0.17.0 h1:blZWM4y7n+KSa9OywwGWyBMPpeVoCl/NCw+jMps8afM=
|
||||
go.opentelemetry.io/otel/log v0.17.0/go.mod h1:VXhjKYep6/laSgf/tjdh2SMAt18Z9XotBFBO0jxSE24=
|
||||
go.opentelemetry.io/otel/log/logtest v0.14.0 h1:BGTqNeluJDK2uIHAY8lRqxjVAYfqgcaTbVk1n3MWe5A=
|
||||
go.opentelemetry.io/otel/log/logtest v0.14.0/go.mod h1:IuguGt8XVP4XA4d2oEEDMVDBBCesMg8/tSGWDjuKfoA=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||
go.opentelemetry.io/otel/sdk/log v0.14.0 h1:JU/U3O7N6fsAXj0+CXz21Czg532dW2V4gG1HE/e8Zrg=
|
||||
go.opentelemetry.io/otel/sdk/log v0.14.0/go.mod h1:imQvII+0ZylXfKU7/wtOND8Hn4OpT3YUoIgqJVksUkM=
|
||||
go.opentelemetry.io/otel/sdk/log/logtest v0.14.0 h1:Ijbtz+JKXl8T2MngiwqBlPaHqc4YCaP/i13Qrow6gAM=
|
||||
go.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||
go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ=
|
||||
go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps=
|
||||
go.opentelemetry.io/otel/sdk v1.41.0 h1:YPIEXKmiAwkGl3Gu1huk1aYWwtpRLeskpV+wPisxBp8=
|
||||
go.opentelemetry.io/otel/sdk v1.41.0/go.mod h1:ahFdU0G5y8IxglBf0QBJXgSe7agzjE4GiTJ6HT9ud90=
|
||||
go.opentelemetry.io/otel/sdk/log v0.17.0 h1:stWOgJB8bWieSlX4VO+gD7BrRZ/Dh1H/u7115amleGE=
|
||||
go.opentelemetry.io/otel/sdk/log v0.17.0/go.mod h1:LQKPUyHraLka2sRvNQ5+W456+sElomqR7VWpOnOefZg=
|
||||
go.opentelemetry.io/otel/sdk/log/logtest v0.17.0 h1:Z4S9W5piCH88itCkWDtX5ppRgO0UTkLXVK/6tPOMM2w=
|
||||
go.opentelemetry.io/otel/sdk/log/logtest v0.17.0/go.mod h1:d9iIX/BwLfu1BTPxO0wi4ucyCenCckfuf9LC0aJDjqM=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.41.0 h1:siZQIYBAUd1rlIWQT2uCxWJxcCO7q3TriaMlf08rXw8=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.41.0/go.mod h1:HNBuSvT7ROaGtGI50ArdRLUnvRTRGniSUZbxiWxSO8Y=
|
||||
go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0=
|
||||
go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
|
||||
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
|
||||
go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=
|
||||
go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4=
|
||||
go.opentelemetry.io/proto/slim/otlp v1.7.1 h1:lZ11gEokjIWYM3JWOUrIILr2wcf6RX+rq5SPObV9oyc=
|
||||
go.opentelemetry.io/proto/slim/otlp v1.7.1/go.mod h1:uZ6LJWa49eNM/EXnnvJGTTu8miokU8RQdnO980LJ57g=
|
||||
go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.0.1 h1:Tr/eXq6N7ZFjN+THBF/BtGLUz8dciA7cuzGRsCEkZ88=
|
||||
@ -1475,7 +1460,6 @@ go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc=
|
||||
golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
@ -1626,8 +1610,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
|
||||
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
|
||||
golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
|
||||
golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@ -1741,14 +1725,12 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
@ -1932,10 +1914,10 @@ google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxH
|
||||
google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM=
|
||||
google.golang.org/genproto v0.0.0-20260128011058-8636f8732409/go.mod h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20 h1:Jr5R2J6F6qWyzINc+4AM8t5pfUz6beZpHp678GNrMbE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
@ -1953,8 +1935,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
|
||||
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
|
||||
google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY=
|
||||
google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@ -2045,7 +2027,6 @@ mvdan.cc/xurls/v2 v2.5.0 h1:lyBNOm8Wo71UknhUs4QTFUNNMyxy2JEIaKKo0RWOh+8=
|
||||
mvdan.cc/xurls/v2 v2.5.0/go.mod h1:yQgaGQ1rFtJUzkmKiHYSSfuQxqfYmd//X6PxvholpeE=
|
||||
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
|
||||
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
|
||||
38
integration/fixtures/simple_acme_bypass_redirect.toml
Normal file
38
integration/fixtures/simple_acme_bypass_redirect.toml
Normal file
@ -0,0 +1,38 @@
|
||||
[global]
|
||||
checkNewVersion = false
|
||||
sendAnonymousUsage = false
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
noColor = true
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8888"
|
||||
allowACMEByPass = true
|
||||
[entryPoints.web.http.redirections.entryPoint]
|
||||
to = ":8443"
|
||||
scheme = "https"
|
||||
|
||||
[entryPoints.websecure]
|
||||
address = ":8443"
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
[providers.file]
|
||||
filename = "{{ .SelfFilename }}"
|
||||
|
||||
## dynamic configuration ##
|
||||
|
||||
[http.routers]
|
||||
[http.routers.acme-challenge]
|
||||
entryPoints = ["web"]
|
||||
rule = "PathPrefix(`/.well-known/acme-challenge/`)"
|
||||
service = "acme-solver"
|
||||
|
||||
[http.services]
|
||||
[http.services.acme-solver]
|
||||
[http.services.acme-solver.loadBalancer]
|
||||
[[http.services.acme-solver.loadBalancer.servers]]
|
||||
url = "{{ .AcmeSolverURL }}"
|
||||
@ -232,15 +232,17 @@ func (s *BaseSuite) createComposeProject(name string) {
|
||||
|
||||
func (s *BaseSuite) createContainer(ctx context.Context, containerConfig composeService, id string, mounts []mount.Mount) (testcontainers.Container, error) {
|
||||
req := testcontainers.ContainerRequest{
|
||||
Image: containerConfig.Image,
|
||||
Env: containerConfig.Environment,
|
||||
Cmd: containerConfig.Command,
|
||||
Labels: containerConfig.Labels,
|
||||
Name: id,
|
||||
Hostname: containerConfig.Hostname,
|
||||
Privileged: containerConfig.Privileged,
|
||||
Networks: []string{s.network.Name},
|
||||
Image: containerConfig.Image,
|
||||
Env: containerConfig.Environment,
|
||||
Cmd: containerConfig.Command,
|
||||
Labels: containerConfig.Labels,
|
||||
Name: id,
|
||||
Networks: []string{s.network.Name},
|
||||
ConfigModifier: func(config *container.Config) {
|
||||
config.Hostname = containerConfig.Hostname
|
||||
},
|
||||
HostConfigModifier: func(config *container.HostConfig) {
|
||||
config.Privileged = containerConfig.Privileged
|
||||
if containerConfig.CapAdd != nil {
|
||||
config.CapAdd = containerConfig.CapAdd
|
||||
}
|
||||
|
||||
@ -7,12 +7,10 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -20,6 +18,8 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/modules/k3s"
|
||||
"github.com/traefik/traefik/v3/integration/try"
|
||||
"github.com/traefik/traefik/v3/pkg/api"
|
||||
)
|
||||
@ -27,7 +27,11 @@ import (
|
||||
var updateExpected = flag.Bool("update_expected", false, "Update expected files in testdata")
|
||||
|
||||
// K8sSuite tests suite.
|
||||
type K8sSuite struct{ BaseSuite }
|
||||
type K8sSuite struct {
|
||||
BaseSuite
|
||||
|
||||
k3sContainer *k3s.K3sContainer
|
||||
}
|
||||
|
||||
func TestK8sSuite(t *testing.T) {
|
||||
suite.Run(t, new(K8sSuite))
|
||||
@ -36,47 +40,45 @@ func TestK8sSuite(t *testing.T) {
|
||||
func (s *K8sSuite) SetupSuite() {
|
||||
s.BaseSuite.SetupSuite()
|
||||
|
||||
s.createComposeProject("k8s")
|
||||
s.composeUp()
|
||||
|
||||
abs, err := filepath.Abs("./fixtures/k8s/config.skip/kubeconfig.yaml")
|
||||
manifests, err := filepath.Glob("./fixtures/k8s/*.yml")
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
err = try.Do(60*time.Second, func() error {
|
||||
_, err := os.Stat(abs)
|
||||
return err
|
||||
})
|
||||
opts := make([]testcontainers.ContainerCustomizer, 0, len(manifests))
|
||||
for _, m := range manifests {
|
||||
opts = append(opts, k3s.WithManifest(m))
|
||||
}
|
||||
|
||||
s.k3sContainer, err = k3s.Run(s.T().Context(), k3sImage, opts...)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
data, err := os.ReadFile(abs)
|
||||
kubeConfigYaml, err := s.k3sContainer.GetKubeConfig(s.T().Context())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
content := strings.ReplaceAll(string(data), "https://server:6443", fmt.Sprintf("https://%s", net.JoinHostPort(s.getComposeServiceIP("server"), "6443")))
|
||||
|
||||
err = os.WriteFile(abs, []byte(content), 0o644)
|
||||
kubeconfigPath := filepath.Join(s.T().TempDir(), "kubeconfig.yaml")
|
||||
err = os.WriteFile(kubeconfigPath, kubeConfigYaml, 0o644)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
err = os.Setenv("KUBECONFIG", abs)
|
||||
err = os.Setenv("KUBECONFIG", kubeconfigPath)
|
||||
require.NoError(s.T(), err)
|
||||
}
|
||||
|
||||
func (s *K8sSuite) TearDownSuite() {
|
||||
s.BaseSuite.TearDownSuite()
|
||||
if s.k3sContainer != nil {
|
||||
if s.T().Failed() || *showLog {
|
||||
k3sLogs, err := s.k3sContainer.Logs(s.T().Context())
|
||||
if err == nil {
|
||||
if res, err := io.ReadAll(k3sLogs); err == nil {
|
||||
s.T().Log(string(res))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generatedFiles := []string{
|
||||
"./fixtures/k8s/config.skip/kubeconfig.yaml",
|
||||
"./fixtures/k8s/config.skip/k3s.log",
|
||||
"./fixtures/k8s/coredns.yaml",
|
||||
"./fixtures/k8s/rolebindings.yaml",
|
||||
"./fixtures/k8s/traefik.yaml",
|
||||
"./fixtures/k8s/ccm.yaml",
|
||||
}
|
||||
|
||||
for _, filename := range generatedFiles {
|
||||
if err := os.Remove(filename); err != nil {
|
||||
if err := s.k3sContainer.Terminate(s.T().Context()); err != nil {
|
||||
log.Warn().Err(err).Send()
|
||||
}
|
||||
}
|
||||
|
||||
s.BaseSuite.TearDownSuite()
|
||||
}
|
||||
|
||||
func (s *K8sSuite) TestIngressConfiguration() {
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
services:
|
||||
server:
|
||||
image: rancher/k3s:v1.34.2-k3s1
|
||||
privileged: true
|
||||
command:
|
||||
- server
|
||||
- --disable-agent
|
||||
- --disable=coredns
|
||||
- --disable=servicelb
|
||||
- --disable=traefik
|
||||
- --disable=local-storage
|
||||
- --disable=metrics-server
|
||||
- --log=/output/k3s.log
|
||||
- --bind-address=server
|
||||
- --tls-san=server
|
||||
- --tls-san=172.31.42.3
|
||||
- --tls-san=172.31.42.4
|
||||
environment:
|
||||
K3S_CLUSTER_SECRET: somethingtotallyrandom
|
||||
K3S_TOKEN: somethingtotallyrandom
|
||||
K3S_KUBECONFIG_OUTPUT: /output/kubeconfig.yaml
|
||||
K3S_KUBECONFIG_MODE: 666
|
||||
volumes:
|
||||
- ./fixtures/k8s/config.skip:/output
|
||||
- ./fixtures/k8s:/var/lib/rancher/k3s/server/manifests
|
||||
|
||||
node:
|
||||
image: rancher/k3s:v1.34.2-k3s1
|
||||
privileged: true
|
||||
environment:
|
||||
K3S_TOKEN: somethingtotallyrandom
|
||||
K3S_URL: https://server:6443
|
||||
K3S_CLUSTER_SECRET: somethingtotallyrandom
|
||||
@ -2419,6 +2419,43 @@ func waitForWritePartial(t *testing.T, conn net.Conn) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SimpleSuite) TestAllowACMEByPassRedirect() {
|
||||
// Start a local server that simulates an ACME challenge solver.
|
||||
acmeSolver := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
_, _ = rw.Write([]byte("acme-challenge-token"))
|
||||
}))
|
||||
defer acmeSolver.Close()
|
||||
|
||||
file := s.adaptFile("fixtures/simple_acme_bypass_redirect.toml", struct {
|
||||
AcmeSolverURL string
|
||||
}{
|
||||
AcmeSolverURL: acmeSolver.URL,
|
||||
})
|
||||
|
||||
s.traefikCmd(withConfigFile(file))
|
||||
|
||||
// Wait for Traefik to be ready with the user-defined ACME challenge router.
|
||||
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 5*time.Second, try.BodyContains("acme-challenge@file"))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
noRedirectClient := &http.Client{
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
|
||||
// ACME challenge path should NOT be redirected — it should reach the solver.
|
||||
resp, err := noRedirectClient.Get("http://127.0.0.1:8888/.well-known/acme-challenge/test-token")
|
||||
require.NoError(s.T(), err)
|
||||
assert.Equal(s.T(), http.StatusOK, resp.StatusCode)
|
||||
|
||||
// Normal path should be redirected to HTTPS.
|
||||
resp, err = noRedirectClient.Get("http://127.0.0.1:8888/other-path")
|
||||
require.NoError(s.T(), err)
|
||||
assert.Equal(s.T(), http.StatusMovedPermanently, resp.StatusCode)
|
||||
}
|
||||
|
||||
func (s *SimpleSuite) TestFailoverService() {
|
||||
s.createComposeProject("base")
|
||||
|
||||
|
||||
30
integration/testdata/rawdata-gateway.json
vendored
30
integration/testdata/rawdata-gateway.json
vendored
@ -5,7 +5,7 @@
|
||||
"traefik"
|
||||
],
|
||||
"service": "api@internal",
|
||||
"rule": "PathPrefix(`/api`)",
|
||||
"rule": "PathPrefix(\"/api\")",
|
||||
"ruleSyntax": "default",
|
||||
"priority": 9223372036854775806,
|
||||
"observability": {
|
||||
@ -28,7 +28,7 @@
|
||||
"dashboard_stripprefix@internal"
|
||||
],
|
||||
"service": "dashboard@internal",
|
||||
"rule": "PathPrefix(`/`)",
|
||||
"rule": "PathPrefix(\"/\")",
|
||||
"ruleSyntax": "default",
|
||||
"priority": 9223372036854775805,
|
||||
"observability": {
|
||||
@ -42,12 +42,12 @@
|
||||
"traefik"
|
||||
]
|
||||
},
|
||||
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06@kubernetesgateway": {
|
||||
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-af329269dd38031b03e3@kubernetesgateway": {
|
||||
"entryPoints": [
|
||||
"web"
|
||||
],
|
||||
"service": "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr",
|
||||
"rule": "Host(`foo.com`) \u0026\u0026 Path(`/bar`)",
|
||||
"service": "httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-af329269dd38031b03e3-wrr",
|
||||
"rule": "Host(\"foo.com\") \u0026\u0026 Path(\"/bar\")",
|
||||
"ruleSyntax": "default",
|
||||
"priority": 100008,
|
||||
"observability": {
|
||||
@ -61,12 +61,12 @@
|
||||
"web"
|
||||
]
|
||||
},
|
||||
"httproute-default-http-app-1-gw-default-my-https-gateway-ep-websecure-0-1c0cf64bde37d9d0df06@kubernetesgateway": {
|
||||
"httproute-default-http-app-1-gw-default-my-https-gateway-ep-websecure-0-af329269dd38031b03e3@kubernetesgateway": {
|
||||
"entryPoints": [
|
||||
"websecure"
|
||||
],
|
||||
"service": "httproute-default-http-app-1-gw-default-my-https-gateway-ep-websecure-0-1c0cf64bde37d9d0df06-wrr",
|
||||
"rule": "Host(`foo.com`) \u0026\u0026 Path(`/bar`)",
|
||||
"service": "httproute-default-http-app-1-gw-default-my-https-gateway-ep-websecure-0-af329269dd38031b03e3-wrr",
|
||||
"rule": "Host(\"foo.com\") \u0026\u0026 Path(\"/bar\")",
|
||||
"ruleSyntax": "default",
|
||||
"priority": 100008,
|
||||
"tls": {},
|
||||
@ -142,7 +142,7 @@
|
||||
"http://10.42.0.6:80": "UP"
|
||||
}
|
||||
},
|
||||
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06-wrr@kubernetesgateway": {
|
||||
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-af329269dd38031b03e3-wrr@kubernetesgateway": {
|
||||
"weighted": {
|
||||
"services": [
|
||||
{
|
||||
@ -153,10 +153,10 @@
|
||||
},
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-1c0cf64bde37d9d0df06@kubernetesgateway"
|
||||
"httproute-default-http-app-1-gw-default-my-gateway-ep-web-0-af329269dd38031b03e3@kubernetesgateway"
|
||||
]
|
||||
},
|
||||
"httproute-default-http-app-1-gw-default-my-https-gateway-ep-websecure-0-1c0cf64bde37d9d0df06-wrr@kubernetesgateway": {
|
||||
"httproute-default-http-app-1-gw-default-my-https-gateway-ep-websecure-0-af329269dd38031b03e3-wrr@kubernetesgateway": {
|
||||
"weighted": {
|
||||
"services": [
|
||||
{
|
||||
@ -167,7 +167,7 @@
|
||||
},
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"httproute-default-http-app-1-gw-default-my-https-gateway-ep-websecure-0-1c0cf64bde37d9d0df06@kubernetesgateway"
|
||||
"httproute-default-http-app-1-gw-default-my-https-gateway-ep-websecure-0-af329269dd38031b03e3@kubernetesgateway"
|
||||
]
|
||||
},
|
||||
"noop@internal": {
|
||||
@ -180,7 +180,7 @@
|
||||
"footcp"
|
||||
],
|
||||
"service": "tcproute-default-tcp-app-1-gw-default-my-tcp-gateway-ep-footcp-0-e3b0c44298fc1c149afb-wrr",
|
||||
"rule": "HostSNI(`*`)",
|
||||
"rule": "HostSNI(\"*\")",
|
||||
"ruleSyntax": "default",
|
||||
"priority": -1,
|
||||
"status": "enabled",
|
||||
@ -193,7 +193,7 @@
|
||||
"footlsterminate"
|
||||
],
|
||||
"service": "tcproute-default-tcp-app-1-gw-default-my-tls-gateway-ep-footlsterminate-0-e3b0c44298fc1c149afb-wrr",
|
||||
"rule": "HostSNI(`*`)",
|
||||
"rule": "HostSNI(\"*\")",
|
||||
"ruleSyntax": "default",
|
||||
"priority": -1,
|
||||
"tls": {
|
||||
@ -209,7 +209,7 @@
|
||||
"footlspassthrough"
|
||||
],
|
||||
"service": "tlsroute-default-tls-app-1-gw-default-my-tls-gateway-ep-footlspassthrough-0-e3b0c44298fc1c149afb-wrr",
|
||||
"rule": "HostSNI(`foo.bar`)",
|
||||
"rule": "HostSNI(\"foo.bar\")",
|
||||
"ruleSyntax": "default",
|
||||
"priority": 7,
|
||||
"tls": {
|
||||
|
||||
@ -2,11 +2,11 @@ package dashboard
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
@ -17,8 +17,9 @@ import (
|
||||
type routerRepresentation struct {
|
||||
*runtime.RouterInfo
|
||||
|
||||
Name string `json:"name,omitempty"`
|
||||
Provider string `json:"provider,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Provider string `json:"provider,omitempty"`
|
||||
PriorityStr string `json:"priorityStr,omitempty"`
|
||||
}
|
||||
|
||||
func newRouterRepresentation(name string, rt *runtime.RouterInfo) routerRepresentation {
|
||||
@ -27,9 +28,10 @@ func newRouterRepresentation(name string, rt *runtime.RouterInfo) routerRepresen
|
||||
}
|
||||
|
||||
return routerRepresentation{
|
||||
RouterInfo: rt,
|
||||
Name: name,
|
||||
Provider: getProviderName(name),
|
||||
RouterInfo: rt,
|
||||
Name: name,
|
||||
Provider: getProviderName(name),
|
||||
PriorityStr: strconv.FormatInt(int64(rt.Priority), 10),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,8 +16,9 @@ import (
|
||||
type tcpRouterRepresentation struct {
|
||||
*runtime.TCPRouterInfo
|
||||
|
||||
Name string `json:"name,omitempty"`
|
||||
Provider string `json:"provider,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Provider string `json:"provider,omitempty"`
|
||||
PriorityStr string `json:"priorityStr,omitempty"`
|
||||
}
|
||||
|
||||
func newTCPRouterRepresentation(name string, rt *runtime.TCPRouterInfo) tcpRouterRepresentation {
|
||||
@ -25,6 +26,7 @@ func newTCPRouterRepresentation(name string, rt *runtime.TCPRouterInfo) tcpRoute
|
||||
TCPRouterInfo: rt,
|
||||
Name: name,
|
||||
Provider: getProviderName(name),
|
||||
PriorityStr: strconv.FormatInt(int64(rt.Priority), 10),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1
pkg/api/testdata/router-bar.json
vendored
1
pkg/api/testdata/router-bar.json
vendored
@ -8,6 +8,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
],
|
||||
"name": "baz@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.baz`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"tls": {
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
],
|
||||
"name": "baz@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.baz`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"tls": {
|
||||
|
||||
1
pkg/api/testdata/router-foo-slash-bar.json
vendored
1
pkg/api/testdata/router-foo-slash-bar.json
vendored
@ -8,6 +8,7 @@
|
||||
],
|
||||
"name": "foo / bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "disabled",
|
||||
@ -26,6 +27,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`fii.bar.other`)",
|
||||
"service": "fii-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`fii.bar.other`)",
|
||||
"service": "fii-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "foo@otherprovider",
|
||||
"provider": "otherprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`fii.foo.other`)",
|
||||
"service": "fii-service",
|
||||
"status": "enabled",
|
||||
@ -22,6 +23,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`fii.bar.other`)",
|
||||
"service": "fii-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar.other`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
5
pkg/api/testdata/routers-many-lastpage.json
vendored
5
pkg/api/testdata/routers-many-lastpage.json
vendored
@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "bar14@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar14`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
@ -18,6 +19,7 @@
|
||||
],
|
||||
"name": "bar15@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar15`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
@ -31,6 +33,7 @@
|
||||
],
|
||||
"name": "bar16@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar16`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
@ -44,6 +47,7 @@
|
||||
],
|
||||
"name": "bar17@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar17`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
@ -57,6 +61,7 @@
|
||||
],
|
||||
"name": "bar18@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar18`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
1
pkg/api/testdata/routers-page2.json
vendored
1
pkg/api/testdata/routers-page2.json
vendored
@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "baz@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`toto.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
2
pkg/api/testdata/routers.json
vendored
2
pkg/api/testdata/routers.json
vendored
@ -9,6 +9,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
@ -26,6 +27,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar.other`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
1
pkg/api/testdata/tcprouter-bar.json
vendored
1
pkg/api/testdata/tcprouter-bar.json
vendored
@ -4,6 +4,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
],
|
||||
"name": "foo / bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service",
|
||||
"status": "warning",
|
||||
@ -26,6 +27,7 @@
|
||||
],
|
||||
"name": "foo@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "bar-service@myprovider",
|
||||
"status": "disabled",
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "warning",
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service",
|
||||
"status": "warning",
|
||||
@ -18,6 +19,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar.other`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar.other`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
1
pkg/api/testdata/tcprouters-page2.json
vendored
1
pkg/api/testdata/tcprouters-page2.json
vendored
@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "baz@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`toto.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
3
pkg/api/testdata/tcprouters.json
vendored
3
pkg/api/testdata/tcprouters.json
vendored
@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "warning",
|
||||
@ -18,6 +19,7 @@
|
||||
],
|
||||
"name": "foo@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "disabled",
|
||||
@ -31,6 +33,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar.other`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
func Test_GetStrategy_ipv6Subnet(t *testing.T) {
|
||||
@ -19,16 +20,16 @@ func Test_GetStrategy_ipv6Subnet(t *testing.T) {
|
||||
{
|
||||
desc: "Zero subnet",
|
||||
expectError: true,
|
||||
ipv6Subnet: intPtr(0),
|
||||
ipv6Subnet: ptr.To(0),
|
||||
},
|
||||
{
|
||||
desc: "Subnet greater that 128",
|
||||
expectError: true,
|
||||
ipv6Subnet: intPtr(129),
|
||||
ipv6Subnet: ptr.To(129),
|
||||
},
|
||||
{
|
||||
desc: "Valid subnet",
|
||||
ipv6Subnet: intPtr(128),
|
||||
ipv6Subnet: ptr.To(128),
|
||||
},
|
||||
}
|
||||
|
||||
@ -52,6 +53,58 @@ func Test_GetStrategy_ipv6Subnet(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func intPtr(value int) *int {
|
||||
return &value
|
||||
func TestHasSecureHeadersDefined(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
headers *Headers
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
desc: "Nil headers",
|
||||
headers: nil,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
desc: "Empty headers",
|
||||
headers: &Headers{},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
desc: "STSSeconds set to non-zero",
|
||||
headers: &Headers{
|
||||
STSSeconds: ptr.To(int64(42)),
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
desc: "STSSeconds set to zero",
|
||||
headers: &Headers{
|
||||
STSSeconds: ptr.To(int64(0)),
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
desc: "STSSeconds nil (not set)",
|
||||
headers: &Headers{
|
||||
FrameDeny: true,
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
desc: "Only ForceSTSHeader",
|
||||
headers: &Headers{
|
||||
ForceSTSHeader: true,
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
result := test.headers.HasSecureHeadersDefined()
|
||||
assert.Equal(t, test.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -373,7 +373,7 @@ type Headers struct {
|
||||
// STSSeconds defines the max-age of the Strict-Transport-Security header.
|
||||
// If set to 0, the header is not set.
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
STSSeconds int64 `json:"stsSeconds,omitempty" toml:"stsSeconds,omitempty" yaml:"stsSeconds,omitempty" export:"true"`
|
||||
STSSeconds *int64 `json:"stsSeconds,omitempty" toml:"stsSeconds,omitempty" yaml:"stsSeconds,omitempty" export:"true"`
|
||||
// STSIncludeSubdomains defines whether the includeSubDomains directive is appended to the Strict-Transport-Security header.
|
||||
STSIncludeSubdomains bool `json:"stsIncludeSubdomains,omitempty" toml:"stsIncludeSubdomains,omitempty" yaml:"stsIncludeSubdomains,omitempty" export:"true"`
|
||||
// STSPreload defines whether the preload flag is appended to the Strict-Transport-Security header.
|
||||
@ -449,7 +449,7 @@ func (h *Headers) HasSecureHeadersDefined() bool {
|
||||
(h.SSLForceHost != nil && *h.SSLForceHost) ||
|
||||
(h.SSLHost != nil && *h.SSLHost != "") ||
|
||||
len(h.SSLProxyHeaders) != 0 ||
|
||||
h.STSSeconds != 0 ||
|
||||
h.STSSeconds != nil ||
|
||||
h.STSIncludeSubdomains ||
|
||||
h.STSPreload ||
|
||||
h.ForceSTSHeader ||
|
||||
|
||||
@ -750,6 +750,11 @@ func (in *Headers) DeepCopyInto(out *Headers) {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.STSSeconds != nil {
|
||||
in, out := &in.STSSeconds, &out.STSSeconds
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
if in.FeaturePolicy != nil {
|
||||
in, out := &in.FeaturePolicy, &out.FeaturePolicy
|
||||
*out = new(string)
|
||||
|
||||
@ -650,7 +650,7 @@ func TestDecodeConfiguration(t *testing.T) {
|
||||
"name1": "foobar",
|
||||
},
|
||||
SSLForceHost: pointer(true),
|
||||
STSSeconds: 42,
|
||||
STSSeconds: pointer(int64(42)),
|
||||
STSIncludeSubdomains: true,
|
||||
STSPreload: true,
|
||||
ForceSTSHeader: true,
|
||||
@ -1210,7 +1210,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
||||
"name1": "foobar",
|
||||
},
|
||||
SSLForceHost: pointer(true),
|
||||
STSSeconds: 42,
|
||||
STSSeconds: pointer(int64(42)),
|
||||
STSIncludeSubdomains: true,
|
||||
STSPreload: true,
|
||||
ForceSTSHeader: true,
|
||||
|
||||
@ -3,7 +3,7 @@ package static
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -57,6 +57,9 @@ const (
|
||||
DefaultUDPTimeout = 3 * time.Second
|
||||
)
|
||||
|
||||
// Allowed characters in URL following RFC 3986 (https://www.rfc-editor.org/rfc/rfc3986#section-2)
|
||||
var validBasePath = regexp.MustCompile(`^/[a-zA-Z0-9/_.-]*$`)
|
||||
|
||||
// Configuration is the static configuration.
|
||||
type Configuration struct {
|
||||
Global *Global `description:"Global configuration options" json:"global,omitempty" toml:"global,omitempty" yaml:"global,omitempty" export:"true"`
|
||||
@ -467,8 +470,8 @@ func (c *Configuration) ValidateConfiguration() error {
|
||||
}
|
||||
}
|
||||
|
||||
if c.API != nil && !path.IsAbs(c.API.BasePath) {
|
||||
return errors.New("API basePath must be a valid absolute path")
|
||||
if c.API != nil && !validBasePath.MatchString(c.API.BasePath) {
|
||||
return errors.New("API basePath must be a valid absolute URL path")
|
||||
}
|
||||
|
||||
if c.OCSP != nil {
|
||||
|
||||
@ -282,3 +282,89 @@ func TestConfiguration_SetEffectiveConfiguration(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateConfiguration_BasePath(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
basePath string
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
desc: "valid simple path",
|
||||
basePath: "/api",
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
desc: "valid path with segments",
|
||||
basePath: "/my/base/path",
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
desc: "valid path with allowed special chars",
|
||||
basePath: "/valid/path-123",
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
desc: "relative path",
|
||||
basePath: "api/path",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
desc: "XSS payload",
|
||||
basePath: `/api/"></script><script>alert("XSS")</script>`,
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
desc: "path with spaces",
|
||||
basePath: "/path with spaces",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
desc: "path with angle brackets",
|
||||
basePath: "/path/<evil>",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
desc: "path with query string",
|
||||
basePath: "/api?foo=bar",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
desc: "path with fragment",
|
||||
basePath: "/api#section",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
desc: "valid root path",
|
||||
basePath: "/",
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
desc: "path with quote",
|
||||
basePath: "/api/'onclick=alert(1)",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
desc: "path with encoded character",
|
||||
basePath: "/api%2Ftoto",
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cfg := &Configuration{
|
||||
API: &API{BasePath: test.basePath},
|
||||
}
|
||||
|
||||
err := cfg.ValidateConfiguration()
|
||||
if test.expectErr {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,10 +213,18 @@ func (shc *ServiceHealthChecker) executeHealthCheck(ctx context.Context, config
|
||||
ctx, cancel := context.WithDeadline(ctx, time.Now().Add(shc.timeout))
|
||||
defer cancel()
|
||||
|
||||
if config.Mode == modeGRPC {
|
||||
return shc.checkHealthGRPC(ctx, target)
|
||||
switch config.Mode {
|
||||
case modeGRPC:
|
||||
if err := shc.checkHealthGRPC(ctx, target); err != nil {
|
||||
return fmt.Errorf("checking gRPC health: %w", err)
|
||||
}
|
||||
default:
|
||||
if err := shc.checkHealthHTTP(ctx, target); err != nil {
|
||||
return fmt.Errorf("checking HTTP health: %w", err)
|
||||
}
|
||||
}
|
||||
return shc.checkHealthHTTP(ctx, target)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkHealthHTTP returns an error with a meaningful description if the health check failed.
|
||||
@ -287,17 +295,12 @@ func (shc *ServiceHealthChecker) newRequest(ctx context.Context, target *url.URL
|
||||
// checkHealthGRPC returns an error with a meaningful description if the health check failed.
|
||||
// Dedicated to gRPC servers implementing gRPC Health Checking Protocol v1.
|
||||
func (shc *ServiceHealthChecker) checkHealthGRPC(ctx context.Context, serverURL *url.URL) error {
|
||||
u, err := serverURL.Parse(shc.config.Path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse server URL: %w", err)
|
||||
}
|
||||
|
||||
port := u.Port()
|
||||
port := serverURL.Port()
|
||||
if shc.config.Port != 0 {
|
||||
port = strconv.Itoa(shc.config.Port)
|
||||
}
|
||||
|
||||
serverAddr := net.JoinHostPort(u.Hostname(), port)
|
||||
serverAddr := net.JoinHostPort(serverURL.Hostname(), port)
|
||||
|
||||
var opts []grpc.DialOption
|
||||
switch shc.config.Scheme {
|
||||
|
||||
@ -515,7 +515,6 @@ func TestDifferentIntervals(t *testing.T) {
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Go(func() {
|
||||
hc.Launch(ctx)
|
||||
wg.Done()
|
||||
})
|
||||
|
||||
select {
|
||||
|
||||
@ -192,11 +192,9 @@ func TestBasicAuthConcurrentHashOnce(t *testing.T) {
|
||||
defer ts.Close()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
|
||||
for range 2 {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
wg.Go(func() {
|
||||
req := testhelpers.MustNewRequest(http.MethodGet, ts.URL, nil)
|
||||
req.SetBasicAuth("test", "test")
|
||||
|
||||
@ -205,7 +203,7 @@ func TestBasicAuthConcurrentHashOnce(t *testing.T) {
|
||||
defer res.Body.Close()
|
||||
|
||||
assert.Equal(t, http.StatusOK, res.StatusCode, "they should be equal")
|
||||
}()
|
||||
})
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
@ -374,25 +374,18 @@ func Test_FlushAfterWriteNil(t *testing.T) {
|
||||
desc string
|
||||
cfg Config
|
||||
algo string
|
||||
readerBuilder func(io.Reader) (io.Reader, error)
|
||||
acceptEncoding string
|
||||
}{
|
||||
{
|
||||
desc: "brotli",
|
||||
cfg: Config{MinSize: 1024, MiddlewareName: "Test"},
|
||||
algo: brotliName,
|
||||
readerBuilder: func(reader io.Reader) (io.Reader, error) {
|
||||
return brotli.NewReader(reader), nil
|
||||
},
|
||||
desc: "brotli",
|
||||
cfg: Config{MinSize: 1024, MiddlewareName: "Test"},
|
||||
algo: brotliName,
|
||||
acceptEncoding: "br",
|
||||
},
|
||||
{
|
||||
desc: "zstd",
|
||||
cfg: Config{MinSize: 1024, MiddlewareName: "Test"},
|
||||
algo: zstdName,
|
||||
readerBuilder: func(reader io.Reader) (io.Reader, error) {
|
||||
return zstd.NewReader(reader)
|
||||
},
|
||||
desc: "zstd",
|
||||
cfg: Config{MinSize: 1024, MiddlewareName: "Test"},
|
||||
algo: zstdName,
|
||||
acceptEncoding: "zstd",
|
||||
},
|
||||
}
|
||||
@ -423,13 +416,7 @@ func Test_FlushAfterWriteNil(t *testing.T) {
|
||||
|
||||
assert.Equal(t, http.StatusOK, res.StatusCode)
|
||||
assert.Empty(t, res.Header.Get(contentEncoding))
|
||||
|
||||
reader, err := test.readerBuilder(res.Body)
|
||||
require.NoError(t, err)
|
||||
|
||||
got, err := io.ReadAll(reader)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, got)
|
||||
assert.Equal(t, http.NoBody, res.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
func TestNew_withoutOptions(t *testing.T) {
|
||||
@ -24,6 +25,14 @@ func TestNew_withoutOptions(t *testing.T) {
|
||||
assert.Nil(t, mid)
|
||||
}
|
||||
|
||||
func TestNew_withSTSSecondsZero(t *testing.T) {
|
||||
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })
|
||||
|
||||
mid, err := New(t.Context(), next, dynamic.Headers{STSSeconds: ptr.To(int64(0))}, "testing")
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, mid)
|
||||
}
|
||||
|
||||
func TestNew_allowedHosts(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"github.com/unrolled/secure"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
type secureHeader struct {
|
||||
@ -33,7 +34,7 @@ func newSecure(next http.Handler, cfg dynamic.Headers, contextKey string) *secur
|
||||
AllowedHosts: cfg.AllowedHosts,
|
||||
HostsProxyHeaders: cfg.HostsProxyHeaders,
|
||||
SSLProxyHeaders: cfg.SSLProxyHeaders,
|
||||
STSSeconds: cfg.STSSeconds,
|
||||
STSSeconds: ptr.Deref(cfg.STSSeconds, 0),
|
||||
PermissionsPolicy: cfg.PermissionsPolicy,
|
||||
SecureContextKey: contextKey,
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
// Middleware tests based on https://github.com/unrolled/secure
|
||||
@ -27,7 +28,7 @@ func Test_newSecure_modifyResponse(t *testing.T) {
|
||||
{
|
||||
desc: "STSSeconds",
|
||||
cfg: dynamic.Headers{
|
||||
STSSeconds: 1,
|
||||
STSSeconds: ptr.To(int64(1)),
|
||||
ForceSTSHeader: true,
|
||||
},
|
||||
expected: http.Header{"Strict-Transport-Security": []string{"max-age=1"}},
|
||||
@ -35,7 +36,7 @@ func Test_newSecure_modifyResponse(t *testing.T) {
|
||||
{
|
||||
desc: "STSSeconds and STSPreload",
|
||||
cfg: dynamic.Headers{
|
||||
STSSeconds: 1,
|
||||
STSSeconds: ptr.To(int64(1)),
|
||||
ForceSTSHeader: true,
|
||||
STSPreload: true,
|
||||
},
|
||||
|
||||
@ -6,7 +6,6 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/rs/zerolog/log"
|
||||
"golang.org/x/mod/module"
|
||||
)
|
||||
@ -84,29 +83,30 @@ func SetupLocalPlugins(plugins map[string]LocalDescriptor) error {
|
||||
|
||||
uniq := make(map[string]struct{})
|
||||
|
||||
var errs *multierror.Error
|
||||
var errs []error
|
||||
for pAlias, descriptor := range plugins {
|
||||
if descriptor.ModuleName == "" {
|
||||
errs = multierror.Append(errs, fmt.Errorf("%s: plugin name is missing", pAlias))
|
||||
errs = append(errs, fmt.Errorf("%s: plugin name is missing", pAlias))
|
||||
}
|
||||
|
||||
if strings.HasPrefix(descriptor.ModuleName, "/") || strings.HasSuffix(descriptor.ModuleName, "/") {
|
||||
errs = multierror.Append(errs, fmt.Errorf("%s: plugin name should not start or end with a /", pAlias))
|
||||
errs = append(errs, fmt.Errorf("%s: plugin name should not start or end with a /", pAlias))
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := uniq[descriptor.ModuleName]; ok {
|
||||
errs = multierror.Append(errs, fmt.Errorf("only one version of a plugin is allowed, there is a duplicate of %s", descriptor.ModuleName))
|
||||
errs = append(errs, fmt.Errorf("only one version of a plugin is allowed, there is a duplicate of %s", descriptor.ModuleName))
|
||||
continue
|
||||
}
|
||||
|
||||
uniq[descriptor.ModuleName] = struct{}{}
|
||||
|
||||
err := checkLocalPluginManifest(descriptor)
|
||||
errs = multierror.Append(errs, err)
|
||||
if err := checkLocalPluginManifest(descriptor); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
return errs.ErrorOrNil()
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func checkLocalPluginManifest(descriptor LocalDescriptor) error {
|
||||
@ -115,44 +115,44 @@ func checkLocalPluginManifest(descriptor LocalDescriptor) error {
|
||||
return err
|
||||
}
|
||||
|
||||
var errs *multierror.Error
|
||||
var errs []error
|
||||
|
||||
switch m.Type {
|
||||
case typeMiddleware:
|
||||
if m.Runtime != runtimeYaegi && m.Runtime != runtimeWasm && m.Runtime != "" {
|
||||
errs = multierror.Append(errs, fmt.Errorf("%s: unsupported runtime '%q'", descriptor.ModuleName, m.Runtime))
|
||||
errs = append(errs, fmt.Errorf("%s: unsupported runtime '%q'", descriptor.ModuleName, m.Runtime))
|
||||
}
|
||||
|
||||
case typeProvider:
|
||||
if m.Runtime != runtimeYaegi && m.Runtime != "" {
|
||||
errs = multierror.Append(errs, fmt.Errorf("%s: unsupported runtime '%q'", descriptor.ModuleName, m.Runtime))
|
||||
errs = append(errs, fmt.Errorf("%s: unsupported runtime '%q'", descriptor.ModuleName, m.Runtime))
|
||||
}
|
||||
|
||||
default:
|
||||
errs = multierror.Append(errs, fmt.Errorf("%s: unsupported type %q", descriptor.ModuleName, m.Type))
|
||||
errs = append(errs, fmt.Errorf("%s: unsupported type %q", descriptor.ModuleName, m.Type))
|
||||
}
|
||||
|
||||
if m.IsYaegiPlugin() {
|
||||
if m.Import == "" {
|
||||
errs = multierror.Append(errs, fmt.Errorf("%s: missing import", descriptor.ModuleName))
|
||||
errs = append(errs, fmt.Errorf("%s: missing import", descriptor.ModuleName))
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(m.Import, descriptor.ModuleName) {
|
||||
errs = multierror.Append(errs, fmt.Errorf("the import %q must be related to the module name %q", m.Import, descriptor.ModuleName))
|
||||
errs = append(errs, fmt.Errorf("the import %q must be related to the module name %q", m.Import, descriptor.ModuleName))
|
||||
}
|
||||
}
|
||||
|
||||
if m.DisplayName == "" {
|
||||
errs = multierror.Append(errs, fmt.Errorf("%s: missing DisplayName", descriptor.ModuleName))
|
||||
errs = append(errs, fmt.Errorf("%s: missing DisplayName", descriptor.ModuleName))
|
||||
}
|
||||
|
||||
if m.Summary == "" {
|
||||
errs = multierror.Append(errs, fmt.Errorf("%s: missing Summary", descriptor.ModuleName))
|
||||
errs = append(errs, fmt.Errorf("%s: missing Summary", descriptor.ModuleName))
|
||||
}
|
||||
|
||||
if m.TestData == nil {
|
||||
errs = multierror.Append(errs, fmt.Errorf("%s: missing TestData", descriptor.ModuleName))
|
||||
errs = append(errs, fmt.Errorf("%s: missing TestData", descriptor.ModuleName))
|
||||
}
|
||||
|
||||
return errs.ErrorOrNil()
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
@ -14,10 +14,8 @@ func containerJSON(ops ...func(*containertypes.InspectResponse)) containertypes.
|
||||
HostConfig: &containertypes.HostConfig{},
|
||||
State: &containertypes.State{},
|
||||
},
|
||||
Config: &containertypes.Config{},
|
||||
NetworkSettings: &containertypes.NetworkSettings{
|
||||
NetworkSettingsBase: containertypes.NetworkSettingsBase{},
|
||||
},
|
||||
Config: &containertypes.Config{},
|
||||
NetworkSettings: &containertypes.NetworkSettings{},
|
||||
}
|
||||
|
||||
for _, op := range ops {
|
||||
@ -41,7 +39,7 @@ func networkMode(mode string) func(*containertypes.InspectResponse) {
|
||||
|
||||
func ports(portMap nat.PortMap) func(*containertypes.InspectResponse) {
|
||||
return func(c *containertypes.InspectResponse) {
|
||||
c.NetworkSettings.NetworkSettingsBase.Ports = portMap
|
||||
c.NetworkSettings.Ports = portMap
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -391,7 +391,7 @@ func buildGRPCMatchRule(hostnames []gatev1.Hostname, match gatev1.GRPCRouteMatch
|
||||
|
||||
func buildGRPCMethodRule(method *gatev1.GRPCMethodMatch) string {
|
||||
if method == nil {
|
||||
return "PathPrefix(`/`)"
|
||||
return `PathPrefix("/")`
|
||||
}
|
||||
|
||||
sExpr := "[^/]+"
|
||||
@ -404,7 +404,7 @@ func buildGRPCMethodRule(method *gatev1.GRPCMethodMatch) string {
|
||||
mExpr = m
|
||||
}
|
||||
|
||||
return fmt.Sprintf("PathRegexp(`/%s/%s`)", sExpr, mExpr)
|
||||
return fmt.Sprintf("PathRegexp(%q)", fmt.Sprintf("/%s/%s", sExpr, mExpr))
|
||||
}
|
||||
|
||||
func buildGRPCHeaderRules(headers []gatev1.GRPCHeaderMatch) []string {
|
||||
@ -412,9 +412,9 @@ func buildGRPCHeaderRules(headers []gatev1.GRPCHeaderMatch) []string {
|
||||
for _, header := range headers {
|
||||
switch ptr.Deref(header.Type, gatev1.GRPCHeaderMatchExact) {
|
||||
case gatev1.GRPCHeaderMatchExact:
|
||||
rules = append(rules, fmt.Sprintf("Header(`%s`,`%s`)", header.Name, header.Value))
|
||||
rules = append(rules, fmt.Sprintf("Header(%q,%q)", header.Name, header.Value))
|
||||
case gatev1.GRPCHeaderMatchRegularExpression:
|
||||
rules = append(rules, fmt.Sprintf("HeaderRegexp(`%s`,`%s`)", header.Name, header.Value))
|
||||
rules = append(rules, fmt.Sprintf("HeaderRegexp(%q,%q)", header.Name, header.Value))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -19,13 +19,13 @@ func Test_buildGRPCMatchRule(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
desc: "Empty rule and matches",
|
||||
expectedRule: "PathPrefix(`/`)",
|
||||
expectedRule: `PathPrefix("/")`,
|
||||
expectedPriority: 15,
|
||||
},
|
||||
{
|
||||
desc: "One Host rule without match",
|
||||
hostnames: []gatev1.Hostname{"foo.com"},
|
||||
expectedRule: "Host(`foo.com`) && PathPrefix(`/`)",
|
||||
expectedRule: `Host("foo.com") && PathPrefix("/")`,
|
||||
expectedPriority: 22,
|
||||
},
|
||||
{
|
||||
@ -37,7 +37,7 @@ func Test_buildGRPCMatchRule(t *testing.T) {
|
||||
Method: ptr.To("bar"),
|
||||
},
|
||||
},
|
||||
expectedRule: "PathRegexp(`/foo/bar`)",
|
||||
expectedRule: `PathRegexp("/foo/bar")`,
|
||||
expectedPriority: 22,
|
||||
},
|
||||
{
|
||||
@ -56,7 +56,7 @@ func Test_buildGRPCMatchRule(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedRule: "PathRegexp(`/foo/bar`) && Header(`foo`,`bar`)",
|
||||
expectedRule: `PathRegexp("/foo/bar") && Header("foo","bar")`,
|
||||
expectedPriority: 45,
|
||||
},
|
||||
{
|
||||
@ -76,7 +76,7 @@ func Test_buildGRPCMatchRule(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedRule: "Host(`foo.com`) && PathRegexp(`/foo/bar`) && Header(`foo`,`bar`)",
|
||||
expectedRule: `Host("foo.com") && PathRegexp("/foo/bar") && Header("foo","bar")`,
|
||||
expectedPriority: 52,
|
||||
},
|
||||
}
|
||||
@ -100,7 +100,7 @@ func Test_buildGRPCMethodRule(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
desc: "Empty",
|
||||
expectedRule: "PathPrefix(`/`)",
|
||||
expectedRule: `PathPrefix("/")`,
|
||||
},
|
||||
{
|
||||
desc: "Exact service matching",
|
||||
@ -108,7 +108,7 @@ func Test_buildGRPCMethodRule(t *testing.T) {
|
||||
Type: ptr.To(gatev1.GRPCMethodMatchExact),
|
||||
Service: ptr.To("foo"),
|
||||
},
|
||||
expectedRule: "PathRegexp(`/foo/[^/]+`)",
|
||||
expectedRule: `PathRegexp("/foo/[^/]+")`,
|
||||
},
|
||||
{
|
||||
desc: "Exact method matching",
|
||||
@ -116,7 +116,7 @@ func Test_buildGRPCMethodRule(t *testing.T) {
|
||||
Type: ptr.To(gatev1.GRPCMethodMatchExact),
|
||||
Method: ptr.To("bar"),
|
||||
},
|
||||
expectedRule: "PathRegexp(`/[^/]+/bar`)",
|
||||
expectedRule: `PathRegexp("/[^/]+/bar")`,
|
||||
},
|
||||
{
|
||||
desc: "Exact service and method matching",
|
||||
@ -125,7 +125,7 @@ func Test_buildGRPCMethodRule(t *testing.T) {
|
||||
Service: ptr.To("foo"),
|
||||
Method: ptr.To("bar"),
|
||||
},
|
||||
expectedRule: "PathRegexp(`/foo/bar`)",
|
||||
expectedRule: `PathRegexp("/foo/bar")`,
|
||||
},
|
||||
{
|
||||
desc: "Regexp service matching",
|
||||
@ -133,7 +133,7 @@ func Test_buildGRPCMethodRule(t *testing.T) {
|
||||
Type: ptr.To(gatev1.GRPCMethodMatchRegularExpression),
|
||||
Service: ptr.To("[^1-9/]"),
|
||||
},
|
||||
expectedRule: "PathRegexp(`/[^1-9/]/[^/]+`)",
|
||||
expectedRule: `PathRegexp("/[^1-9/]/[^/]+")`,
|
||||
},
|
||||
{
|
||||
desc: "Regexp method matching",
|
||||
@ -141,7 +141,7 @@ func Test_buildGRPCMethodRule(t *testing.T) {
|
||||
Type: ptr.To(gatev1.GRPCMethodMatchRegularExpression),
|
||||
Method: ptr.To("[^1-9/]"),
|
||||
},
|
||||
expectedRule: "PathRegexp(`/[^/]+/[^1-9/]`)",
|
||||
expectedRule: `PathRegexp("/[^/]+/[^1-9/]")`,
|
||||
},
|
||||
{
|
||||
desc: "Regexp service and method matching",
|
||||
@ -150,7 +150,7 @@ func Test_buildGRPCMethodRule(t *testing.T) {
|
||||
Service: ptr.To("[^1-9/]"),
|
||||
Method: ptr.To("[^1-9/]"),
|
||||
},
|
||||
expectedRule: "PathRegexp(`/[^1-9/]/[^1-9/]`)",
|
||||
expectedRule: `PathRegexp("/[^1-9/]/[^1-9/]")`,
|
||||
},
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@ func Test_buildGRPCHeaderRules(t *testing.T) {
|
||||
Value: "bar",
|
||||
},
|
||||
},
|
||||
expectedRules: []string{"Header(`foo`,`bar`)"},
|
||||
expectedRules: []string{`Header("foo","bar")`},
|
||||
},
|
||||
{
|
||||
desc: "One regexp match type",
|
||||
@ -193,7 +193,7 @@ func Test_buildGRPCHeaderRules(t *testing.T) {
|
||||
Value: ".*",
|
||||
},
|
||||
},
|
||||
expectedRules: []string{"HeaderRegexp(`foo`,`.*`)"},
|
||||
expectedRules: []string{`HeaderRegexp("foo",".*")`},
|
||||
},
|
||||
{
|
||||
desc: "One exact and regexp match type",
|
||||
@ -210,8 +210,8 @@ func Test_buildGRPCHeaderRules(t *testing.T) {
|
||||
},
|
||||
},
|
||||
expectedRules: []string{
|
||||
"Header(`foo`,`bar`)",
|
||||
"HeaderRegexp(`foo`,`.*`)",
|
||||
`Header("foo","bar")`,
|
||||
`HeaderRegexp("foo",".*")`,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -645,12 +645,12 @@ func buildHostRule(hostnames []gatev1.Hostname) (string, int) {
|
||||
|
||||
wildcard := strings.Count(host, "*")
|
||||
if wildcard == 0 {
|
||||
rules = append(rules, fmt.Sprintf("Host(`%s`)", host))
|
||||
rules = append(rules, fmt.Sprintf("Host(%q)", host))
|
||||
continue
|
||||
}
|
||||
|
||||
host = strings.Replace(regexp.QuoteMeta(host), `\*\.`, `[a-z0-9-\.]+\.`, 1)
|
||||
rules = append(rules, fmt.Sprintf("HostRegexp(`^%s$`)", host))
|
||||
rules = append(rules, fmt.Sprintf("HostRegexp(%q)", fmt.Sprintf("^%s$", host)))
|
||||
}
|
||||
|
||||
switch len(rules) {
|
||||
@ -688,7 +688,7 @@ func buildMatchRule(hostnames []gatev1.Hostname, match gatev1.HTTPRouteMatch) (s
|
||||
priority += pathPriority
|
||||
|
||||
if match.Method != nil {
|
||||
matchRules = append(matchRules, fmt.Sprintf("Method(`%s`)", *match.Method))
|
||||
matchRules = append(matchRules, fmt.Sprintf("Method(%q)", *match.Method))
|
||||
priority += 1000
|
||||
}
|
||||
|
||||
@ -719,23 +719,23 @@ func buildPathRule(pathMatch gatev1.HTTPPathMatch) (string, int) {
|
||||
|
||||
switch pathType {
|
||||
case gatev1.PathMatchExact:
|
||||
return fmt.Sprintf("Path(`%s`)", pathValue), 100000
|
||||
return fmt.Sprintf("Path(%q)", pathValue), 100000
|
||||
|
||||
case gatev1.PathMatchPathPrefix:
|
||||
// PathPrefix(`/`) rule is a catch-all,
|
||||
// here we ensure it would be evaluated last.
|
||||
if pathValue == "/" {
|
||||
return "PathPrefix(`/`)", 1
|
||||
return `PathPrefix("/")`, 1
|
||||
}
|
||||
|
||||
pv := strings.TrimSuffix(pathValue, "/")
|
||||
return fmt.Sprintf("(Path(`%[1]s`) || PathPrefix(`%[1]s/`))", pv), 10000 + len(pathValue)*100
|
||||
return fmt.Sprintf("(Path(%q) || PathPrefix(%q))", pv, fmt.Sprintf("%s/", pv)), 10000 + len(pathValue)*100
|
||||
|
||||
case gatev1.PathMatchRegularExpression:
|
||||
return fmt.Sprintf("PathRegexp(`%s`)", pathValue), 10000 + len(pathValue)*100
|
||||
return fmt.Sprintf("PathRegexp(%q)", pathValue), 10000 + len(pathValue)*100
|
||||
|
||||
default:
|
||||
return "PathPrefix(`/`)", 1
|
||||
return `PathPrefix("/")`, 1
|
||||
}
|
||||
}
|
||||
|
||||
@ -748,9 +748,9 @@ func buildHeaderRules(headers []gatev1.HTTPHeaderMatch) ([]string, int) {
|
||||
typ := ptr.Deref(header.Type, gatev1.HeaderMatchExact)
|
||||
switch typ {
|
||||
case gatev1.HeaderMatchExact:
|
||||
rules = append(rules, fmt.Sprintf("Header(`%s`,`%s`)", header.Name, header.Value))
|
||||
rules = append(rules, fmt.Sprintf("Header(%q,%q)", header.Name, header.Value))
|
||||
case gatev1.HeaderMatchRegularExpression:
|
||||
rules = append(rules, fmt.Sprintf("HeaderRegexp(`%s`,`%s`)", header.Name, header.Value))
|
||||
rules = append(rules, fmt.Sprintf("HeaderRegexp(%q,%q)", header.Name, header.Value))
|
||||
}
|
||||
priority += 100
|
||||
}
|
||||
@ -767,9 +767,9 @@ func buildQueryParamRules(queryParams []gatev1.HTTPQueryParamMatch) ([]string, i
|
||||
typ := ptr.Deref(qp.Type, gatev1.QueryParamMatchExact)
|
||||
switch typ {
|
||||
case gatev1.QueryParamMatchExact:
|
||||
rules = append(rules, fmt.Sprintf("Query(`%s`,`%s`)", qp.Name, qp.Value))
|
||||
rules = append(rules, fmt.Sprintf("Query(%q,%q)", qp.Name, qp.Value))
|
||||
case gatev1.QueryParamMatchRegularExpression:
|
||||
rules = append(rules, fmt.Sprintf("QueryRegexp(`%s`,`%s`)", qp.Name, qp.Value))
|
||||
rules = append(rules, fmt.Sprintf("QueryRegexp(%q,%q)", qp.Name, qp.Value))
|
||||
}
|
||||
priority += 10
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ func Test_buildHostRule(t *testing.T) {
|
||||
hostnames: []gatev1.Hostname{
|
||||
"Foo",
|
||||
},
|
||||
expectedRule: "Host(`Foo`)",
|
||||
expectedRule: `Host("Foo")`,
|
||||
expectedPriority: 3,
|
||||
},
|
||||
{
|
||||
@ -35,7 +35,7 @@ func Test_buildHostRule(t *testing.T) {
|
||||
"Bar",
|
||||
"Bir",
|
||||
},
|
||||
expectedRule: "(Host(`Foo`) || Host(`Bar`) || Host(`Bir`))",
|
||||
expectedRule: `(Host("Foo") || Host("Bar") || Host("Bir"))`,
|
||||
expectedPriority: 3,
|
||||
},
|
||||
{
|
||||
@ -45,7 +45,7 @@ func Test_buildHostRule(t *testing.T) {
|
||||
"bar.foo",
|
||||
"foo.foo",
|
||||
},
|
||||
expectedRule: "(HostRegexp(`^[a-z0-9-\\.]+\\.bar\\.foo$`) || Host(`bar.foo`) || Host(`foo.foo`))",
|
||||
expectedRule: `(HostRegexp("^[a-z0-9-\\.]+\\.bar\\.foo$") || Host("bar.foo") || Host("foo.foo"))`,
|
||||
expectedPriority: 9,
|
||||
},
|
||||
{
|
||||
@ -53,7 +53,7 @@ func Test_buildHostRule(t *testing.T) {
|
||||
hostnames: []gatev1.Hostname{
|
||||
"*.bar.foo",
|
||||
},
|
||||
expectedRule: "HostRegexp(`^[a-z0-9-\\.]+\\.bar\\.foo$`)",
|
||||
expectedRule: `HostRegexp("^[a-z0-9-\\.]+\\.bar\\.foo$")`,
|
||||
expectedPriority: 9,
|
||||
},
|
||||
}
|
||||
@ -80,13 +80,13 @@ func Test_buildMatchRule(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
desc: "Empty rule and matches",
|
||||
expectedRule: "PathPrefix(`/`)",
|
||||
expectedRule: `PathPrefix("/")`,
|
||||
expectedPriority: 1,
|
||||
},
|
||||
{
|
||||
desc: "One Host rule without match",
|
||||
hostnames: []gatev1.Hostname{"foo.com"},
|
||||
expectedRule: "Host(`foo.com`) && PathPrefix(`/`)",
|
||||
expectedRule: `Host("foo.com") && PathPrefix("/")`,
|
||||
expectedPriority: 8,
|
||||
},
|
||||
{
|
||||
@ -98,7 +98,7 @@ func Test_buildMatchRule(t *testing.T) {
|
||||
}),
|
||||
Headers: nil,
|
||||
},
|
||||
expectedRule: "PathPrefix(`/`)",
|
||||
expectedRule: `PathPrefix("/")`,
|
||||
expectedPriority: 1,
|
||||
},
|
||||
{
|
||||
@ -112,13 +112,13 @@ func Test_buildMatchRule(t *testing.T) {
|
||||
{Name: "foo", Value: "bar"},
|
||||
},
|
||||
},
|
||||
expectedRule: "PathPrefix(`/`) && Header(`foo`,`bar`)",
|
||||
expectedRule: `PathPrefix("/") && Header("foo","bar")`,
|
||||
expectedPriority: 101,
|
||||
},
|
||||
{
|
||||
desc: "One HTTPRouteMatch with nil HTTPPathMatch",
|
||||
match: gatev1.HTTPRouteMatch{Path: nil},
|
||||
expectedRule: "PathPrefix(`/`)",
|
||||
expectedRule: `PathPrefix("/")`,
|
||||
expectedPriority: 1,
|
||||
},
|
||||
{
|
||||
@ -129,7 +129,7 @@ func Test_buildMatchRule(t *testing.T) {
|
||||
Value: ptr.To("/foo/"),
|
||||
},
|
||||
},
|
||||
expectedRule: "(Path(`/foo`) || PathPrefix(`/foo/`))",
|
||||
expectedRule: `(Path("/foo") || PathPrefix("/foo/"))`,
|
||||
expectedPriority: 10500,
|
||||
},
|
||||
{
|
||||
@ -140,7 +140,7 @@ func Test_buildMatchRule(t *testing.T) {
|
||||
Value: nil,
|
||||
},
|
||||
},
|
||||
expectedRule: "Path(`/`)",
|
||||
expectedRule: `Path("/")`,
|
||||
expectedPriority: 100000,
|
||||
},
|
||||
{
|
||||
@ -151,7 +151,7 @@ func Test_buildMatchRule(t *testing.T) {
|
||||
Value: ptr.To("/foo/"),
|
||||
},
|
||||
},
|
||||
expectedRule: "Path(`/foo/`)",
|
||||
expectedRule: `Path("/foo/")`,
|
||||
expectedPriority: 100000,
|
||||
},
|
||||
{
|
||||
@ -169,7 +169,7 @@ func Test_buildMatchRule(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedRule: "Path(`/foo/`) && Header(`my-header`,`foo`)",
|
||||
expectedRule: `Path("/foo/") && Header("my-header","foo")`,
|
||||
expectedPriority: 100100,
|
||||
},
|
||||
{
|
||||
@ -188,7 +188,7 @@ func Test_buildMatchRule(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedRule: "Host(`foo.com`) && Path(`/foo/`) && Header(`my-header`,`foo`)",
|
||||
expectedRule: `Host("foo.com") && Path("/foo/") && Header("my-header","foo")`,
|
||||
expectedPriority: 100107,
|
||||
},
|
||||
}
|
||||
|
||||
@ -13,7 +13,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff/v4"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/mitchellh/hashstructure"
|
||||
"github.com/rs/zerolog/log"
|
||||
ptypes "github.com/traefik/paerser/types"
|
||||
@ -409,7 +408,7 @@ func (p *Provider) loadConfigurationFromGateways(ctx context.Context) *dynamic.C
|
||||
}
|
||||
var conditionsErr error
|
||||
for message := range messages {
|
||||
conditionsErr = multierror.Append(conditionsErr, errors.New(message))
|
||||
conditionsErr = errors.Join(conditionsErr, errors.New(message))
|
||||
}
|
||||
logger.Error().
|
||||
Err(conditionsErr).
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -119,7 +119,7 @@ func (p *Provider) loadTCPRoute(listener gatewayListener, route *gatev1alpha2.TC
|
||||
}
|
||||
|
||||
router := dynamic.TCPRouter{
|
||||
Rule: "HostSNI(`*`)",
|
||||
Rule: `HostSNI("*")`,
|
||||
EntryPoints: []string{listener.EPName},
|
||||
RuleSyntax: "default",
|
||||
}
|
||||
|
||||
@ -327,16 +327,16 @@ func hostSNIRule(hostnames []gatev1.Hostname) (string, int) {
|
||||
uniqHostnames[hostname] = struct{}{}
|
||||
|
||||
if wildcard == 0 {
|
||||
rules = append(rules, fmt.Sprintf("HostSNI(`%s`)", host))
|
||||
rules = append(rules, fmt.Sprintf("HostSNI(%q)", host))
|
||||
continue
|
||||
}
|
||||
|
||||
host = strings.Replace(regexp.QuoteMeta(host), `\*\.`, `[a-z0-9-\.]+\.`, 1)
|
||||
rules = append(rules, fmt.Sprintf("HostSNIRegexp(`^%s$`)", host))
|
||||
rules = append(rules, fmt.Sprintf("HostSNIRegexp(%q)", fmt.Sprintf("^%s$", host)))
|
||||
}
|
||||
|
||||
if len(hostnames) == 0 || len(rules) == 0 {
|
||||
return "HostSNI(`*`)", 0
|
||||
return `HostSNI("*")`, 0
|
||||
}
|
||||
|
||||
return strings.Join(rules, " || "), priority
|
||||
|
||||
@ -17,49 +17,49 @@ func Test_hostSNIRule(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
desc: "Empty",
|
||||
expectedRule: "HostSNI(`*`)",
|
||||
expectedRule: `HostSNI("*")`,
|
||||
expectedPriority: 0,
|
||||
},
|
||||
{
|
||||
desc: "Empty hostname",
|
||||
hostnames: []gatev1.Hostname{""},
|
||||
expectedRule: "HostSNI(`*`)",
|
||||
expectedRule: `HostSNI("*")`,
|
||||
expectedPriority: 0,
|
||||
},
|
||||
{
|
||||
desc: "Supported wildcard",
|
||||
hostnames: []gatev1.Hostname{"*.foo"},
|
||||
expectedRule: "HostSNIRegexp(`^[a-z0-9-\\.]+\\.foo$`)",
|
||||
expectedRule: `HostSNIRegexp("^[a-z0-9-\\.]+\\.foo$")`,
|
||||
expectedPriority: 4,
|
||||
},
|
||||
{
|
||||
desc: "Some empty hostnames",
|
||||
hostnames: []gatev1.Hostname{"foo", "", "bar"},
|
||||
expectedRule: "HostSNI(`foo`) || HostSNI(`bar`)",
|
||||
expectedRule: `HostSNI("foo") || HostSNI("bar")`,
|
||||
expectedPriority: 3,
|
||||
},
|
||||
{
|
||||
desc: "Valid hostname",
|
||||
hostnames: []gatev1.Hostname{"foo"},
|
||||
expectedRule: "HostSNI(`foo`)",
|
||||
expectedRule: `HostSNI("foo")`,
|
||||
expectedPriority: 3,
|
||||
},
|
||||
{
|
||||
desc: "Multiple valid hostnames",
|
||||
hostnames: []gatev1.Hostname{"foo", "bar"},
|
||||
expectedRule: "HostSNI(`foo`) || HostSNI(`bar`)",
|
||||
expectedRule: `HostSNI("foo") || HostSNI("bar")`,
|
||||
expectedPriority: 3,
|
||||
},
|
||||
{
|
||||
desc: "Multiple valid hostnames with wildcard",
|
||||
hostnames: []gatev1.Hostname{"bar.foo", "foo.foo", "*.foo"},
|
||||
expectedRule: "HostSNI(`bar.foo`) || HostSNI(`foo.foo`) || HostSNIRegexp(`^[a-z0-9-\\.]+\\.foo$`)",
|
||||
expectedRule: `HostSNI("bar.foo") || HostSNI("foo.foo") || HostSNIRegexp("^[a-z0-9-\\.]+\\.foo$")`,
|
||||
expectedPriority: 7,
|
||||
},
|
||||
{
|
||||
desc: "Multiple overlapping hostnames",
|
||||
hostnames: []gatev1.Hostname{"foo", "bar", "foo", "baz"},
|
||||
expectedRule: "HostSNI(`foo`) || HostSNI(`bar`) || HostSNI(`baz`)",
|
||||
expectedRule: `HostSNI("foo") || HostSNI("bar") || HostSNI("baz")`,
|
||||
expectedPriority: 3,
|
||||
},
|
||||
}
|
||||
|
||||
@ -633,7 +633,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
"name0": "foobar",
|
||||
},
|
||||
SSLForceHost: pointer(true),
|
||||
STSSeconds: 42,
|
||||
STSSeconds: pointer(int64(42)),
|
||||
STSIncludeSubdomains: true,
|
||||
STSPreload: true,
|
||||
ForceSTSHeader: true,
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
{
|
||||
"http": {
|
||||
"routers": {
|
||||
"web-to-websecure": {
|
||||
"entryPoints": [
|
||||
"web"
|
||||
],
|
||||
"middlewares": [
|
||||
"redirect-web-to-websecure"
|
||||
],
|
||||
"service": "noop@internal",
|
||||
"rule": "HostRegexp(`^.+$`) \u0026\u0026 !PathPrefix(`/.well-known/acme-challenge/`)",
|
||||
"ruleSyntax": "default"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"noop": {}
|
||||
},
|
||||
"middlewares": {
|
||||
"redirect-web-to-websecure": {
|
||||
"redirectScheme": {
|
||||
"scheme": "https",
|
||||
"port": "443",
|
||||
"permanent": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tcp": {},
|
||||
"tls": {}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
{
|
||||
"http": {
|
||||
"routers": {
|
||||
"acme-http": {
|
||||
"entryPoints": [
|
||||
"web"
|
||||
],
|
||||
"service": "acme-http@internal",
|
||||
"rule": "PathPrefix(`/.well-known/acme-challenge/`)",
|
||||
"ruleSyntax": "default",
|
||||
"priority": 9223372036854775807
|
||||
},
|
||||
"web-to-websecure": {
|
||||
"entryPoints": [
|
||||
"web"
|
||||
],
|
||||
"middlewares": [
|
||||
"redirect-web-to-websecure"
|
||||
],
|
||||
"service": "noop@internal",
|
||||
"rule": "HostRegexp(`^.+$`)",
|
||||
"ruleSyntax": "default"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"acme-http": {},
|
||||
"noop": {}
|
||||
},
|
||||
"middlewares": {
|
||||
"redirect-web-to-websecure": {
|
||||
"redirectScheme": {
|
||||
"scheme": "https",
|
||||
"port": "443",
|
||||
"permanent": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tcp": {},
|
||||
"tls": {}
|
||||
}
|
||||
@ -161,11 +161,16 @@ func (i *Provider) redirection(ctx context.Context, cfg *dynamic.Configuration)
|
||||
continue
|
||||
}
|
||||
|
||||
rule := "HostRegexp(`^.+$`)"
|
||||
if ep.AllowACMEByPass {
|
||||
rule = "HostRegexp(`^.+$`) && !PathPrefix(`/.well-known/acme-challenge/`)"
|
||||
}
|
||||
|
||||
rtName := provider.Normalize(name + "-to-" + def.EntryPoint.To)
|
||||
mdName := "redirect-" + rtName
|
||||
|
||||
rt := &dynamic.Router{
|
||||
Rule: "HostRegexp(`^.+$`)",
|
||||
Rule: rule,
|
||||
// "default" stands for the default rule syntax in Traefik v3, i.e. the v3 syntax.
|
||||
RuleSyntax: "default",
|
||||
EntryPoints: []string{name},
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
"github.com/traefik/traefik/v3/pkg/config/static"
|
||||
otypes "github.com/traefik/traefik/v3/pkg/observability/types"
|
||||
"github.com/traefik/traefik/v3/pkg/ping"
|
||||
acmeprovider "github.com/traefik/traefik/v3/pkg/provider/acme"
|
||||
"github.com/traefik/traefik/v3/pkg/provider/rest"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
)
|
||||
@ -261,6 +262,60 @@ func Test_createConfiguration(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "redirection_with_acme_bypass.json",
|
||||
staticCfg: static.Configuration{
|
||||
EntryPoints: map[string]*static.EntryPoint{
|
||||
"web": {
|
||||
Address: ":80",
|
||||
AllowACMEByPass: true,
|
||||
HTTP: static.HTTPConfig{
|
||||
Redirections: &static.Redirections{
|
||||
EntryPoint: &static.RedirectEntryPoint{
|
||||
To: "websecure",
|
||||
Scheme: "https",
|
||||
Permanent: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"websecure": {
|
||||
Address: ":443",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "redirection_without_acme_bypass.json",
|
||||
staticCfg: static.Configuration{
|
||||
EntryPoints: map[string]*static.EntryPoint{
|
||||
"web": {
|
||||
Address: ":80",
|
||||
HTTP: static.HTTPConfig{
|
||||
Redirections: &static.Redirections{
|
||||
EntryPoint: &static.RedirectEntryPoint{
|
||||
To: "websecure",
|
||||
Scheme: "https",
|
||||
Permanent: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"websecure": {
|
||||
Address: ":443",
|
||||
},
|
||||
},
|
||||
CertificatesResolvers: map[string]static.CertificateResolver{
|
||||
"default": {
|
||||
ACME: &acmeprovider.Configuration{
|
||||
HTTPChallenge: &acmeprovider.HTTPChallenge{
|
||||
EntryPoint: "web",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
|
||||
@ -35,7 +35,7 @@ func TestWebSocketUpgradeCase(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Force answer with "Connection: upgrade" in lowercase.
|
||||
_, err = c.Write([]byte("HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: upgrade\r\nSec-WebSocket-Accept: " + computeAcceptKey(challengeKey) + "\r\n\n"))
|
||||
_, err = c.Write([]byte("HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: upgrade\r\nSec-WebSocket-Accept: " + computeAcceptKey(challengeKey) + "\r\n\r\n"))
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
@ -209,7 +209,7 @@ func init() {
|
||||
AllowedHosts: []string{"foo"},
|
||||
HostsProxyHeaders: []string{"foo"},
|
||||
SSLProxyHeaders: map[string]string{"foo": "bar"},
|
||||
STSSeconds: 42,
|
||||
STSSeconds: pointer(int64(42)),
|
||||
STSIncludeSubdomains: true,
|
||||
STSPreload: true,
|
||||
ForceSTSHeader: true,
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@ -51,8 +51,6 @@ func (eps UDPEntryPoints) Stop() {
|
||||
|
||||
for epn, ep := range eps {
|
||||
wg.Go(func() {
|
||||
defer wg.Done()
|
||||
|
||||
logger := log.With().Str(logs.EntryPointName, epn).Logger()
|
||||
ep.Shutdown(logger.WithContext(context.Background()))
|
||||
|
||||
|
||||
@ -560,13 +560,11 @@ func TestConcurrentResponseTimeUpdates(t *testing.T) {
|
||||
updatesPerGoroutine := 20
|
||||
|
||||
for i := range numGoroutines {
|
||||
wg.Add(1)
|
||||
go func(id int) {
|
||||
defer wg.Done()
|
||||
wg.Go(func() {
|
||||
for range updatesPerGoroutine {
|
||||
handler.updateResponseTime(time.Duration(id+1) * time.Millisecond)
|
||||
handler.updateResponseTime(time.Duration(i+1) * time.Millisecond)
|
||||
}
|
||||
}(i)
|
||||
})
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
@ -4,11 +4,11 @@ RepositoryName = "traefik"
|
||||
OutputType = "file"
|
||||
FileName = "traefik_changelog.md"
|
||||
|
||||
# example new bugfix v3.6.9
|
||||
# example new bugfix v3.6.10
|
||||
CurrentRef = "v3.6"
|
||||
PreviousRef = "v3.6.8"
|
||||
PreviousRef = "v3.6.10"
|
||||
BaseBranch = "v3.6"
|
||||
FutureCurrentRefName = "v3.6.9"
|
||||
FutureCurrentRefName = "v3.6.10"
|
||||
|
||||
ThresholdPreviousRef = 10000
|
||||
ThresholdCurrentRef = 10000
|
||||
|
||||
@ -34,6 +34,8 @@ export const useResourceDetail = (name: string, resource: string, protocol = 'ht
|
||||
status: routeDetail.status,
|
||||
provider: routeDetail.provider,
|
||||
rule: routeDetail.rule,
|
||||
priority: routeDetail.priority,
|
||||
priorityStr: routeDetail.priorityStr,
|
||||
tls: routeDetail.tls,
|
||||
error: routeDetail.error,
|
||||
middlewares: validMiddlewares,
|
||||
|
||||
@ -98,7 +98,8 @@
|
||||
"status": "enabled",
|
||||
"name": "server-redirect@docker",
|
||||
"using": ["web-redirect"],
|
||||
"priority": 9223372036854776000,
|
||||
"priority": 9223372036854775806,
|
||||
"priorityStr": "9223372036854775806",
|
||||
"provider": "docker"
|
||||
},
|
||||
{
|
||||
|
||||
@ -62,7 +62,7 @@ export const makeRowRender = (protocol = 'http'): RenderRowType => {
|
||||
<ProviderIconWithTooltip provider={row.provider} />
|
||||
</AriaTd>
|
||||
<AriaTd>
|
||||
<TooltipText text={row.priority} isTruncated />
|
||||
<TooltipText text={row.priorityStr ?? row.priority} isTruncated />
|
||||
</AriaTd>
|
||||
</ClickableRow>
|
||||
)
|
||||
|
||||
@ -47,7 +47,7 @@ export const makeRowRender = (): RenderRowType => {
|
||||
<ProviderIconWithTooltip provider={row.provider} />
|
||||
</AriaTd>
|
||||
<AriaTd>
|
||||
<TooltipText text={row.priority} isTruncated />
|
||||
<TooltipText text={row.priorityStr ?? row.priority} isTruncated />
|
||||
</AriaTd>
|
||||
</ClickableRow>
|
||||
)
|
||||
|
||||
@ -33,7 +33,7 @@ export const makeRowRender = (): RenderRowType => {
|
||||
<ProviderIconWithTooltip provider={row.provider} />
|
||||
</AriaTd>
|
||||
<AriaTd>
|
||||
<TooltipText text={row.priority} isTruncated />
|
||||
<TooltipText text={row.priorityStr ?? row.priority} isTruncated />
|
||||
</AriaTd>
|
||||
</ClickableRow>
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user