Merge branch v3.0 into master
This commit is contained in:
commit
9d8fd24730
119 changed files with 16917 additions and 500 deletions
4
.github/workflows/build.yaml
vendored
4
.github/workflows/build.yaml
vendored
|
@ -12,7 +12,7 @@ env:
|
|||
jobs:
|
||||
|
||||
build-webui:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
|
@ -35,7 +35,7 @@ jobs:
|
|||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ ubuntu-22.04, macos-latest, windows-latest ]
|
||||
os: [ ubuntu-latest, macos-latest, windows-latest ]
|
||||
needs:
|
||||
- build-webui
|
||||
|
||||
|
|
2
.github/workflows/check_doc.yml
vendored
2
.github/workflows/check_doc.yml
vendored
|
@ -9,7 +9,7 @@ jobs:
|
|||
|
||||
docs:
|
||||
name: Check, verify and build documentation
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
|
|
2
.github/workflows/documentation.yml
vendored
2
.github/workflows/documentation.yml
vendored
|
@ -14,7 +14,7 @@ jobs:
|
|||
|
||||
docs:
|
||||
name: Doc Process
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'traefik/traefik'
|
||||
|
||||
steps:
|
||||
|
|
2
.github/workflows/experimental.yaml
vendored
2
.github/workflows/experimental.yaml
vendored
|
@ -15,7 +15,7 @@ jobs:
|
|||
experimental:
|
||||
if: github.repository == 'traefik/traefik'
|
||||
name: Build experimental image on branch
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
||||
|
|
11
.github/workflows/test-conformance.yaml
vendored
11
.github/workflows/test-conformance.yaml
vendored
|
@ -15,7 +15,7 @@ env:
|
|||
jobs:
|
||||
|
||||
test-conformance:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
|
@ -31,12 +31,5 @@ jobs:
|
|||
- name: Avoid generating webui
|
||||
run: touch webui/static/index.html
|
||||
|
||||
- name: Build binary
|
||||
run: make binary
|
||||
|
||||
- name: Setcap
|
||||
run: |
|
||||
sudo setcap 'cap_net_bind_service=+ep' dist/linux/amd64/traefik
|
||||
|
||||
- name: K8s Gateway API conformance test
|
||||
run: make test-gateway-api-conformance-ci
|
||||
run: make test-gateway-api-conformance
|
||||
|
|
4
.github/workflows/test-integration.yaml
vendored
4
.github/workflows/test-integration.yaml
vendored
|
@ -12,7 +12,7 @@ env:
|
|||
jobs:
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
|
@ -32,7 +32,7 @@ jobs:
|
|||
run: make binary
|
||||
|
||||
test-integration:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build
|
||||
strategy:
|
||||
|
|
2
.github/workflows/test-unit.yaml
vendored
2
.github/workflows/test-unit.yaml
vendored
|
@ -11,7 +11,7 @@ env:
|
|||
jobs:
|
||||
|
||||
test-unit:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
|
|
4
.github/workflows/validate.yaml
vendored
4
.github/workflows/validate.yaml
vendored
|
@ -13,7 +13,7 @@ env:
|
|||
jobs:
|
||||
|
||||
validate:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
|
@ -39,7 +39,7 @@ jobs:
|
|||
run: make validate
|
||||
|
||||
validate-generate:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
|
|
82
CHANGELOG.md
82
CHANGELOG.md
|
@ -1,3 +1,85 @@
|
|||
## [v3.0.0-rc5](https://github.com/traefik/traefik/tree/v3.0.0-rc4) (2024-04-11)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v3.0.0-rc4...v3.0.0-rc5)
|
||||
|
||||
**Misc:**
|
||||
- Merge current v2.11 into v3.0 ([#10604](https://github.com/traefik/traefik/pull/10604) by [ldez](https://github.com/ldez))
|
||||
|
||||
## [v2.11.2](https://github.com/traefik/traefik/tree/v2.11.2) (2024-04-11)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.1...v2.11.2)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[server]** Revert LingeringTimeout and change default value for ReadTimeout ([#10599](https://github.com/traefik/traefik/pull/10599) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[server]** Set default ReadTimeout value to 60s ([#10602](https://github.com/traefik/traefik/pull/10602) by [rtribotte](https://github.com/rtribotte))
|
||||
|
||||
## [v3.0.0-rc4](https://github.com/traefik/traefik/tree/v3.0.0-rc4) (2024-04-10)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v3.0.0-rc3...v3.0.0-rc4)
|
||||
|
||||
**Enhancements:**
|
||||
- **[k8s/gatewayapi]** Add option to set Gateway status address ([#10582](https://github.com/traefik/traefik/pull/10582) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[k8s/gatewayapi]** Handle middlewares in filters extension reference ([#10511](https://github.com/traefik/traefik/pull/10511) by [youkoulayley](https://github.com/youkoulayley))
|
||||
- **[k8s/gatewayapi]** Toggle support for experimental channel ([#10435](https://github.com/traefik/traefik/pull/10435) by [SantoDE](https://github.com/SantoDE))
|
||||
- **[k8s/ingress,k8s/crd,k8s,k8s/gatewayapi]** Use runtime.Object in routerTransform ([#10523](https://github.com/traefik/traefik/pull/10523) by [juliens](https://github.com/juliens))
|
||||
- **[nomad]** Allow empty services ([#10375](https://github.com/traefik/traefik/pull/10375) by [chrispruitt](https://github.com/chrispruitt))
|
||||
- **[webui,middleware,k8s/gatewayapi]** Support RequestHeaderModifier filter ([#10521](https://github.com/traefik/traefik/pull/10521) by [rtribotte](https://github.com/rtribotte))
|
||||
|
||||
**Bug fixes:**
|
||||
- **[docker]** Fix struct names in comment ([#10503](https://github.com/traefik/traefik/pull/10503) by [hishope](https://github.com/hishope))
|
||||
- **[logs]** Avoid cumulative send anonymous usage log ([#10579](https://github.com/traefik/traefik/pull/10579) by [mmatur](https://github.com/mmatur))
|
||||
- **[rules]** Support regexp in path/pathprefix in matcher v2 ([#10546](https://github.com/traefik/traefik/pull/10546) by [youkoulayley](https://github.com/youkoulayley))
|
||||
- **[webui]** Add missing Docker Swarm logo ([#10529](https://github.com/traefik/traefik/pull/10529) by [ldez](https://github.com/ldez))
|
||||
|
||||
**Documentation:**
|
||||
- Fix typo and improve explanation on internal resources ([#10563](https://github.com/traefik/traefik/pull/10563) by [mloiseleur](https://github.com/mloiseleur))
|
||||
- Fix typo in dialer_test.go ([#10552](https://github.com/traefik/traefik/pull/10552) by [eltociear](https://github.com/eltociear))
|
||||
|
||||
**Misc:**
|
||||
- Merge branch v2.11 into v3.0 ([#10587](https://github.com/traefik/traefik/pull/10587) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Merge current v2.11 into v3.0 ([#10566](https://github.com/traefik/traefik/pull/10566) by [mmatur](https://github.com/mmatur))
|
||||
- Merge current v2.11 into v3.0 ([#10564](https://github.com/traefik/traefik/pull/10564) by [ldez](https://github.com/ldez))
|
||||
|
||||
## [v2.11.1](https://github.com/traefik/traefik/tree/v2.11.1) (2024-04-10)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.0...v2.11.1)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[acme,tls]** Enforce handling of ACME-TLS/1 challenges ([#10536](https://github.com/traefik/traefik/pull/10536) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[acme]** Update go-acme/lego to v4.16.1 ([#10508](https://github.com/traefik/traefik/pull/10508) by [ldez](https://github.com/ldez))
|
||||
- **[acme]** Close created file in ACME local store CheckFile func ([#10574](https://github.com/traefik/traefik/pull/10574) by [testwill](https://github.com/testwill))
|
||||
- **[docker,http3]** Update to quic-go v0.42.0 and docker/cli v24.0.9 ([#10572](https://github.com/traefik/traefik/pull/10572) by [mloiseleur](https://github.com/mloiseleur))
|
||||
- **[docker,marathon,rancher,ecs,tls,nomad]** Allow to configure TLSStore default generated certificate with labels ([#10439](https://github.com/traefik/traefik/pull/10439) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[ecs]** Adjust ECS network interface detection logic ([#10550](https://github.com/traefik/traefik/pull/10550) by [amaxine](https://github.com/amaxine))
|
||||
- **[logs,tls]** Fix log when default TLSStore and TLSOptions are defined multiple times ([#10499](https://github.com/traefik/traefik/pull/10499) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[middleware]** Allow empty replacement with ReplacePathRegex middleware ([#10538](https://github.com/traefik/traefik/pull/10538) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[plugins]** Update Yaegi to v0.16.1 ([#10565](https://github.com/traefik/traefik/pull/10565) by [ldez](https://github.com/ldez))
|
||||
- **[provider,rules]** Don't allow routers higher than internal ones ([#10428](https://github.com/traefik/traefik/pull/10428) by [ldez](https://github.com/ldez))
|
||||
- **[rules]** Reserve priority range for internal routers ([#10541](https://github.com/traefik/traefik/pull/10541) by [youkoulayley](https://github.com/youkoulayley))
|
||||
- **[server,tcp]** Introduce Lingering Timeout ([#10569](https://github.com/traefik/traefik/pull/10569) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[tcp]** Enforce failure for TCP HostSNI with hostname ([#10540](https://github.com/traefik/traefik/pull/10540) by [youkoulayley](https://github.com/youkoulayley))
|
||||
- **[tracing]** Bump Elastic APM to v2.4.8 ([#10512](https://github.com/traefik/traefik/pull/10512) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[webui]** Fix dashboard exposition through a router ([#10518](https://github.com/traefik/traefik/pull/10518) by [mmatur](https://github.com/mmatur))
|
||||
- **[webui]** Display IPAllowlist middleware configuration in dashboard ([#10459](https://github.com/traefik/traefik/pull/10459) by [youkoulayley](https://github.com/youkoulayley))
|
||||
- **[webui]** Make text more readable in dark mode ([#10473](https://github.com/traefik/traefik/pull/10473) by [hood](https://github.com/hood))
|
||||
- **[webui]** Migrate to Quasar 2.x and Vue.js 3.x ([#10416](https://github.com/traefik/traefik/pull/10416) by [andsarr](https://github.com/andsarr))
|
||||
- **[webui]** Add a horizontal scroll for the mobile view ([#10480](https://github.com/traefik/traefik/pull/10480) by [framebassman](https://github.com/framebassman))
|
||||
|
||||
**Documentation:**
|
||||
- **[acme]** Update gandiv5 env variable in providers table ([#10506](https://github.com/traefik/traefik/pull/10506) by [dominiwe](https://github.com/dominiwe))
|
||||
- **[acme]** Fix multiple dns provider documentation ([#10496](https://github.com/traefik/traefik/pull/10496) by [mmatur](https://github.com/mmatur))
|
||||
- **[docker]** Fix paragraph in entrypoints and Docker docs ([#10491](https://github.com/traefik/traefik/pull/10491) by [luigir-it](https://github.com/luigir-it))
|
||||
- **[k8s]** Improve middleware example ([#10532](https://github.com/traefik/traefik/pull/10532) by [mloiseleur](https://github.com/mloiseleur))
|
||||
- **[metrics]** Fix host header mention in prometheus metrics doc ([#10502](https://github.com/traefik/traefik/pull/10502) by [MorphBonehunter](https://github.com/MorphBonehunter))
|
||||
- **[metrics]** Fix typo in statsd metrics docs ([#10437](https://github.com/traefik/traefik/pull/10437) by [xpac1985](https://github.com/xpac1985))
|
||||
- **[middleware]** Improve excludedIPs example with IPWhiteList and IPAllowList middleware ([#10554](https://github.com/traefik/traefik/pull/10554) by [mloiseleur](https://github.com/mloiseleur))
|
||||
- **[nomad]** Improve documentation about Nomad ACL minimum rights ([#10482](https://github.com/traefik/traefik/pull/10482) by [Thadir](https://github.com/Thadir))
|
||||
- **[server]** Add specification for TCP TLS routers in documentation ([#10510](https://github.com/traefik/traefik/pull/10510) by [shivanipawar00](https://github.com/shivanipawar00))
|
||||
- **[tls]** Fix default value for peerCertURI option ([#10470](https://github.com/traefik/traefik/pull/10470) by [marcmognol](https://github.com/marcmognol))
|
||||
- Update releases page ([#10449](https://github.com/traefik/traefik/pull/10449) by [ldez](https://github.com/ldez))
|
||||
- Update releases page ([#10443](https://github.com/traefik/traefik/pull/10443) by [ldez](https://github.com/ldez))
|
||||
- Add youkoulayley to maintainers ([#10517](https://github.com/traefik/traefik/pull/10517) by [emilevauge](https://github.com/emilevauge))
|
||||
- Add sdelicata to maintainers ([#10515](https://github.com/traefik/traefik/pull/10515) by [emilevauge](https://github.com/emilevauge))
|
||||
|
||||
**Misc:**
|
||||
- **[webui]** Modify the Hub Button ([#10583](https://github.com/traefik/traefik/pull/10583) by [mdeliatf](https://github.com/mdeliatf))
|
||||
|
||||
## [v3.0.0-rc3](https://github.com/traefik/traefik/tree/v3.0.0-rc3) (2024-03-13)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v3.0.0-rc2...v3.0.0-rc3)
|
||||
|
||||
|
|
11
Makefile
11
Makefile
|
@ -102,15 +102,8 @@ test-integration: binary
|
|||
|
||||
.PHONY: test-gateway-api-conformance
|
||||
#? test-gateway-api-conformance: Run the conformance tests
|
||||
test-gateway-api-conformance: binary
|
||||
GOOS=$(GOOS) GOARCH=$(GOARCH) go test ./integration -v -test.run K8sConformanceSuite -k8sConformance=true $(TESTFLAGS)
|
||||
|
||||
## TODO: Need to be fixed to work in all situations.
|
||||
.PHONY: test-gateway-api-conformance-ci
|
||||
#? test-gateway-api-conformance-ci: Run the conformance tests
|
||||
test-gateway-api-conformance-ci:
|
||||
GOOS=$(GOOS) GOARCH=$(GOARCH) go test ./integration -v -test.run K8sConformanceSuite -k8sConformance=true $(TESTFLAGS)
|
||||
|
||||
test-gateway-api-conformance: build-image-dirty
|
||||
GOOS=$(GOOS) GOARCH=$(GOARCH) go test ./integration -v -test.run K8sConformanceSuite -k8sConformance $(TESTFLAGS)
|
||||
|
||||
.PHONY: pull-images
|
||||
#? pull-images: Pull all Docker images to avoid timeout during integration tests
|
||||
|
|
|
@ -593,16 +593,16 @@ func checkNewVersion() {
|
|||
}
|
||||
|
||||
func stats(staticConfiguration *static.Configuration) {
|
||||
logger := log.Info()
|
||||
logger := log.With().Logger()
|
||||
|
||||
if staticConfiguration.Global.SendAnonymousUsage {
|
||||
logger.Msg(`Stats collection is enabled.`)
|
||||
logger.Msg(`Many thanks for contributing to Traefik's improvement by allowing us to receive anonymous information from your configuration.`)
|
||||
logger.Msg(`Help us improve Traefik by leaving this feature on :)`)
|
||||
logger.Msg(`More details on: https://doc.traefik.io/traefik/contributing/data-collection/`)
|
||||
logger.Info().Msg(`Stats collection is enabled.`)
|
||||
logger.Info().Msg(`Many thanks for contributing to Traefik's improvement by allowing us to receive anonymous information from your configuration.`)
|
||||
logger.Info().Msg(`Help us improve Traefik by leaving this feature on :)`)
|
||||
logger.Info().Msg(`More details on: https://doc.traefik.io/traefik/contributing/data-collection/`)
|
||||
collect(staticConfiguration)
|
||||
} else {
|
||||
logger.Msg(`
|
||||
logger.Info().Msg(`
|
||||
Stats collection is disabled.
|
||||
Help us improve Traefik by turning this feature on :)
|
||||
More details on: https://doc.traefik.io/traefik/contributing/data-collection/
|
||||
|
|
|
@ -93,7 +93,7 @@ The example below is a file provider only version (`yaml`) of what this configur
|
|||
```yaml tab="Static configuration"
|
||||
# traefik.yml
|
||||
|
||||
entrypoints:
|
||||
entryPoints:
|
||||
web:
|
||||
address: :80
|
||||
|
||||
|
|
|
@ -116,8 +116,8 @@ Please check the [configuration examples below](#configuration-examples) for mor
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.web.address=:80
|
||||
--entrypoints.websecure.address=:443
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.websecure.address=:443
|
||||
# ...
|
||||
--certificatesresolvers.myresolver.acme.email=your-email@example.com
|
||||
--certificatesresolvers.myresolver.acme.storage=acme.json
|
||||
|
@ -241,8 +241,8 @@ when using the `HTTP-01` challenge, `certificatesresolvers.myresolver.acme.httpc
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.web.address=:80
|
||||
--entrypoints.websecure.address=:443
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.websecure.address=:443
|
||||
# ...
|
||||
--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
|
||||
```
|
||||
|
|
|
@ -8,11 +8,11 @@ description: "Learn how to use IPAllowList in HTTP middleware for limiting clien
|
|||
Limiting Clients to Specific IPs
|
||||
{: .subtitle }
|
||||
|
||||
IPAllowList accepts / refuses requests based on the client IP.
|
||||
IPAllowList limits allowed requests based on the client IP.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
```yaml tab="Docker & Swarm"
|
||||
```yaml tab="Docker"
|
||||
# Accepts request from defined IP
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
|
@ -35,6 +35,18 @@ spec:
|
|||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange": "127.0.0.1/32,192.168.1.7"
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
# Accepts request from defined IP
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# Accepts request from defined IP
|
||||
http:
|
||||
|
@ -57,6 +69,8 @@ http:
|
|||
|
||||
### `sourceRange`
|
||||
|
||||
_Required_
|
||||
|
||||
The `sourceRange` option sets the allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
||||
|
||||
### `ipStrategy`
|
||||
|
@ -83,7 +97,7 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and take th
|
|||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `3` | `"11.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `5` | `""` |
|
||||
|
||||
```yaml tab="Docker & Swarm"
|
||||
```yaml tab="Docker"
|
||||
# Allowlisting Based on `X-Forwarded-For` with `depth=2`
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
|
@ -111,6 +125,20 @@ spec:
|
|||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange": "127.0.0.1/32, 192.168.1.7",
|
||||
"traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.depth": "2"
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# Allowlisting Based on `X-Forwarded-For` with `depth=2`
|
||||
http:
|
||||
|
@ -149,9 +177,10 @@ http:
|
|||
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,16.0.0.1"` | `"13.0.0.1"` |
|
||||
| `"10.0.0.1,11.0.0.1"` | `"10.0.0.1,11.0.0.1"` | `""` |
|
||||
|
||||
```yaml tab="Docker & Swarm"
|
||||
```yaml tab="Docker"
|
||||
# Exclude from `X-Forwarded-For`
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourceRange=127.0.0.1/32, 192.168.1.0/24"
|
||||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||
```
|
||||
|
||||
|
@ -163,6 +192,9 @@ metadata:
|
|||
name: test-ipallowlist
|
||||
spec:
|
||||
ipAllowList:
|
||||
sourceRange:
|
||||
- 127.0.0.1/32
|
||||
- 192.168.1.0/24
|
||||
ipStrategy:
|
||||
excludedIPs:
|
||||
- 127.0.0.1/32
|
||||
|
@ -171,25 +203,44 @@ spec:
|
|||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Exclude from `X-Forwarded-For`
|
||||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourceRange=127.0.0.1/32, 192.168.1.0/24"
|
||||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-ipallowlist.ipallowlist.sourceRange=127.0.0.1/32, 192.168.1.0/24"
|
||||
"traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.excludedips": "127.0.0.1/32, 192.168.1.7"
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
# Exclude from `X-Forwarded-For`
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourceRange=127.0.0.1/32, 192.168.1.0/24"
|
||||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# Exclude from `X-Forwarded-For`
|
||||
http:
|
||||
middlewares:
|
||||
test-ipallowlist:
|
||||
ipAllowList:
|
||||
sourceRange:
|
||||
- 127.0.0.1/32
|
||||
- 192.168.1.0/24
|
||||
ipStrategy:
|
||||
excludedIPs:
|
||||
- "127.0.0.1/32"
|
||||
- "192.168.1.7"
|
||||
- 127.0.0.1/32
|
||||
- 192.168.1.7
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
# Exclude from `X-Forwarded-For`
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-ipallowlist.ipAllowList]
|
||||
sourceRange = ["127.0.0.1/32", "192.168.1.0/24"]
|
||||
[http.middlewares.test-ipallowlist.ipAllowList.ipStrategy]
|
||||
excludedIPs = ["127.0.0.1/32", "192.168.1.7"]
|
||||
```
|
||||
|
|
|
@ -10,7 +10,7 @@ Limiting Clients to Specific IPs
|
|||
|
||||
![IPWhiteList](../../assets/img/middleware/ipwhitelist.png)
|
||||
|
||||
IPWhiteList accepts / refuses requests based on the client IP.
|
||||
IPWhiteList limits allowed requests based on the client IP.
|
||||
|
||||
!!! warning
|
||||
|
||||
|
@ -63,6 +63,8 @@ http:
|
|||
|
||||
### `sourceRange`
|
||||
|
||||
_Required_
|
||||
|
||||
The `sourceRange` option sets the allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
||||
|
||||
### `ipStrategy`
|
||||
|
@ -158,6 +160,7 @@ http:
|
|||
```yaml tab="Docker"
|
||||
# Exclude from `X-Forwarded-For`
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourceRange=127.0.0.1/32, 192.168.1.0/24"
|
||||
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||
```
|
||||
|
||||
|
@ -170,6 +173,9 @@ metadata:
|
|||
spec:
|
||||
ipWhiteList:
|
||||
ipStrategy:
|
||||
sourceRange:
|
||||
- 127.0.0.1/32
|
||||
- 192.168.1.0/24
|
||||
excludedIPs:
|
||||
- 127.0.0.1/32
|
||||
- 192.168.1.7
|
||||
|
@ -177,6 +183,7 @@ spec:
|
|||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Exclude from `X-Forwarded-For`
|
||||
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourceRange=127.0.0.1/32, 192.168.1.0/24"
|
||||
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||
```
|
||||
|
||||
|
@ -186,16 +193,20 @@ http:
|
|||
middlewares:
|
||||
test-ipwhitelist:
|
||||
ipWhiteList:
|
||||
sourceRange:
|
||||
- 127.0.0.1/32
|
||||
- 192.168.1.0/24
|
||||
ipStrategy:
|
||||
excludedIPs:
|
||||
- "127.0.0.1/32"
|
||||
- "192.168.1.7"
|
||||
- 127.0.0.1/32
|
||||
- 192.168.1.7
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
# Exclude from `X-Forwarded-For`
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-ipwhitelist.ipWhiteList]
|
||||
sourceRange = ["127.0.0.1/32", "192.168.1.0/24"]
|
||||
[http.middlewares.test-ipwhitelist.ipWhiteList.ipStrategy]
|
||||
excludedIPs = ["127.0.0.1/32", "192.168.1.7"]
|
||||
```
|
||||
|
|
|
@ -8,7 +8,7 @@ description: "Learn how to use IPAllowList in TCP middleware for limiting client
|
|||
Limiting Clients to Specific IPs
|
||||
{: .subtitle }
|
||||
|
||||
IPAllowList accepts / refuses connections based on the client IP.
|
||||
IPAllowList limits allowed requests based on the client IP.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
|
|
|
@ -354,7 +354,7 @@ To apply a redirection:
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints=Name:web Address::80 Redirect.EntryPoint:websecure
|
||||
--entryPoints=Name:web Address::80 Redirect.EntryPoint:websecure
|
||||
--entryPoints='Name:websecure Address::443 TLS'
|
||||
```
|
||||
|
||||
|
@ -394,10 +394,10 @@ To apply a redirection:
|
|||
```bash tab="CLI"
|
||||
## static configuration
|
||||
|
||||
--entrypoints.web.address=:80
|
||||
--entrypoints.web.http.redirections.entrypoint.to=websecure
|
||||
--entrypoints.web.http.redirections.entrypoint.scheme=https
|
||||
--entrypoints.websecure.address=:443
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.web.http.redirections.entrypoint.to=websecure
|
||||
--entryPoints.web.http.redirections.entrypoint.scheme=https
|
||||
--entryPoints.websecure.address=:443
|
||||
--providers.docker=true
|
||||
```
|
||||
|
||||
|
@ -750,8 +750,8 @@ with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, yo
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.web.address=:80
|
||||
--entrypoints.websecure.address=:443
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.websecure.address=:443
|
||||
--certificatesresolvers.myresolver.acme.email=your-email@example.com
|
||||
--certificatesresolvers.myresolver.acme.storage=acme.json
|
||||
--certificatesresolvers.myresolver.acme.tlschallenge=true
|
||||
|
@ -1078,7 +1078,7 @@ To activate the dashboard, you can either:
|
|||
routers:
|
||||
api:
|
||||
rule: Host(`traefik.docker.localhost`)
|
||||
entrypoints:
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: api@internal
|
||||
middlewares:
|
||||
|
|
|
@ -724,7 +724,7 @@ Here are two possible transition strategies:
|
|||
|
||||
Please check the [OpenTelemetry Tracing provider documention](../observability/tracing/opentelemetry.md) for more information.
|
||||
|
||||
#### Internal Resources Observability (AccessLogs, Metrics and Tracing)
|
||||
#### Internal Resources Observability
|
||||
|
||||
In v3, observability for internal routers or services (e.g.: `ping@internal`) is disabled by default.
|
||||
To enable it one should use the new `addInternals` option for AccessLogs, Metrics or Tracing.
|
||||
|
@ -732,4 +732,4 @@ Please take a look at the observability documentation for more information:
|
|||
|
||||
- [AccessLogs](../observability/access-logs.md#addinternals)
|
||||
- [Metrics](../observability/metrics/overview.md#addinternals)
|
||||
- [AccessLogs](../observability/tracing/overview.md#addinternals)
|
||||
- [Tracing](../observability/tracing/overview.md#addinternals)
|
||||
|
|
|
@ -580,3 +580,63 @@ the maximum user-defined router priority value is:
|
|||
|
||||
- `(MaxInt32 - 1000)` for 32-bit platforms,
|
||||
- `(MaxInt64 - 1000)` for 64-bit platforms.
|
||||
|
||||
### EntryPoint.Transport.RespondingTimeouts.<Timeout>
|
||||
|
||||
Starting with `v2.11.1` the following timeout options are deprecated:
|
||||
|
||||
- `<entryPoint>.transport.respondingTimeouts.readTimeout`
|
||||
- `<entryPoint>.transport.respondingTimeouts.writeTimeout`
|
||||
- `<entryPoint>.transport.respondingTimeouts.idleTimeout`
|
||||
|
||||
They have been replaced by:
|
||||
|
||||
- `<entryPoint>.transport.respondingTimeouts.http.readTimeout`
|
||||
- `<entryPoint>.transport.respondingTimeouts.http.writeTimeout`
|
||||
- `<entryPoint>.transport.respondingTimeouts.http.idleTimeout`
|
||||
|
||||
### EntryPoint.Transport.RespondingTimeouts.TCP.LingeringTimeout
|
||||
|
||||
Starting with `v2.11.1` a new `lingeringTimeout` entryPoints option has been introduced, with a default value of 2s.
|
||||
|
||||
The lingering timeout defines the maximum duration between each TCP read operation on the connection.
|
||||
As a layer 4 timeout, it applies during HTTP handling but respects the configured HTTP server `readTimeout`.
|
||||
|
||||
This change avoids Traefik instances with the default configuration hanging while waiting for bytes to be read on the connection.
|
||||
|
||||
We suggest to adapt this value accordingly to your situation.
|
||||
The new default value is purposely narrowed and can close the connection too early.
|
||||
|
||||
Increasing the `lingeringTimeout` value could be the solution notably if you are dealing with the following errors:
|
||||
|
||||
- TCP: `Error while handling TCP connection: readfrom tcp X.X.X.X:X->X.X.X.X:X: read tcp X.X.X.X:X->X.X.X.X:X: i/o timeout`
|
||||
- HTTP: `'499 Client Closed Request' caused by: context canceled`
|
||||
- HTTP: `ReverseProxy read error during body copy: read tcp X.X.X.X:X->X.X.X.X:X: use of closed network connection`
|
||||
|
||||
## v2.11.2
|
||||
|
||||
### LingeringTimeout
|
||||
|
||||
Starting with `v2.11.2` the `<entrypoint>.transport.respondingTimeouts.tcp.lingeringTimeout` introduced in `v2.11.1` has been removed.
|
||||
|
||||
### RespondingTimeouts.TCP and RespondingTimeouts.HTTP
|
||||
|
||||
Starting with `v2.11.2` the `respondingTimeouts.tcp` and `respondingTimeouts.http` sections introduced in `v2.11.1` have been removed.
|
||||
To configure the responding timeouts, please use the [`respondingTimeouts`](../routing/entrypoints.md#respondingtimeouts) section.
|
||||
|
||||
### EntryPoint.Transport.RespondingTimeouts.ReadTimeout
|
||||
|
||||
Starting with `v2.11.2` the entryPoints [`readTimeout`](../routing/entrypoints.md#respondingtimeouts) option default value changed to 60 seconds.
|
||||
|
||||
For HTTP, this option defines the maximum duration for reading the entire request, including the body.
|
||||
For TCP, this option defines the maximum duration for the first bytes to be read on the connection.
|
||||
|
||||
The default value was previously set to zero, which means no timeout.
|
||||
|
||||
This change has been done to avoid Traefik instances with the default configuration to be hanging forever while waiting for bytes to be read on the connection.
|
||||
|
||||
Increasing the `readTimeout` value could be the solution notably if you are dealing with the following errors:
|
||||
|
||||
- TCP: `Error while handling TCP connection: readfrom tcp X.X.X.X:X->X.X.X.X:X: read tcp X.X.X.X:X->X.X.X.X:X: i/o timeout`
|
||||
- HTTP: `'499 Client Closed Request' caused by: context canceled`
|
||||
- HTTP: `ReverseProxy read error during body copy: read tcp X.X.X.X:X->X.X.X.X:X: use of closed network connection`
|
||||
|
|
|
@ -30,7 +30,7 @@ accessLog: {}
|
|||
|
||||
_Optional, Default="false"_
|
||||
|
||||
Enables accessLogs for internal resources.
|
||||
Enables accessLogs for internal resources (e.g.: `ping@internal`).
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
accesslog:
|
||||
|
|
|
@ -21,7 +21,7 @@ and [Kubernetes](https://grafana.com/grafana/dashboards/17347) deployments.
|
|||
|
||||
_Optional, Default="false"_
|
||||
|
||||
Enables metrics for internal resources.
|
||||
Enables metrics for internal resources (e.g.: `ping@internals`).
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
metrics:
|
||||
|
|
|
@ -36,7 +36,7 @@ tracing: {}
|
|||
|
||||
_Optional, Default="false"_
|
||||
|
||||
Enables tracing for internal resources.
|
||||
Enables tracing for internal resources (e.g.: `ping@internal`).
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
tracing:
|
||||
|
|
|
@ -212,6 +212,85 @@ providers:
|
|||
--providers.kubernetesgateway.namespaces=default,production
|
||||
```
|
||||
|
||||
### `statusAddress`
|
||||
|
||||
#### `ip`
|
||||
|
||||
_Optional, Default: ""_
|
||||
|
||||
This IP will get copied to the Gateway `status.addresses`, and currently only supports one IP value (IPv4 or IPv6).
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
kubernetesGateway:
|
||||
statusAddress:
|
||||
ip: "1.2.3.4"
|
||||
# ...
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesGateway.statusAddress]
|
||||
ip = "1.2.3.4"
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.kubernetesgateway.statusaddress.ip=1.2.3.4
|
||||
```
|
||||
|
||||
#### `hostname`
|
||||
|
||||
_Optional, Default: ""_
|
||||
|
||||
This Hostname will get copied to the Gateway `status.addresses`.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
kubernetesGateway:
|
||||
statusAddress:
|
||||
hostname: "example.net"
|
||||
# ...
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesGateway.statusAddress]
|
||||
hostname = "example.net"
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.kubernetesgateway.statusaddress.hostname=example.net
|
||||
```
|
||||
|
||||
#### `service`
|
||||
|
||||
_Optional_
|
||||
|
||||
The Kubernetes service to copy status addresses from.
|
||||
When using third parties tools like External-DNS, this option can be used to copy the service `loadbalancer.status` (containing the service's endpoints IPs) to the gateways.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
kubernetesGateway:
|
||||
statusAddress:
|
||||
service:
|
||||
namespace: default
|
||||
name: foo
|
||||
# ...
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesGateway.statusAddress.service]
|
||||
namespace = "default"
|
||||
name = "foo"
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.kubernetesgateway.statusaddress.service.namespace=default
|
||||
--providers.kubernetesgateway.statusaddress.service.name=foo
|
||||
```
|
||||
|
||||
### `experimentalChannel`
|
||||
|
||||
_Optional, Default: false_
|
||||
|
|
|
@ -163,6 +163,7 @@ providers:
|
|||
_Optional, Default=""_
|
||||
|
||||
Token is used to provide a per-request ACL token, if Nomad ACLs are enabled.
|
||||
The appropriate ACL privilege for this token is 'read-job', as outlined in the [Nomad documentation on ACL](https://developer.hashicorp.com/nomad/tutorials/access-control/access-control-policies).
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
|
@ -511,3 +512,27 @@ providers:
|
|||
--providers.nomad.namespaces=ns1,ns2
|
||||
# ...
|
||||
```
|
||||
|
||||
### `allowEmptyServices`
|
||||
|
||||
_Optional, Default: false_
|
||||
|
||||
If the parameter is set to `true`,
|
||||
it allows the creation of an empty [servers load balancer](../routing/services/index.md#servers-load-balancer) if the targeted Nomad service has no endpoints available. This results in a `503` HTTP response instead of a `404`.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
nomad:
|
||||
allowEmptyServices: true
|
||||
# ...
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.nomad]
|
||||
allowEmptyServices = true
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.nomad.allowEmptyServices=true
|
||||
```
|
||||
|
|
|
@ -835,6 +835,10 @@ spec:
|
|||
breaker will try to recover (as soon as it is in recovering
|
||||
state).
|
||||
x-kubernetes-int-or-string: true
|
||||
responseCode:
|
||||
description: ResponseCode is the status code that the circuit
|
||||
breaker will return while it is in the open state.
|
||||
type: integer
|
||||
type: object
|
||||
compress:
|
||||
description: |-
|
||||
|
@ -1331,7 +1335,7 @@ spec:
|
|||
ipAllowList:
|
||||
description: |-
|
||||
IPAllowList holds the IP allowlist middleware configuration.
|
||||
This middleware accepts / refuses requests based on the client IP.
|
||||
This middleware limits allowed requests based on the client IP.
|
||||
More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/ipallowlist/
|
||||
properties:
|
||||
ipStrategy:
|
||||
|
@ -1385,7 +1389,7 @@ spec:
|
|||
type: object
|
||||
sourceRange:
|
||||
description: SourceRange defines the set of allowed IPs (or ranges
|
||||
of allowed IPs by using CIDR notation).
|
||||
of allowed IPs by using CIDR notation). Required.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
|
|
|
@ -27,8 +27,8 @@ spec:
|
|||
- name: traefik
|
||||
image: traefik:v3.0
|
||||
args:
|
||||
- --entrypoints.web.address=:80
|
||||
- --entrypoints.websecure.address=:443
|
||||
- --entryPoints.web.address=:80
|
||||
- --entryPoints.websecure.address=:443
|
||||
- --experimental.kubernetesgateway
|
||||
- --providers.kubernetesgateway
|
||||
|
||||
|
|
|
@ -172,6 +172,10 @@ spec:
|
|||
breaker will try to recover (as soon as it is in recovering
|
||||
state).
|
||||
x-kubernetes-int-or-string: true
|
||||
responseCode:
|
||||
description: ResponseCode is the status code that the circuit
|
||||
breaker will return while it is in the open state.
|
||||
type: integer
|
||||
type: object
|
||||
compress:
|
||||
description: |-
|
||||
|
@ -668,7 +672,7 @@ spec:
|
|||
ipAllowList:
|
||||
description: |-
|
||||
IPAllowList holds the IP allowlist middleware configuration.
|
||||
This middleware accepts / refuses requests based on the client IP.
|
||||
This middleware limits allowed requests based on the client IP.
|
||||
More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/ipallowlist/
|
||||
properties:
|
||||
ipStrategy:
|
||||
|
@ -722,7 +726,7 @@ spec:
|
|||
type: object
|
||||
sourceRange:
|
||||
description: SourceRange defines the set of allowed IPs (or ranges
|
||||
of allowed IPs by using CIDR notation).
|
||||
of allowed IPs by using CIDR notation). Required.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
|
|
|
@ -202,7 +202,7 @@ Duration to keep accepting requests before Traefik initiates the graceful shutdo
|
|||
IdleTimeout is the maximum amount duration an idle (keep-alive) connection will remain idle before closing itself. If zero, no timeout is set. (Default: ```180```)
|
||||
|
||||
`--entrypoints.<name>.transport.respondingtimeouts.readtimeout`:
|
||||
ReadTimeout is the maximum duration for reading the entire request, including the body. If zero, no timeout is set. (Default: ```0```)
|
||||
ReadTimeout is the maximum duration for reading the entire request, including the body. If zero, no timeout is set. (Default: ```60```)
|
||||
|
||||
`--entrypoints.<name>.transport.respondingtimeouts.writetimeout`:
|
||||
WriteTimeout is the maximum duration before timing out writes of the response. If zero, no timeout is set. (Default: ```0```)
|
||||
|
@ -738,6 +738,21 @@ Kubernetes label selector to select specific GatewayClasses.
|
|||
`--providers.kubernetesgateway.namespaces`:
|
||||
Kubernetes namespaces.
|
||||
|
||||
`--providers.kubernetesgateway.statusaddress.hostname`:
|
||||
Hostname used for Kubernetes Gateway status address.
|
||||
|
||||
`--providers.kubernetesgateway.statusaddress.ip`:
|
||||
IP used to set Kubernetes Gateway status address.
|
||||
|
||||
`--providers.kubernetesgateway.statusaddress.service`:
|
||||
Published Kubernetes Service to copy status addresses from.
|
||||
|
||||
`--providers.kubernetesgateway.statusaddress.service.name`:
|
||||
Name of the Kubernetes service.
|
||||
|
||||
`--providers.kubernetesgateway.statusaddress.service.namespace`:
|
||||
Namespace of the Kubernetes service.
|
||||
|
||||
`--providers.kubernetesgateway.throttleduration`:
|
||||
Kubernetes refresh throttle duration (Default: ```0```)
|
||||
|
||||
|
@ -789,6 +804,9 @@ Kubernetes bearer token (not needed for in-cluster client). It accepts either a
|
|||
`--providers.nomad`:
|
||||
Enable Nomad backend with default settings. (Default: ```false```)
|
||||
|
||||
`--providers.nomad.allowemptyservices`:
|
||||
Allow the creation of services without endpoints. (Default: ```false```)
|
||||
|
||||
`--providers.nomad.constraints`:
|
||||
Constraints is an expression that Traefik matches against the Nomad service's tags to determine whether to create route(s) for that service.
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ Duration to keep accepting requests before Traefik initiates the graceful shutdo
|
|||
IdleTimeout is the maximum amount duration an idle (keep-alive) connection will remain idle before closing itself. If zero, no timeout is set. (Default: ```180```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_TRANSPORT_RESPONDINGTIMEOUTS_READTIMEOUT`:
|
||||
ReadTimeout is the maximum duration for reading the entire request, including the body. If zero, no timeout is set. (Default: ```0```)
|
||||
ReadTimeout is the maximum duration for reading the entire request, including the body. If zero, no timeout is set. (Default: ```60```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_TRANSPORT_RESPONDINGTIMEOUTS_WRITETIMEOUT`:
|
||||
WriteTimeout is the maximum duration before timing out writes of the response. If zero, no timeout is set. (Default: ```0```)
|
||||
|
@ -738,6 +738,21 @@ Kubernetes label selector to select specific GatewayClasses.
|
|||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_NAMESPACES`:
|
||||
Kubernetes namespaces.
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_STATUSADDRESS_HOSTNAME`:
|
||||
Hostname used for Kubernetes Gateway status address.
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_STATUSADDRESS_IP`:
|
||||
IP used to set Kubernetes Gateway status address.
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_STATUSADDRESS_SERVICE`:
|
||||
Published Kubernetes Service to copy status addresses from.
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_STATUSADDRESS_SERVICE_NAME`:
|
||||
Name of the Kubernetes service.
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_STATUSADDRESS_SERVICE_NAMESPACE`:
|
||||
Namespace of the Kubernetes service.
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESGATEWAY_THROTTLEDURATION`:
|
||||
Kubernetes refresh throttle duration (Default: ```0```)
|
||||
|
||||
|
@ -789,6 +804,9 @@ Kubernetes bearer token (not needed for in-cluster client). It accepts either a
|
|||
`TRAEFIK_PROVIDERS_NOMAD`:
|
||||
Enable Nomad backend with default settings. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_NOMAD_ALLOWEMPTYSERVICES`:
|
||||
Allow the creation of services without endpoints. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_NOMAD_CONSTRAINTS`:
|
||||
Constraints is an expression that Traefik matches against the Nomad service's tags to determine whether to create route(s) for that service.
|
||||
|
||||
|
|
|
@ -147,6 +147,12 @@
|
|||
labelSelector = "foobar"
|
||||
throttleDuration = "42s"
|
||||
experimentalChannel = true
|
||||
[providers.kubernetesGateway.statusAddress]
|
||||
ip = "foobar"
|
||||
hostname = "foobar"
|
||||
[providers.kubernetesGateway.statusAddress.service]
|
||||
name = "foobar"
|
||||
namespace = "foobar"
|
||||
[providers.rest]
|
||||
insecure = true
|
||||
[providers.consulCatalog]
|
||||
|
@ -185,6 +191,7 @@
|
|||
stale = true
|
||||
exposedByDefault = true
|
||||
refreshInterval = "42s"
|
||||
allowEmptyServices = true
|
||||
namespaces = ["foobar", "foobar"]
|
||||
[providers.nomad.endpoint]
|
||||
address = "foobar"
|
||||
|
|
|
@ -164,6 +164,12 @@ providers:
|
|||
labelSelector: foobar
|
||||
throttleDuration: 42s
|
||||
experimentalChannel: true
|
||||
statusAddress:
|
||||
ip: foobar
|
||||
hostname: foobar
|
||||
service:
|
||||
name: foobar
|
||||
namespace: foobar
|
||||
rest:
|
||||
insecure: true
|
||||
consulCatalog:
|
||||
|
@ -216,6 +222,7 @@ providers:
|
|||
stale: true
|
||||
exposedByDefault: true
|
||||
refreshInterval: 42s
|
||||
allowEmptyServices: true
|
||||
namespaces:
|
||||
- foobar
|
||||
- foobar
|
||||
|
|
|
@ -227,8 +227,8 @@ If both TCP and UDP are wanted for the same port, two entryPoints definitions ar
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.specificIPv4.address=192.168.2.7:8888
|
||||
--entrypoints.specificIPv6.address=[2001:db8::1]:8888
|
||||
--entryPoints.specificIPv4.address=192.168.2.7:8888
|
||||
--entryPoints.specificIPv6.address=[2001:db8::1]:8888
|
||||
```
|
||||
|
||||
Full details for how to specify `address` can be found in [net.Listen](https://golang.org/pkg/net/#Listen) (and [net.Dial](https://golang.org/pkg/net/#Dial)) of the doc for go.
|
||||
|
@ -270,8 +270,8 @@ reloading the static configuration without any service downtime.
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.web.address=:80
|
||||
--entrypoints.web.reusePort=true
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.web.reusePort=true
|
||||
```
|
||||
|
||||
Now it is possible to run multiple Traefik processes with the same EntryPoint configuration.
|
||||
|
@ -298,10 +298,10 @@ reloading the static configuration without any service downtime.
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.web.address=:80
|
||||
--entrypoints.web.reusePort=true
|
||||
--entrypoints.privateWeb.address=192.168.1.2:80
|
||||
--entrypoints.privateWeb.reusePort=true
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.web.reusePort=true
|
||||
--entryPoints.privateWeb.address=192.168.1.2:80
|
||||
--entryPoints.privateWeb.reusePort=true
|
||||
```
|
||||
|
||||
Requests to `192.168.1.2:80` will only be handled by routers that have `privateWeb` as the entry point.
|
||||
|
@ -349,9 +349,9 @@ EntryPoints in this list are used (by default) on HTTP and TCP routers that do n
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.web.address=:80
|
||||
--entrypoints.websecure.address=:443
|
||||
--entrypoints.websecure.asDefault=true
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.websecure.asDefault=true
|
||||
```
|
||||
|
||||
### HTTP/2
|
||||
|
@ -401,7 +401,7 @@ entryPoints:
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.name.http3
|
||||
--entryPoints.name.http3
|
||||
```
|
||||
|
||||
??? info "HTTP/3 uses UDP+TLS"
|
||||
|
@ -433,7 +433,7 @@ It can be used to override the authority in the `alt-svc` header, for example if
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.name.http3.advertisedport=443
|
||||
--entryPoints.name.http3.advertisedport=443
|
||||
```
|
||||
|
||||
### Forwarded Headers
|
||||
|
@ -509,13 +509,14 @@ Setting them has no effect for UDP entryPoints.
|
|||
|
||||
??? info "`transport.respondingTimeouts.readTimeout`"
|
||||
|
||||
_Optional, Default=0s_
|
||||
_Optional, Default=60s_
|
||||
|
||||
`readTimeout` is the maximum duration for reading the entire request, including the body.
|
||||
|
||||
If zero, no timeout exists.
|
||||
Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).
|
||||
If no units are provided, the value is parsed assuming seconds.
|
||||
We strongly suggest to adapt this value accordingly to the your needs.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Static configuration
|
||||
|
@ -869,10 +870,10 @@ This whole section is dedicated to options, keyed by entry point, that will appl
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.web.address=:80
|
||||
--entrypoints.web.http.redirections.entryPoint.to=websecure
|
||||
--entrypoints.web.http.redirections.entryPoint.scheme=https
|
||||
--entrypoints.websecure.address=:443
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.web.http.redirections.entryPoint.to=websecure
|
||||
--entryPoints.web.http.redirections.entryPoint.scheme=https
|
||||
--entryPoints.websecure.address=:443
|
||||
```
|
||||
|
||||
#### `entryPoint`
|
||||
|
@ -907,7 +908,7 @@ This section is a convenience to enable (permanent) redirecting of all incoming
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.foo.http.redirections.entryPoint.to=websecure
|
||||
--entryPoints.foo.http.redirections.entryPoint.to=websecure
|
||||
```
|
||||
|
||||
??? info "`entryPoint.scheme`"
|
||||
|
@ -937,7 +938,7 @@ This section is a convenience to enable (permanent) redirecting of all incoming
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.foo.http.redirections.entryPoint.scheme=https
|
||||
--entryPoints.foo.http.redirections.entryPoint.scheme=https
|
||||
```
|
||||
|
||||
??? info "`entryPoint.permanent`"
|
||||
|
@ -967,7 +968,7 @@ This section is a convenience to enable (permanent) redirecting of all incoming
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.foo.http.redirections.entrypoint.permanent=true
|
||||
--entryPoints.foo.http.redirections.entrypoint.permanent=true
|
||||
```
|
||||
|
||||
??? info "`entryPoint.priority`"
|
||||
|
@ -997,7 +998,7 @@ This section is a convenience to enable (permanent) redirecting of all incoming
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.foo.http.redirections.entrypoint.priority=10
|
||||
--entryPoints.foo.http.redirections.entrypoint.priority=10
|
||||
```
|
||||
|
||||
### EncodeQuerySemicolons
|
||||
|
@ -1025,8 +1026,8 @@ entryPoints:
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.websecure.address=:443
|
||||
--entrypoints.websecure.http.encodequerysemicolons=true
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.websecure.http.encodequerysemicolons=true
|
||||
```
|
||||
|
||||
#### Examples
|
||||
|
@ -1061,8 +1062,8 @@ entryPoints:
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.websecure.address=:443
|
||||
--entrypoints.websecure.http.middlewares=auth@file,strip@file
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.websecure.http.middlewares=auth@file,strip@file
|
||||
```
|
||||
|
||||
### TLS
|
||||
|
@ -1108,13 +1109,13 @@ entryPoints:
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.websecure.address=:443
|
||||
--entrypoints.websecure.http.tls.options=foobar
|
||||
--entrypoints.websecure.http.tls.certResolver=leresolver
|
||||
--entrypoints.websecure.http.tls.domains[0].main=example.com
|
||||
--entrypoints.websecure.http.tls.domains[0].sans=foo.example.com,bar.example.com
|
||||
--entrypoints.websecure.http.tls.domains[1].main=test.com
|
||||
--entrypoints.websecure.http.tls.domains[1].sans=foo.test.com,bar.test.com
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.websecure.http.tls.options=foobar
|
||||
--entryPoints.websecure.http.tls.certResolver=leresolver
|
||||
--entryPoints.websecure.http.tls.domains[0].main=example.com
|
||||
--entryPoints.websecure.http.tls.domains[0].sans=foo.example.com,bar.example.com
|
||||
--entryPoints.websecure.http.tls.domains[1].main=test.com
|
||||
--entryPoints.websecure.http.tls.domains[1].sans=foo.test.com,bar.test.com
|
||||
```
|
||||
|
||||
??? example "Let's Encrypt"
|
||||
|
@ -1137,8 +1138,8 @@ entryPoints:
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entrypoints.websecure.address=:443
|
||||
--entrypoints.websecure.http.tls.certResolver=leresolver
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.websecure.http.tls.certResolver=leresolver
|
||||
```
|
||||
|
||||
## UDP Options
|
||||
|
@ -1169,8 +1170,8 @@ entryPoints:
|
|||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
entrypoints.foo.address=:8000/udp
|
||||
entrypoints.foo.udp.timeout=10s
|
||||
--entryPoints.foo.address=:8000/udp
|
||||
--entryPoints.foo.udp.timeout=10s
|
||||
```
|
||||
|
||||
{!traefik-for-business-applications.md!}
|
||||
|
|
|
@ -53,9 +53,9 @@ The Kubernetes Ingress Controller, The Custom Resource Way.
|
|||
- --log.level=DEBUG
|
||||
- --api
|
||||
- --api.insecure
|
||||
- --entrypoints.web.address=:80
|
||||
- --entrypoints.tcpep.address=:8000
|
||||
- --entrypoints.udpep.address=:9000/udp
|
||||
- --entryPoints.web.address=:80
|
||||
- --entryPoints.tcpep.address=:8000
|
||||
- --entryPoints.udpep.address=:9000/udp
|
||||
- --providers.kubernetescrd
|
||||
ports:
|
||||
- name: web
|
||||
|
|
|
@ -234,7 +234,7 @@ Kubernetes cluster before creating `HTTPRoute` objects.
|
|||
- headers: # [11]
|
||||
name: foo # [12]
|
||||
value: bar # [13]
|
||||
- backendRefs: # [14]
|
||||
backendRefs: # [14]
|
||||
- name: whoamitcp # [15]
|
||||
weight: 1 # [16]
|
||||
port: 8080 # [17]
|
||||
|
@ -251,10 +251,20 @@ Kubernetes cluster before creating `HTTPRoute` objects.
|
|||
requestRedirect: # [27]
|
||||
scheme: https # [28]
|
||||
statusCode: 301 # [29]
|
||||
- type: RequestHeaderModifier # [30]
|
||||
requestHeaderModifier: # [31]
|
||||
set:
|
||||
- name: X-Foo
|
||||
value: Bar
|
||||
add:
|
||||
- name: X-Bar
|
||||
value: Foo
|
||||
remove:
|
||||
- X-Baz
|
||||
```
|
||||
|
||||
| Ref | Attribute | Description |
|
||||
|------|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|------|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [1] | `parentRefs` | References the resources (usually Gateways) that a Route wants to be attached to. |
|
||||
| [2] | `name` | Name of the referent. |
|
||||
| [3] | `namespace` | Namespace of the referent. When unspecified (or empty string), this refers to the local namespace of the Route. |
|
||||
|
@ -263,7 +273,7 @@ Kubernetes cluster before creating `HTTPRoute` objects.
|
|||
| [6] | `rules` | A list of HTTP matchers, filters and actions. |
|
||||
| [7] | `matches` | Conditions used for matching the rule against incoming HTTP requests. Each match is independent, i.e. this rule will be matched if **any** one of the matches is satisfied. |
|
||||
| [8] | `path` | An HTTP request path matcher. If this field is not specified, a default prefix match on the "/" path is provided. |
|
||||
| [9] | `type` | Type of match against the path Value (supported types: `Exact`, `Prefix`). |
|
||||
| [9] | `type` | Type of match against the path Value (supported types: `Exact`, `PathPrefix`). |
|
||||
| [10] | `value` | The value of the HTTP path to match against. |
|
||||
| [11] | `headers` | Conditions to select a HTTP route by matching HTTP request headers. |
|
||||
| [12] | `name` | Name of the HTTP header to be matched. |
|
||||
|
@ -284,6 +294,8 @@ Kubernetes cluster before creating `HTTPRoute` objects.
|
|||
| [27] | `requestRedirect` | Configuration of redirect filter. |
|
||||
| [28] | `scheme` | Scheme is the scheme to be used in the value of the Location header in the response. |
|
||||
| [29] | `statusCode` | StatusCode is the HTTP status code to be used in response. |
|
||||
| [30] | `type` | Defines the type of filter; RequestHeaderModifier modifies request headers. |
|
||||
| [31] | `requestHeaderModifier` | Configuration of RequestHeaderModifier filter. |
|
||||
|
||||
### Kind: `TCPRoute`
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ which in turn will create the resulting routers, services, handlers, etc.
|
|||
- name: traefik
|
||||
image: traefik:v3.0
|
||||
args:
|
||||
- --entrypoints.web.address=:80
|
||||
- --entryPoints.web.address=:80
|
||||
- --providers.kubernetesingress
|
||||
ports:
|
||||
- name: web
|
||||
|
@ -391,8 +391,8 @@ TLS can be enabled through the [HTTP options](../entrypoints.md#tls) of an Entry
|
|||
|
||||
```bash tab="CLI"
|
||||
# Static configuration
|
||||
--entrypoints.websecure.address=:443
|
||||
--entrypoints.websecure.http.tls
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.websecure.http.tls
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
|
@ -524,8 +524,8 @@ This way, any Ingress attached to this Entrypoint will have TLS termination by d
|
|||
- name: traefik
|
||||
image: traefik:v3.0
|
||||
args:
|
||||
- --entrypoints.websecure.address=:443
|
||||
- --entrypoints.websecure.http.tls
|
||||
- --entryPoints.websecure.address=:443
|
||||
- --entryPoints.websecure.http.tls
|
||||
- --providers.kubernetesingress
|
||||
ports:
|
||||
- name: websecure
|
||||
|
@ -710,7 +710,7 @@ For more options, please refer to the available [annotations](#on-ingress).
|
|||
- name: traefik
|
||||
image: traefik:v3.0
|
||||
args:
|
||||
- --entrypoints.websecure.address=:443
|
||||
- --entryPoints.websecure.address=:443
|
||||
- --providers.kubernetesingress
|
||||
ports:
|
||||
- name: websecure
|
||||
|
|
|
@ -146,9 +146,9 @@ If you want to limit the router scope to a set of entry points, set the `entryPo
|
|||
|
||||
```bash tab="CLI"
|
||||
## Static configuration
|
||||
--entrypoints.web.address=:80
|
||||
--entrypoints.websecure.address=:443
|
||||
--entrypoints.other.address=:9090
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.other.address=:9090
|
||||
```
|
||||
|
||||
??? example "Listens to Specific EntryPoints"
|
||||
|
@ -204,9 +204,9 @@ If you want to limit the router scope to a set of entry points, set the `entryPo
|
|||
|
||||
```bash tab="CLI"
|
||||
## Static configuration
|
||||
--entrypoints.web.address=:80
|
||||
--entrypoints.websecure.address=:443
|
||||
--entrypoints.other.address=:9090
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.other.address=:9090
|
||||
```
|
||||
|
||||
### Rule
|
||||
|
@ -959,9 +959,9 @@ If you want to limit the router scope to a set of entry points, set the entry po
|
|||
|
||||
```bash tab="CLI"
|
||||
## Static configuration
|
||||
--entrypoints.web.address=:80
|
||||
--entrypoints.websecure.address=:443
|
||||
--entrypoints.other.address=:9090
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.other.address=:9090
|
||||
```
|
||||
|
||||
??? example "Listens to Specific EntryPoints"
|
||||
|
@ -1023,9 +1023,9 @@ If you want to limit the router scope to a set of entry points, set the entry po
|
|||
|
||||
```bash tab="CLI"
|
||||
## Static configuration
|
||||
--entrypoints.web.address=:80
|
||||
--entrypoints.websecure.address=:443
|
||||
--entrypoints.other.address=:9090
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.other.address=:9090
|
||||
```
|
||||
|
||||
### Rule
|
||||
|
@ -1610,9 +1610,9 @@ If one wants to limit the router scope to a set of EntryPoints, one should set t
|
|||
|
||||
```bash tab="CLI"
|
||||
## Static configuration
|
||||
--entrypoints.web.address=":80"
|
||||
--entrypoints.other.address=":9090/udp"
|
||||
--entrypoints.streaming.address=":9191/udp"
|
||||
--entryPoints.web.address=":80"
|
||||
--entryPoints.other.address=":9090/udp"
|
||||
--entryPoints.streaming.address=":9191/udp"
|
||||
```
|
||||
|
||||
??? example "Listens to Specific EntryPoints"
|
||||
|
@ -1667,9 +1667,9 @@ If one wants to limit the router scope to a set of EntryPoints, one should set t
|
|||
|
||||
```bash tab="CLI"
|
||||
## Static configuration
|
||||
--entrypoints.web.address=":80"
|
||||
--entrypoints.other.address=":9090/udp"
|
||||
--entrypoints.streaming.address=":9191/udp"
|
||||
--entryPoints.web.address=":80"
|
||||
--entryPoints.other.address=":9090/udp"
|
||||
--entryPoints.streaming.address=":9191/udp"
|
||||
```
|
||||
|
||||
### Services
|
||||
|
|
|
@ -30,8 +30,8 @@ spec:
|
|||
args:
|
||||
- --api.insecure
|
||||
- --accesslog
|
||||
- --entrypoints.web.Address=:8000
|
||||
- --entrypoints.websecure.Address=:4443
|
||||
- --entryPoints.web.Address=:8000
|
||||
- --entryPoints.websecure.Address=:4443
|
||||
- --providers.kubernetescrd
|
||||
- --certificatesresolvers.myresolver.acme.tlschallenge
|
||||
- --certificatesresolvers.myresolver.acme.email=foo@you.com
|
||||
|
|
|
@ -10,8 +10,8 @@ services:
|
|||
- "--api.insecure=true"
|
||||
- "--providers.docker=true"
|
||||
- "--providers.docker.exposedbydefault=false"
|
||||
- "--entrypoints.web.address=:80"
|
||||
- "--entrypoints.websecure.address=:443"
|
||||
- "--entryPoints.web.address=:80"
|
||||
- "--entryPoints.websecure.address=:443"
|
||||
- "--certificatesresolvers.myresolver.acme.dnschallenge=true"
|
||||
- "--certificatesresolvers.myresolver.acme.dnschallenge.provider=ovh"
|
||||
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
|
|
|
@ -20,8 +20,8 @@ services:
|
|||
- "--api.insecure=true"
|
||||
- "--providers.docker=true"
|
||||
- "--providers.docker.exposedbydefault=false"
|
||||
- "--entrypoints.web.address=:80"
|
||||
- "--entrypoints.websecure.address=:443"
|
||||
- "--entryPoints.web.address=:80"
|
||||
- "--entryPoints.websecure.address=:443"
|
||||
- "--certificatesresolvers.myresolver.acme.dnschallenge=true"
|
||||
- "--certificatesresolvers.myresolver.acme.dnschallenge.provider=ovh"
|
||||
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
|
|
|
@ -64,7 +64,7 @@ What changed between the initial setup:
|
|||
```yaml
|
||||
command:
|
||||
# Traefik will listen to incoming request on the port 443 (https)
|
||||
- "--entrypoints.websecure.address=:443"
|
||||
- "--entryPoints.websecure.address=:443"
|
||||
ports:
|
||||
- "443:443"
|
||||
```
|
||||
|
|
|
@ -10,8 +10,8 @@ services:
|
|||
- "--api.insecure=true"
|
||||
- "--providers.docker=true"
|
||||
- "--providers.docker.exposedbydefault=false"
|
||||
- "--entrypoints.web.address=:80"
|
||||
- "--entrypoints.websecure.address=:443"
|
||||
- "--entryPoints.web.address=:80"
|
||||
- "--entryPoints.websecure.address=:443"
|
||||
- "--certificatesresolvers.myresolver.acme.httpchallenge=true"
|
||||
- "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
|
||||
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
|
|
|
@ -50,7 +50,7 @@ What changed between the basic example:
|
|||
```yaml
|
||||
command:
|
||||
# Traefik will listen to incoming request on the port 443 (https)
|
||||
- "--entrypoints.websecure.address=:443"
|
||||
- "--entryPoints.websecure.address=:443"
|
||||
ports:
|
||||
- "443:443"
|
||||
```
|
||||
|
|
|
@ -10,7 +10,7 @@ services:
|
|||
- "--api.insecure=true"
|
||||
- "--providers.docker=true"
|
||||
- "--providers.docker.exposedbydefault=false"
|
||||
- "--entrypoints.websecure.address=:443"
|
||||
- "--entryPoints.websecure.address=:443"
|
||||
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
|
||||
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
- "--certificatesresolvers.myresolver.acme.email=postmaster@example.com"
|
||||
|
|
|
@ -50,7 +50,7 @@ What changed between the basic example:
|
|||
```yaml
|
||||
command:
|
||||
# Traefik will listen to incoming request on the port 443 (https)
|
||||
- "--entrypoints.websecure.address=:443"
|
||||
- "--entryPoints.websecure.address=:443"
|
||||
ports:
|
||||
- "443:443"
|
||||
```
|
||||
|
|
|
@ -10,7 +10,7 @@ services:
|
|||
- "--api.insecure=true"
|
||||
- "--providers.docker=true"
|
||||
- "--providers.docker.exposedbydefault=false"
|
||||
- "--entrypoints.web.address=:80"
|
||||
- "--entryPoints.web.address=:80"
|
||||
ports:
|
||||
- "80:80"
|
||||
- "8080:8080"
|
||||
|
|
|
@ -86,7 +86,7 @@ Second, you define an entry point, along with the exposure of the matching port
|
|||
```yaml
|
||||
command:
|
||||
# Traefik will listen to incoming request on the port 80 (HTTP)
|
||||
- "--entrypoints.web.address=:80"
|
||||
- "--entryPoints.web.address=:80"
|
||||
|
||||
ports:
|
||||
- "80:80"
|
||||
|
|
61
go.mod
61
go.mod
|
@ -12,9 +12,9 @@ require (
|
|||
github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd
|
||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
|
||||
github.com/docker/cli v24.0.7+incompatible
|
||||
github.com/docker/docker v24.0.7+incompatible
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/docker/cli v24.0.9+incompatible
|
||||
github.com/docker/docker v25.0.5+incompatible
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/fatih/structs v1.1.0
|
||||
github.com/fsnotify/fsnotify v1.7.0
|
||||
github.com/go-acme/lego/v4 v4.16.1
|
||||
|
@ -49,14 +49,15 @@ require (
|
|||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
|
||||
github.com/prometheus/client_golang v1.17.0
|
||||
github.com/prometheus/client_model v0.5.0
|
||||
github.com/quic-go/quic-go v0.40.1
|
||||
github.com/quic-go/quic-go v0.42.0
|
||||
github.com/rs/zerolog v1.29.0
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spiffe/go-spiffe/v2 v2.1.1
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154
|
||||
github.com/tailscale/tscert v0.0.0-20220316030059-54bbcb9f74e2
|
||||
github.com/testcontainers/testcontainers-go v0.27.0
|
||||
github.com/testcontainers/testcontainers-go v0.30.0
|
||||
github.com/testcontainers/testcontainers-go/modules/k3s v0.30.0
|
||||
github.com/tetratelabs/wazero v1.5.0
|
||||
github.com/tidwall/gjson v1.17.0
|
||||
github.com/traefik/grpc-web v0.16.0
|
||||
|
@ -79,18 +80,18 @@ require (
|
|||
go.opentelemetry.io/otel/sdk/metric v1.24.0
|
||||
go.opentelemetry.io/otel/trace v1.24.0
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
|
||||
golang.org/x/mod v0.14.0
|
||||
golang.org/x/net v0.20.0
|
||||
golang.org/x/sys v0.17.0
|
||||
golang.org/x/mod v0.17.0
|
||||
golang.org/x/net v0.24.0
|
||||
golang.org/x/sys v0.19.0
|
||||
golang.org/x/text v0.14.0
|
||||
golang.org/x/time v0.5.0
|
||||
golang.org/x/tools v0.17.0
|
||||
golang.org/x/tools v0.20.0
|
||||
google.golang.org/grpc v1.61.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/api v0.28.4
|
||||
k8s.io/api v0.29.2
|
||||
k8s.io/apiextensions-apiserver v0.28.3
|
||||
k8s.io/apimachinery v0.28.4
|
||||
k8s.io/client-go v0.28.4
|
||||
k8s.io/apimachinery v0.29.2
|
||||
k8s.io/client-go v0.29.2
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
|
||||
mvdan.cc/xurls/v2 v2.5.0
|
||||
sigs.k8s.io/controller-runtime v0.16.3
|
||||
|
@ -151,7 +152,7 @@ require (
|
|||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/civo/civogo v0.3.11 // indirect
|
||||
github.com/cloudflare/cloudflare-go v0.86.0 // indirect
|
||||
github.com/containerd/containerd v1.7.11 // indirect
|
||||
github.com/containerd/containerd v1.7.12 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
|
@ -161,14 +162,15 @@ require (
|
|||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dimchansky/utfbom v1.1.1 // indirect
|
||||
github.com/distribution/reference v0.5.0 // indirect
|
||||
github.com/dnsimple/dnsimple-go v1.2.0 // indirect
|
||||
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.7.0 // indirect
|
||||
github.com/exoscale/egoscale v0.102.3 // indirect
|
||||
github.com/fatih/color v1.15.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/gin-gonic/gin v1.9.1 // indirect
|
||||
github.com/go-errors/errors v1.0.1 // indirect
|
||||
|
@ -176,6 +178,7 @@ require (
|
|||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-logr/zapr v1.2.4 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.20.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
|
@ -196,7 +199,7 @@ require (
|
|||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect
|
||||
github.com/google/s2a-go v0.1.7 // indirect
|
||||
github.com/google/uuid v1.4.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
||||
github.com/gophercloud/gophercloud v1.0.0 // indirect
|
||||
|
@ -244,11 +247,13 @@ require (
|
|||
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||
github.com/moby/spdystream v0.2.0 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/moby/sys/user v0.1.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 // indirect
|
||||
github.com/nrdcg/auroradns v1.1.0 // indirect
|
||||
github.com/nrdcg/bunny-go v0.0.0-20230728143221-c9dda82568d9 // indirect
|
||||
|
@ -262,10 +267,9 @@ require (
|
|||
github.com/nrdcg/porkbun v0.3.0 // indirect
|
||||
github.com/nzdjb/go-metaname v1.0.0 // indirect
|
||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.11.0 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.17.1 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
|
||||
github.com/opencontainers/runc v1.1.7 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect
|
||||
github.com/ovh/go-ovh v1.4.3 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
|
||||
|
@ -276,7 +280,6 @@ require (
|
|||
github.com/prometheus/common v0.45.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
|
||||
github.com/redis/go-redis/v9 v9.2.1 // indirect
|
||||
github.com/rs/cors v1.7.0 // indirect
|
||||
github.com/sacloud/api-client-go v0.2.8 // indirect
|
||||
|
@ -284,7 +287,7 @@ require (
|
|||
github.com/sacloud/iaas-api-go v1.11.1 // indirect
|
||||
github.com/sacloud/packages-go v0.0.9 // indirect
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.22 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.23.11 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.23.12 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/shopspring/decimal v1.2.0 // indirect
|
||||
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect
|
||||
|
@ -292,7 +295,7 @@ require (
|
|||
github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stretchr/objx v0.5.1 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.490 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
|
@ -311,37 +314,39 @@ require (
|
|||
go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.9 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/aws v1.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/ot v1.24.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.1.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/mock v0.3.0 // indirect
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/ratelimit v0.2.0 // indirect
|
||||
go.uber.org/zap v1.26.0 // indirect
|
||||
golang.org/x/arch v0.4.0 // indirect
|
||||
golang.org/x/crypto v0.19.0 // indirect
|
||||
golang.org/x/crypto v0.22.0 // indirect
|
||||
golang.org/x/oauth2 v0.16.0 // indirect
|
||||
golang.org/x/term v0.17.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/term v0.19.0 // indirect
|
||||
google.golang.org/api v0.149.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 // indirect
|
||||
google.golang.org/protobuf v1.32.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/h2non/gock.v1 v1.0.16 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/ns1/ns1-go.v2 v2.7.13 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
k8s.io/klog/v2 v2.100.1 // indirect
|
||||
k8s.io/klog/v2 v2.110.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
|
||||
nhooyr.io/websocket v1.8.7 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
)
|
||||
|
||||
|
|
136
go.sum
136
go.sum
|
@ -152,6 +152,7 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGz
|
|||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U=
|
||||
github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM=
|
||||
github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
|
@ -206,8 +207,8 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH
|
|||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw=
|
||||
github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE=
|
||||
github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0=
|
||||
github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd h1:0n+lFLh5zU0l6KSk3KpnDwfbPGAR44aRLgTbCnhRBHU=
|
||||
|
@ -261,18 +262,18 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cu
|
|||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
|
||||
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
|
||||
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
|
||||
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/dnsimple/dnsimple-go v1.2.0 h1:ddTGyLVKly5HKb5L65AkLqFqwZlWo3WnR0BlFZlIddM=
|
||||
github.com/dnsimple/dnsimple-go v1.2.0/go.mod h1:z/cs26v/eiRvUyXsHQBLd8lWF8+cD6GbmkPH84plM4U=
|
||||
github.com/docker/cli v24.0.7+incompatible h1:wa/nIwYFW7BVTGa7SWPVyyXU9lgORqUb1xfI36MSkFg=
|
||||
github.com/docker/cli v24.0.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM=
|
||||
github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/cli v24.0.9+incompatible h1:OxbimnP/z+qVjDLpq9wbeFU3Nc30XhSe+LkwYQisD50=
|
||||
github.com/docker/cli v24.0.9+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker v25.0.5+incompatible h1:UmQydMduGkrD5nQde1mecF/YnSbTOaPeFIeP5C4W+DE=
|
||||
github.com/docker/docker v25.0.5+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/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 v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
|
@ -306,8 +307,8 @@ github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
|||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
|
@ -348,8 +349,9 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
|
|||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
|
@ -496,8 +498,8 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
|||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
|
||||
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
|
@ -794,6 +796,8 @@ github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8
|
|||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
|
||||
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
|
||||
github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
|
||||
github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
@ -810,6 +814,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m
|
|||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 h1:o6uBwrhM5C8Ll3MAAxrQxRHEu7FkapwTuI2WmL1rw4g=
|
||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8=
|
||||
github.com/natefinch/lumberjack v0.0.0-20201021141957-47ffae23317c h1:194MYKszq5DlJ73wpFuOTEsC/ryOOxt2F901D/07tec=
|
||||
|
@ -860,23 +866,21 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
|||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
|
||||
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
|
||||
github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
|
||||
github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
|
||||
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
|
||||
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
|
||||
github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk=
|
||||
github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
|
@ -961,10 +965,8 @@ github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3c
|
|||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs=
|
||||
github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q=
|
||||
github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c=
|
||||
github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM=
|
||||
github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/redis/go-redis/v9 v9.2.1 h1:WlYJg71ODF0dVspZZCpYmoF1+U1Jjk9Rwd7pq6QmlCg=
|
||||
github.com/redis/go-redis/v9 v9.2.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
|
||||
|
@ -997,8 +999,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUt
|
|||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM=
|
||||
github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=
|
||||
github.com/shirou/gopsutil/v3 v3.23.11 h1:i3jP9NjCPUz7FiZKxlMnODZkdSIp2gnzfrvsu9CuWEQ=
|
||||
github.com/shirou/gopsutil/v3 v3.23.11/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM=
|
||||
github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4=
|
||||
github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM=
|
||||
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=
|
||||
|
@ -1052,8 +1054,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0=
|
||||
github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
|
@ -1064,9 +1066,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 h1:XGopsea1Dw7ecQ8JscCNQXDGYAKDiWjDeXnpN/+BY9g=
|
||||
github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
|
@ -1076,8 +1078,10 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490 h1:mmz2
|
|||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.490 h1:g9SWTaTy/rEuhMErC2jWq9Qt5ci+jBYSvXnJsLq4adg=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.490/go.mod h1:l9q4vc1QiawUB1m3RU+87yLvrrxe54jc0w/kEl4DbSQ=
|
||||
github.com/testcontainers/testcontainers-go v0.27.0 h1:IeIrJN4twonTDuMuBNQdKZ+K97yd7VrmNGu+lDpYcDk=
|
||||
github.com/testcontainers/testcontainers-go v0.27.0/go.mod h1:+HgYZcd17GshBUZv9b+jKFJ198heWPQq3KQIp2+N+7U=
|
||||
github.com/testcontainers/testcontainers-go v0.30.0 h1:jmn/XS22q4YRrcMwWg0pAwlClzs/abopbsBzrepyc4E=
|
||||
github.com/testcontainers/testcontainers-go v0.30.0/go.mod h1:K+kHNGiM5zjklKjgTtcrEetF3uhWbMUyqAQoyoh8Pf0=
|
||||
github.com/testcontainers/testcontainers-go/modules/k3s v0.30.0 h1:Mk47J0WcLoY2ig72lPl+/w8GTPYbRCdHoWcPjV2mVr8=
|
||||
github.com/testcontainers/testcontainers-go/modules/k3s v0.30.0/go.mod h1:CNnA3717kbp5wRxz+gU/cAwX6+4+OOispIsjHmKsEWQ=
|
||||
github.com/tetratelabs/wazero v1.5.0 h1:Yz3fZHivfDiZFUXnWMPUoiW7s8tC1sjdBtlJn08qYa0=
|
||||
github.com/tetratelabs/wazero v1.5.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A=
|
||||
github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM=
|
||||
|
@ -1166,6 +1170,8 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
|||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/collector/pdata v1.2.0 h1:N6VdyEFYJyoHIKqHd0F372eNVD5b+AbH0ZQf7Z2jJ9I=
|
||||
go.opentelemetry.io/collector/pdata v1.2.0/go.mod h1:mKXb6527Syb8PT4P9CZOJNbkuHOHjjGTZNNwSKESJhc=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||
go.opentelemetry.io/contrib/propagators/autoprop v0.49.0 h1:Jbr/9/jv1QpINge/fvJD4kUkW9/TqRNWU7H2GSK/Vb8=
|
||||
go.opentelemetry.io/contrib/propagators/autoprop v0.49.0/go.mod h1:aZTdrjEnMOr6ODgjCQ955njFMLRDo1IJdTNS+agSPjA=
|
||||
go.opentelemetry.io/contrib/propagators/aws v1.24.0 h1:cuwQmy9nGJi99fbwUfZSygCL3d347ddnSCWRuiVjhJ8=
|
||||
|
@ -1205,12 +1211,14 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
|||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
|
||||
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/ratelimit v0.2.0 h1:UQE2Bgi7p2B85uP5dC2bbRtig0C+OeNRnNEafLjsLPA=
|
||||
|
@ -1218,6 +1226,7 @@ go.uber.org/ratelimit v0.2.0/go.mod h1:YYBV4e4naJvhpitQrWJu1vCpgB7CboMe0qhltKt6m
|
|||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
|
@ -1247,8 +1256,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0
|
|||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -1280,8 +1289,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -1323,8 +1332,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
|||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
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=
|
||||
|
@ -1342,8 +1351,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -1417,8 +1426,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||
golang.org/x/sys v0.11.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.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
@ -1427,8 +1436,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
|||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
|
@ -1485,11 +1494,12 @@ golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4X
|
|||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
|
||||
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
|
||||
golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
|
||||
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -1573,8 +1583,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
|||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
@ -1629,16 +1639,16 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
|
|||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY=
|
||||
k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0=
|
||||
k8s.io/api v0.29.2 h1:hBC7B9+MU+ptchxEqTNW2DkUosJpp1P+Wn6YncZ474A=
|
||||
k8s.io/api v0.29.2/go.mod h1:sdIaaKuU7P44aoyyLlikSLayT6Vb7bvJNCX105xZXY0=
|
||||
k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08=
|
||||
k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc=
|
||||
k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8=
|
||||
k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg=
|
||||
k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY=
|
||||
k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4=
|
||||
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
|
||||
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/apimachinery v0.29.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8=
|
||||
k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU=
|
||||
k8s.io/client-go v0.29.2 h1:FEg85el1TeZp+/vYJM7hkDlSTFZ+c5nnK44DJ4FyoRg=
|
||||
k8s.io/client-go v0.29.2/go.mod h1:knlvFZE58VpqbQpJNbCbctTVXcd35mMyAAwBdpt4jrA=
|
||||
k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
|
||||
k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
|
||||
|
@ -1656,8 +1666,8 @@ sigs.k8s.io/gateway-api v1.0.0 h1:iPTStSv41+d9p0xFydll6d7f7MOBGuqXM6p2/zVYMAs=
|
|||
sigs.k8s.io/gateway-api v1.0.0/go.mod h1:4cUgr0Lnp5FZ0Cdq8FdRwCvpiWws7LVhLHGIudLlf4c=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.3.0/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
|
|
11763
integration/fixtures/k8s-conformance/00-experimental-v1.0.0.yml
Normal file
11763
integration/fixtures/k8s-conformance/00-experimental-v1.0.0.yml
Normal file
File diff suppressed because it is too large
Load diff
61
integration/fixtures/k8s-conformance/01-rbac.yml
Normal file
61
integration/fixtures/k8s-conformance/01-rbac.yml
Normal file
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: gateway-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- namespaces
|
||||
verbs:
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- services
|
||||
- endpoints
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- gateway.networking.k8s.io
|
||||
resources:
|
||||
- gatewayclasses
|
||||
- gateways
|
||||
- httproutes
|
||||
- tcproutes
|
||||
- tlsroutes
|
||||
- referencegrants
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- gateway.networking.k8s.io
|
||||
resources:
|
||||
- gatewayclasses/status
|
||||
- gateways/status
|
||||
- httproutes/status
|
||||
- tcproutes/status
|
||||
- tlsroutes/status
|
||||
- referencegrants/status
|
||||
verbs:
|
||||
- update
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: traefik
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: gateway-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: traefik
|
||||
namespace: traefik
|
82
integration/fixtures/k8s-conformance/02-traefik.yml
Normal file
82
integration/fixtures/k8s-conformance/02-traefik.yml
Normal file
|
@ -0,0 +1,82 @@
|
|||
---
|
||||
kind: GatewayClass
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
metadata:
|
||||
name: traefik
|
||||
spec:
|
||||
controllerName: traefik.io/gateway-controller
|
||||
|
||||
---
|
||||
kind: Namespace
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: traefik
|
||||
|
||||
---
|
||||
kind: ServiceAccount
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: traefik
|
||||
namespace: traefik
|
||||
|
||||
---
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: traefik
|
||||
namespace: traefik
|
||||
labels:
|
||||
app: traefik
|
||||
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: traefik
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: traefik
|
||||
spec:
|
||||
serviceAccountName: traefik
|
||||
containers:
|
||||
- name: traefik
|
||||
image: traefik/traefik:latest
|
||||
imagePullPolicy: Never
|
||||
args:
|
||||
- --log.level=DEBUG
|
||||
- --api.insecure
|
||||
- --entrypoints.web.address=:80
|
||||
- --entrypoints.websecure.address=:443
|
||||
- --experimental.kubernetesgateway
|
||||
- --providers.kubernetesgateway.experimentalChannel
|
||||
- --providers.kubernetesgateway.statusaddress.service.namespace=traefik
|
||||
- --providers.kubernetesgateway.statusaddress.service.name=traefik
|
||||
ports:
|
||||
- name: web
|
||||
containerPort: 80
|
||||
- name: admin
|
||||
containerPort: 8080
|
||||
- name: websecure
|
||||
containerPort: 443
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: traefik
|
||||
namespace: traefik
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
selector:
|
||||
app: traefik
|
||||
ports:
|
||||
- port: 80
|
||||
name: web
|
||||
targetPort: web
|
||||
- port: 443
|
||||
name: websecure
|
||||
targetPort: websecure
|
||||
- port: 8080
|
||||
name: admin
|
||||
targetPort: admin
|
|
@ -835,6 +835,10 @@ spec:
|
|||
breaker will try to recover (as soon as it is in recovering
|
||||
state).
|
||||
x-kubernetes-int-or-string: true
|
||||
responseCode:
|
||||
description: ResponseCode is the status code that the circuit
|
||||
breaker will return while it is in the open state.
|
||||
type: integer
|
||||
type: object
|
||||
compress:
|
||||
description: |-
|
||||
|
@ -1331,7 +1335,7 @@ spec:
|
|||
ipAllowList:
|
||||
description: |-
|
||||
IPAllowList holds the IP allowlist middleware configuration.
|
||||
This middleware accepts / refuses requests based on the client IP.
|
||||
This middleware limits allowed requests based on the client IP.
|
||||
More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/ipallowlist/
|
||||
properties:
|
||||
ipStrategy:
|
||||
|
@ -1385,7 +1389,7 @@ spec:
|
|||
type: object
|
||||
sourceRange:
|
||||
description: SourceRange defines the set of allowed IPs (or ranges
|
||||
of allowed IPs by using CIDR notation).
|
||||
of allowed IPs by using CIDR notation). Required.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
|
|
|
@ -3,24 +3,27 @@ package integration
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"slices"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"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/testcontainers/testcontainers-go/network"
|
||||
"github.com/traefik/traefik/v3/integration/try"
|
||||
"github.com/traefik/traefik/v3/pkg/version"
|
||||
"gopkg.in/yaml.v3"
|
||||
ktypes "k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
kclientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
klog "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
gatev1 "sigs.k8s.io/gateway-api/apis/v1"
|
||||
gatev1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
gatev1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
@ -30,106 +33,146 @@ import (
|
|||
ksuite "sigs.k8s.io/gateway-api/conformance/utils/suite"
|
||||
)
|
||||
|
||||
const (
|
||||
k3sImage = "docker.io/rancher/k3s:v1.29.3-k3s1"
|
||||
traefikImage = "traefik/traefik:latest"
|
||||
traefikDeployment = "deployments/traefik"
|
||||
traefikNamespace = "traefik"
|
||||
)
|
||||
|
||||
// K8sConformanceSuite tests suite.
|
||||
type K8sConformanceSuite struct{ BaseSuite }
|
||||
type K8sConformanceSuite struct {
|
||||
BaseSuite
|
||||
|
||||
k3sContainer *k3s.K3sContainer
|
||||
kubeClient client.Client
|
||||
clientSet *kclientset.Clientset
|
||||
}
|
||||
|
||||
func TestK8sConformanceSuite(t *testing.T) {
|
||||
suite.Run(t, new(K8sConformanceSuite))
|
||||
}
|
||||
|
||||
func (s *K8sConformanceSuite) SetupSuite() {
|
||||
s.BaseSuite.SetupSuite()
|
||||
|
||||
s.createComposeProject("k8s")
|
||||
s.composeUp()
|
||||
|
||||
abs, err := filepath.Abs("./fixtures/k8s/config.skip/kubeconfig.yaml")
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
err = try.Do(60*time.Second, func() error {
|
||||
_, err := os.Stat(abs)
|
||||
return err
|
||||
})
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
data, err := os.ReadFile(abs)
|
||||
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)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
err = os.Setenv("KUBECONFIG", abs)
|
||||
require.NoError(s.T(), err)
|
||||
}
|
||||
|
||||
func (s *K8sConformanceSuite) TearDownSuite() {
|
||||
s.BaseSuite.TearDownSuite()
|
||||
|
||||
generatedFiles := []string{
|
||||
"./fixtures/k8s/config.skip/kubeconfig.yaml",
|
||||
"./fixtures/k8s/config.skip/k3s.log",
|
||||
"./fixtures/k8s/rolebindings.yaml",
|
||||
"./fixtures/k8s/ccm.yaml",
|
||||
}
|
||||
|
||||
for _, filename := range generatedFiles {
|
||||
if err := os.Remove(filename); err != nil {
|
||||
log.Warn().Err(err).Send()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *K8sConformanceSuite) TestK8sGatewayAPIConformance() {
|
||||
if !*k8sConformance {
|
||||
s.T().Skip("Skip because it can take a long time to execute. To enable pass the `k8sConformance` flag.")
|
||||
}
|
||||
|
||||
configFromFlags, err := clientcmd.BuildConfigFromFlags("", os.Getenv("KUBECONFIG"))
|
||||
s.BaseSuite.SetupSuite()
|
||||
|
||||
// Avoid panic.
|
||||
klog.SetLogger(zap.New())
|
||||
|
||||
provider, err := testcontainers.ProviderDocker.GetProvider()
|
||||
if err != nil {
|
||||
s.T().Fatal(err)
|
||||
}
|
||||
|
||||
kClient, err := client.New(configFromFlags, client.Options{})
|
||||
ctx := context.Background()
|
||||
|
||||
// Ensure image is available locally.
|
||||
images, err := provider.ListImages(ctx)
|
||||
if err != nil {
|
||||
s.T().Fatal(err)
|
||||
}
|
||||
|
||||
if !slices.ContainsFunc(images, func(img testcontainers.ImageInfo) bool {
|
||||
return img.Name == traefikImage
|
||||
}) {
|
||||
s.T().Fatal("Traefik image is not present")
|
||||
}
|
||||
|
||||
s.k3sContainer, err = k3s.RunContainer(ctx,
|
||||
testcontainers.WithImage(k3sImage),
|
||||
k3s.WithManifest("./fixtures/k8s-conformance/00-experimental-v1.0.0.yml"),
|
||||
k3s.WithManifest("./fixtures/k8s-conformance/01-rbac.yml"),
|
||||
k3s.WithManifest("./fixtures/k8s-conformance/02-traefik.yml"),
|
||||
network.WithNetwork(nil, s.network),
|
||||
)
|
||||
if err != nil {
|
||||
s.T().Fatal(err)
|
||||
}
|
||||
|
||||
if err = s.k3sContainer.LoadImages(ctx, traefikImage); err != nil {
|
||||
s.T().Fatal(err)
|
||||
}
|
||||
|
||||
exitCode, _, err := s.k3sContainer.Exec(ctx, []string{"kubectl", "wait", "-n", traefikNamespace, traefikDeployment, "--for=condition=Available", "--timeout=30s"})
|
||||
if err != nil || exitCode > 0 {
|
||||
s.T().Fatalf("Traefik pod is not ready: %v", err)
|
||||
}
|
||||
|
||||
kubeConfigYaml, err := s.k3sContainer.GetKubeConfig(ctx)
|
||||
if err != nil {
|
||||
s.T().Fatal(err)
|
||||
}
|
||||
|
||||
restConfig, err := clientcmd.RESTConfigFromKubeConfig(kubeConfigYaml)
|
||||
if err != nil {
|
||||
s.T().Fatalf("Error loading Kubernetes config: %v", err)
|
||||
}
|
||||
|
||||
s.kubeClient, err = client.New(restConfig, client.Options{})
|
||||
if err != nil {
|
||||
s.T().Fatalf("Error initializing Kubernetes client: %v", err)
|
||||
}
|
||||
|
||||
kClientSet, err := kclientset.NewForConfig(configFromFlags)
|
||||
s.clientSet, err = kclientset.NewForConfig(restConfig)
|
||||
if err != nil {
|
||||
s.T().Fatalf("Error initializing Kubernetes REST client: %v", err)
|
||||
}
|
||||
|
||||
if err = gatev1alpha2.AddToScheme(s.kubeClient.Scheme()); err != nil {
|
||||
s.T().Fatal(err)
|
||||
}
|
||||
|
||||
err = gatev1alpha2.AddToScheme(kClient.Scheme())
|
||||
require.NoError(s.T(), err)
|
||||
err = gatev1beta1.AddToScheme(kClient.Scheme())
|
||||
require.NoError(s.T(), err)
|
||||
err = gatev1.AddToScheme(kClient.Scheme())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
s.traefikCmd(withConfigFile("fixtures/k8s_gateway_conformance.toml"))
|
||||
|
||||
// Wait for traefik to start
|
||||
err = try.GetRequest("http://127.0.0.1:8080/api/entrypoints", 10*time.Second, try.BodyContains(`"name":"web"`))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
err = try.Do(10*time.Second, func() error {
|
||||
gwc := &gatev1.GatewayClass{}
|
||||
err := kClient.Get(context.Background(), ktypes.NamespacedName{Name: "my-gateway-class"}, gwc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error fetching GatewayClass: %w", err)
|
||||
if err = gatev1beta1.AddToScheme(s.kubeClient.Scheme()); err != nil {
|
||||
s.T().Fatal(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err = gatev1.AddToScheme(s.kubeClient.Scheme()); err != nil {
|
||||
s.T().Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *K8sConformanceSuite) TearDownSuite() {
|
||||
ctx := context.Background()
|
||||
|
||||
if s.T().Failed() || *showLog {
|
||||
k3sLogs, err := s.k3sContainer.Logs(ctx)
|
||||
if err == nil {
|
||||
if res, err := io.ReadAll(k3sLogs); err == nil {
|
||||
s.T().Log(string(res))
|
||||
}
|
||||
}
|
||||
|
||||
exitCode, result, err := s.k3sContainer.Exec(ctx, []string{"kubectl", "logs", "-n", traefikNamespace, traefikDeployment})
|
||||
if err == nil || exitCode == 0 {
|
||||
if res, err := io.ReadAll(result); err == nil {
|
||||
s.T().Log(string(res))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.k3sContainer.Terminate(ctx); err != nil {
|
||||
s.T().Fatal(err)
|
||||
}
|
||||
|
||||
s.BaseSuite.TearDownSuite()
|
||||
}
|
||||
|
||||
func (s *K8sConformanceSuite) TestK8sGatewayAPIConformance() {
|
||||
// Wait for traefik to start
|
||||
k3sContainerIP, err := s.k3sContainer.ContainerIP(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
err = try.GetRequest("http://"+k3sContainerIP+":8080/api/entrypoints", 10*time.Second, try.BodyContains(`"name":"web"`))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
opts := ksuite.Options{
|
||||
Client: kClient,
|
||||
RestConfig: configFromFlags,
|
||||
Clientset: kClientSet,
|
||||
GatewayClassName: "my-gateway-class",
|
||||
Client: s.kubeClient,
|
||||
Clientset: s.clientSet,
|
||||
GatewayClassName: "traefik",
|
||||
Debug: true,
|
||||
CleanupBaseResources: true,
|
||||
TimeoutConfig: config.TimeoutConfig{
|
||||
|
|
|
@ -207,7 +207,13 @@ func clean(element any) {
|
|||
|
||||
var svcFieldNames []string
|
||||
for i := range valueSvcRoot.NumField() {
|
||||
svcFieldNames = append(svcFieldNames, valueSvcRoot.Type().Field(i).Name)
|
||||
field := valueSvcRoot.Type().Field(i)
|
||||
// do not create empty node for hidden config.
|
||||
if field.Tag.Get("file") == "-" && field.Tag.Get("kv") == "-" && field.Tag.Get("label") == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
svcFieldNames = append(svcFieldNames, field.Name)
|
||||
}
|
||||
|
||||
sort.Strings(svcFieldNames)
|
||||
|
|
|
@ -39,6 +39,9 @@ type Middleware struct {
|
|||
GrpcWeb *GrpcWeb `json:"grpcWeb,omitempty" toml:"grpcWeb,omitempty" yaml:"grpcWeb,omitempty" export:"true"`
|
||||
|
||||
Plugin map[string]PluginConf `json:"plugin,omitempty" toml:"plugin,omitempty" yaml:"plugin,omitempty" export:"true"`
|
||||
|
||||
// Gateway API HTTPRoute filters middlewares.
|
||||
RequestHeaderModifier *RequestHeaderModifier `json:"requestHeaderModifier,omitempty" toml:"-" yaml:"-" label:"-" file:"-" kv:"-" export:"true"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
|
@ -420,11 +423,11 @@ func (s *IPStrategy) Get() (ip.Strategy, error) {
|
|||
// +k8s:deepcopy-gen=true
|
||||
|
||||
// IPWhiteList holds the IP whitelist middleware configuration.
|
||||
// This middleware accepts / refuses requests based on the client IP.
|
||||
// This middleware limits allowed requests based on the client IP.
|
||||
// More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/ipwhitelist/
|
||||
// Deprecated: please use IPAllowList instead.
|
||||
type IPWhiteList struct {
|
||||
// SourceRange defines the set of allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
||||
// SourceRange defines the set of allowed IPs (or ranges of allowed IPs by using CIDR notation). Required.
|
||||
SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"`
|
||||
IPStrategy *IPStrategy `json:"ipStrategy,omitempty" toml:"ipStrategy,omitempty" yaml:"ipStrategy,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"`
|
||||
}
|
||||
|
@ -432,7 +435,7 @@ type IPWhiteList struct {
|
|||
// +k8s:deepcopy-gen=true
|
||||
|
||||
// IPAllowList holds the IP allowlist middleware configuration.
|
||||
// This middleware accepts / refuses requests based on the client IP.
|
||||
// This middleware limits allowed requests based on the client IP.
|
||||
// More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/ipallowlist/
|
||||
type IPAllowList struct {
|
||||
// SourceRange defines the set of allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
||||
|
@ -673,3 +676,12 @@ type TLSClientCertificateSubjectDNInfo struct {
|
|||
|
||||
// Users holds a list of users.
|
||||
type Users []string
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
|
||||
// RequestHeaderModifier holds the request header modifier configuration.
|
||||
type RequestHeaderModifier struct {
|
||||
Set map[string]string `json:"set,omitempty"`
|
||||
Add map[string]string `json:"add,omitempty"`
|
||||
Remove []string `json:"remove,omitempty"`
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ type TCPIPWhiteList struct {
|
|||
// +k8s:deepcopy-gen=true
|
||||
|
||||
// TCPIPAllowList holds the TCP IPAllowList middleware configuration.
|
||||
// This middleware limits allowed requests based on the client IP.
|
||||
// More info: https://doc.traefik.io/traefik/v3.0/middlewares/tcp/ipallowlist/
|
||||
type TCPIPAllowList struct {
|
||||
// SourceRange defines the allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
||||
SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"`
|
||||
|
|
|
@ -859,6 +859,11 @@ func (in *Middleware) DeepCopyInto(out *Middleware) {
|
|||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.RequestHeaderModifier != nil {
|
||||
in, out := &in.RequestHeaderModifier, &out.RequestHeaderModifier
|
||||
*out = new(RequestHeaderModifier)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1067,6 +1072,41 @@ func (in *ReplacePathRegex) DeepCopy() *ReplacePathRegex {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RequestHeaderModifier) DeepCopyInto(out *RequestHeaderModifier) {
|
||||
*out = *in
|
||||
if in.Set != nil {
|
||||
in, out := &in.Set, &out.Set
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Add != nil {
|
||||
in, out := &in.Add, &out.Add
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Remove != nil {
|
||||
in, out := &in.Remove, &out.Remove
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RequestHeaderModifier.
|
||||
func (in *RequestHeaderModifier) DeepCopy() *RequestHeaderModifier {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RequestHeaderModifier)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResponseForwarding) DeepCopyInto(out *ResponseForwarding) {
|
||||
*out = *in
|
||||
|
|
|
@ -42,6 +42,9 @@ const (
|
|||
// DefaultIdleTimeout before closing an idle connection.
|
||||
DefaultIdleTimeout = 180 * time.Second
|
||||
|
||||
// DefaultReadTimeout defines the default maximum duration for reading the entire request, including the body.
|
||||
DefaultReadTimeout = 60 * time.Second
|
||||
|
||||
// DefaultAcmeCAServer is the default ACME API endpoint.
|
||||
DefaultAcmeCAServer = "https://acme-v02.api.letsencrypt.org/directory"
|
||||
|
||||
|
@ -164,6 +167,7 @@ type RespondingTimeouts struct {
|
|||
|
||||
// SetDefaults sets the default values.
|
||||
func (a *RespondingTimeouts) SetDefaults() {
|
||||
a.ReadTimeout = ptypes.Duration(DefaultReadTimeout)
|
||||
a.IdleTimeout = ptypes.Duration(DefaultIdleTimeout)
|
||||
}
|
||||
|
||||
|
|
56
pkg/middlewares/headermodifier/request_header_modifier.go
Normal file
56
pkg/middlewares/headermodifier/request_header_modifier.go
Normal file
|
@ -0,0 +1,56 @@
|
|||
package headermodifier
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v3/pkg/middlewares"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const typeName = "RequestHeaderModifier"
|
||||
|
||||
// requestHeaderModifier is a middleware used to modify the headers of an HTTP request.
|
||||
type requestHeaderModifier struct {
|
||||
next http.Handler
|
||||
name string
|
||||
|
||||
set map[string]string
|
||||
add map[string]string
|
||||
remove []string
|
||||
}
|
||||
|
||||
// NewRequestHeaderModifier creates a new request header modifier middleware.
|
||||
func NewRequestHeaderModifier(ctx context.Context, next http.Handler, config dynamic.RequestHeaderModifier, name string) (http.Handler, error) {
|
||||
logger := middlewares.GetLogger(ctx, name, typeName)
|
||||
logger.Debug().Msg("Creating middleware")
|
||||
|
||||
return &requestHeaderModifier{
|
||||
next: next,
|
||||
name: name,
|
||||
set: config.Set,
|
||||
add: config.Add,
|
||||
remove: config.Remove,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *requestHeaderModifier) GetTracingInformation() (string, string, trace.SpanKind) {
|
||||
return r.name, typeName, trace.SpanKindUnspecified
|
||||
}
|
||||
|
||||
func (r *requestHeaderModifier) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
for headerName, headerValue := range r.set {
|
||||
req.Header.Set(headerName, headerValue)
|
||||
}
|
||||
|
||||
for headerName, headerValue := range r.add {
|
||||
req.Header.Add(headerName, headerValue)
|
||||
}
|
||||
|
||||
for _, headerName := range r.remove {
|
||||
req.Header.Del(headerName)
|
||||
}
|
||||
|
||||
r.next.ServeHTTP(rw, req)
|
||||
}
|
121
pkg/middlewares/headermodifier/request_header_modifier_test.go
Normal file
121
pkg/middlewares/headermodifier/request_header_modifier_test.go
Normal file
|
@ -0,0 +1,121 @@
|
|||
package headermodifier
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v3/pkg/testhelpers"
|
||||
)
|
||||
|
||||
func TestRequestHeaderModifier(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
config dynamic.RequestHeaderModifier
|
||||
requestHeaders http.Header
|
||||
expectedHeaders http.Header
|
||||
}{
|
||||
{
|
||||
desc: "no config",
|
||||
config: dynamic.RequestHeaderModifier{},
|
||||
expectedHeaders: map[string][]string{},
|
||||
},
|
||||
{
|
||||
desc: "set header",
|
||||
config: dynamic.RequestHeaderModifier{
|
||||
Set: map[string]string{"Foo": "Bar"},
|
||||
},
|
||||
expectedHeaders: map[string][]string{"Foo": {"Bar"}},
|
||||
},
|
||||
{
|
||||
desc: "set header with existing headers",
|
||||
config: dynamic.RequestHeaderModifier{
|
||||
Set: map[string]string{"Foo": "Bar"},
|
||||
},
|
||||
requestHeaders: map[string][]string{"Foo": {"Baz"}, "Bar": {"Foo"}},
|
||||
expectedHeaders: map[string][]string{"Foo": {"Bar"}, "Bar": {"Foo"}},
|
||||
},
|
||||
{
|
||||
desc: "set multiple headers with existing headers",
|
||||
config: dynamic.RequestHeaderModifier{
|
||||
Set: map[string]string{"Foo": "Bar", "Bar": "Foo"},
|
||||
},
|
||||
requestHeaders: map[string][]string{"Foo": {"Baz"}, "Bar": {"Foobar"}},
|
||||
expectedHeaders: map[string][]string{"Foo": {"Bar"}, "Bar": {"Foo"}},
|
||||
},
|
||||
{
|
||||
desc: "add header",
|
||||
config: dynamic.RequestHeaderModifier{
|
||||
Add: map[string]string{"Foo": "Bar"},
|
||||
},
|
||||
expectedHeaders: map[string][]string{"Foo": {"Bar"}},
|
||||
},
|
||||
{
|
||||
desc: "add header with existing headers",
|
||||
config: dynamic.RequestHeaderModifier{
|
||||
Add: map[string]string{"Foo": "Bar"},
|
||||
},
|
||||
requestHeaders: map[string][]string{"Foo": {"Baz"}, "Bar": {"Foo"}},
|
||||
expectedHeaders: map[string][]string{"Foo": {"Baz", "Bar"}, "Bar": {"Foo"}},
|
||||
},
|
||||
{
|
||||
desc: "add multiple headers with existing headers",
|
||||
config: dynamic.RequestHeaderModifier{
|
||||
Add: map[string]string{"Foo": "Bar", "Bar": "Foo"},
|
||||
},
|
||||
requestHeaders: map[string][]string{"Foo": {"Baz"}, "Bar": {"Foobar"}},
|
||||
expectedHeaders: map[string][]string{"Foo": {"Baz", "Bar"}, "Bar": {"Foobar", "Foo"}},
|
||||
},
|
||||
{
|
||||
desc: "remove header",
|
||||
config: dynamic.RequestHeaderModifier{
|
||||
Remove: []string{"Foo"},
|
||||
},
|
||||
expectedHeaders: map[string][]string{},
|
||||
},
|
||||
{
|
||||
desc: "remove header with existing headers",
|
||||
config: dynamic.RequestHeaderModifier{
|
||||
Remove: []string{"Foo"},
|
||||
},
|
||||
requestHeaders: map[string][]string{"Foo": {"Baz"}, "Bar": {"Foo"}},
|
||||
expectedHeaders: map[string][]string{"Bar": {"Foo"}},
|
||||
},
|
||||
{
|
||||
desc: "remove multiple headers with existing headers",
|
||||
config: dynamic.RequestHeaderModifier{
|
||||
Remove: []string{"Foo", "Bar"},
|
||||
},
|
||||
requestHeaders: map[string][]string{"Foo": {"Bar"}, "Bar": {"Foo"}, "Baz": {"Bar"}},
|
||||
expectedHeaders: map[string][]string{"Baz": {"Bar"}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var gotHeaders http.Header
|
||||
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
gotHeaders = r.Header
|
||||
})
|
||||
|
||||
handler, err := NewRequestHeaderModifier(context.Background(), next, test.config, "foo-request-header-modifier")
|
||||
require.NoError(t, err)
|
||||
|
||||
req := testhelpers.MustNewRequest(http.MethodGet, "http://localhost", nil)
|
||||
if test.requestHeaders != nil {
|
||||
req.Header = test.requestHeaders
|
||||
}
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
handler.ServeHTTP(resp, req)
|
||||
|
||||
assert.Equal(t, test.expectedHeaders, gotHeaders)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -141,7 +141,7 @@ func newMiddlewareBuilder(ctx context.Context, goPath string, manifest *Manifest
|
|||
case runtimeYaegi, "":
|
||||
i, err := newInterpreter(ctx, goPath, manifest.Import)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to craete Yaegi intepreter: %w", err)
|
||||
return nil, fmt.Errorf("failed to create Yaegi interpreter: %w", err)
|
||||
}
|
||||
|
||||
return newYaegiMiddlewareBuilder(i, manifest.BasePkg, manifest.Import)
|
||||
|
|
|
@ -11,14 +11,15 @@ import (
|
|||
// CheckFile checks file permissions and content size.
|
||||
func CheckFile(name string) (bool, error) {
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
f, err = os.Create(name)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
nf, err := os.Create(name)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, f.Chmod(0o600)
|
||||
defer nf.Close()
|
||||
return false, nf.Chmod(0o600)
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
|
|
@ -135,7 +135,7 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
|
|||
case event := <-eventsc:
|
||||
if event.Action == "start" ||
|
||||
event.Action == "die" ||
|
||||
strings.HasPrefix(event.Action, "health_status") {
|
||||
strings.HasPrefix(string(event.Action), "health_status") {
|
||||
startStopHandle(event)
|
||||
}
|
||||
case err := <-errc:
|
||||
|
|
|
@ -319,7 +319,7 @@ func (p *Provider) listInstances(ctx context.Context, client *awsClient) ([]ecsI
|
|||
}
|
||||
|
||||
var mach *machine
|
||||
if len(task.Attachments) != 0 {
|
||||
if aws.StringValue(taskDef.NetworkMode) == "awsvpc" && len(task.Attachments) != 0 {
|
||||
if len(container.NetworkInterfaces) == 0 {
|
||||
logger.Error().Msgf("Skip container %s: no network interfaces", aws.StringValue(container.Name))
|
||||
continue
|
||||
|
|
|
@ -645,6 +645,10 @@ func createCircuitBreakerMiddleware(circuitBreaker *traefikv1alpha1.CircuitBreak
|
|||
}
|
||||
}
|
||||
|
||||
if circuitBreaker.ResponseCode != 0 {
|
||||
cb.ResponseCode = circuitBreaker.ResponseCode
|
||||
}
|
||||
|
||||
return cb, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,8 @@ type CircuitBreaker struct {
|
|||
FallbackDuration *intstr.IntOrString `json:"fallbackDuration,omitempty" toml:"fallbackDuration,omitempty" yaml:"fallbackDuration,omitempty" export:"true"`
|
||||
// RecoveryDuration is the duration for which the circuit breaker will try to recover (as soon as it is in recovering state).
|
||||
RecoveryDuration *intstr.IntOrString `json:"recoveryDuration,omitempty" toml:"recoveryDuration,omitempty" yaml:"recoveryDuration,omitempty" export:"true"`
|
||||
// ResponseCode is the status code that the circuit breaker will return while it is in the open state.
|
||||
ResponseCode int `json:"responseCode,omitempty" toml:"responseCode,omitempty" yaml:"responseCode,omitempty" export:"true"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
kind: GatewayClass
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
metadata:
|
||||
name: my-gateway-class
|
||||
spec:
|
||||
controllerName: traefik.io/gateway-controller
|
||||
|
||||
---
|
||||
kind: Gateway
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
metadata:
|
||||
name: my-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gatewayClassName: my-gateway-class
|
||||
listeners: # Use GatewayClass defaults for listener definition.
|
||||
- name: http
|
||||
protocol: HTTP
|
||||
port: 80
|
||||
allowedRoutes:
|
||||
kinds:
|
||||
- kind: HTTPRoute
|
||||
group: gateway.networking.k8s.io
|
||||
namespaces:
|
||||
from: Same
|
||||
|
||||
---
|
||||
kind: HTTPRoute
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
metadata:
|
||||
name: http-app-1
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: my-gateway
|
||||
kind: Gateway
|
||||
group: gateway.networking.k8s.io
|
||||
hostnames:
|
||||
- "example.org"
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: whoami
|
||||
port: 80
|
||||
weight: 1
|
||||
kind: Service
|
||||
group: ""
|
||||
filters:
|
||||
- type: RequestHeaderModifier
|
||||
requestHeaderModifier:
|
||||
set:
|
||||
- name: X-Foo
|
||||
value: Bar
|
||||
add:
|
||||
- name: X-Bar
|
||||
value: Foo
|
||||
remove:
|
||||
- X-Baz
|
|
@ -269,3 +269,16 @@ spec:
|
|||
- protocol: TCP
|
||||
port: 10000
|
||||
name: tcp-2
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: status-address
|
||||
namespace: default
|
||||
|
||||
status:
|
||||
loadBalancer:
|
||||
ingress:
|
||||
- hostname: foo.bar
|
||||
- ip: 1.2.3.4
|
||||
|
|
|
@ -58,6 +58,7 @@ type Provider struct {
|
|||
LabelSelector string `description:"Kubernetes label selector to select specific GatewayClasses." json:"labelSelector,omitempty" toml:"labelSelector,omitempty" yaml:"labelSelector,omitempty" export:"true"`
|
||||
ThrottleDuration ptypes.Duration `description:"Kubernetes refresh throttle duration" json:"throttleDuration,omitempty" toml:"throttleDuration,omitempty" yaml:"throttleDuration,omitempty" export:"true"`
|
||||
ExperimentalChannel bool `description:"Toggles Experimental Channel resources support (TCPRoute, TLSRoute...)." json:"experimentalChannel,omitempty" toml:"experimentalChannel,omitempty" yaml:"experimentalChannel,omitempty" export:"true"`
|
||||
StatusAddress *StatusAddress `description:"Defines the Kubernetes Gateway status address." json:"statusAddress,omitempty" toml:"statusAddress,omitempty" yaml:"statusAddress,omitempty" export:"true"`
|
||||
|
||||
EntryPoints map[string]Entrypoint `json:"-" toml:"-" yaml:"-" label:"-" file:"-"`
|
||||
|
||||
|
@ -71,6 +72,19 @@ type Provider struct {
|
|||
routerTransform k8s.RouterTransform
|
||||
}
|
||||
|
||||
// StatusAddress holds the Gateway Status address configuration.
|
||||
type StatusAddress struct {
|
||||
IP string `description:"IP used to set Kubernetes Gateway status address." json:"ip,omitempty" toml:"ip,omitempty" yaml:"ip,omitempty"`
|
||||
Hostname string `description:"Hostname used for Kubernetes Gateway status address." json:"hostname,omitempty" toml:"hostname,omitempty" yaml:"hostname,omitempty"`
|
||||
Service ServiceRef `description:"Published Kubernetes Service to copy status addresses from." json:"service,omitempty" toml:"service,omitempty" yaml:"service,omitempty"`
|
||||
}
|
||||
|
||||
// ServiceRef holds a Kubernetes service reference.
|
||||
type ServiceRef struct {
|
||||
Name string `description:"Name of the Kubernetes service." json:"name,omitempty" toml:"name,omitempty" yaml:"name,omitempty"`
|
||||
Namespace string `description:"Namespace of the Kubernetes service." json:"namespace,omitempty" toml:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
// BuildFilterFunc returns the name of the filter and the related dynamic.Middleware if needed.
|
||||
type BuildFilterFunc func(name, namespace string) (string, *dynamic.Middleware, error)
|
||||
|
||||
|
@ -368,9 +382,14 @@ func (p *Provider) createGatewayConf(ctx context.Context, client Client, gateway
|
|||
// and cannot be configured on the Gateway.
|
||||
listenerStatuses := p.fillGatewayConf(ctx, client, gateway, conf, tlsConfigs)
|
||||
|
||||
gatewayStatus, errG := p.makeGatewayStatus(gateway, listenerStatuses)
|
||||
addresses, err := p.gatewayAddresses(client)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get Gateway status addresses: %w", err)
|
||||
}
|
||||
|
||||
err := client.UpdateGatewayStatus(gateway, gatewayStatus)
|
||||
gatewayStatus, errG := p.makeGatewayStatus(gateway, listenerStatuses, addresses)
|
||||
|
||||
err = client.UpdateGatewayStatus(gateway, gatewayStatus)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("an error occurred while updating gateway status: %w", err)
|
||||
}
|
||||
|
@ -618,11 +637,8 @@ func (p *Provider) fillGatewayConf(ctx context.Context, client Client, gateway *
|
|||
return listenerStatuses
|
||||
}
|
||||
|
||||
func (p *Provider) makeGatewayStatus(gateway *gatev1.Gateway, listenerStatuses []gatev1.ListenerStatus) (gatev1.GatewayStatus, error) {
|
||||
// As Status.Addresses are not implemented yet, we initialize an empty array to follow the API expectations.
|
||||
gatewayStatus := gatev1.GatewayStatus{
|
||||
Addresses: []gatev1.GatewayStatusAddress{},
|
||||
}
|
||||
func (p *Provider) makeGatewayStatus(gateway *gatev1.Gateway, listenerStatuses []gatev1.ListenerStatus, addresses []gatev1.GatewayStatusAddress) (gatev1.GatewayStatus, error) {
|
||||
gatewayStatus := gatev1.GatewayStatus{Addresses: addresses}
|
||||
|
||||
var result error
|
||||
for i, listener := range listenerStatuses {
|
||||
|
@ -701,6 +717,57 @@ func (p *Provider) makeGatewayStatus(gateway *gatev1.Gateway, listenerStatuses [
|
|||
return gatewayStatus, nil
|
||||
}
|
||||
|
||||
func (p *Provider) gatewayAddresses(client Client) ([]gatev1.GatewayStatusAddress, error) {
|
||||
if p.StatusAddress == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if p.StatusAddress.IP != "" {
|
||||
return []gatev1.GatewayStatusAddress{{
|
||||
Type: ptr.To(gatev1.IPAddressType),
|
||||
Value: p.StatusAddress.IP,
|
||||
}}, nil
|
||||
}
|
||||
|
||||
if p.StatusAddress.Hostname != "" {
|
||||
return []gatev1.GatewayStatusAddress{{
|
||||
Type: ptr.To(gatev1.HostnameAddressType),
|
||||
Value: p.StatusAddress.Hostname,
|
||||
}}, nil
|
||||
}
|
||||
|
||||
svcRef := p.StatusAddress.Service
|
||||
if svcRef.Name != "" && svcRef.Namespace != "" {
|
||||
svc, exists, err := client.GetService(svcRef.Namespace, svcRef.Name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get service: %w", err)
|
||||
}
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("could not find a service with name %s in namespace %s", svcRef.Name, svcRef.Namespace)
|
||||
}
|
||||
|
||||
var addresses []gatev1.GatewayStatusAddress
|
||||
for _, addr := range svc.Status.LoadBalancer.Ingress {
|
||||
switch {
|
||||
case addr.IP != "":
|
||||
addresses = append(addresses, gatev1.GatewayStatusAddress{
|
||||
Type: ptr.To(gatev1.IPAddressType),
|
||||
Value: addr.IP,
|
||||
})
|
||||
|
||||
case addr.Hostname != "":
|
||||
addresses = append(addresses, gatev1.GatewayStatusAddress{
|
||||
Type: ptr.To(gatev1.HostnameAddressType),
|
||||
Value: addr.Hostname,
|
||||
})
|
||||
}
|
||||
}
|
||||
return addresses, nil
|
||||
}
|
||||
|
||||
return nil, errors.New("empty Gateway status address configuration")
|
||||
}
|
||||
|
||||
func (p *Provider) entryPointName(port gatev1.PortNumber, protocol gatev1.ProtocolType) (string, error) {
|
||||
portStr := strconv.FormatInt(int64(port), 10)
|
||||
|
||||
|
@ -1921,6 +1988,11 @@ func (p *Provider) loadMiddlewares(listener gatev1.Listener, namespace string, p
|
|||
}
|
||||
|
||||
middlewares[name] = middleware
|
||||
|
||||
case gatev1.HTTPRouteFilterRequestHeaderModifier:
|
||||
middlewareName := provider.Normalize(fmt.Sprintf("%s-%s-%d", prefix, strings.ToLower(string(filter.Type)), i))
|
||||
middlewares[middlewareName] = createRequestHeaderModifier(filter.RequestHeaderModifier)
|
||||
|
||||
default:
|
||||
// As per the spec:
|
||||
// https://gateway-api.sigs.k8s.io/api-types/httproute/#filters-optional
|
||||
|
@ -1950,6 +2022,28 @@ func (p *Provider) loadHTTPRouteFilterExtensionRef(namespace string, extensionRe
|
|||
return filterFunc(string(extensionRef.Name), namespace)
|
||||
}
|
||||
|
||||
// createRequestHeaderModifier does not enforce/check the configuration,
|
||||
// as the spec indicates that either the webhook or CEL (since v1.0 GA Release) should enforce that.
|
||||
func createRequestHeaderModifier(filter *gatev1.HTTPHeaderFilter) *dynamic.Middleware {
|
||||
sets := map[string]string{}
|
||||
for _, header := range filter.Set {
|
||||
sets[string(header.Name)] = header.Value
|
||||
}
|
||||
|
||||
adds := map[string]string{}
|
||||
for _, header := range filter.Add {
|
||||
adds[string(header.Name)] = header.Value
|
||||
}
|
||||
|
||||
return &dynamic.Middleware{
|
||||
RequestHeaderModifier: &dynamic.RequestHeaderModifier{
|
||||
Set: sets,
|
||||
Add: adds,
|
||||
Remove: filter.Remove,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func createRedirectRegexMiddleware(scheme string, filter *gatev1.HTTPRequestRedirectFilter) (*dynamic.Middleware, error) {
|
||||
// Use the HTTPRequestRedirectFilter scheme if defined.
|
||||
filterScheme := scheme
|
||||
|
|
|
@ -1517,6 +1517,75 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
|||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Simple HTTPRoute, request header modifier",
|
||||
paths: []string{"services.yml", "httproute/filter_request_header_modifier.yml"},
|
||||
entryPoints: map[string]Entrypoint{"web": {
|
||||
Address: ":80",
|
||||
}},
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
Services: map[string]*dynamic.UDPService{},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4": {
|
||||
EntryPoints: []string{"web"},
|
||||
Service: "default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4-wrr",
|
||||
Rule: "Host(`example.org`) && PathPrefix(`/`)",
|
||||
RuleSyntax: "v3",
|
||||
Middlewares: []string{"default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4-requestheadermodifier-0"},
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{
|
||||
"default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4-requestheadermodifier-0": {
|
||||
RequestHeaderModifier: &dynamic.RequestHeaderModifier{
|
||||
Set: map[string]string{"X-Foo": "Bar"},
|
||||
Add: map[string]string{"X-Bar": "Foo"},
|
||||
Remove: []string{"X-Baz"},
|
||||
},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4-wrr": {
|
||||
Weighted: &dynamic.WeightedRoundRobin{
|
||||
Services: []dynamic.WRRService{
|
||||
{
|
||||
Name: "default-whoami-80",
|
||||
Weight: func(i int) *int { return &i }(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"default-whoami-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
},
|
||||
{
|
||||
URL: "http://10.10.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: ptr.To(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Simple HTTPRoute, redirect HTTP to HTTPS",
|
||||
paths: []string{"services.yml", "httproute/filter_http_to_https.yml"},
|
||||
|
@ -6227,30 +6296,6 @@ func Test_makeListenerKey(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func hostnamePtr(hostname gatev1.Hostname) *gatev1.Hostname {
|
||||
return &hostname
|
||||
}
|
||||
|
||||
func groupPtr(group gatev1.Group) *gatev1.Group {
|
||||
return &group
|
||||
}
|
||||
|
||||
func sectionNamePtr(sectionName gatev1.SectionName) *gatev1.SectionName {
|
||||
return §ionName
|
||||
}
|
||||
|
||||
func namespacePtr(namespace gatev1.Namespace) *gatev1.Namespace {
|
||||
return &namespace
|
||||
}
|
||||
|
||||
func kindPtr(kind gatev1.Kind) *gatev1.Kind {
|
||||
return &kind
|
||||
}
|
||||
|
||||
func pathMatchTypePtr(p gatev1.PathMatchType) *gatev1.PathMatchType { return &p }
|
||||
|
||||
func headerMatchTypePtr(h gatev1.HeaderMatchType) *gatev1.HeaderMatchType { return &h }
|
||||
|
||||
func Test_referenceGrantMatchesFrom(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
@ -6489,6 +6534,131 @@ func Test_referenceGrantMatchesTo(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_gatewayAddresses(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
statusAddress *StatusAddress
|
||||
paths []string
|
||||
wantErr require.ErrorAssertionFunc
|
||||
want []gatev1.GatewayStatusAddress
|
||||
}{
|
||||
{
|
||||
desc: "nothing",
|
||||
wantErr: require.NoError,
|
||||
},
|
||||
{
|
||||
desc: "empty configuration",
|
||||
statusAddress: &StatusAddress{},
|
||||
wantErr: require.Error,
|
||||
},
|
||||
{
|
||||
desc: "IP address",
|
||||
statusAddress: &StatusAddress{
|
||||
IP: "1.2.3.4",
|
||||
},
|
||||
wantErr: require.NoError,
|
||||
want: []gatev1.GatewayStatusAddress{
|
||||
{
|
||||
Type: ptr.To(gatev1.IPAddressType),
|
||||
Value: "1.2.3.4",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "hostname address",
|
||||
statusAddress: &StatusAddress{
|
||||
Hostname: "foo.bar",
|
||||
},
|
||||
wantErr: require.NoError,
|
||||
want: []gatev1.GatewayStatusAddress{
|
||||
{
|
||||
Type: ptr.To(gatev1.HostnameAddressType),
|
||||
Value: "foo.bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "service",
|
||||
statusAddress: &StatusAddress{
|
||||
Service: ServiceRef{
|
||||
Name: "status-address",
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
paths: []string{"services.yml"},
|
||||
wantErr: require.NoError,
|
||||
want: []gatev1.GatewayStatusAddress{
|
||||
{
|
||||
Type: ptr.To(gatev1.HostnameAddressType),
|
||||
Value: "foo.bar",
|
||||
},
|
||||
{
|
||||
Type: ptr.To(gatev1.IPAddressType),
|
||||
Value: "1.2.3.4",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "missing service",
|
||||
statusAddress: &StatusAddress{
|
||||
Service: ServiceRef{
|
||||
Name: "status-address2",
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
wantErr: require.Error,
|
||||
},
|
||||
{
|
||||
desc: "service without load-balancer status",
|
||||
statusAddress: &StatusAddress{
|
||||
Service: ServiceRef{
|
||||
Name: "whoamitcp-bar",
|
||||
Namespace: "bar",
|
||||
},
|
||||
},
|
||||
paths: []string{"services.yml"},
|
||||
wantErr: require.NoError,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p := Provider{StatusAddress: test.statusAddress}
|
||||
|
||||
got, err := p.gatewayAddresses(newClientMock(test.paths...))
|
||||
test.wantErr(t, err)
|
||||
|
||||
assert.Equal(t, test.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func hostnamePtr(hostname gatev1.Hostname) *gatev1.Hostname {
|
||||
return &hostname
|
||||
}
|
||||
|
||||
func groupPtr(group gatev1.Group) *gatev1.Group {
|
||||
return &group
|
||||
}
|
||||
|
||||
func sectionNamePtr(sectionName gatev1.SectionName) *gatev1.SectionName {
|
||||
return §ionName
|
||||
}
|
||||
|
||||
func namespacePtr(namespace gatev1.Namespace) *gatev1.Namespace {
|
||||
return &namespace
|
||||
}
|
||||
|
||||
func kindPtr(kind gatev1.Kind) *gatev1.Kind {
|
||||
return &kind
|
||||
}
|
||||
|
||||
func pathMatchTypePtr(p gatev1.PathMatchType) *gatev1.PathMatchType { return &p }
|
||||
|
||||
func headerMatchTypePtr(h gatev1.HeaderMatchType) *gatev1.HeaderMatchType { return &h }
|
||||
|
||||
func objectNamePtr(objectName gatev1.ObjectName) *gatev1.ObjectName {
|
||||
return &objectName
|
||||
}
|
||||
|
|
|
@ -97,10 +97,13 @@ func (p *Provider) buildTCPConfig(i item, configuration *dynamic.TCPConfiguratio
|
|||
}
|
||||
|
||||
for _, service := range configuration.Services {
|
||||
// Leave load balancer empty when no address and allowEmptyServices = true
|
||||
if !(i.Address == "" && p.AllowEmptyServices) {
|
||||
if err := p.addServerTCP(i, service.LoadBalancer); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -115,10 +118,13 @@ func (p *Provider) buildUDPConfig(i item, configuration *dynamic.UDPConfiguratio
|
|||
}
|
||||
|
||||
for _, service := range configuration.Services {
|
||||
// Leave load balancer empty when no address and allowEmptyServices = true
|
||||
if !(i.Address == "" && p.AllowEmptyServices) {
|
||||
if err := p.addServerUDP(i, service.LoadBalancer); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -136,10 +142,13 @@ func (p *Provider) buildServiceConfig(i item, configuration *dynamic.HTTPConfigu
|
|||
}
|
||||
|
||||
for _, service := range configuration.Services {
|
||||
// Leave load balancer empty when no address and allowEmptyServices = true
|
||||
if !(i.Address == "" && p.AllowEmptyServices) {
|
||||
if err := p.addServer(i, service.LoadBalancer); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -706,6 +706,42 @@ func Test_buildConfig(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "empty service",
|
||||
items: []item{
|
||||
{
|
||||
ID: "id1",
|
||||
Name: "Test",
|
||||
Tags: []string{
|
||||
"traefik.enable=true",
|
||||
},
|
||||
Address: "",
|
||||
Port: -1,
|
||||
ExtraConf: configuration{Enable: true},
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
||||
},
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
Services: map[string]*dynamic.UDPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Stores: map[string]tls.Store{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "one service with rule label",
|
||||
items: []item{
|
||||
|
@ -2825,6 +2861,307 @@ func Test_buildConfig(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_buildConfigAllowEmptyServicesTrue(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
items []item
|
||||
constraints string
|
||||
expected *dynamic.Configuration
|
||||
}{
|
||||
{
|
||||
desc: "empty service http",
|
||||
items: []item{
|
||||
{
|
||||
ID: "id1",
|
||||
Name: "Test",
|
||||
Tags: []string{
|
||||
"traefik.enable=true",
|
||||
},
|
||||
Address: "",
|
||||
Port: -1,
|
||||
ExtraConf: configuration{Enable: true},
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
||||
},
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
Services: map[string]*dynamic.UDPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"Test": {
|
||||
Service: "Test",
|
||||
Rule: "Host(`Test.traefik.test`)",
|
||||
DefaultRule: true,
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Servers: nil,
|
||||
PassHostHeader: Bool(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Stores: map[string]tls.Store{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "empty service tcp",
|
||||
items: []item{
|
||||
{
|
||||
ID: "id1",
|
||||
Name: "Test",
|
||||
Tags: []string{
|
||||
"traefik.tcp.routers.test.rule = HostSNI(`foobar`)",
|
||||
},
|
||||
Address: "",
|
||||
Port: -1,
|
||||
ExtraConf: configuration{Enable: true},
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{
|
||||
"test": {
|
||||
Rule: "HostSNI(`foobar`)",
|
||||
Service: "Test",
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
||||
Services: map[string]*dynamic.TCPService{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.TCPServersLoadBalancer{},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
||||
},
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
Services: map[string]*dynamic.UDPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Stores: map[string]tls.Store{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "empty service udp",
|
||||
items: []item{
|
||||
{
|
||||
ID: "id1",
|
||||
Name: "Test",
|
||||
Tags: []string{
|
||||
"traefik.udp.routers.test.entrypoints = udp",
|
||||
},
|
||||
Address: "",
|
||||
Port: -1,
|
||||
ExtraConf: configuration{Enable: true},
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
||||
},
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"test": {
|
||||
EntryPoints: []string{"udp"},
|
||||
Service: "Test",
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{},
|
||||
},
|
||||
},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Stores: map[string]tls.Store{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
p := new(Provider)
|
||||
p.SetDefaults()
|
||||
p.AllowEmptyServices = true
|
||||
p.DefaultRule = "Host(`{{ normalize .Name }}.traefik.test`)"
|
||||
p.Constraints = test.constraints
|
||||
err := p.Init()
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := context.TODO()
|
||||
c := p.buildConfig(ctx, test.items)
|
||||
require.Equal(t, test.expected, c)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_buildConfigAllowEmptyServicesFalseDefault(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
items []item
|
||||
constraints string
|
||||
expected *dynamic.Configuration
|
||||
}{
|
||||
{
|
||||
desc: "empty service http",
|
||||
items: []item{
|
||||
{
|
||||
ID: "id1",
|
||||
Name: "Test",
|
||||
Tags: []string{
|
||||
"traefik.enable=true",
|
||||
},
|
||||
Address: "",
|
||||
Port: -1,
|
||||
ExtraConf: configuration{Enable: true},
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
||||
},
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
Services: map[string]*dynamic.UDPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Stores: map[string]tls.Store{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "empty service tcp",
|
||||
items: []item{
|
||||
{
|
||||
ID: "id1",
|
||||
Name: "Test",
|
||||
Tags: []string{
|
||||
"traefik.tcp.routers.test.rule = HostSNI(`foobar`)",
|
||||
},
|
||||
Address: "",
|
||||
Port: -1,
|
||||
ExtraConf: configuration{Enable: true},
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
||||
},
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
Services: map[string]*dynamic.UDPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Stores: map[string]tls.Store{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "empty service udp",
|
||||
items: []item{
|
||||
{
|
||||
ID: "id1",
|
||||
Name: "Test",
|
||||
Tags: []string{
|
||||
"traefik.udp.routers.test.entrypoints = udp",
|
||||
},
|
||||
Address: "",
|
||||
Port: -1,
|
||||
ExtraConf: configuration{Enable: true},
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
||||
},
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
Services: map[string]*dynamic.UDPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Stores: map[string]tls.Store{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
p := new(Provider)
|
||||
p.SetDefaults()
|
||||
p.DefaultRule = "Host(`{{ normalize .Name }}.traefik.test`)"
|
||||
p.Constraints = test.constraints
|
||||
err := p.Init()
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := context.TODO()
|
||||
c := p.buildConfig(ctx, test.items)
|
||||
require.Equal(t, test.expected, c)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_keepItem(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
{
|
||||
"Stop": false,
|
||||
"Region": "global",
|
||||
"Namespace": "default",
|
||||
"ID": "job1",
|
||||
"ParentID": "",
|
||||
"Name": "job1",
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"AllAtOnce": false,
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"TaskGroups": [
|
||||
{
|
||||
"Name": "group1",
|
||||
"Count": 1,
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000,
|
||||
"ProgressDeadline": 600000000000,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Migrate": {
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000
|
||||
},
|
||||
"Constraints": [
|
||||
{
|
||||
"LTarget": "${attr.nomad.service_discovery}",
|
||||
"RTarget": "true",
|
||||
"Operand": "="
|
||||
}
|
||||
],
|
||||
"Scaling": {
|
||||
"ID": "654cb8ee-9c81-4fe8-02a0-2aecdea35ae3",
|
||||
"Type": "horizontal",
|
||||
"Target": {
|
||||
"Job": "job1",
|
||||
"Group": "group1",
|
||||
"Namespace": "default"
|
||||
},
|
||||
"Policy": null,
|
||||
"Min": 0,
|
||||
"Max": 3,
|
||||
"Enabled": true,
|
||||
"CreateIndex": 0,
|
||||
"ModifyIndex": 0
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"Tasks": [
|
||||
{
|
||||
"Name": "task1",
|
||||
"Driver": "docker",
|
||||
"User": "",
|
||||
"Config": {
|
||||
"image": "nginx",
|
||||
"ports": [
|
||||
"http"
|
||||
]
|
||||
},
|
||||
"Env": null,
|
||||
"Services": null,
|
||||
"Vault": null,
|
||||
"Templates": null,
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Resources": {
|
||||
"CPU": 100,
|
||||
"Cores": 0,
|
||||
"MemoryMB": 300,
|
||||
"MemoryMaxMB": 0,
|
||||
"DiskMB": 0,
|
||||
"IOPS": 0,
|
||||
"Networks": null,
|
||||
"Devices": null
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"DispatchPayload": null,
|
||||
"Lifecycle": null,
|
||||
"Meta": null,
|
||||
"KillTimeout": 5000000000,
|
||||
"LogConfig": {
|
||||
"MaxFiles": 10,
|
||||
"MaxFileSizeMB": 10,
|
||||
"Disabled": false
|
||||
},
|
||||
"Artifacts": null,
|
||||
"Leader": false,
|
||||
"ShutdownDelay": 0,
|
||||
"VolumeMounts": null,
|
||||
"ScalingPolicies": null,
|
||||
"KillSignal": "",
|
||||
"Kind": "",
|
||||
"CSIPluginConfig": null,
|
||||
"Identity": null
|
||||
}
|
||||
],
|
||||
"EphemeralDisk": {
|
||||
"Sticky": false,
|
||||
"SizeMB": 300,
|
||||
"Migrate": false
|
||||
},
|
||||
"Meta": null,
|
||||
"ReschedulePolicy": {
|
||||
"Attempts": 0,
|
||||
"Interval": 0,
|
||||
"Delay": 30000000000,
|
||||
"DelayFunction": "exponential",
|
||||
"MaxDelay": 3600000000000,
|
||||
"Unlimited": true
|
||||
},
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"Networks": [
|
||||
{
|
||||
"Mode": "",
|
||||
"Device": "",
|
||||
"CIDR": "",
|
||||
"IP": "",
|
||||
"Hostname": "",
|
||||
"MBits": 0,
|
||||
"DNS": null,
|
||||
"ReservedPorts": null,
|
||||
"DynamicPorts": [
|
||||
{
|
||||
"Label": "http",
|
||||
"Value": 0,
|
||||
"To": 80,
|
||||
"HostNetwork": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Consul": {
|
||||
"Namespace": ""
|
||||
},
|
||||
"Services": [
|
||||
{
|
||||
"Name": "job1",
|
||||
"TaskName": "",
|
||||
"PortLabel": "http",
|
||||
"AddressMode": "auto",
|
||||
"Address": "",
|
||||
"EnableTagOverride": false,
|
||||
"Tags": [
|
||||
"traefik.enable=true"
|
||||
],
|
||||
"CanaryTags": null,
|
||||
"Checks": null,
|
||||
"Connect": null,
|
||||
"Meta": null,
|
||||
"CanaryMeta": null,
|
||||
"TaggedAddresses": null,
|
||||
"Namespace": "default",
|
||||
"OnUpdate": "require_healthy",
|
||||
"Provider": "nomad"
|
||||
}
|
||||
],
|
||||
"Volumes": null,
|
||||
"ShutdownDelay": null,
|
||||
"StopAfterClientDisconnect": null,
|
||||
"MaxClientDisconnect": null
|
||||
}
|
||||
],
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "",
|
||||
"MinHealthyTime": 0,
|
||||
"HealthyDeadline": 0,
|
||||
"ProgressDeadline": 0,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Multiregion": null,
|
||||
"Periodic": null,
|
||||
"ParameterizedJob": null,
|
||||
"Dispatched": false,
|
||||
"DispatchIdempotencyToken": "",
|
||||
"Payload": null,
|
||||
"Meta": null,
|
||||
"ConsulToken": "",
|
||||
"ConsulNamespace": "",
|
||||
"VaultToken": "",
|
||||
"VaultNamespace": "",
|
||||
"NomadTokenID": "",
|
||||
"Status": "running",
|
||||
"StatusDescription": "",
|
||||
"Stable": true,
|
||||
"Version": 11,
|
||||
"SubmitTime": 1705690395733241600,
|
||||
"CreateIndex": 493,
|
||||
"ModifyIndex": 9961,
|
||||
"JobModifyIndex": 9955
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
{
|
||||
"Stop": false,
|
||||
"Region": "global",
|
||||
"Namespace": "default",
|
||||
"ID": "job2",
|
||||
"ParentID": "",
|
||||
"Name": "job2",
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"AllAtOnce": false,
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"TaskGroups": [
|
||||
{
|
||||
"Name": "group1",
|
||||
"Count": 0,
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000,
|
||||
"ProgressDeadline": 600000000000,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Migrate": {
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000
|
||||
},
|
||||
"Constraints": [
|
||||
{
|
||||
"LTarget": "${attr.nomad.service_discovery}",
|
||||
"RTarget": "true",
|
||||
"Operand": "="
|
||||
}
|
||||
],
|
||||
"Scaling": {
|
||||
"ID": "0ae1d8fa-aa84-0b1b-941f-82dc71bc4664",
|
||||
"Type": "horizontal",
|
||||
"Target": {
|
||||
"Group": "group1",
|
||||
"Namespace": "default",
|
||||
"Job": "job2"
|
||||
},
|
||||
"Policy": null,
|
||||
"Min": 0,
|
||||
"Max": 3,
|
||||
"Enabled": true,
|
||||
"CreateIndex": 9975,
|
||||
"ModifyIndex": 9975
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"Tasks": [
|
||||
{
|
||||
"Name": "task1",
|
||||
"Driver": "docker",
|
||||
"User": "",
|
||||
"Config": {
|
||||
"ports": [
|
||||
"http"
|
||||
],
|
||||
"image": "nginx"
|
||||
},
|
||||
"Env": null,
|
||||
"Services": null,
|
||||
"Vault": null,
|
||||
"Templates": null,
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Resources": {
|
||||
"CPU": 100,
|
||||
"Cores": 0,
|
||||
"MemoryMB": 300,
|
||||
"MemoryMaxMB": 0,
|
||||
"DiskMB": 0,
|
||||
"IOPS": 0,
|
||||
"Networks": null,
|
||||
"Devices": null
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"DispatchPayload": null,
|
||||
"Lifecycle": null,
|
||||
"Meta": null,
|
||||
"KillTimeout": 5000000000,
|
||||
"LogConfig": {
|
||||
"MaxFiles": 10,
|
||||
"MaxFileSizeMB": 10,
|
||||
"Disabled": false
|
||||
},
|
||||
"Artifacts": null,
|
||||
"Leader": false,
|
||||
"ShutdownDelay": 0,
|
||||
"VolumeMounts": null,
|
||||
"ScalingPolicies": null,
|
||||
"KillSignal": "",
|
||||
"Kind": "",
|
||||
"CSIPluginConfig": null,
|
||||
"Identity": null
|
||||
}
|
||||
],
|
||||
"EphemeralDisk": {
|
||||
"Sticky": false,
|
||||
"SizeMB": 300,
|
||||
"Migrate": false
|
||||
},
|
||||
"Meta": null,
|
||||
"ReschedulePolicy": {
|
||||
"Attempts": 0,
|
||||
"Interval": 0,
|
||||
"Delay": 30000000000,
|
||||
"DelayFunction": "exponential",
|
||||
"MaxDelay": 3600000000000,
|
||||
"Unlimited": true
|
||||
},
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"Networks": [
|
||||
{
|
||||
"Mode": "",
|
||||
"Device": "",
|
||||
"CIDR": "",
|
||||
"IP": "",
|
||||
"Hostname": "",
|
||||
"MBits": 0,
|
||||
"DNS": null,
|
||||
"ReservedPorts": null,
|
||||
"DynamicPorts": [
|
||||
{
|
||||
"Label": "http",
|
||||
"Value": 0,
|
||||
"To": 80,
|
||||
"HostNetwork": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Consul": {
|
||||
"Namespace": ""
|
||||
},
|
||||
"Services": [
|
||||
{
|
||||
"Name": "job2",
|
||||
"TaskName": "",
|
||||
"PortLabel": "http",
|
||||
"AddressMode": "auto",
|
||||
"Address": "",
|
||||
"EnableTagOverride": false,
|
||||
"Tags": [
|
||||
"traefik.enable=true"
|
||||
],
|
||||
"CanaryTags": null,
|
||||
"Checks": null,
|
||||
"Connect": null,
|
||||
"Meta": null,
|
||||
"CanaryMeta": null,
|
||||
"TaggedAddresses": null,
|
||||
"Namespace": "default",
|
||||
"OnUpdate": "require_healthy",
|
||||
"Provider": "nomad"
|
||||
}
|
||||
],
|
||||
"Volumes": null,
|
||||
"ShutdownDelay": null,
|
||||
"StopAfterClientDisconnect": null,
|
||||
"MaxClientDisconnect": null
|
||||
}
|
||||
],
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "",
|
||||
"MinHealthyTime": 0,
|
||||
"HealthyDeadline": 0,
|
||||
"ProgressDeadline": 0,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Multiregion": null,
|
||||
"Periodic": null,
|
||||
"ParameterizedJob": null,
|
||||
"Dispatched": false,
|
||||
"DispatchIdempotencyToken": "",
|
||||
"Payload": null,
|
||||
"Meta": null,
|
||||
"ConsulToken": "",
|
||||
"ConsulNamespace": "",
|
||||
"VaultToken": "",
|
||||
"VaultNamespace": "",
|
||||
"NomadTokenID": "",
|
||||
"Status": "dead",
|
||||
"StatusDescription": "",
|
||||
"Stable": true,
|
||||
"Version": 10,
|
||||
"SubmitTime": 1705690880440177400,
|
||||
"CreateIndex": 2923,
|
||||
"ModifyIndex": 10048,
|
||||
"JobModifyIndex": 10044
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
{
|
||||
"Stop": false,
|
||||
"Region": "global",
|
||||
"Namespace": "default",
|
||||
"ID": "job3",
|
||||
"ParentID": "",
|
||||
"Name": "job3",
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"AllAtOnce": false,
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"TaskGroups": [
|
||||
{
|
||||
"Name": "group1",
|
||||
"Count": 1,
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000,
|
||||
"ProgressDeadline": 600000000000,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Migrate": {
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000
|
||||
},
|
||||
"Constraints": [
|
||||
{
|
||||
"LTarget": "${attr.nomad.service_discovery}",
|
||||
"RTarget": "true",
|
||||
"Operand": "="
|
||||
}
|
||||
],
|
||||
"Scaling": null,
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"Tasks": [
|
||||
{
|
||||
"Name": "task1",
|
||||
"Driver": "docker",
|
||||
"User": "",
|
||||
"Config": {
|
||||
"ports": [
|
||||
"http"
|
||||
],
|
||||
"image": "nginx"
|
||||
},
|
||||
"Env": null,
|
||||
"Services": null,
|
||||
"Vault": null,
|
||||
"Templates": null,
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Resources": {
|
||||
"CPU": 100,
|
||||
"Cores": 0,
|
||||
"MemoryMB": 300,
|
||||
"MemoryMaxMB": 0,
|
||||
"DiskMB": 0,
|
||||
"IOPS": 0,
|
||||
"Networks": null,
|
||||
"Devices": null
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"DispatchPayload": null,
|
||||
"Lifecycle": null,
|
||||
"Meta": null,
|
||||
"KillTimeout": 5000000000,
|
||||
"LogConfig": {
|
||||
"MaxFiles": 10,
|
||||
"MaxFileSizeMB": 10,
|
||||
"Disabled": false
|
||||
},
|
||||
"Artifacts": null,
|
||||
"Leader": false,
|
||||
"ShutdownDelay": 0,
|
||||
"VolumeMounts": null,
|
||||
"ScalingPolicies": null,
|
||||
"KillSignal": "",
|
||||
"Kind": "",
|
||||
"CSIPluginConfig": null,
|
||||
"Identity": null
|
||||
}
|
||||
],
|
||||
"EphemeralDisk": {
|
||||
"Sticky": false,
|
||||
"SizeMB": 300,
|
||||
"Migrate": false
|
||||
},
|
||||
"Meta": null,
|
||||
"ReschedulePolicy": {
|
||||
"Attempts": 0,
|
||||
"Interval": 0,
|
||||
"Delay": 30000000000,
|
||||
"DelayFunction": "exponential",
|
||||
"MaxDelay": 3600000000000,
|
||||
"Unlimited": true
|
||||
},
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"Networks": [
|
||||
{
|
||||
"Mode": "",
|
||||
"Device": "",
|
||||
"CIDR": "",
|
||||
"IP": "",
|
||||
"Hostname": "",
|
||||
"MBits": 0,
|
||||
"DNS": null,
|
||||
"ReservedPorts": null,
|
||||
"DynamicPorts": [
|
||||
{
|
||||
"Label": "http",
|
||||
"Value": 0,
|
||||
"To": 80,
|
||||
"HostNetwork": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Consul": {
|
||||
"Namespace": ""
|
||||
},
|
||||
"Services": [
|
||||
{
|
||||
"Name": "job3",
|
||||
"TaskName": "",
|
||||
"PortLabel": "http",
|
||||
"AddressMode": "auto",
|
||||
"Address": "",
|
||||
"EnableTagOverride": false,
|
||||
"Tags": [
|
||||
"traefik.enable=true"
|
||||
],
|
||||
"CanaryTags": null,
|
||||
"Checks": null,
|
||||
"Connect": null,
|
||||
"Meta": null,
|
||||
"CanaryMeta": null,
|
||||
"TaggedAddresses": null,
|
||||
"Namespace": "default",
|
||||
"OnUpdate": "require_healthy",
|
||||
"Provider": "nomad"
|
||||
}
|
||||
],
|
||||
"Volumes": null,
|
||||
"ShutdownDelay": null,
|
||||
"StopAfterClientDisconnect": null,
|
||||
"MaxClientDisconnect": null
|
||||
}
|
||||
],
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "",
|
||||
"MinHealthyTime": 0,
|
||||
"HealthyDeadline": 0,
|
||||
"ProgressDeadline": 0,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Multiregion": null,
|
||||
"Periodic": null,
|
||||
"ParameterizedJob": null,
|
||||
"Dispatched": false,
|
||||
"DispatchIdempotencyToken": "",
|
||||
"Payload": null,
|
||||
"Meta": null,
|
||||
"ConsulToken": "",
|
||||
"ConsulNamespace": "",
|
||||
"VaultToken": "",
|
||||
"VaultNamespace": "",
|
||||
"NomadTokenID": "",
|
||||
"Status": "running",
|
||||
"StatusDescription": "",
|
||||
"Stable": true,
|
||||
"Version": 4,
|
||||
"SubmitTime": 1705690892484556300,
|
||||
"CreateIndex": 2932,
|
||||
"ModifyIndex": 9992,
|
||||
"JobModifyIndex": 9983
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
{
|
||||
"Stop": true,
|
||||
"Region": "global",
|
||||
"Namespace": "default",
|
||||
"ID": "job4",
|
||||
"ParentID": "",
|
||||
"Name": "job4",
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"AllAtOnce": false,
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"TaskGroups": [
|
||||
{
|
||||
"Name": "group1",
|
||||
"Count": 1,
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000,
|
||||
"ProgressDeadline": 600000000000,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Migrate": {
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000
|
||||
},
|
||||
"Constraints": [
|
||||
{
|
||||
"LTarget": "${attr.nomad.service_discovery}",
|
||||
"RTarget": "true",
|
||||
"Operand": "="
|
||||
}
|
||||
],
|
||||
"Scaling": null,
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"Tasks": [
|
||||
{
|
||||
"Name": "task1",
|
||||
"Driver": "docker",
|
||||
"User": "",
|
||||
"Config": {
|
||||
"image": "nginx",
|
||||
"ports": [
|
||||
"http"
|
||||
]
|
||||
},
|
||||
"Env": null,
|
||||
"Services": null,
|
||||
"Vault": null,
|
||||
"Templates": null,
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Resources": {
|
||||
"CPU": 100,
|
||||
"Cores": 0,
|
||||
"MemoryMB": 300,
|
||||
"MemoryMaxMB": 0,
|
||||
"DiskMB": 0,
|
||||
"IOPS": 0,
|
||||
"Networks": null,
|
||||
"Devices": null
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"DispatchPayload": null,
|
||||
"Lifecycle": null,
|
||||
"Meta": null,
|
||||
"KillTimeout": 5000000000,
|
||||
"LogConfig": {
|
||||
"MaxFiles": 10,
|
||||
"MaxFileSizeMB": 10,
|
||||
"Disabled": false
|
||||
},
|
||||
"Artifacts": null,
|
||||
"Leader": false,
|
||||
"ShutdownDelay": 0,
|
||||
"VolumeMounts": null,
|
||||
"ScalingPolicies": null,
|
||||
"KillSignal": "",
|
||||
"Kind": "",
|
||||
"CSIPluginConfig": null,
|
||||
"Identity": null
|
||||
}
|
||||
],
|
||||
"EphemeralDisk": {
|
||||
"Sticky": false,
|
||||
"SizeMB": 300,
|
||||
"Migrate": false
|
||||
},
|
||||
"Meta": null,
|
||||
"ReschedulePolicy": {
|
||||
"Attempts": 0,
|
||||
"Interval": 0,
|
||||
"Delay": 30000000000,
|
||||
"DelayFunction": "exponential",
|
||||
"MaxDelay": 3600000000000,
|
||||
"Unlimited": true
|
||||
},
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"Networks": [
|
||||
{
|
||||
"Mode": "",
|
||||
"Device": "",
|
||||
"CIDR": "",
|
||||
"IP": "",
|
||||
"Hostname": "",
|
||||
"MBits": 0,
|
||||
"DNS": null,
|
||||
"ReservedPorts": null,
|
||||
"DynamicPorts": [
|
||||
{
|
||||
"Label": "http",
|
||||
"Value": 0,
|
||||
"To": 80,
|
||||
"HostNetwork": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Consul": {
|
||||
"Namespace": ""
|
||||
},
|
||||
"Services": [
|
||||
{
|
||||
"Name": "job4",
|
||||
"TaskName": "",
|
||||
"PortLabel": "http",
|
||||
"AddressMode": "auto",
|
||||
"Address": "",
|
||||
"EnableTagOverride": false,
|
||||
"Tags": [
|
||||
"traefik.enable=true"
|
||||
],
|
||||
"CanaryTags": null,
|
||||
"Checks": null,
|
||||
"Connect": null,
|
||||
"Meta": null,
|
||||
"CanaryMeta": null,
|
||||
"TaggedAddresses": null,
|
||||
"Namespace": "default",
|
||||
"OnUpdate": "require_healthy",
|
||||
"Provider": "nomad"
|
||||
}
|
||||
],
|
||||
"Volumes": null,
|
||||
"ShutdownDelay": null,
|
||||
"StopAfterClientDisconnect": null,
|
||||
"MaxClientDisconnect": null
|
||||
}
|
||||
],
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "",
|
||||
"MinHealthyTime": 0,
|
||||
"HealthyDeadline": 0,
|
||||
"ProgressDeadline": 0,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Multiregion": null,
|
||||
"Periodic": null,
|
||||
"ParameterizedJob": null,
|
||||
"Dispatched": false,
|
||||
"DispatchIdempotencyToken": "",
|
||||
"Payload": null,
|
||||
"Meta": null,
|
||||
"ConsulToken": "",
|
||||
"ConsulNamespace": "",
|
||||
"VaultToken": "",
|
||||
"VaultNamespace": "",
|
||||
"NomadTokenID": "",
|
||||
"Status": "dead",
|
||||
"StatusDescription": "",
|
||||
"Stable": true,
|
||||
"Version": 11,
|
||||
"SubmitTime": 1705690905317339000,
|
||||
"CreateIndex": 3079,
|
||||
"ModifyIndex": 10054,
|
||||
"JobModifyIndex": 10052
|
||||
}
|
|
@ -0,0 +1,299 @@
|
|||
{
|
||||
"Stop": false,
|
||||
"Region": "global",
|
||||
"Namespace": "default",
|
||||
"ID": "job5",
|
||||
"ParentID": "",
|
||||
"Name": "job5",
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"AllAtOnce": false,
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"TaskGroups": [
|
||||
{
|
||||
"Name": "group1",
|
||||
"Count": 1,
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000,
|
||||
"ProgressDeadline": 600000000000,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Migrate": {
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000
|
||||
},
|
||||
"Constraints": [
|
||||
{
|
||||
"LTarget": "${attr.nomad.service_discovery}",
|
||||
"RTarget": "true",
|
||||
"Operand": "="
|
||||
}
|
||||
],
|
||||
"Scaling": {
|
||||
"ID": "56d57f83-7b9e-fbfa-af96-e2c7f5dc698c",
|
||||
"Type": "horizontal",
|
||||
"Target": {
|
||||
"Namespace": "default",
|
||||
"Job": "job5",
|
||||
"Group": "group1"
|
||||
},
|
||||
"Policy": null,
|
||||
"Min": 0,
|
||||
"Max": 3,
|
||||
"Enabled": true,
|
||||
"CreateIndex": 0,
|
||||
"ModifyIndex": 0
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"Tasks": [
|
||||
{
|
||||
"Name": "task1",
|
||||
"Driver": "docker",
|
||||
"User": "",
|
||||
"Config": {
|
||||
"image": "nginx",
|
||||
"ports": [
|
||||
"http"
|
||||
]
|
||||
},
|
||||
"Env": null,
|
||||
"Services": [
|
||||
{
|
||||
"Name": "job5task1",
|
||||
"TaskName": "task1",
|
||||
"PortLabel": "http",
|
||||
"AddressMode": "auto",
|
||||
"Address": "",
|
||||
"EnableTagOverride": false,
|
||||
"Tags": [
|
||||
"traefik.enable=true"
|
||||
],
|
||||
"CanaryTags": null,
|
||||
"Checks": null,
|
||||
"Connect": null,
|
||||
"Meta": null,
|
||||
"CanaryMeta": null,
|
||||
"TaggedAddresses": null,
|
||||
"Namespace": "default",
|
||||
"OnUpdate": "require_healthy",
|
||||
"Provider": "nomad"
|
||||
}
|
||||
],
|
||||
"Vault": null,
|
||||
"Templates": null,
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Resources": {
|
||||
"CPU": 100,
|
||||
"Cores": 0,
|
||||
"MemoryMB": 300,
|
||||
"MemoryMaxMB": 0,
|
||||
"DiskMB": 0,
|
||||
"IOPS": 0,
|
||||
"Networks": null,
|
||||
"Devices": null
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"DispatchPayload": null,
|
||||
"Lifecycle": null,
|
||||
"Meta": null,
|
||||
"KillTimeout": 5000000000,
|
||||
"LogConfig": {
|
||||
"MaxFiles": 10,
|
||||
"MaxFileSizeMB": 10,
|
||||
"Disabled": false
|
||||
},
|
||||
"Artifacts": null,
|
||||
"Leader": false,
|
||||
"ShutdownDelay": 0,
|
||||
"VolumeMounts": null,
|
||||
"ScalingPolicies": null,
|
||||
"KillSignal": "",
|
||||
"Kind": "",
|
||||
"CSIPluginConfig": null,
|
||||
"Identity": null
|
||||
},
|
||||
{
|
||||
"Name": "task2",
|
||||
"Driver": "docker",
|
||||
"User": "",
|
||||
"Config": {
|
||||
"ports": [
|
||||
"other"
|
||||
],
|
||||
"image": "nginx"
|
||||
},
|
||||
"Env": null,
|
||||
"Services": [
|
||||
{
|
||||
"Name": "job5task2",
|
||||
"TaskName": "task2",
|
||||
"PortLabel": "other",
|
||||
"AddressMode": "auto",
|
||||
"Address": "",
|
||||
"EnableTagOverride": false,
|
||||
"Tags": [
|
||||
"traefik.enable=true"
|
||||
],
|
||||
"CanaryTags": null,
|
||||
"Checks": null,
|
||||
"Connect": null,
|
||||
"Meta": null,
|
||||
"CanaryMeta": null,
|
||||
"TaggedAddresses": null,
|
||||
"Namespace": "default",
|
||||
"OnUpdate": "require_healthy",
|
||||
"Provider": "nomad"
|
||||
}
|
||||
],
|
||||
"Vault": null,
|
||||
"Templates": null,
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Resources": {
|
||||
"CPU": 100,
|
||||
"Cores": 0,
|
||||
"MemoryMB": 300,
|
||||
"MemoryMaxMB": 0,
|
||||
"DiskMB": 0,
|
||||
"IOPS": 0,
|
||||
"Networks": null,
|
||||
"Devices": null
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"DispatchPayload": null,
|
||||
"Lifecycle": null,
|
||||
"Meta": null,
|
||||
"KillTimeout": 5000000000,
|
||||
"LogConfig": {
|
||||
"MaxFiles": 10,
|
||||
"MaxFileSizeMB": 10,
|
||||
"Disabled": false
|
||||
},
|
||||
"Artifacts": null,
|
||||
"Leader": false,
|
||||
"ShutdownDelay": 0,
|
||||
"VolumeMounts": null,
|
||||
"ScalingPolicies": null,
|
||||
"KillSignal": "",
|
||||
"Kind": "",
|
||||
"CSIPluginConfig": null,
|
||||
"Identity": null
|
||||
}
|
||||
],
|
||||
"EphemeralDisk": {
|
||||
"Sticky": false,
|
||||
"SizeMB": 300,
|
||||
"Migrate": false
|
||||
},
|
||||
"Meta": null,
|
||||
"ReschedulePolicy": {
|
||||
"Attempts": 0,
|
||||
"Interval": 0,
|
||||
"Delay": 30000000000,
|
||||
"DelayFunction": "exponential",
|
||||
"MaxDelay": 3600000000000,
|
||||
"Unlimited": true
|
||||
},
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"Networks": [
|
||||
{
|
||||
"Mode": "",
|
||||
"Device": "",
|
||||
"CIDR": "",
|
||||
"IP": "",
|
||||
"Hostname": "",
|
||||
"MBits": 0,
|
||||
"DNS": null,
|
||||
"ReservedPorts": null,
|
||||
"DynamicPorts": [
|
||||
{
|
||||
"Label": "http",
|
||||
"Value": 0,
|
||||
"To": 80,
|
||||
"HostNetwork": "default"
|
||||
},
|
||||
{
|
||||
"Label": "other",
|
||||
"Value": 0,
|
||||
"To": 80,
|
||||
"HostNetwork": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Consul": {
|
||||
"Namespace": ""
|
||||
},
|
||||
"Services": null,
|
||||
"Volumes": null,
|
||||
"ShutdownDelay": null,
|
||||
"StopAfterClientDisconnect": null,
|
||||
"MaxClientDisconnect": null
|
||||
}
|
||||
],
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "",
|
||||
"MinHealthyTime": 0,
|
||||
"HealthyDeadline": 0,
|
||||
"ProgressDeadline": 0,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Multiregion": null,
|
||||
"Periodic": null,
|
||||
"ParameterizedJob": null,
|
||||
"Dispatched": false,
|
||||
"DispatchIdempotencyToken": "",
|
||||
"Payload": null,
|
||||
"Meta": null,
|
||||
"ConsulToken": "",
|
||||
"ConsulNamespace": "",
|
||||
"VaultToken": "",
|
||||
"VaultNamespace": "",
|
||||
"NomadTokenID": "",
|
||||
"Status": "running",
|
||||
"StatusDescription": "",
|
||||
"Stable": true,
|
||||
"Version": 7,
|
||||
"SubmitTime": 1705690918813110300,
|
||||
"CreateIndex": 3095,
|
||||
"ModifyIndex": 10018,
|
||||
"JobModifyIndex": 10008
|
||||
}
|
|
@ -0,0 +1,299 @@
|
|||
{
|
||||
"Stop": false,
|
||||
"Region": "global",
|
||||
"Namespace": "default",
|
||||
"ID": "job6",
|
||||
"ParentID": "",
|
||||
"Name": "job6",
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"AllAtOnce": false,
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"TaskGroups": [
|
||||
{
|
||||
"Name": "group1",
|
||||
"Count": 0,
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000,
|
||||
"ProgressDeadline": 600000000000,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Migrate": {
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000
|
||||
},
|
||||
"Constraints": [
|
||||
{
|
||||
"LTarget": "${attr.nomad.service_discovery}",
|
||||
"RTarget": "true",
|
||||
"Operand": "="
|
||||
}
|
||||
],
|
||||
"Scaling": {
|
||||
"ID": "d18b02ae-5a68-e635-8100-06b110910b5f",
|
||||
"Type": "horizontal",
|
||||
"Target": {
|
||||
"Job": "job6",
|
||||
"Group": "group1",
|
||||
"Namespace": "default"
|
||||
},
|
||||
"Policy": null,
|
||||
"Min": 0,
|
||||
"Max": 3,
|
||||
"Enabled": true,
|
||||
"CreateIndex": 10020,
|
||||
"ModifyIndex": 10020
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"Tasks": [
|
||||
{
|
||||
"Name": "task1",
|
||||
"Driver": "docker",
|
||||
"User": "",
|
||||
"Config": {
|
||||
"image": "nginx",
|
||||
"ports": [
|
||||
"http"
|
||||
]
|
||||
},
|
||||
"Env": null,
|
||||
"Services": [
|
||||
{
|
||||
"Name": "job6task1",
|
||||
"TaskName": "task1",
|
||||
"PortLabel": "http",
|
||||
"AddressMode": "auto",
|
||||
"Address": "",
|
||||
"EnableTagOverride": false,
|
||||
"Tags": [
|
||||
"traefik.enable=true"
|
||||
],
|
||||
"CanaryTags": null,
|
||||
"Checks": null,
|
||||
"Connect": null,
|
||||
"Meta": null,
|
||||
"CanaryMeta": null,
|
||||
"TaggedAddresses": null,
|
||||
"Namespace": "default",
|
||||
"OnUpdate": "require_healthy",
|
||||
"Provider": "nomad"
|
||||
}
|
||||
],
|
||||
"Vault": null,
|
||||
"Templates": null,
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Resources": {
|
||||
"CPU": 100,
|
||||
"Cores": 0,
|
||||
"MemoryMB": 300,
|
||||
"MemoryMaxMB": 0,
|
||||
"DiskMB": 0,
|
||||
"IOPS": 0,
|
||||
"Networks": null,
|
||||
"Devices": null
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"DispatchPayload": null,
|
||||
"Lifecycle": null,
|
||||
"Meta": null,
|
||||
"KillTimeout": 5000000000,
|
||||
"LogConfig": {
|
||||
"MaxFiles": 10,
|
||||
"MaxFileSizeMB": 10,
|
||||
"Disabled": false
|
||||
},
|
||||
"Artifacts": null,
|
||||
"Leader": false,
|
||||
"ShutdownDelay": 0,
|
||||
"VolumeMounts": null,
|
||||
"ScalingPolicies": null,
|
||||
"KillSignal": "",
|
||||
"Kind": "",
|
||||
"CSIPluginConfig": null,
|
||||
"Identity": null
|
||||
},
|
||||
{
|
||||
"Name": "task2",
|
||||
"Driver": "docker",
|
||||
"User": "",
|
||||
"Config": {
|
||||
"image": "nginx",
|
||||
"ports": [
|
||||
"other"
|
||||
]
|
||||
},
|
||||
"Env": null,
|
||||
"Services": [
|
||||
{
|
||||
"Name": "job6task2",
|
||||
"TaskName": "task2",
|
||||
"PortLabel": "other",
|
||||
"AddressMode": "auto",
|
||||
"Address": "",
|
||||
"EnableTagOverride": false,
|
||||
"Tags": [
|
||||
"traefik.enable=true"
|
||||
],
|
||||
"CanaryTags": null,
|
||||
"Checks": null,
|
||||
"Connect": null,
|
||||
"Meta": null,
|
||||
"CanaryMeta": null,
|
||||
"TaggedAddresses": null,
|
||||
"Namespace": "default",
|
||||
"OnUpdate": "require_healthy",
|
||||
"Provider": "nomad"
|
||||
}
|
||||
],
|
||||
"Vault": null,
|
||||
"Templates": null,
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Resources": {
|
||||
"CPU": 100,
|
||||
"Cores": 0,
|
||||
"MemoryMB": 300,
|
||||
"MemoryMaxMB": 0,
|
||||
"DiskMB": 0,
|
||||
"IOPS": 0,
|
||||
"Networks": null,
|
||||
"Devices": null
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"DispatchPayload": null,
|
||||
"Lifecycle": null,
|
||||
"Meta": null,
|
||||
"KillTimeout": 5000000000,
|
||||
"LogConfig": {
|
||||
"MaxFiles": 10,
|
||||
"MaxFileSizeMB": 10,
|
||||
"Disabled": false
|
||||
},
|
||||
"Artifacts": null,
|
||||
"Leader": false,
|
||||
"ShutdownDelay": 0,
|
||||
"VolumeMounts": null,
|
||||
"ScalingPolicies": null,
|
||||
"KillSignal": "",
|
||||
"Kind": "",
|
||||
"CSIPluginConfig": null,
|
||||
"Identity": null
|
||||
}
|
||||
],
|
||||
"EphemeralDisk": {
|
||||
"Sticky": false,
|
||||
"SizeMB": 300,
|
||||
"Migrate": false
|
||||
},
|
||||
"Meta": null,
|
||||
"ReschedulePolicy": {
|
||||
"Attempts": 0,
|
||||
"Interval": 0,
|
||||
"Delay": 30000000000,
|
||||
"DelayFunction": "exponential",
|
||||
"MaxDelay": 3600000000000,
|
||||
"Unlimited": true
|
||||
},
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"Networks": [
|
||||
{
|
||||
"Mode": "",
|
||||
"Device": "",
|
||||
"CIDR": "",
|
||||
"IP": "",
|
||||
"Hostname": "",
|
||||
"MBits": 0,
|
||||
"DNS": null,
|
||||
"ReservedPorts": null,
|
||||
"DynamicPorts": [
|
||||
{
|
||||
"Label": "http",
|
||||
"Value": 0,
|
||||
"To": 80,
|
||||
"HostNetwork": "default"
|
||||
},
|
||||
{
|
||||
"Label": "other",
|
||||
"Value": 0,
|
||||
"To": 80,
|
||||
"HostNetwork": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Consul": {
|
||||
"Namespace": ""
|
||||
},
|
||||
"Services": null,
|
||||
"Volumes": null,
|
||||
"ShutdownDelay": null,
|
||||
"StopAfterClientDisconnect": null,
|
||||
"MaxClientDisconnect": null
|
||||
}
|
||||
],
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "",
|
||||
"MinHealthyTime": 0,
|
||||
"HealthyDeadline": 0,
|
||||
"ProgressDeadline": 0,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Multiregion": null,
|
||||
"Periodic": null,
|
||||
"ParameterizedJob": null,
|
||||
"Dispatched": false,
|
||||
"DispatchIdempotencyToken": "",
|
||||
"Payload": null,
|
||||
"Meta": null,
|
||||
"ConsulToken": "",
|
||||
"ConsulNamespace": "",
|
||||
"VaultToken": "",
|
||||
"VaultNamespace": "",
|
||||
"NomadTokenID": "",
|
||||
"Status": "dead",
|
||||
"StatusDescription": "",
|
||||
"Stable": true,
|
||||
"Version": 3,
|
||||
"SubmitTime": 1705690931854150700,
|
||||
"CreateIndex": 9941,
|
||||
"ModifyIndex": 10078,
|
||||
"JobModifyIndex": 10074
|
||||
}
|
222
pkg/provider/nomad/fixtures/job_job7_TCP.json
Normal file
222
pkg/provider/nomad/fixtures/job_job7_TCP.json
Normal file
|
@ -0,0 +1,222 @@
|
|||
{
|
||||
"Stop": false,
|
||||
"Region": "global",
|
||||
"Namespace": "default",
|
||||
"ID": "job7",
|
||||
"ParentID": "",
|
||||
"Name": "job7",
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"AllAtOnce": false,
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"TaskGroups": [
|
||||
{
|
||||
"Name": "group1",
|
||||
"Count": 1,
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000,
|
||||
"ProgressDeadline": 600000000000,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Migrate": {
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000
|
||||
},
|
||||
"Constraints": [
|
||||
{
|
||||
"LTarget": "${attr.nomad.service_discovery}",
|
||||
"RTarget": "true",
|
||||
"Operand": "="
|
||||
}
|
||||
],
|
||||
"Scaling": {
|
||||
"ID": "e3b82307-1b7f-5fc6-901a-d9174418461f",
|
||||
"Type": "horizontal",
|
||||
"Target": {
|
||||
"Namespace": "default",
|
||||
"Job": "job7",
|
||||
"Group": "group1"
|
||||
},
|
||||
"Policy": null,
|
||||
"Min": 0,
|
||||
"Max": 3,
|
||||
"Enabled": true,
|
||||
"CreateIndex": 0,
|
||||
"ModifyIndex": 0
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"Tasks": [
|
||||
{
|
||||
"Name": "task1",
|
||||
"Driver": "docker",
|
||||
"User": "",
|
||||
"Config": {
|
||||
"image": "nginx",
|
||||
"ports": [
|
||||
"http"
|
||||
]
|
||||
},
|
||||
"Env": null,
|
||||
"Services": null,
|
||||
"Vault": null,
|
||||
"Templates": null,
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Resources": {
|
||||
"CPU": 100,
|
||||
"Cores": 0,
|
||||
"MemoryMB": 300,
|
||||
"MemoryMaxMB": 0,
|
||||
"DiskMB": 0,
|
||||
"IOPS": 0,
|
||||
"Networks": null,
|
||||
"Devices": null
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"DispatchPayload": null,
|
||||
"Lifecycle": null,
|
||||
"Meta": null,
|
||||
"KillTimeout": 5000000000,
|
||||
"LogConfig": {
|
||||
"MaxFiles": 10,
|
||||
"MaxFileSizeMB": 10,
|
||||
"Disabled": false
|
||||
},
|
||||
"Artifacts": null,
|
||||
"Leader": false,
|
||||
"ShutdownDelay": 0,
|
||||
"VolumeMounts": null,
|
||||
"ScalingPolicies": null,
|
||||
"KillSignal": "",
|
||||
"Kind": "",
|
||||
"CSIPluginConfig": null,
|
||||
"Identity": null
|
||||
}
|
||||
],
|
||||
"EphemeralDisk": {
|
||||
"Sticky": false,
|
||||
"SizeMB": 300,
|
||||
"Migrate": false
|
||||
},
|
||||
"Meta": null,
|
||||
"ReschedulePolicy": {
|
||||
"Attempts": 0,
|
||||
"Interval": 0,
|
||||
"Delay": 30000000000,
|
||||
"DelayFunction": "exponential",
|
||||
"MaxDelay": 3600000000000,
|
||||
"Unlimited": true
|
||||
},
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"Networks": [
|
||||
{
|
||||
"Mode": "",
|
||||
"Device": "",
|
||||
"CIDR": "",
|
||||
"IP": "",
|
||||
"Hostname": "",
|
||||
"MBits": 0,
|
||||
"DNS": null,
|
||||
"ReservedPorts": null,
|
||||
"DynamicPorts": [
|
||||
{
|
||||
"Label": "http",
|
||||
"Value": 0,
|
||||
"To": 80,
|
||||
"HostNetwork": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Consul": {
|
||||
"Namespace": ""
|
||||
},
|
||||
"Services": [
|
||||
{
|
||||
"Name": "job7",
|
||||
"TaskName": "",
|
||||
"PortLabel": "http",
|
||||
"AddressMode": "auto",
|
||||
"Address": "",
|
||||
"EnableTagOverride": false,
|
||||
"Tags": [
|
||||
"traefik.enable=true",
|
||||
"traefik.tcp.routers.job7.rule=HostSNI(`job7`)",
|
||||
"traefik.tcp.routers.job7.tls.passthrough=true"
|
||||
],
|
||||
"CanaryTags": null,
|
||||
"Checks": null,
|
||||
"Connect": null,
|
||||
"Meta": null,
|
||||
"CanaryMeta": null,
|
||||
"TaggedAddresses": null,
|
||||
"Namespace": "default",
|
||||
"OnUpdate": "require_healthy",
|
||||
"Provider": "nomad"
|
||||
}
|
||||
],
|
||||
"Volumes": null,
|
||||
"ShutdownDelay": null,
|
||||
"StopAfterClientDisconnect": null,
|
||||
"MaxClientDisconnect": null
|
||||
}
|
||||
],
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "",
|
||||
"MinHealthyTime": 0,
|
||||
"HealthyDeadline": 0,
|
||||
"ProgressDeadline": 0,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Multiregion": null,
|
||||
"Periodic": null,
|
||||
"ParameterizedJob": null,
|
||||
"Dispatched": false,
|
||||
"DispatchIdempotencyToken": "",
|
||||
"Payload": null,
|
||||
"Meta": null,
|
||||
"ConsulToken": "",
|
||||
"ConsulNamespace": "",
|
||||
"VaultToken": "",
|
||||
"VaultNamespace": "",
|
||||
"NomadTokenID": "",
|
||||
"Status": "running",
|
||||
"StatusDescription": "",
|
||||
"Stable": true,
|
||||
"Version": 1,
|
||||
"SubmitTime": 1705752438438572000,
|
||||
"CreateIndex": 11221,
|
||||
"ModifyIndex": 11238,
|
||||
"JobModifyIndex": 11232
|
||||
}
|
221
pkg/provider/nomad/fixtures/job_job8_UDP.json
Normal file
221
pkg/provider/nomad/fixtures/job_job8_UDP.json
Normal file
|
@ -0,0 +1,221 @@
|
|||
{
|
||||
"Stop": false,
|
||||
"Region": "global",
|
||||
"Namespace": "default",
|
||||
"ID": "job8",
|
||||
"ParentID": "",
|
||||
"Name": "job8",
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"AllAtOnce": false,
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"TaskGroups": [
|
||||
{
|
||||
"Name": "group1",
|
||||
"Count": 1,
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000,
|
||||
"ProgressDeadline": 600000000000,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Migrate": {
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000
|
||||
},
|
||||
"Constraints": [
|
||||
{
|
||||
"LTarget": "${attr.nomad.service_discovery}",
|
||||
"RTarget": "true",
|
||||
"Operand": "="
|
||||
}
|
||||
],
|
||||
"Scaling": {
|
||||
"ID": "3828aaa9-4e16-cde5-cc80-f0cec4a7c82d",
|
||||
"Type": "horizontal",
|
||||
"Target": {
|
||||
"Namespace": "default",
|
||||
"Job": "job8",
|
||||
"Group": "group1"
|
||||
},
|
||||
"Policy": null,
|
||||
"Min": 0,
|
||||
"Max": 3,
|
||||
"Enabled": true,
|
||||
"CreateIndex": 0,
|
||||
"ModifyIndex": 0
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"Tasks": [
|
||||
{
|
||||
"Name": "task1",
|
||||
"Driver": "docker",
|
||||
"User": "",
|
||||
"Config": {
|
||||
"ports": [
|
||||
"http"
|
||||
],
|
||||
"image": "nginx"
|
||||
},
|
||||
"Env": null,
|
||||
"Services": null,
|
||||
"Vault": null,
|
||||
"Templates": null,
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Resources": {
|
||||
"CPU": 100,
|
||||
"Cores": 0,
|
||||
"MemoryMB": 300,
|
||||
"MemoryMaxMB": 0,
|
||||
"DiskMB": 0,
|
||||
"IOPS": 0,
|
||||
"Networks": null,
|
||||
"Devices": null
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"DispatchPayload": null,
|
||||
"Lifecycle": null,
|
||||
"Meta": null,
|
||||
"KillTimeout": 5000000000,
|
||||
"LogConfig": {
|
||||
"MaxFiles": 10,
|
||||
"MaxFileSizeMB": 10,
|
||||
"Disabled": false
|
||||
},
|
||||
"Artifacts": null,
|
||||
"Leader": false,
|
||||
"ShutdownDelay": 0,
|
||||
"VolumeMounts": null,
|
||||
"ScalingPolicies": null,
|
||||
"KillSignal": "",
|
||||
"Kind": "",
|
||||
"CSIPluginConfig": null,
|
||||
"Identity": null
|
||||
}
|
||||
],
|
||||
"EphemeralDisk": {
|
||||
"Sticky": false,
|
||||
"SizeMB": 300,
|
||||
"Migrate": false
|
||||
},
|
||||
"Meta": null,
|
||||
"ReschedulePolicy": {
|
||||
"Attempts": 0,
|
||||
"Interval": 0,
|
||||
"Delay": 30000000000,
|
||||
"DelayFunction": "exponential",
|
||||
"MaxDelay": 3600000000000,
|
||||
"Unlimited": true
|
||||
},
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"Networks": [
|
||||
{
|
||||
"Mode": "",
|
||||
"Device": "",
|
||||
"CIDR": "",
|
||||
"IP": "",
|
||||
"Hostname": "",
|
||||
"MBits": 0,
|
||||
"DNS": null,
|
||||
"ReservedPorts": null,
|
||||
"DynamicPorts": [
|
||||
{
|
||||
"Label": "http",
|
||||
"Value": 0,
|
||||
"To": 80,
|
||||
"HostNetwork": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Consul": {
|
||||
"Namespace": ""
|
||||
},
|
||||
"Services": [
|
||||
{
|
||||
"Name": "job8",
|
||||
"TaskName": "",
|
||||
"PortLabel": "http",
|
||||
"AddressMode": "auto",
|
||||
"Address": "",
|
||||
"EnableTagOverride": false,
|
||||
"Tags": [
|
||||
"traefik.enable=true",
|
||||
"traefik.udp.routers.job8.service=job8"
|
||||
],
|
||||
"CanaryTags": null,
|
||||
"Checks": null,
|
||||
"Connect": null,
|
||||
"Meta": null,
|
||||
"CanaryMeta": null,
|
||||
"TaggedAddresses": null,
|
||||
"Namespace": "default",
|
||||
"OnUpdate": "require_healthy",
|
||||
"Provider": "nomad"
|
||||
}
|
||||
],
|
||||
"Volumes": null,
|
||||
"ShutdownDelay": null,
|
||||
"StopAfterClientDisconnect": null,
|
||||
"MaxClientDisconnect": null
|
||||
}
|
||||
],
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "",
|
||||
"MinHealthyTime": 0,
|
||||
"HealthyDeadline": 0,
|
||||
"ProgressDeadline": 0,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Multiregion": null,
|
||||
"Periodic": null,
|
||||
"ParameterizedJob": null,
|
||||
"Dispatched": false,
|
||||
"DispatchIdempotencyToken": "",
|
||||
"Payload": null,
|
||||
"Meta": null,
|
||||
"ConsulToken": "",
|
||||
"ConsulNamespace": "",
|
||||
"VaultToken": "",
|
||||
"VaultNamespace": "",
|
||||
"NomadTokenID": "",
|
||||
"Status": "running",
|
||||
"StatusDescription": "",
|
||||
"Stable": true,
|
||||
"Version": 2,
|
||||
"SubmitTime": 1705753285493029600,
|
||||
"CreateIndex": 11276,
|
||||
"ModifyIndex": 11303,
|
||||
"JobModifyIndex": 11297
|
||||
}
|
220
pkg/provider/nomad/fixtures/job_job9_ScalingEnabled_Stopped.json
Normal file
220
pkg/provider/nomad/fixtures/job_job9_ScalingEnabled_Stopped.json
Normal file
|
@ -0,0 +1,220 @@
|
|||
{
|
||||
"Stop": true,
|
||||
"Region": "global",
|
||||
"Namespace": "default",
|
||||
"ID": "job9",
|
||||
"ParentID": "",
|
||||
"Name": "job9",
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"AllAtOnce": false,
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"TaskGroups": [
|
||||
{
|
||||
"Name": "group1",
|
||||
"Count": 1,
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000,
|
||||
"ProgressDeadline": 600000000000,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Migrate": {
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "checks",
|
||||
"MinHealthyTime": 10000000000,
|
||||
"HealthyDeadline": 300000000000
|
||||
},
|
||||
"Constraints": [
|
||||
{
|
||||
"LTarget": "${attr.nomad.service_discovery}",
|
||||
"RTarget": "true",
|
||||
"Operand": "="
|
||||
}
|
||||
],
|
||||
"Scaling": {
|
||||
"ID": "094d38a7-24cf-d3a4-3a82-cfc50ef7c597",
|
||||
"Type": "horizontal",
|
||||
"Target": {
|
||||
"Group": "group1",
|
||||
"Namespace": "default",
|
||||
"Job": "job9"
|
||||
},
|
||||
"Policy": null,
|
||||
"Min": 0,
|
||||
"Max": 3,
|
||||
"Enabled": true,
|
||||
"CreateIndex": 0,
|
||||
"ModifyIndex": 0
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"Tasks": [
|
||||
{
|
||||
"Name": "task1",
|
||||
"Driver": "docker",
|
||||
"User": "",
|
||||
"Config": {
|
||||
"image": "nginx",
|
||||
"ports": [
|
||||
"http"
|
||||
]
|
||||
},
|
||||
"Env": null,
|
||||
"Services": null,
|
||||
"Vault": null,
|
||||
"Templates": null,
|
||||
"Constraints": null,
|
||||
"Affinities": null,
|
||||
"Resources": {
|
||||
"CPU": 100,
|
||||
"Cores": 0,
|
||||
"MemoryMB": 300,
|
||||
"MemoryMaxMB": 0,
|
||||
"DiskMB": 0,
|
||||
"IOPS": 0,
|
||||
"Networks": null,
|
||||
"Devices": null
|
||||
},
|
||||
"RestartPolicy": {
|
||||
"Attempts": 2,
|
||||
"Interval": 1800000000000,
|
||||
"Delay": 15000000000,
|
||||
"Mode": "fail",
|
||||
"RenderTemplates": false
|
||||
},
|
||||
"DispatchPayload": null,
|
||||
"Lifecycle": null,
|
||||
"Meta": null,
|
||||
"KillTimeout": 5000000000,
|
||||
"LogConfig": {
|
||||
"MaxFiles": 10,
|
||||
"MaxFileSizeMB": 10,
|
||||
"Disabled": false
|
||||
},
|
||||
"Artifacts": null,
|
||||
"Leader": false,
|
||||
"ShutdownDelay": 0,
|
||||
"VolumeMounts": null,
|
||||
"ScalingPolicies": null,
|
||||
"KillSignal": "",
|
||||
"Kind": "",
|
||||
"CSIPluginConfig": null,
|
||||
"Identity": null
|
||||
}
|
||||
],
|
||||
"EphemeralDisk": {
|
||||
"Sticky": false,
|
||||
"SizeMB": 300,
|
||||
"Migrate": false
|
||||
},
|
||||
"Meta": null,
|
||||
"ReschedulePolicy": {
|
||||
"Attempts": 0,
|
||||
"Interval": 0,
|
||||
"Delay": 30000000000,
|
||||
"DelayFunction": "exponential",
|
||||
"MaxDelay": 3600000000000,
|
||||
"Unlimited": true
|
||||
},
|
||||
"Affinities": null,
|
||||
"Spreads": null,
|
||||
"Networks": [
|
||||
{
|
||||
"Mode": "",
|
||||
"Device": "",
|
||||
"CIDR": "",
|
||||
"IP": "",
|
||||
"Hostname": "",
|
||||
"MBits": 0,
|
||||
"DNS": null,
|
||||
"ReservedPorts": null,
|
||||
"DynamicPorts": [
|
||||
{
|
||||
"Label": "http",
|
||||
"Value": 0,
|
||||
"To": 80,
|
||||
"HostNetwork": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Consul": {
|
||||
"Namespace": ""
|
||||
},
|
||||
"Services": [
|
||||
{
|
||||
"Name": "job9",
|
||||
"TaskName": "",
|
||||
"PortLabel": "http",
|
||||
"AddressMode": "auto",
|
||||
"Address": "",
|
||||
"EnableTagOverride": false,
|
||||
"Tags": [
|
||||
"traefik.enable=true"
|
||||
],
|
||||
"CanaryTags": null,
|
||||
"Checks": null,
|
||||
"Connect": null,
|
||||
"Meta": null,
|
||||
"CanaryMeta": null,
|
||||
"TaggedAddresses": null,
|
||||
"Namespace": "default",
|
||||
"OnUpdate": "require_healthy",
|
||||
"Provider": "nomad"
|
||||
}
|
||||
],
|
||||
"Volumes": null,
|
||||
"ShutdownDelay": null,
|
||||
"StopAfterClientDisconnect": null,
|
||||
"MaxClientDisconnect": null
|
||||
}
|
||||
],
|
||||
"Update": {
|
||||
"Stagger": 30000000000,
|
||||
"MaxParallel": 1,
|
||||
"HealthCheck": "",
|
||||
"MinHealthyTime": 0,
|
||||
"HealthyDeadline": 0,
|
||||
"ProgressDeadline": 0,
|
||||
"AutoRevert": false,
|
||||
"AutoPromote": false,
|
||||
"Canary": 0
|
||||
},
|
||||
"Multiregion": null,
|
||||
"Periodic": null,
|
||||
"ParameterizedJob": null,
|
||||
"Dispatched": false,
|
||||
"DispatchIdempotencyToken": "",
|
||||
"Payload": null,
|
||||
"Meta": null,
|
||||
"ConsulToken": "",
|
||||
"ConsulNamespace": "",
|
||||
"VaultToken": "",
|
||||
"VaultNamespace": "",
|
||||
"NomadTokenID": "",
|
||||
"Status": "dead",
|
||||
"StatusDescription": "",
|
||||
"Stable": true,
|
||||
"Version": 3,
|
||||
"SubmitTime": 1705753979676559600,
|
||||
"CreateIndex": 11317,
|
||||
"ModifyIndex": 11346,
|
||||
"JobModifyIndex": 11344
|
||||
}
|
56
pkg/provider/nomad/fixtures/jobs_job1.json
Normal file
56
pkg/provider/nomad/fixtures/jobs_job1.json
Normal file
|
@ -0,0 +1,56 @@
|
|||
[
|
||||
{
|
||||
"ID": "job1",
|
||||
"ParentID": "",
|
||||
"Name": "job1",
|
||||
"Namespace": "default",
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Multiregion": null,
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"Periodic": false,
|
||||
"ParameterizedJob": false,
|
||||
"Stop": false,
|
||||
"Status": "running",
|
||||
"StatusDescription": "",
|
||||
"JobSummary": {
|
||||
"JobID": "job1",
|
||||
"Namespace": "default",
|
||||
"Summary": {
|
||||
"job1": {
|
||||
"Queued": 0,
|
||||
"Complete": 1,
|
||||
"Failed": 0,
|
||||
"Running": 0,
|
||||
"Starting": 0,
|
||||
"Lost": 0,
|
||||
"Unknown": 0
|
||||
},
|
||||
"group1": {
|
||||
"Queued": 0,
|
||||
"Complete": 6,
|
||||
"Failed": 1,
|
||||
"Running": 1,
|
||||
"Starting": 0,
|
||||
"Lost": 0,
|
||||
"Unknown": 0
|
||||
}
|
||||
},
|
||||
"Children": {
|
||||
"Pending": 0,
|
||||
"Running": 0,
|
||||
"Dead": 0
|
||||
},
|
||||
"CreateIndex": 493,
|
||||
"ModifyIndex": 9909
|
||||
},
|
||||
"CreateIndex": 493,
|
||||
"ModifyIndex": 9961,
|
||||
"JobModifyIndex": 9955,
|
||||
"SubmitTime": 1705690395733241600,
|
||||
"Meta": null
|
||||
}
|
||||
]
|
47
pkg/provider/nomad/fixtures/jobs_job2.json
Normal file
47
pkg/provider/nomad/fixtures/jobs_job2.json
Normal file
|
@ -0,0 +1,47 @@
|
|||
[
|
||||
{
|
||||
"ID": "job2",
|
||||
"ParentID": "",
|
||||
"Name": "job2",
|
||||
"Namespace": "default",
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Multiregion": null,
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"Periodic": false,
|
||||
"ParameterizedJob": false,
|
||||
"Stop": false,
|
||||
"Status": "dead",
|
||||
"StatusDescription": "",
|
||||
"JobSummary": {
|
||||
"JobID": "job2",
|
||||
"Namespace": "default",
|
||||
"Summary": {
|
||||
"group1": {
|
||||
"Queued": 0,
|
||||
"Complete": 6,
|
||||
"Failed": 6,
|
||||
"Running": 0,
|
||||
"Starting": 0,
|
||||
"Lost": 0,
|
||||
"Unknown": 0
|
||||
}
|
||||
},
|
||||
"Children": {
|
||||
"Pending": 0,
|
||||
"Running": 0,
|
||||
"Dead": 0
|
||||
},
|
||||
"CreateIndex": 2923,
|
||||
"ModifyIndex": 10051
|
||||
},
|
||||
"CreateIndex": 2923,
|
||||
"ModifyIndex": 10048,
|
||||
"JobModifyIndex": 10044,
|
||||
"SubmitTime": 1705690880440177400,
|
||||
"Meta": null
|
||||
}
|
||||
]
|
47
pkg/provider/nomad/fixtures/jobs_job3.json
Normal file
47
pkg/provider/nomad/fixtures/jobs_job3.json
Normal file
|
@ -0,0 +1,47 @@
|
|||
[
|
||||
{
|
||||
"ID": "job3",
|
||||
"ParentID": "",
|
||||
"Name": "job3",
|
||||
"Namespace": "default",
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Multiregion": null,
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"Periodic": false,
|
||||
"ParameterizedJob": false,
|
||||
"Stop": false,
|
||||
"Status": "running",
|
||||
"StatusDescription": "",
|
||||
"JobSummary": {
|
||||
"JobID": "job3",
|
||||
"Namespace": "default",
|
||||
"Summary": {
|
||||
"group1": {
|
||||
"Queued": 0,
|
||||
"Complete": 1,
|
||||
"Failed": 0,
|
||||
"Running": 1,
|
||||
"Starting": 0,
|
||||
"Lost": 0,
|
||||
"Unknown": 0
|
||||
}
|
||||
},
|
||||
"Children": {
|
||||
"Pending": 0,
|
||||
"Running": 0,
|
||||
"Dead": 0
|
||||
},
|
||||
"CreateIndex": 2932,
|
||||
"ModifyIndex": 9989
|
||||
},
|
||||
"CreateIndex": 2932,
|
||||
"ModifyIndex": 9992,
|
||||
"JobModifyIndex": 9983,
|
||||
"SubmitTime": 1705690892484556300,
|
||||
"Meta": null
|
||||
}
|
||||
]
|
47
pkg/provider/nomad/fixtures/jobs_job4.json
Normal file
47
pkg/provider/nomad/fixtures/jobs_job4.json
Normal file
|
@ -0,0 +1,47 @@
|
|||
[
|
||||
{
|
||||
"ID": "job4",
|
||||
"ParentID": "",
|
||||
"Name": "job4",
|
||||
"Namespace": "default",
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Multiregion": null,
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"Periodic": false,
|
||||
"ParameterizedJob": false,
|
||||
"Stop": true,
|
||||
"Status": "dead",
|
||||
"StatusDescription": "",
|
||||
"JobSummary": {
|
||||
"JobID": "job4",
|
||||
"Namespace": "default",
|
||||
"Summary": {
|
||||
"group1": {
|
||||
"Queued": 0,
|
||||
"Complete": 6,
|
||||
"Failed": 0,
|
||||
"Running": 0,
|
||||
"Starting": 0,
|
||||
"Lost": 0,
|
||||
"Unknown": 0
|
||||
}
|
||||
},
|
||||
"Children": {
|
||||
"Pending": 0,
|
||||
"Running": 0,
|
||||
"Dead": 0
|
||||
},
|
||||
"CreateIndex": 3079,
|
||||
"ModifyIndex": 10057
|
||||
},
|
||||
"CreateIndex": 3079,
|
||||
"ModifyIndex": 10054,
|
||||
"JobModifyIndex": 10052,
|
||||
"SubmitTime": 1705690905317339000,
|
||||
"Meta": null
|
||||
}
|
||||
]
|
56
pkg/provider/nomad/fixtures/jobs_job5.json
Normal file
56
pkg/provider/nomad/fixtures/jobs_job5.json
Normal file
|
@ -0,0 +1,56 @@
|
|||
[
|
||||
{
|
||||
"ID": "job5",
|
||||
"ParentID": "",
|
||||
"Name": "job5",
|
||||
"Namespace": "default",
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Multiregion": null,
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"Periodic": false,
|
||||
"ParameterizedJob": false,
|
||||
"Stop": false,
|
||||
"Status": "running",
|
||||
"StatusDescription": "",
|
||||
"JobSummary": {
|
||||
"JobID": "job5",
|
||||
"Namespace": "default",
|
||||
"Summary": {
|
||||
"job5": {
|
||||
"Queued": 0,
|
||||
"Complete": 2,
|
||||
"Failed": 0,
|
||||
"Running": 0,
|
||||
"Starting": 0,
|
||||
"Lost": 0,
|
||||
"Unknown": 0
|
||||
},
|
||||
"group1": {
|
||||
"Queued": 0,
|
||||
"Complete": 4,
|
||||
"Failed": 0,
|
||||
"Running": 1,
|
||||
"Starting": 0,
|
||||
"Lost": 0,
|
||||
"Unknown": 0
|
||||
}
|
||||
},
|
||||
"Children": {
|
||||
"Pending": 0,
|
||||
"Running": 0,
|
||||
"Dead": 0
|
||||
},
|
||||
"CreateIndex": 3095,
|
||||
"ModifyIndex": 10015
|
||||
},
|
||||
"CreateIndex": 3095,
|
||||
"ModifyIndex": 10018,
|
||||
"JobModifyIndex": 10008,
|
||||
"SubmitTime": 1705690918813110300,
|
||||
"Meta": null
|
||||
}
|
||||
]
|
47
pkg/provider/nomad/fixtures/jobs_job6.json
Normal file
47
pkg/provider/nomad/fixtures/jobs_job6.json
Normal file
|
@ -0,0 +1,47 @@
|
|||
[
|
||||
{
|
||||
"ID": "job6",
|
||||
"ParentID": "",
|
||||
"Name": "job6",
|
||||
"Namespace": "default",
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Multiregion": null,
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"Periodic": false,
|
||||
"ParameterizedJob": false,
|
||||
"Stop": false,
|
||||
"Status": "dead",
|
||||
"StatusDescription": "",
|
||||
"JobSummary": {
|
||||
"JobID": "job6",
|
||||
"Namespace": "default",
|
||||
"Summary": {
|
||||
"group1": {
|
||||
"Queued": 0,
|
||||
"Complete": 3,
|
||||
"Failed": 0,
|
||||
"Running": 0,
|
||||
"Starting": 0,
|
||||
"Lost": 0,
|
||||
"Unknown": 0
|
||||
}
|
||||
},
|
||||
"Children": {
|
||||
"Pending": 0,
|
||||
"Running": 0,
|
||||
"Dead": 0
|
||||
},
|
||||
"CreateIndex": 9941,
|
||||
"ModifyIndex": 10082
|
||||
},
|
||||
"CreateIndex": 9941,
|
||||
"ModifyIndex": 10078,
|
||||
"JobModifyIndex": 10074,
|
||||
"SubmitTime": 1705690931854150700,
|
||||
"Meta": null
|
||||
}
|
||||
]
|
47
pkg/provider/nomad/fixtures/jobs_job7.json
Normal file
47
pkg/provider/nomad/fixtures/jobs_job7.json
Normal file
|
@ -0,0 +1,47 @@
|
|||
[
|
||||
{
|
||||
"ID": "job7",
|
||||
"ParentID": "",
|
||||
"Name": "job7",
|
||||
"Namespace": "default",
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Multiregion": null,
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"Periodic": false,
|
||||
"ParameterizedJob": false,
|
||||
"Stop": false,
|
||||
"Status": "running",
|
||||
"StatusDescription": "",
|
||||
"JobSummary": {
|
||||
"JobID": "job7",
|
||||
"Namespace": "default",
|
||||
"Summary": {
|
||||
"group1": {
|
||||
"Queued": 0,
|
||||
"Complete": 0,
|
||||
"Failed": 0,
|
||||
"Running": 1,
|
||||
"Starting": 0,
|
||||
"Lost": 0,
|
||||
"Unknown": 0
|
||||
}
|
||||
},
|
||||
"Children": {
|
||||
"Pending": 0,
|
||||
"Running": 0,
|
||||
"Dead": 0
|
||||
},
|
||||
"CreateIndex": 11221,
|
||||
"ModifyIndex": 11225
|
||||
},
|
||||
"CreateIndex": 11221,
|
||||
"ModifyIndex": 11238,
|
||||
"JobModifyIndex": 11232,
|
||||
"SubmitTime": 1705752438438572000,
|
||||
"Meta": null
|
||||
}
|
||||
]
|
47
pkg/provider/nomad/fixtures/jobs_job8.json
Normal file
47
pkg/provider/nomad/fixtures/jobs_job8.json
Normal file
|
@ -0,0 +1,47 @@
|
|||
[
|
||||
{
|
||||
"ID": "job8",
|
||||
"ParentID": "",
|
||||
"Name": "job8",
|
||||
"Namespace": "default",
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Multiregion": null,
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"Periodic": false,
|
||||
"ParameterizedJob": false,
|
||||
"Stop": false,
|
||||
"Status": "running",
|
||||
"StatusDescription": "",
|
||||
"JobSummary": {
|
||||
"JobID": "job8",
|
||||
"Namespace": "default",
|
||||
"Summary": {
|
||||
"group1": {
|
||||
"Queued": 0,
|
||||
"Complete": 0,
|
||||
"Failed": 0,
|
||||
"Running": 1,
|
||||
"Starting": 0,
|
||||
"Lost": 0,
|
||||
"Unknown": 0
|
||||
}
|
||||
},
|
||||
"Children": {
|
||||
"Pending": 0,
|
||||
"Running": 0,
|
||||
"Dead": 0
|
||||
},
|
||||
"CreateIndex": 11276,
|
||||
"ModifyIndex": 11281
|
||||
},
|
||||
"CreateIndex": 11276,
|
||||
"ModifyIndex": 11303,
|
||||
"JobModifyIndex": 11297,
|
||||
"SubmitTime": 1705753285493029600,
|
||||
"Meta": null
|
||||
}
|
||||
]
|
47
pkg/provider/nomad/fixtures/jobs_job9.json
Normal file
47
pkg/provider/nomad/fixtures/jobs_job9.json
Normal file
|
@ -0,0 +1,47 @@
|
|||
[
|
||||
{
|
||||
"ID": "job9",
|
||||
"ParentID": "",
|
||||
"Name": "job9",
|
||||
"Namespace": "default",
|
||||
"Datacenters": [
|
||||
"dc1"
|
||||
],
|
||||
"NodePool": "default",
|
||||
"Multiregion": null,
|
||||
"Type": "service",
|
||||
"Priority": 50,
|
||||
"Periodic": false,
|
||||
"ParameterizedJob": false,
|
||||
"Stop": true,
|
||||
"Status": "dead",
|
||||
"StatusDescription": "",
|
||||
"JobSummary": {
|
||||
"JobID": "job9",
|
||||
"Namespace": "default",
|
||||
"Summary": {
|
||||
"group1": {
|
||||
"Queued": 0,
|
||||
"Complete": 1,
|
||||
"Failed": 0,
|
||||
"Running": 0,
|
||||
"Starting": 0,
|
||||
"Lost": 0,
|
||||
"Unknown": 0
|
||||
}
|
||||
},
|
||||
"Children": {
|
||||
"Pending": 0,
|
||||
"Running": 0,
|
||||
"Dead": 0
|
||||
},
|
||||
"CreateIndex": 11317,
|
||||
"ModifyIndex": 11349
|
||||
},
|
||||
"CreateIndex": 11317,
|
||||
"ModifyIndex": 11346,
|
||||
"JobModifyIndex": 11344,
|
||||
"SubmitTime": 1705753979676559600,
|
||||
"Meta": null
|
||||
}
|
||||
]
|
20
pkg/provider/nomad/fixtures/service_hello.json
Normal file
20
pkg/provider/nomad/fixtures/service_hello.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
[
|
||||
{
|
||||
"Address": "127.0.0.1",
|
||||
"AllocID": "71a63a80-a98a-93ee-4fd7-73b808577c20",
|
||||
"CreateIndex": 18,
|
||||
"Datacenter": "dc1",
|
||||
"ID": "_nomad-task-71a63a80-a98a-93ee-4fd7-73b808577c20-group-hello-nomad-hello-nomad-http",
|
||||
"JobID": "echo",
|
||||
"ModifyIndex": 18,
|
||||
"Namespace": "default",
|
||||
"NodeID": "6d7f412e-e7ff-2e66-d47b-867b0e9d8726",
|
||||
"Port": 20627,
|
||||
"ServiceName": "hello-nomad",
|
||||
"Tags": [
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.hellon.entrypoints=web",
|
||||
"traefik.http.routers.hellon.service=hello-nomad"
|
||||
]
|
||||
}
|
||||
]
|
18
pkg/provider/nomad/fixtures/service_job1.json
Normal file
18
pkg/provider/nomad/fixtures/service_job1.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
[
|
||||
{
|
||||
"ID": "_nomad-task-03c7270c-f475-5981-1932-87c0a8a5aa24-group-group1-job1-http",
|
||||
"ServiceName": "job1",
|
||||
"Namespace": "default",
|
||||
"NodeID": "e262ecb6-a7ac-7c3e-4de0-06445559e596",
|
||||
"Datacenter": "dc1",
|
||||
"JobID": "job1",
|
||||
"AllocID": "03c7270c-f475-5981-1932-87c0a8a5aa24",
|
||||
"Tags": [
|
||||
"traefik.enable=true"
|
||||
],
|
||||
"Address": "192.168.1.21",
|
||||
"Port": 29916,
|
||||
"CreateIndex": 5753,
|
||||
"ModifyIndex": 9958
|
||||
}
|
||||
]
|
1
pkg/provider/nomad/fixtures/service_job2.json
Normal file
1
pkg/provider/nomad/fixtures/service_job2.json
Normal file
|
@ -0,0 +1 @@
|
|||
[]
|
18
pkg/provider/nomad/fixtures/service_job3.json
Normal file
18
pkg/provider/nomad/fixtures/service_job3.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
[
|
||||
{
|
||||
"ID": "_nomad-task-dd945b55-70fa-0efc-6512-b88fb55ce33f-group-group1-job3-http",
|
||||
"ServiceName": "job3",
|
||||
"Namespace": "default",
|
||||
"NodeID": "e262ecb6-a7ac-7c3e-4de0-06445559e596",
|
||||
"Datacenter": "dc1",
|
||||
"JobID": "job3",
|
||||
"AllocID": "dd945b55-70fa-0efc-6512-b88fb55ce33f",
|
||||
"Tags": [
|
||||
"traefik.enable=true"
|
||||
],
|
||||
"Address": "192.168.1.21",
|
||||
"Port": 29983,
|
||||
"CreateIndex": 9987,
|
||||
"ModifyIndex": 9987
|
||||
}
|
||||
]
|
1
pkg/provider/nomad/fixtures/service_job4.json
Normal file
1
pkg/provider/nomad/fixtures/service_job4.json
Normal file
|
@ -0,0 +1 @@
|
|||
[]
|
18
pkg/provider/nomad/fixtures/service_job5task1.json
Normal file
18
pkg/provider/nomad/fixtures/service_job5task1.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
[
|
||||
{
|
||||
"ID": "_nomad-task-a98bac3d-5382-3032-1954-57aff58b20c1-task1-job5task1-http",
|
||||
"ServiceName": "job5task1",
|
||||
"Namespace": "default",
|
||||
"NodeID": "e262ecb6-a7ac-7c3e-4de0-06445559e596",
|
||||
"Datacenter": "dc1",
|
||||
"JobID": "job5",
|
||||
"AllocID": "a98bac3d-5382-3032-1954-57aff58b20c1",
|
||||
"Tags": [
|
||||
"traefik.enable=true"
|
||||
],
|
||||
"Address": "192.168.1.21",
|
||||
"Port": 24542,
|
||||
"CreateIndex": 10013,
|
||||
"ModifyIndex": 10013
|
||||
}
|
||||
]
|
18
pkg/provider/nomad/fixtures/service_job5task2.json
Normal file
18
pkg/provider/nomad/fixtures/service_job5task2.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
[
|
||||
{
|
||||
"ID": "_nomad-task-a98bac3d-5382-3032-1954-57aff58b20c1-task2-job5task2-other",
|
||||
"ServiceName": "job5task2",
|
||||
"Namespace": "default",
|
||||
"NodeID": "e262ecb6-a7ac-7c3e-4de0-06445559e596",
|
||||
"Datacenter": "dc1",
|
||||
"JobID": "job5",
|
||||
"AllocID": "a98bac3d-5382-3032-1954-57aff58b20c1",
|
||||
"Tags": [
|
||||
"traefik.enable=true"
|
||||
],
|
||||
"Address": "192.168.1.21",
|
||||
"Port": 30165,
|
||||
"CreateIndex": 10014,
|
||||
"ModifyIndex": 10014
|
||||
}
|
||||
]
|
1
pkg/provider/nomad/fixtures/service_job6task1.json
Normal file
1
pkg/provider/nomad/fixtures/service_job6task1.json
Normal file
|
@ -0,0 +1 @@
|
|||
[]
|
1
pkg/provider/nomad/fixtures/service_job6task2.json
Normal file
1
pkg/provider/nomad/fixtures/service_job6task2.json
Normal file
|
@ -0,0 +1 @@
|
|||
[]
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue