Merge branch 'v3.0' of github.com:traefik/traefik
Signed-off-by: baalajimaestro <me@baalajimaestro.me>
This commit is contained in:
commit
f006e9bec1
123 changed files with 1424 additions and 1379 deletions
|
@ -87,8 +87,6 @@ linters-settings:
|
||||||
pkg: "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
pkg: "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||||
|
|
||||||
# Traefik Kubernetes rewrites:
|
# Traefik Kubernetes rewrites:
|
||||||
- alias: containousv1alpha1
|
|
||||||
pkg: "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1"
|
|
||||||
- alias: traefikv1alpha1
|
- alias: traefikv1alpha1
|
||||||
pkg: "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
pkg: "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||||
- alias: traefikclientset
|
- alias: traefikclientset
|
||||||
|
@ -151,6 +149,19 @@ linters-settings:
|
||||||
- github.com/mailgun/minheap
|
- github.com/mailgun/minheap
|
||||||
- github.com/mailgun/multibuf
|
- github.com/mailgun/multibuf
|
||||||
- github.com/jaguilar/vt100
|
- github.com/jaguilar/vt100
|
||||||
|
testifylint:
|
||||||
|
enable:
|
||||||
|
- bool-compare
|
||||||
|
- compares
|
||||||
|
- empty
|
||||||
|
- error-is-as
|
||||||
|
- error-nil
|
||||||
|
- expected-actual
|
||||||
|
- float-compare
|
||||||
|
- len
|
||||||
|
- suite-dont-use-pkg
|
||||||
|
- suite-extra-assert-call
|
||||||
|
- suite-thelper
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
enable-all: true
|
enable-all: true
|
||||||
|
|
|
@ -25,7 +25,7 @@ global_job_config:
|
||||||
- export "PATH=${GOPATH}/bin:${PATH}"
|
- export "PATH=${GOPATH}/bin:${PATH}"
|
||||||
- mkdir -vp "${SEMAPHORE_GIT_DIR}" "${GOPATH}/bin"
|
- mkdir -vp "${SEMAPHORE_GIT_DIR}" "${GOPATH}/bin"
|
||||||
- export GOPROXY=https://proxy.golang.org,direct
|
- export GOPROXY=https://proxy.golang.org,direct
|
||||||
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "${GOPATH}/bin" v1.54.1
|
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "${GOPATH}/bin" v1.55.2
|
||||||
- curl -sSfL https://gist.githubusercontent.com/traefiker/6d7ac019c11d011e4f131bb2cca8900e/raw/goreleaser.sh | bash -s -- -b "${GOPATH}/bin"
|
- curl -sSfL https://gist.githubusercontent.com/traefiker/6d7ac019c11d011e4f131bb2cca8900e/raw/goreleaser.sh | bash -s -- -b "${GOPATH}/bin"
|
||||||
- checkout
|
- checkout
|
||||||
- cache restore traefik-$(checksum go.sum)
|
- cache restore traefik-$(checksum go.sum)
|
||||||
|
|
47
CHANGELOG.md
47
CHANGELOG.md
|
@ -1,3 +1,50 @@
|
||||||
|
## [v3.0.0-beta5](https://github.com/traefik/traefik/tree/v3.0.0-beta5) (2023-11-29)
|
||||||
|
[All Commits](https://github.com/traefik/traefik/compare/v3.0.0-beta4...v3.0.0-beta5)
|
||||||
|
|
||||||
|
**Enhancements:**
|
||||||
|
- **[metrics]** Upgrade OpenTelemetry dependencies ([#10181](https://github.com/traefik/traefik/pull/10181) by [mmatur](https://github.com/mmatur))
|
||||||
|
|
||||||
|
**Misc:**
|
||||||
|
- Merge current v2.10 into v3.0 ([#10272](https://github.com/traefik/traefik/pull/10272) by [rtribotte](https://github.com/rtribotte))
|
||||||
|
|
||||||
|
## [v2.10.6](https://github.com/traefik/traefik/tree/v2.10.6) (2023-11-28)
|
||||||
|
[All Commits](https://github.com/traefik/traefik/compare/v2.10.5...v2.10.6)
|
||||||
|
|
||||||
|
**Bug fixes:**
|
||||||
|
- **[acme]** Remove backoff for http challenge ([#10224](https://github.com/traefik/traefik/pull/10224) by [youkoulayley](https://github.com/youkoulayley))
|
||||||
|
- **[consul,consulcatalog]** Update github.com/hashicorp/consul/api ([#10220](https://github.com/traefik/traefik/pull/10220) by [kevinpollet](https://github.com/kevinpollet))
|
||||||
|
- **[http3]** Update quic-go to v0.39.1 ([#10171](https://github.com/traefik/traefik/pull/10171) by [tomMoulard](https://github.com/tomMoulard))
|
||||||
|
- **[middleware]** Fix stripPrefix middleware is not applied to retried attempts ([#10255](https://github.com/traefik/traefik/pull/10255) by [niki-timofe](https://github.com/niki-timofe))
|
||||||
|
- **[provider]** Refuse recursive requests ([#10242](https://github.com/traefik/traefik/pull/10242) by [rtribotte](https://github.com/rtribotte))
|
||||||
|
- **[server]** Deny request with fragment in URL path ([#10229](https://github.com/traefik/traefik/pull/10229) by [lbenguigui](https://github.com/lbenguigui))
|
||||||
|
- **[tracing]** Remove deprecated code usage for datadog tracer ([#10196](https://github.com/traefik/traefik/pull/10196) by [mmatur](https://github.com/mmatur))
|
||||||
|
|
||||||
|
**Documentation:**
|
||||||
|
- **[governance]** Update the review process and maintainers team documentation ([#10230](https://github.com/traefik/traefik/pull/10230) by [geraldcroes](https://github.com/geraldcroes))
|
||||||
|
- **[governance]** Guidelines Update ([#10197](https://github.com/traefik/traefik/pull/10197) by [geraldcroes](https://github.com/geraldcroes))
|
||||||
|
- **[metrics]** Add a mention for the host header in metrics headers labels doc ([#10172](https://github.com/traefik/traefik/pull/10172) by [rtribotte](https://github.com/rtribotte))
|
||||||
|
- **[middleware]** Rephrase BasicAuth and DigestAuth docs ([#10226](https://github.com/traefik/traefik/pull/10226) by [sssash18](https://github.com/sssash18))
|
||||||
|
- **[middleware]** Improve ErrorPages examples ([#10209](https://github.com/traefik/traefik/pull/10209) by [arendhummeling](https://github.com/arendhummeling))
|
||||||
|
- Add @lbenguigui to maintainers ([#10222](https://github.com/traefik/traefik/pull/10222) by [kevinpollet](https://github.com/kevinpollet))
|
||||||
|
|
||||||
|
## [v3.0.0-beta4](https://github.com/traefik/traefik/tree/v3.0.0-beta4) (2023-10-11)
|
||||||
|
[All Commits](https://github.com/traefik/traefik/compare/v3.0.0-beta3...v3.0.0-beta4)
|
||||||
|
|
||||||
|
**Bug fixes:**
|
||||||
|
- **[consul,tls]** Enable TLS for Consul Connect TCP services ([#10140](https://github.com/traefik/traefik/pull/10140) by [rtribotte](https://github.com/rtribotte))
|
||||||
|
- **[middleware]** Allow short healthcheck interval with long timeout ([#9832](https://github.com/traefik/traefik/pull/9832) by [kevinmcconnell](https://github.com/kevinmcconnell))
|
||||||
|
- **[middleware]** Fix GrpcWeb middleware to clear ContentLength after translating to normal gRPC message ([#9782](https://github.com/traefik/traefik/pull/9782) by [CleverUnderDog](https://github.com/CleverUnderDog))
|
||||||
|
- **[sticky-session,server]** Set sameSite field for wrr load balancer sticky cookie ([#10066](https://github.com/traefik/traefik/pull/10066) by [sunyakun](https://github.com/sunyakun))
|
||||||
|
|
||||||
|
**Documentation:**
|
||||||
|
- **[docker/swarm]** Fix minor typo in swarm example ([#10071](https://github.com/traefik/traefik/pull/10071) by [kaznovac](https://github.com/kaznovac))
|
||||||
|
- **[docker/swarm]** Remove documentation of old swarm options ([#10001](https://github.com/traefik/traefik/pull/10001) by [ldez](https://github.com/ldez))
|
||||||
|
- Fix bad anchor on documentation ([#10041](https://github.com/traefik/traefik/pull/10041) by [mmatur](https://github.com/mmatur))
|
||||||
|
- Fix migration guide heading ([#9989](https://github.com/traefik/traefik/pull/9989) by [ldez](https://github.com/ldez))
|
||||||
|
|
||||||
|
**Misc:**
|
||||||
|
- Merge current v2.10 into v3.0 ([#10038](https://github.com/traefik/traefik/pull/10038) by [mmatur](https://github.com/mmatur))
|
||||||
|
|
||||||
## [v2.10.5](https://github.com/traefik/traefik/tree/v2.10.5) (2023-10-11)
|
## [v2.10.5](https://github.com/traefik/traefik/tree/v2.10.5) (2023-10-11)
|
||||||
[All Commits](https://github.com/traefik/traefik/compare/v2.10.4...v2.10.5)
|
[All Commits](https://github.com/traefik/traefik/compare/v2.10.4...v2.10.5)
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,18 @@ Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||||
|
|
||||||
|
When an inapropriate behavior is reported, maintainers will discuss on the Maintainer's Discord before marking the message as "abuse".
|
||||||
|
This conversation beforehand avoids one-sided decisions.
|
||||||
|
|
||||||
|
The first message will be edited and marked as abuse.
|
||||||
|
The second edited message and marked as abuse results in a 7-day ban.
|
||||||
|
The third edited message and marked as abuse results in a permanent ban.
|
||||||
|
|
||||||
|
The content of edited messages is:
|
||||||
|
`Dear user, we want traefik to provide a welcoming and respectful environment. Your [comment/issue/PR] has been reported and marked as abuse according to our [Code of Conduct](./CODE_OF_CONDUCT.md). Thank you.`
|
||||||
|
|
||||||
|
The [report must be resolved](https://docs.github.com/en/communities/moderating-comments-and-conversations/managing-reported-content-in-your-organizations-repository#resolving-a-report) accordingly.
|
||||||
|
|
||||||
## Attribution
|
## Attribution
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -178,7 +178,7 @@ docs-pull-images:
|
||||||
## Generate CRD clientset and CRD manifests
|
## Generate CRD clientset and CRD manifests
|
||||||
.PHONY: generate-crd
|
.PHONY: generate-crd
|
||||||
generate-crd:
|
generate-crd:
|
||||||
@$(CURDIR)/script/code-gen.sh
|
@$(CURDIR)/script/code-gen-docker.sh
|
||||||
|
|
||||||
## Generate code from dynamic configuration https://github.com/traefik/genconf
|
## Generate code from dynamic configuration https://github.com/traefik/genconf
|
||||||
.PHONY: generate-genconf
|
.PHONY: generate-genconf
|
||||||
|
|
|
@ -125,8 +125,8 @@ You can find high level and deep dive videos on [videos.traefik.io](https://vide
|
||||||
## Maintainers
|
## Maintainers
|
||||||
|
|
||||||
We are strongly promoting a philosophy of openness and sharing, and firmly standing against the elitist closed approach. Being part of the core team should be accessible to anyone who is motivated and want to be part of that journey!
|
We are strongly promoting a philosophy of openness and sharing, and firmly standing against the elitist closed approach. Being part of the core team should be accessible to anyone who is motivated and want to be part of that journey!
|
||||||
This [document](docs/content/contributing/maintainers-guidelines.md) describes how to be part of the core team as well as various responsibilities and guidelines for Traefik maintainers.
|
This [document](docs/content/contributing/maintainers-guidelines.md) describes how to be part of the [maintainers' team](docs/content/contributing/maintainers.md) as well as various responsibilities and guidelines for Traefik maintainers.
|
||||||
You can also find more information on our process to review pull requests and manage issues [in this document](docs/content/contributing/maintainers.md).
|
You can also find more information on our process to review pull requests and manage issues [in this document](https://github.com/traefik/contributors-guide/blob/master/issue_triage.md).
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ RUN mkdir -p /usr/local/bin \
|
||||||
| tar -xzC /usr/local/bin --transform 's#^.+/##x'
|
| tar -xzC /usr/local/bin --transform 's#^.+/##x'
|
||||||
|
|
||||||
# Download golangci-lint binary to bin folder in $GOPATH
|
# Download golangci-lint binary to bin folder in $GOPATH
|
||||||
RUN curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash -s -- -b $GOPATH/bin v1.54.1
|
RUN curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash -s -- -b $GOPATH/bin v1.55.2
|
||||||
|
|
||||||
# Download misspell binary to bin folder in $GOPATH
|
# Download misspell binary to bin folder in $GOPATH
|
||||||
RUN curl -sfL https://raw.githubusercontent.com/golangci/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.4.0
|
RUN curl -sfL https://raw.githubusercontent.com/golangci/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.4.0
|
||||||
|
|
|
@ -131,12 +131,6 @@ func TestGetDefaultsEntrypoints(t *testing.T) {
|
||||||
"traefik": {
|
"traefik": {
|
||||||
Address: ":8080",
|
Address: ":8080",
|
||||||
},
|
},
|
||||||
"traefikhub-api": {
|
|
||||||
Address: ":9900",
|
|
||||||
},
|
|
||||||
"traefikhub-tunl": {
|
|
||||||
Address: ":9901",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expected: []string{"web"},
|
expected: []string{"web"},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
---
|
---
|
||||||
title: "Traefik Advocation Documentation"
|
title: "Traefik Advocation Documentation"
|
||||||
description: "There are many ways to contribute to Traefik Proxy. If you're talking about Traefik, let us know and we'll promote your enthusiasm!"
|
description: "There are many ways to contribute to Traefik Proxy. Let us know if you’re talking about Traefik, and we'll promote your enthusiasm!"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Advocating
|
# Advocating
|
||||||
|
|
||||||
Spread the Love & Tell Us about It
|
Spread the Love & Tell Us About It
|
||||||
{: .subtitle }
|
{: .subtitle }
|
||||||
|
|
||||||
Traefik Proxy was started by the community for the community.
|
Traefik Proxy was started by the community and for the community.
|
||||||
You can contribute to the Traefik community in three main ways:
|
You can contribute to the Traefik community in three main ways:
|
||||||
|
|
||||||
**Spread the word!** Guides, videos, blog posts, how-to articles, and showing off your network design all help spread the word about Traefik Proxy
|
**Spread the word!** Guides, videos, blog posts, how-to articles, and showing off your network design all help spread the word about Traefik Proxy
|
||||||
|
|
|
@ -7,89 +7,75 @@ description: "Interested in contributing more to the community and becoming a Tr
|
||||||
|
|
||||||
![Maintainer's Guidelines](../assets/img/maintainers-guidelines.png)
|
![Maintainer's Guidelines](../assets/img/maintainers-guidelines.png)
|
||||||
|
|
||||||
Note: the document is a work in progress.
|
|
||||||
|
|
||||||
Welcome to the Traefik Community.
|
Welcome to the Traefik Community.
|
||||||
This document describes how to be part of the core team
|
|
||||||
together with various responsibilities
|
|
||||||
and guidelines for Traefik maintainers.
|
|
||||||
We are strongly promoting a philosophy of openness and sharing,
|
We are strongly promoting a philosophy of openness and sharing,
|
||||||
and firmly standing against the elitist closed approach.
|
and firmly standing against the elitist closed approach.
|
||||||
Being part of the core team should be accessible to anyone motivated
|
Being part of the core team should be accessible to anyone motivated
|
||||||
and wants to be part of that journey!
|
and wants to be part of that journey!
|
||||||
|
|
||||||
## Onboarding Process
|
## Becoming a Maintainer
|
||||||
|
|
||||||
If you consider joining our community, please drop us a line using Twitter or leave a note in the issue.
|
Before a contributor becomes a maintainer, they should meet the following requirements:
|
||||||
We will schedule a quick call to meet you and learn more about your motivation.
|
|
||||||
During the call, the team will discuss the process of becoming a maintainer.
|
|
||||||
We will be happy to answer any questions and explain all your doubts.
|
|
||||||
|
|
||||||
## Maintainer's Requirements
|
- The contributor enabled [2FA](https://docs.github.com/en/authentication/securing-your-account-with-two-factor-authentication-2fa/configuring-two-factor-authentication) on their GitHub account
|
||||||
|
|
||||||
Note: you do not have to meet all the listed requirements,
|
- The contributor showed a consistent pattern of helpful, non-threatening, and friendly behavior towards other community members in the past.
|
||||||
but must have achieved several.
|
|
||||||
|
- The contributor has read and accepted the maintainer's guidelines.
|
||||||
|
|
||||||
|
The contributor should also meet one or several of the following requirements:
|
||||||
|
|
||||||
- Enabled [2FA](https://docs.github.com/en/authentication/securing-your-account-with-two-factor-authentication-2fa/configuring-two-factor-authentication) on your GitHub account
|
|
||||||
- The contributor has opened and successfully run medium to large PR’s in the past 6 months.
|
- The contributor has opened and successfully run medium to large PR’s in the past 6 months.
|
||||||
|
|
||||||
- The contributor has participated in multiple code reviews of other PR’s,
|
- The contributor has participated in multiple code reviews of other PR’s,
|
||||||
including those of other maintainers and contributors.
|
including those of other maintainers and contributors.
|
||||||
- The contributor showed a consistent pattern of helpful, non-threatening, and friendly behavior towards other community members in the past.
|
|
||||||
- The contributor is active on Traefik Community forums
|
- The contributor is active on Traefik Community forums
|
||||||
or other technical forums/boards such as K8S slack, Reddit, StackOverflow, hacker news.
|
or other technical forums/boards such as K8S slack, Reddit, StackOverflow, hacker news.
|
||||||
- Have read and accepted the contributor guidelines.
|
|
||||||
|
Any existing active maintainer can create an issue to discuss promoting a contributor to maintainer.
|
||||||
|
Other maintainers can vote on the issue, and if the quorum is reached, the contributor is promoted to maintainer.
|
||||||
|
If the quorum is not reached within one month after the issue is created, it is closed.
|
||||||
|
|
||||||
## Maintainer's Responsibilities and Privileges
|
## Maintainer's Responsibilities and Privileges
|
||||||
|
|
||||||
There are lots of areas where you can contribute to the project,
|
As a maintainer, you are granted a vote for the following:
|
||||||
but we can suggest you start with activities such as:
|
|
||||||
|
|
||||||
- PR reviewing.
|
- [PR review](https://github.com/traefik/contributors-guide/blob/master/pr_guidelines.md).
|
||||||
- According to our guidelines we require you have at least 3 reviewers,
|
|
||||||
thus you can review a PR and leave the relevant comment if it is necessary.
|
|
||||||
- Participating in a daily [issue triage](https://github.com/traefik/contributors-guide/blob/master/issue_triage.md).
|
|
||||||
- The process helps to understand and prioritize the reported issue according to its importance and severity.
|
|
||||||
This is crucial to learn how our users implement Traefik.
|
|
||||||
Each of the issues that are labeled as bug/possible bug/confirmed requires a reproducible use case.
|
|
||||||
You can help in creating a reproducible use case if it has not been added to the issue
|
|
||||||
or use the sample code provided by the reporter.
|
|
||||||
Typically, a simple Docker Compose should be enough to reproduce the issue.
|
|
||||||
- Code contribution.
|
|
||||||
- Documentation contribution.
|
|
||||||
- Technical documentation is one of the most important components of the product.
|
|
||||||
The ability to set up a testing environment in a few minutes,
|
|
||||||
using the official documentation,
|
|
||||||
is a game changer.
|
|
||||||
- You will be listed on our Maintainers GitHub page
|
|
||||||
and on our website in the section [maintainers](maintainers.md).
|
|
||||||
- We will be promoting you on social channels (mostly on Twitter).
|
|
||||||
|
|
||||||
## Governance
|
- [Design review](https://github.com/traefik/contributors-guide/blob/master/proposals.md).
|
||||||
|
|
||||||
- Roadmap meetings on a regular basis where all maintainers are welcome.
|
- [Proposals](https://github.com/traefik/contributors-guide/blob/master/proposals.md).
|
||||||
|
|
||||||
|
Maintainers are also added to the maintainer's Discord server where happens the [issue triage](https://github.com/traefik/contributors-guide/blob/master/issue_triage.md)
|
||||||
|
and appear on the [Maintainers](maintainers.md) page.
|
||||||
|
|
||||||
|
As a maintainer, you should:
|
||||||
|
|
||||||
|
- Prioritize PR reviews, design reviews, and issue triage above any other task.
|
||||||
|
|
||||||
|
Making sure contributors and community members are listened to and have an impact on the project is essential to keeping the project active and develop a thriving community.
|
||||||
|
|
||||||
|
- Prioritize helping contributors reaching the expecting quality level over rewriting contributions.
|
||||||
|
|
||||||
|
Any triage activity on issues and PRs (e.g. labels, marking messages as off-topic, refusing, marking duplicates) should result from a collective decision to ensure knowledge is shared among maintainers.
|
||||||
|
|
||||||
## Communicating
|
## Communicating
|
||||||
|
|
||||||
- All of our maintainers are added to the Traefik Maintainers Discord server that belongs to Traefik labs.
|
- All of our maintainers are added to the Traefik Maintainers Discord server that belongs to Traefik labs.
|
||||||
Having the team in one place helps us to communicate effectively.
|
Having the team in one place helps us to communicate effectively.
|
||||||
You can reach Traefik core developers directly,
|
Maintainers can discuss issues, pull requests, enhancements more efficiently
|
||||||
which offers the possibility to discuss issues, pull requests, enhancements more efficiently
|
|
||||||
and get the feedback almost immediately.
|
and get the feedback almost immediately.
|
||||||
Fewer blockers mean more fun and engaging work.
|
Fewer blockers mean more fun and engaging work.
|
||||||
|
|
||||||
- On a daily basis, we publish a report that includes all the activities performed during the day.
|
- Every decision made on the discord server among maintainers is documented so it's visible to the rest of the community.
|
||||||
You are updated in regard to the workload that has been processed including:
|
|
||||||
working on the new features and enhancements,
|
|
||||||
activities related to the reported issues and PR’s,
|
|
||||||
other important project-related announcements.
|
|
||||||
|
|
||||||
- At 2:15pm CET every Monday and Thursday we review all the created issues that have been reported,
|
- Maintainers express their opinions on issues and reviews.
|
||||||
assign them the appropriate *[labels](maintainers.md#labels)*
|
It is fine to have different point of views.
|
||||||
and prioritize them based on the severity of the problem.
|
We encourage active and open conversations which goals are to improve Traefik.
|
||||||
The process is called *[issue triaging](https://github.com/traefik/contributors-guide/blob/master/issue_triage.md)*.
|
|
||||||
Each of the maintainers is welcome to join the meeting.
|
- When discussing issues and proposals, maintainers should share as much information as possible to help solve the issue.
|
||||||
For that purpose, we use the Traefik Maintainers Discord server
|
|
||||||
where you are invited once you have become an official maintainer.
|
|
||||||
|
|
||||||
## Maintainers Activity
|
## Maintainers Activity
|
||||||
|
|
||||||
|
@ -97,38 +83,45 @@ In order to keep the core team efficient and dynamic,
|
||||||
maintainers' activity and involvement will be reviewed on a regular basis.
|
maintainers' activity and involvement will be reviewed on a regular basis.
|
||||||
|
|
||||||
- Has the maintainer engaged with the team and the community by meeting two or more of these benchmarks in the past six months?
|
- Has the maintainer engaged with the team and the community by meeting two or more of these benchmarks in the past six months?
|
||||||
|
|
||||||
- Has the maintainer participated in at least two or three maintainer meetings?
|
- Has the maintainer participated in at least two or three maintainer meetings?
|
||||||
|
|
||||||
- Substantial review of at least one or two PRs from either contributors or maintainers.
|
- Substantial review of at least one or two PRs from either contributors or maintainers.
|
||||||
|
|
||||||
- Opened at least one or two bug fixes or feature request PRs
|
- Opened at least one or two bug fixes or feature request PRs
|
||||||
that were eventually merged (or on a trajectory for merge).
|
that were eventually merged (or on a trajectory for merge).
|
||||||
|
|
||||||
- Substantial participation in the Help Wanted program (answered questions, helped identify issues, applied guidelines from the Help Wanted guide to open issues).
|
- Substantial participation in the Help Wanted program (answered questions, helped identify issues, applied guidelines from the Help Wanted guide to open issues).
|
||||||
|
|
||||||
- Substantial participation with the community in general.
|
- Substantial participation with the community in general.
|
||||||
|
|
||||||
- Has the maintainer shown a consistent pattern of helpful,
|
- Has the maintainer shown a consistent pattern of helpful,
|
||||||
non-threatening,
|
non-threatening,
|
||||||
and friendly behavior towards other people on the maintainer team and with our community?
|
and friendly behavior towards other people on the maintainer team and with our community?
|
||||||
|
|
||||||
## Additional Comments for (not only) Maintainers
|
## Additional Comments for Maintainers (that should apply to any contributor)
|
||||||
|
|
||||||
|
- Be respectful with other maintainers and other community members.
|
||||||
|
|
||||||
|
- Be open minded when participating in conversations: try to put yourself in others’ shoes.
|
||||||
|
|
||||||
- Be able to put yourself in users’ shoes.
|
|
||||||
- Be open-minded and respectful with other maintainers and other community members.
|
|
||||||
- Keep the communication public -
|
- Keep the communication public -
|
||||||
if anyone tries to communicate with you directly,
|
if anyone tries to communicate with you directly,
|
||||||
ask politely to move the conversation to a public communication channel.
|
ask politely to move the conversation to a public communication channel.
|
||||||
|
|
||||||
- Stay away from defensive comments.
|
- Stay away from defensive comments.
|
||||||
|
|
||||||
- Please try to express your thoughts clearly enough
|
- Please try to express your thoughts clearly enough
|
||||||
and note that some of us are not native English speakers.
|
and note that some of us are not native English speakers.
|
||||||
Try to rephrase your sentences, avoiding mental shortcuts;
|
Try to rephrase your sentences, avoiding mental shortcuts;
|
||||||
none of us is able to predict your thoughts.
|
none of us is able to predict anyone's thoughts.
|
||||||
- There are a lot of use cases of using Traefik
|
|
||||||
and even more issues that are difficult to reproduce.
|
|
||||||
If the issue can’t be replicated due to a lack of reproducible case (a simple Docker Compose should be enough) -
|
|
||||||
set your time limits while working on the issue
|
|
||||||
and express clearly that you were not able to replicate it.
|
|
||||||
You can come back later to that case.
|
|
||||||
- Be proactive.
|
- Be proactive.
|
||||||
|
|
||||||
- Emoji are fine,
|
- Emoji are fine,
|
||||||
but if you express yourself clearly enough they are not necessary.
|
but if you express yourself clearly enough they are not necessary.
|
||||||
They will not replace good communication.
|
They will not replace good communication.
|
||||||
- Embrace mentorship.
|
|
||||||
- Keep in mind that we all have the same intent to improve the project.
|
- Embrace mentorship: help others grow and match the quality level we strive for.
|
||||||
|
|
||||||
|
- Keep in mind that we all have the same goal: improve the project.
|
||||||
|
|
|
@ -5,18 +5,13 @@ description: "Traefik Proxy is an open source software with a thriving community
|
||||||
|
|
||||||
# Maintainers
|
# Maintainers
|
||||||
|
|
||||||
## The Team
|
## Active Maintainers
|
||||||
|
|
||||||
* Emile Vauge [@emilevauge](https://github.com/emilevauge)
|
* Emile Vauge [@emilevauge](https://github.com/emilevauge)
|
||||||
* Vincent Demeester [@vdemeester](https://github.com/vdemeester)
|
|
||||||
* Ed Robinson [@errm](https://github.com/errm)
|
|
||||||
* Daniel Tomcej [@dtomcej](https://github.com/dtomcej)
|
|
||||||
* Manuel Zapf [@SantoDE](https://github.com/SantoDE)
|
* Manuel Zapf [@SantoDE](https://github.com/SantoDE)
|
||||||
* Timo Reimann [@timoreimann](https://github.com/timoreimann)
|
|
||||||
* Ludovic Fernandez [@ldez](https://github.com/ldez)
|
* Ludovic Fernandez [@ldez](https://github.com/ldez)
|
||||||
* Julien Salleyron [@juliens](https://github.com/juliens)
|
* Julien Salleyron [@juliens](https://github.com/juliens)
|
||||||
* Nicolas Mengin [@nmengin](https://github.com/nmengin)
|
* Nicolas Mengin [@nmengin](https://github.com/nmengin)
|
||||||
* Marco Jantke [@mjantke](https://github.com/mjeri)
|
|
||||||
* Michaël Matur [@mmatur](https://github.com/mmatur)
|
* Michaël Matur [@mmatur](https://github.com/mmatur)
|
||||||
* Gérald Croës [@geraldcroes](https://github.com/geraldcroes)
|
* Gérald Croës [@geraldcroes](https://github.com/geraldcroes)
|
||||||
* Jean-Baptiste Doumenjou [@jbdoumenjou](https://github.com/jbdoumenjou)
|
* Jean-Baptiste Doumenjou [@jbdoumenjou](https://github.com/jbdoumenjou)
|
||||||
|
@ -25,108 +20,18 @@ description: "Traefik Proxy is an open source software with a thriving community
|
||||||
* Kevin Pollet [@kevinpollet](https://github.com/kevinpollet)
|
* Kevin Pollet [@kevinpollet](https://github.com/kevinpollet)
|
||||||
* Harold Ozouf [@jspdown](https://github.com/jspdown)
|
* Harold Ozouf [@jspdown](https://github.com/jspdown)
|
||||||
* Tom Moulard [@tommoulard](https://github.com/tommoulard)
|
* Tom Moulard [@tommoulard](https://github.com/tommoulard)
|
||||||
|
* Landry Benguigui [@lbenguigui](https://github.com/lbenguigui)
|
||||||
|
|
||||||
|
## Past Maintainers
|
||||||
|
|
||||||
|
People who have had an incredibly positive impact on the project, and are now focusing on other projects.
|
||||||
|
|
||||||
|
* Vincent Demeester [@vdemeester](https://github.com/vdemeester)
|
||||||
|
* Ed Robinson [@errm](https://github.com/errm)
|
||||||
|
* Daniel Tomcej [@dtomcej](https://github.com/dtomcej)
|
||||||
|
* Timo Reimann [@timoreimann](https://github.com/timoreimann)
|
||||||
|
* Marco Jantke [@mjantke](https://github.com/mjeri)
|
||||||
|
|
||||||
## Maintainer's Guidelines
|
## Maintainer's Guidelines
|
||||||
|
|
||||||
Please read the [maintainer's guidelines](maintainers-guidelines.md)
|
Please read the [maintainer's guidelines](maintainers-guidelines.md).
|
||||||
|
|
||||||
## Issue Triage
|
|
||||||
|
|
||||||
Issues and PRs are triaged daily and the process for triaging may be found under [triaging issues](https://github.com/traefik/contributors-guide/blob/master/issue_triage.md) in our [contributors guide repository](https://github.com/traefik/contributors-guide).
|
|
||||||
|
|
||||||
## PR Review Process
|
|
||||||
|
|
||||||
The process for reviewing PRs may be found under [review guidelines](https://github.com/traefik/contributors-guide/blob/master/review_guidelines.md) in our contributors guide repository.
|
|
||||||
|
|
||||||
## Labels
|
|
||||||
|
|
||||||
A maintainer that looks at an issue/PR must define its `kind/*`, `area/*`, and `status/*`.
|
|
||||||
|
|
||||||
### Status - Workflow
|
|
||||||
|
|
||||||
The `status/*` labels represent the desired state in the workflow.
|
|
||||||
|
|
||||||
* `status/0-needs-triage`: all the new issues and PRs have this status. _[bot only]_
|
|
||||||
* `status/1-needs-design-review`: needs a design review. **(only for PR)**
|
|
||||||
* `status/2-needs-review`: needs a code/documentation review. **(only for PR)**
|
|
||||||
* `status/3-needs-merge`: ready to merge. **(only for PR)**
|
|
||||||
* `status/4-merge-in-progress`: merge is in progress. _[bot only]_
|
|
||||||
|
|
||||||
### Contributor
|
|
||||||
|
|
||||||
* `contributor/need-more-information`: we need more information from the contributor in order to analyze a problem.
|
|
||||||
* `contributor/waiting-for-feedback`: we need the contributor to give us feedback.
|
|
||||||
* `contributor/waiting-for-corrections`: we need the contributor to take actions in order to move forward with a PR. **(only for PR)** _[bot, humans]_
|
|
||||||
* `contributor/needs-resolve-conflicts`: use it only when there is some conflicts (and an automatic rebase is not possible). **(only for PR)** _[bot, humans]_
|
|
||||||
|
|
||||||
### Kind
|
|
||||||
|
|
||||||
* `kind/enhancement`: a new or improved feature.
|
|
||||||
* `kind/question`: a question. **(only for issue)**
|
|
||||||
* `kind/proposal`: a proposal that needs to be discussed.
|
|
||||||
* _Proposal issues_ are design proposals
|
|
||||||
* _Proposal PRs_ are technical prototypes that need to be refined with multiple contributors.
|
|
||||||
|
|
||||||
* `kind/bug/possible`: a possible bug that needs analysis before it is confirmed or fixed. **(only for issues)**
|
|
||||||
* `kind/bug/confirmed`: a confirmed bug (reproducible). **(only for issues)**
|
|
||||||
* `kind/bug/fix`: a bug fix. **(only for PR)**
|
|
||||||
|
|
||||||
### Resolution
|
|
||||||
|
|
||||||
* `resolution/duplicate`: a duplicate issue/PR.
|
|
||||||
* `resolution/declined`: declined (Rule #1 of open-source: no is temporary, yes is forever).
|
|
||||||
* `WIP`: Work In Progress. **(only for PR)**
|
|
||||||
|
|
||||||
### Platform
|
|
||||||
|
|
||||||
* `platform/windows`: Windows related.
|
|
||||||
|
|
||||||
### Area
|
|
||||||
|
|
||||||
* `area/acme`: ACME related.
|
|
||||||
* `area/api`: Traefik API related.
|
|
||||||
* `area/authentication`: Authentication related.
|
|
||||||
* `area/cluster`: Traefik clustering related.
|
|
||||||
* `area/documentation`: Documentation related.
|
|
||||||
* `area/infrastructure`: CI or Traefik building scripts related.
|
|
||||||
* `area/healthcheck`: Health-check related.
|
|
||||||
* `area/logs`: Logs related.
|
|
||||||
* `area/middleware`: Middleware related.
|
|
||||||
* `area/middleware/metrics`: Metrics related. (Prometheus, StatsD, ...)
|
|
||||||
* `area/middleware/tracing`: Tracing related. (Jaeger, Zipkin, ...)
|
|
||||||
* `area/oxy`: Oxy related.
|
|
||||||
* `area/provider`: related to all providers.
|
|
||||||
* `area/provider/boltdb`: Boltd DB related.
|
|
||||||
* `area/provider/consul`: Consul related.
|
|
||||||
* `area/provider/docker`: Docker and Swarm related.
|
|
||||||
* `area/provider/ecs`: ECS related.
|
|
||||||
* `area/provider/etcd`: Etcd related.
|
|
||||||
* `area/provider/eureka`: Eureka related.
|
|
||||||
* `area/provider/file`: file provider related.
|
|
||||||
* `area/provider/k8s`: Kubernetes related.
|
|
||||||
* `area/provider/kv`: KV related.
|
|
||||||
* `area/provider/marathon`: Marathon related.
|
|
||||||
* `area/provider/mesos`: Mesos related.
|
|
||||||
* `area/provider/servicefabric`: Azure service fabric related.
|
|
||||||
* `area/provider/zk`: Zoo Keeper related.
|
|
||||||
* `area/rules`: Rules related.
|
|
||||||
* `area/server`: Server related.
|
|
||||||
* `area/sticky-session`: Sticky session related.
|
|
||||||
* `area/tls`: TLS related.
|
|
||||||
* `area/websocket`: WebSocket related.
|
|
||||||
* `area/webui`: Web UI related.
|
|
||||||
|
|
||||||
### Issues Priority
|
|
||||||
|
|
||||||
* `priority/P0`: needs hot fix.
|
|
||||||
* `priority/P1`: need to be fixed in next release.
|
|
||||||
* `priority/P2`: need to be fixed in the future.
|
|
||||||
* `priority/P3`: maybe.
|
|
||||||
|
|
||||||
### PR Size
|
|
||||||
|
|
||||||
Automatically set by a bot.
|
|
||||||
|
|
||||||
* `size/S`: small PR.
|
|
||||||
* `size/M`: medium PR.
|
|
||||||
* `size/L`: Large PR.
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ Help Us Help You!
|
||||||
Issues are perfect for requesting a feature/enhancement or reporting a suspected bug.
|
Issues are perfect for requesting a feature/enhancement or reporting a suspected bug.
|
||||||
We use the [GitHub issue tracker](https://github.com/traefik/traefik/issues) to keep track of issues in Traefik.
|
We use the [GitHub issue tracker](https://github.com/traefik/traefik/issues) to keep track of issues in Traefik.
|
||||||
|
|
||||||
The process of sorting and checking the issues is a daunting task, and requires a lot of work (more than an hour a day ... just for sorting).
|
The process of sorting and checking the issues is a daunting task, and requires a lot of work.
|
||||||
To help us (and other community members) quickly and effortlessly understand what you need,
|
To help maintainers (and other community members) quickly and effortlessly understand what you need,
|
||||||
be sure to follow the guidelines below.
|
be sure to follow the guidelines below.
|
||||||
|
|
||||||
!!! important "Getting Help Vs Reporting an Issue"
|
!!! important "Getting Help Vs Reporting an Issue"
|
||||||
|
|
|
@ -17,12 +17,9 @@ or the list of [confirmed bugs](https://github.com/traefik/traefik/labels/kind%2
|
||||||
|
|
||||||
## How We Prioritize
|
## How We Prioritize
|
||||||
|
|
||||||
We wish we could review every pull request right away.
|
We wish we could review every pull request right away, but because it's a time consuming operation, it's not always possible.
|
||||||
Unfortunately, our team has to prioritize pull requests (PRs) for review
|
|
||||||
(but we are welcoming new [maintainers](https://github.com/traefik/traefik/blob/master/docs/content/contributing/maintainers-guidelines.md) to speed this up,
|
|
||||||
if you are interested, check it out and apply).
|
|
||||||
|
|
||||||
The PRs we are able to handle fastest are:
|
The PRs we are able to handle the fastest are:
|
||||||
|
|
||||||
* Documentation updates.
|
* Documentation updates.
|
||||||
* Bug fixes.
|
* Bug fixes.
|
||||||
|
@ -59,7 +56,7 @@ Merging a PR requires the following steps to be completed before it is merged au
|
||||||
* Ensure your PR is not a draft. We do not review drafts, but do answer questions and confer with developers on them as needed.
|
* Ensure your PR is not a draft. We do not review drafts, but do answer questions and confer with developers on them as needed.
|
||||||
* Pass the validation check.
|
* Pass the validation check.
|
||||||
* Pass all tests.
|
* Pass all tests.
|
||||||
* Receive 3 approving reviews maintainers.
|
* Receive 3 approving reviews from maintainers.
|
||||||
|
|
||||||
## Pull Request Review Cycle
|
## Pull Request Review Cycle
|
||||||
|
|
||||||
|
@ -198,7 +195,7 @@ here are some things you can do to move the process along:
|
||||||
* If you have fixed all the issues from a review,
|
* If you have fixed all the issues from a review,
|
||||||
remember to re-request a review (using the designated button) to let your reviewer know that you are ready.
|
remember to re-request a review (using the designated button) to let your reviewer know that you are ready.
|
||||||
You can choose to comment with the changes you made.
|
You can choose to comment with the changes you made.
|
||||||
* Ping `@tfny` if you have not been assigned to a reviewer.
|
* Kindly comment on the pull request. Doing so will automatically give your PR visibility during the triage process.
|
||||||
|
|
||||||
For more information on best practices, try these links:
|
For more information on best practices, try these links:
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ _You_ Made It
|
||||||
{: .subtitle}
|
{: .subtitle}
|
||||||
|
|
||||||
Traefik Proxy truly is an [open-source project](https://github.com/traefik/traefik/),
|
Traefik Proxy truly is an [open-source project](https://github.com/traefik/traefik/),
|
||||||
and wouldn't have become what it is today without the help of our [many contributors](https://github.com/traefik/traefik/graphs/contributors) (at the time of writing this),
|
and wouldn't have become what it is today without the help of our [many contributors](https://github.com/traefik/traefik/graphs/contributors),
|
||||||
not accounting for people having helped with issues, tests, comments, articles, ... or just enjoy using Traefik Proxy and share with others.
|
not accounting for people having helped with issues, tests, comments, articles, ... or just enjoy using Traefik Proxy and share with others.
|
||||||
|
|
||||||
So once again, thank you for your invaluable help in making Traefik such a good product!
|
So once again, thank you for your invaluable help in making Traefik such a good product!
|
||||||
|
@ -17,16 +17,16 @@ So once again, thank you for your invaluable help in making Traefik such a good
|
||||||
!!! question "Where to Go Next?"
|
!!! question "Where to Go Next?"
|
||||||
If you want to:
|
If you want to:
|
||||||
|
|
||||||
- Propose and idea, request a feature a report a bug,
|
- Propose an idea, request a feature, or report a bug,
|
||||||
read the page [Submitting Issues](./submitting-issues.md).
|
then read [Submitting Issues](./submitting-issues.md).
|
||||||
- Discover how to make an efficient contribution,
|
- Discover how to make an efficient contribution,
|
||||||
read the page [Submitting Pull Requests](./submitting-pull-requests.md).
|
then read [Submitting Pull Requests](./submitting-pull-requests.md).
|
||||||
- Learn how to build and test Traefik,
|
- Learn how to build and test Traefik,
|
||||||
the page [Building and Testing](./building-testing.md) is for you.
|
then the page [Building and Testing](./building-testing.md) is for you.
|
||||||
- Contribute to the documentation,
|
- Contribute to the documentation,
|
||||||
read the related page [Documentation](./documentation.md).
|
then read the page about [Documentation](./documentation.md).
|
||||||
- Understand how do we learn about Traefik usage,
|
- Understand how do we learn about Traefik usage,
|
||||||
read the [Data Collection](./data-collection.md) page.
|
read the [Data Collection](./data-collection.md) page.
|
||||||
- Spread the love about Traefik, please check the [Advocating](./advocating.md) page.
|
- Spread the love about Traefik, please check the [Advocating](./advocating.md) page.
|
||||||
- Learn about who are the maintainers and how they work on the project,
|
- Learn about who are the maintainers and how they work on the project,
|
||||||
read the [Maintainers](./maintainers.md) page.
|
read the [Maintainers](./maintainers.md) and [Maintainer Guidelines](./maintainers-guidelines.md) pages.
|
||||||
|
|
|
@ -10,7 +10,7 @@ Adding Basic Authentication
|
||||||
|
|
||||||
![BasicAuth](../../assets/img/middleware/basicauth.png)
|
![BasicAuth](../../assets/img/middleware/basicauth.png)
|
||||||
|
|
||||||
The BasicAuth middleware restricts access to your services to known users.
|
The BasicAuth middleware grants access to services to authorized users only.
|
||||||
|
|
||||||
## Configuration Examples
|
## Configuration Examples
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ Adding Digest Authentication
|
||||||
|
|
||||||
![BasicAuth](../../assets/img/middleware/digestauth.png)
|
![BasicAuth](../../assets/img/middleware/digestauth.png)
|
||||||
|
|
||||||
The DigestAuth middleware restricts access to your services to known users.
|
The DigestAuth middleware grants access to services to authorized users only.
|
||||||
|
|
||||||
## Configuration Examples
|
## Configuration Examples
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ The Errors middleware returns a custom page in lieu of the default, according to
|
||||||
```yaml tab="Docker & Swarm"
|
```yaml tab="Docker & Swarm"
|
||||||
# Dynamic Custom Error Page for 5XX Status Code
|
# Dynamic Custom Error Page for 5XX Status Code
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.middlewares.test-errors.errors.status=500-599"
|
- "traefik.http.middlewares.test-errors.errors.status=500,501,503,505-599"
|
||||||
- "traefik.http.middlewares.test-errors.errors.service=serviceError"
|
- "traefik.http.middlewares.test-errors.errors.service=serviceError"
|
||||||
- "traefik.http.middlewares.test-errors.errors.query=/{status}.html"
|
- "traefik.http.middlewares.test-errors.errors.query=/{status}.html"
|
||||||
```
|
```
|
||||||
|
@ -34,7 +34,10 @@ metadata:
|
||||||
spec:
|
spec:
|
||||||
errors:
|
errors:
|
||||||
status:
|
status:
|
||||||
- "500-599"
|
- "500"
|
||||||
|
- "501"
|
||||||
|
- "503"
|
||||||
|
- "505-599"
|
||||||
query: /{status}.html
|
query: /{status}.html
|
||||||
service:
|
service:
|
||||||
name: whoami
|
name: whoami
|
||||||
|
@ -42,20 +45,23 @@ spec:
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Consul Catalog"
|
```yaml tab="Consul Catalog"
|
||||||
# Dynamic Custom Error Page for 5XX Status Code
|
# Dynamic Custom Error Page for 5XX Status Code excluding 502 and 504
|
||||||
- "traefik.http.middlewares.test-errors.errors.status=500-599"
|
- "traefik.http.middlewares.test-errors.errors.status=500,501,503,505-599"
|
||||||
- "traefik.http.middlewares.test-errors.errors.service=serviceError"
|
- "traefik.http.middlewares.test-errors.errors.service=serviceError"
|
||||||
- "traefik.http.middlewares.test-errors.errors.query=/{status}.html"
|
- "traefik.http.middlewares.test-errors.errors.query=/{status}.html"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
# Custom Error Page for 5XX
|
# Dynamic Custom Error Page for 5XX Status Code excluding 502 and 504
|
||||||
http:
|
http:
|
||||||
middlewares:
|
middlewares:
|
||||||
test-errors:
|
test-errors:
|
||||||
errors:
|
errors:
|
||||||
status:
|
status:
|
||||||
- "500-599"
|
- "500"
|
||||||
|
- "501"
|
||||||
|
- "503"
|
||||||
|
- "505-599"
|
||||||
service: serviceError
|
service: serviceError
|
||||||
query: "/{status}.html"
|
query: "/{status}.html"
|
||||||
|
|
||||||
|
@ -64,10 +70,10 @@ http:
|
||||||
```
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
# Custom Error Page for 5XX
|
# Dynamic Custom Error Page for 5XX Status Code excluding 502 and 504
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-errors.errors]
|
[http.middlewares.test-errors.errors]
|
||||||
status = ["500-599"]
|
status = ["500","501","503","505-599"]
|
||||||
service = "serviceError"
|
service = "serviceError"
|
||||||
query = "/{status}.html"
|
query = "/{status}.html"
|
||||||
|
|
||||||
|
@ -85,14 +91,16 @@ http:
|
||||||
|
|
||||||
The `status` option defines which status or range of statuses should result in an error page.
|
The `status` option defines which status or range of statuses should result in an error page.
|
||||||
|
|
||||||
The status code ranges are inclusive (`500-599` will trigger with every code between `500` and `599`, `500` and `599` included).
|
The status code ranges are inclusive (`505-599` will trigger with every code between `505` and `599`, `505` and `599` included).
|
||||||
|
|
||||||
!!! note ""
|
!!! note ""
|
||||||
|
|
||||||
You can define either a status code as a number (`500`),
|
You can define either a status code as a number (`500`),
|
||||||
as multiple comma-separated numbers (`500,502`),
|
as multiple comma-separated numbers (`500,502`),
|
||||||
as ranges by separating two codes with a dash (`500-599`),
|
as ranges by separating two codes with a dash (`505-599`),
|
||||||
or a combination of the two (`404,418,500-599`).
|
or a combination of the two (`404,418,505-599`).
|
||||||
|
The comma-separated syntax is only available for label-based providers.
|
||||||
|
The examples above demonstrate which syntax is appropriate for each provider.
|
||||||
|
|
||||||
### `service`
|
### `service`
|
||||||
|
|
||||||
|
|
|
@ -228,3 +228,11 @@ The following metric is produced :
|
||||||
```bash
|
```bash
|
||||||
traefik_entrypoint_requests_total{code="200",entrypoint="web",method="GET",protocol="http",useragent="foobar"} 1
|
traefik_entrypoint_requests_total{code="200",entrypoint="web",method="GET",protocol="http",useragent="foobar"} 1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
!!! info "`Host` header value"
|
||||||
|
|
||||||
|
The `Host` header is never present in the Header map of a request, as per go documentation says:
|
||||||
|
// For incoming requests, the Host header is promoted to the
|
||||||
|
// Request.Host field and removed from the Header map.
|
||||||
|
|
||||||
|
As a workaround, to obtain the Host of a request as a label, one should use instead the `X-Forwarded-For` header.
|
||||||
|
|
|
@ -529,6 +529,13 @@ providers:
|
||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
??? info "Default rule and Traefik service"
|
||||||
|
|
||||||
|
The exposure of the Traefik container, combined with the default rule mechanism,
|
||||||
|
can lead to create a router targeting itself in a loop.
|
||||||
|
In this case, to prevent an infinite loop,
|
||||||
|
Traefik adds an internal middleware to refuse the request if it comes from the same router.
|
||||||
|
|
||||||
### `connectAware`
|
### `connectAware`
|
||||||
|
|
||||||
_Optional, Default=false_
|
_Optional, Default=false_
|
||||||
|
|
|
@ -362,6 +362,13 @@ providers:
|
||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
??? info "Default rule and Traefik service"
|
||||||
|
|
||||||
|
The exposure of the Traefik container, combined with the default rule mechanism,
|
||||||
|
can lead to create a router targeting itself in a loop.
|
||||||
|
In this case, to prevent an infinite loop,
|
||||||
|
Traefik adds an internal middleware to refuse the request if it comes from the same router.
|
||||||
|
|
||||||
### `httpClientTimeout`
|
### `httpClientTimeout`
|
||||||
|
|
||||||
_Optional, Default=0_
|
_Optional, Default=0_
|
||||||
|
|
|
@ -287,6 +287,13 @@ providers:
|
||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
??? info "Default rule and Traefik service"
|
||||||
|
|
||||||
|
The exposure of the Traefik container, combined with the default rule mechanism,
|
||||||
|
can lead to create a router targeting itself in a loop.
|
||||||
|
In this case, to prevent an infinite loop,
|
||||||
|
Traefik adds an internal middleware to refuse the request if it comes from the same router.
|
||||||
|
|
||||||
### `refreshSeconds`
|
### `refreshSeconds`
|
||||||
|
|
||||||
_Optional, Default=15_
|
_Optional, Default=15_
|
||||||
|
|
|
@ -377,6 +377,13 @@ providers:
|
||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
??? info "Default rule and Traefik service"
|
||||||
|
|
||||||
|
The exposure of the Traefik container, combined with the default rule mechanism,
|
||||||
|
can lead to create a router targeting itself in a loop.
|
||||||
|
In this case, to prevent an infinite loop,
|
||||||
|
Traefik adds an internal middleware to refuse the request if it comes from the same router.
|
||||||
|
|
||||||
### `constraints`
|
### `constraints`
|
||||||
|
|
||||||
_Optional, Default=""_
|
_Optional, Default=""_
|
||||||
|
|
|
@ -407,6 +407,13 @@ providers:
|
||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
??? info "Default rule and Traefik service"
|
||||||
|
|
||||||
|
The exposure of the Traefik container, combined with the default rule mechanism,
|
||||||
|
can lead to create a router targeting itself in a loop.
|
||||||
|
In this case, to prevent an infinite loop,
|
||||||
|
Traefik adds an internal middleware to refuse the request if it comes from the same router.
|
||||||
|
|
||||||
### `refreshSeconds`
|
### `refreshSeconds`
|
||||||
|
|
||||||
_Optional, Default=15_
|
_Optional, Default=15_
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: ingressroutes.traefik.io
|
name: ingressroutes.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -267,20 +265,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: ingressroutetcps.traefik.io
|
name: ingressroutetcps.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -486,20 +476,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: ingressrouteudps.traefik.io
|
name: ingressrouteudps.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -591,20 +573,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: middlewares.traefik.io
|
name: middlewares.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -1493,20 +1467,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: middlewaretcps.traefik.io
|
name: middlewaretcps.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -1565,20 +1531,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: serverstransports.traefik.io
|
name: serverstransports.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -1706,20 +1664,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: serverstransporttcps.traefik.io
|
name: serverstransporttcps.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -1828,20 +1778,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: tlsoptions.traefik.io
|
name: tlsoptions.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -1935,20 +1877,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: tlsstores.traefik.io
|
name: tlsstores.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -2034,20 +1968,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: traefikservices.traefik.io
|
name: traefikservices.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -2436,9 +2362,3 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: ingressroutes.traefik.io
|
name: ingressroutes.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -267,9 +265,3 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: ingressroutetcps.traefik.io
|
name: ingressroutetcps.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -211,9 +209,3 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: ingressrouteudps.traefik.io
|
name: ingressrouteudps.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -97,9 +95,3 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: middlewares.traefik.io
|
name: middlewares.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -894,9 +892,3 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: middlewaretcps.traefik.io
|
name: middlewaretcps.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -64,9 +62,3 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: serverstransports.traefik.io
|
name: serverstransports.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -133,9 +131,3 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: serverstransporttcps.traefik.io
|
name: serverstransporttcps.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -114,9 +112,3 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: tlsoptions.traefik.io
|
name: tlsoptions.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -99,9 +97,3 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: tlsstores.traefik.io
|
name: tlsstores.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -91,9 +89,3 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: traefikservices.traefik.io
|
name: traefikservices.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -394,9 +392,3 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
|
@ -248,7 +248,7 @@ EntryPoints in this list are used (by default) on HTTP and TCP routers that do n
|
||||||
If at least one EntryPoint has the `AsDefault` option set to `true`,
|
If at least one EntryPoint has the `AsDefault` option set to `true`,
|
||||||
then the list of default EntryPoints includes only EntryPoints that have the `AsDefault` option set to `true`.
|
then the list of default EntryPoints includes only EntryPoints that have the `AsDefault` option set to `true`.
|
||||||
|
|
||||||
Some built-in EntryPoints are always excluded from the list, namely: `traefik`, `traefikhub-api`, and `traefikhub-tunl`.
|
Some built-in EntryPoints are always excluded from the list, namely: `traefik`.
|
||||||
|
|
||||||
!!! warning "Only TCP and HTTP"
|
!!! warning "Only TCP and HTTP"
|
||||||
|
|
||||||
|
|
144
go.mod
144
go.mod
|
@ -7,13 +7,13 @@ require (
|
||||||
github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61
|
github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61
|
||||||
github.com/Masterminds/sprig/v3 v3.2.3
|
github.com/Masterminds/sprig/v3 v3.2.3
|
||||||
github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000
|
github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000
|
||||||
github.com/andybalholm/brotli v1.0.4
|
github.com/andybalholm/brotli v1.0.6
|
||||||
github.com/aws/aws-sdk-go v1.44.47
|
github.com/aws/aws-sdk-go v1.44.327
|
||||||
github.com/cenkalti/backoff/v4 v4.2.1
|
github.com/cenkalti/backoff/v4 v4.2.1
|
||||||
github.com/compose-spec/compose-go v1.0.3
|
github.com/compose-spec/compose-go v1.0.3
|
||||||
github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd
|
github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd
|
||||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
|
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
|
||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
|
||||||
github.com/docker/cli v20.10.11+incompatible
|
github.com/docker/cli v20.10.11+incompatible
|
||||||
github.com/docker/compose/v2 v2.0.1
|
github.com/docker/compose/v2 v2.0.1
|
||||||
github.com/docker/docker v20.10.21+incompatible
|
github.com/docker/docker v20.10.21+incompatible
|
||||||
|
@ -26,9 +26,8 @@ require (
|
||||||
github.com/google/go-github/v28 v28.1.1
|
github.com/google/go-github/v28 v28.1.1
|
||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/gorilla/websocket v1.5.0
|
github.com/gorilla/websocket v1.5.0
|
||||||
github.com/hashicorp/consul v1.10.12
|
github.com/hashicorp/consul/api v1.26.1
|
||||||
github.com/hashicorp/consul/api v1.14.0
|
github.com/hashicorp/go-hclog v1.5.0
|
||||||
github.com/hashicorp/go-hclog v1.2.0
|
|
||||||
github.com/hashicorp/go-multierror v1.1.1
|
github.com/hashicorp/go-multierror v1.1.1
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.4
|
github.com/hashicorp/go-retryablehttp v0.7.4
|
||||||
github.com/hashicorp/go-version v1.6.0
|
github.com/hashicorp/go-version v1.6.0
|
||||||
|
@ -36,7 +35,7 @@ require (
|
||||||
github.com/influxdata/influxdb-client-go/v2 v2.7.0
|
github.com/influxdata/influxdb-client-go/v2 v2.7.0
|
||||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d
|
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d
|
||||||
github.com/instana/go-sensor v1.38.3
|
github.com/instana/go-sensor v1.38.3
|
||||||
github.com/klauspost/compress v1.16.7
|
github.com/klauspost/compress v1.17.1
|
||||||
github.com/kvtools/consul v1.0.2
|
github.com/kvtools/consul v1.0.2
|
||||||
github.com/kvtools/etcdv3 v1.0.2
|
github.com/kvtools/etcdv3 v1.0.2
|
||||||
github.com/kvtools/redis v1.0.2
|
github.com/kvtools/redis v1.0.2
|
||||||
|
@ -53,10 +52,10 @@ require (
|
||||||
github.com/openzipkin/zipkin-go v0.2.2
|
github.com/openzipkin/zipkin-go v0.2.2
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/pires/go-proxyproto v0.6.1
|
github.com/pires/go-proxyproto v0.6.1
|
||||||
github.com/pmezard/go-difflib v1.0.0
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
|
||||||
github.com/prometheus/client_golang v1.14.0
|
github.com/prometheus/client_golang v1.14.0
|
||||||
github.com/prometheus/client_model v0.3.0
|
github.com/prometheus/client_model v0.3.0
|
||||||
github.com/quic-go/quic-go v0.39.0
|
github.com/quic-go/quic-go v0.39.1
|
||||||
github.com/rs/zerolog v1.28.0
|
github.com/rs/zerolog v1.28.0
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/spiffe/go-spiffe/v2 v2.1.1
|
github.com/spiffe/go-spiffe/v2 v2.1.1
|
||||||
|
@ -75,26 +74,26 @@ require (
|
||||||
github.com/vulcand/predicate v1.2.0
|
github.com/vulcand/predicate v1.2.0
|
||||||
go.elastic.co/apm v1.13.1
|
go.elastic.co/apm v1.13.1
|
||||||
go.elastic.co/apm/module/apmot v1.13.1
|
go.elastic.co/apm/module/apmot v1.13.1
|
||||||
go.opentelemetry.io/collector/pdata v0.64.1
|
go.opentelemetry.io/collector/pdata v0.66.0
|
||||||
go.opentelemetry.io/otel v1.14.0
|
go.opentelemetry.io/otel v1.19.0
|
||||||
go.opentelemetry.io/otel/bridge/opentracing v1.11.2
|
go.opentelemetry.io/otel/bridge/opentracing v1.19.0
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.37.0
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.42.0
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.37.0
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.2
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.2
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.2
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0
|
||||||
go.opentelemetry.io/otel/metric v0.37.0
|
go.opentelemetry.io/otel/metric v1.19.0
|
||||||
go.opentelemetry.io/otel/sdk v1.14.0
|
go.opentelemetry.io/otel/sdk v1.19.0
|
||||||
go.opentelemetry.io/otel/sdk/metric v0.37.0
|
go.opentelemetry.io/otel/sdk/metric v1.19.0
|
||||||
go.opentelemetry.io/otel/trace v1.14.0
|
go.opentelemetry.io/otel/trace v1.19.0
|
||||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db
|
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
|
||||||
golang.org/x/mod v0.11.0
|
golang.org/x/mod v0.12.0
|
||||||
golang.org/x/net v0.17.0
|
golang.org/x/net v0.17.0
|
||||||
golang.org/x/text v0.13.0
|
golang.org/x/text v0.13.0
|
||||||
golang.org/x/time v0.3.0
|
golang.org/x/time v0.3.0
|
||||||
golang.org/x/tools v0.10.0
|
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846
|
||||||
google.golang.org/grpc v1.58.3
|
google.golang.org/grpc v1.58.3
|
||||||
gopkg.in/DataDog/dd-trace-go.v1 v1.51.0
|
gopkg.in/DataDog/dd-trace-go.v1 v1.56.1
|
||||||
gopkg.in/fsnotify.v1 v1.4.7
|
gopkg.in/fsnotify.v1 v1.4.7
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
k8s.io/api v0.26.3
|
k8s.io/api v0.26.3
|
||||||
|
@ -107,7 +106,7 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/compute v1.21.0 // indirect
|
cloud.google.com/go/compute v1.23.0 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||||
github.com/AdamSLevy/jsonrpc2/v14 v14.1.0 // indirect
|
github.com/AdamSLevy/jsonrpc2/v14 v14.1.0 // indirect
|
||||||
github.com/AlecAivazis/survey/v2 v2.2.3 // indirect
|
github.com/AlecAivazis/survey/v2 v2.2.3 // indirect
|
||||||
|
@ -129,47 +128,43 @@ require (
|
||||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect
|
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect
|
||||||
github.com/DataDog/appsec-internal-go v1.0.0 // indirect
|
github.com/DataDog/appsec-internal-go v1.0.0 // indirect
|
||||||
github.com/DataDog/datadog-agent/pkg/obfuscate v0.45.0-rc.1 // indirect
|
github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.0 // indirect
|
||||||
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.45.0-rc.1 // indirect
|
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.0-devel.0.20230725154044-2549ba9058df // indirect
|
||||||
github.com/DataDog/datadog-go v4.8.2+incompatible // indirect
|
github.com/DataDog/datadog-go/v5 v5.3.0 // indirect
|
||||||
github.com/DataDog/datadog-go/v5 v5.1.1 // indirect
|
github.com/DataDog/go-libddwaf v1.5.0 // indirect
|
||||||
github.com/DataDog/go-libddwaf v1.2.0 // indirect
|
github.com/DataDog/go-tuf v1.0.2-0.5.2 // indirect
|
||||||
github.com/DataDog/go-tuf v0.3.0--fix-localmeta-fork // indirect
|
github.com/DataDog/sketches-go v1.4.2 // indirect
|
||||||
github.com/DataDog/sketches-go v1.2.1 // indirect
|
|
||||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
|
github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
|
||||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
github.com/Masterminds/semver/v3 v3.2.0 // indirect
|
github.com/Masterminds/semver/v3 v3.2.0 // indirect
|
||||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||||
github.com/Microsoft/hcsshim v0.8.25 // indirect
|
github.com/Microsoft/hcsshim v0.8.25 // indirect
|
||||||
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 // indirect
|
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 // indirect
|
||||||
github.com/Shopify/sarama v1.23.1 // indirect
|
|
||||||
github.com/VividCortex/gohistogram v1.0.0 // indirect
|
github.com/VividCortex/gohistogram v1.0.0 // indirect
|
||||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 // indirect
|
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 // indirect
|
||||||
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 // indirect
|
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 // indirect
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1755 // indirect
|
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1755 // indirect
|
||||||
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
|
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
|
||||||
github.com/armon/go-metrics v0.3.10 // indirect
|
github.com/armon/go-metrics v0.4.1 // indirect
|
||||||
github.com/armon/go-radix v1.0.0 // indirect
|
github.com/armon/go-radix v1.0.0 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2 v1.19.0 // indirect
|
github.com/aws/aws-sdk-go-v2 v1.20.3 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.18.28 // indirect
|
github.com/aws/aws-sdk-go-v2/config v1.18.28 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.27 // indirect
|
github.com/aws/aws-sdk-go-v2/credentials v1.13.27 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.5 // indirect
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.5 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.35 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.40 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.29 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.34 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.36 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.36 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.29 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.34 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.27.2 // indirect
|
github.com/aws/aws-sdk-go-v2/service/lightsail v1.27.2 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.28.4 // indirect
|
github.com/aws/aws-sdk-go-v2/service/route53 v1.28.4 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.12.13 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sso v1.12.13 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.13 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.13 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.19.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sts v1.19.3 // indirect
|
||||||
github.com/aws/smithy-go v1.13.5 // indirect
|
github.com/aws/smithy-go v1.14.2 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||||
github.com/buger/goterm v1.0.0 // indirect
|
github.com/buger/goterm v1.0.0 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible // indirect
|
|
||||||
github.com/circonus-labs/circonusllhist v0.1.3 // indirect
|
|
||||||
github.com/civo/civogo v0.3.11 // indirect
|
github.com/civo/civogo v0.3.11 // indirect
|
||||||
github.com/cloudflare/cloudflare-go v0.70.0 // indirect
|
github.com/cloudflare/cloudflare-go v0.70.0 // indirect
|
||||||
github.com/compose-spec/godotenv v1.0.0 // indirect
|
github.com/compose-spec/godotenv v1.0.0 // indirect
|
||||||
|
@ -193,14 +188,15 @@ require (
|
||||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
||||||
github.com/docker/go-metrics v0.0.1 // indirect
|
github.com/docker/go-metrics v0.0.1 // indirect
|
||||||
github.com/docker/go-units v0.4.0 // indirect
|
github.com/docker/go-units v0.4.0 // indirect
|
||||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
|
github.com/ebitengine/purego v0.5.0-alpha.1 // indirect
|
||||||
github.com/elastic/go-licenser v0.3.1 // indirect
|
github.com/elastic/go-licenser v0.3.1 // indirect
|
||||||
github.com/elastic/go-sysinfo v1.1.1 // indirect
|
github.com/elastic/go-sysinfo v1.1.1 // indirect
|
||||||
github.com/elastic/go-windows v1.0.0 // indirect
|
github.com/elastic/go-windows v1.0.0 // indirect
|
||||||
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
|
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||||
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
|
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
|
||||||
github.com/exoscale/egoscale v0.100.1 // indirect
|
github.com/exoscale/egoscale v0.100.1 // indirect
|
||||||
github.com/fatih/color v1.13.0 // indirect
|
github.com/fatih/color v1.15.0 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||||
github.com/fvbommel/sortorder v1.0.1 // indirect
|
github.com/fvbommel/sortorder v1.0.1 // indirect
|
||||||
github.com/ghodss/yaml v1.0.0 // indirect
|
github.com/ghodss/yaml v1.0.0 // indirect
|
||||||
|
@ -222,39 +218,29 @@ require (
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
github.com/golang/mock v1.6.0 // indirect
|
github.com/golang/mock v1.6.0 // indirect
|
||||||
github.com/google/btree v1.0.1 // indirect
|
|
||||||
github.com/google/gnostic v0.5.7-v3refs // indirect
|
github.com/google/gnostic v0.5.7-v3refs // indirect
|
||||||
github.com/google/go-cmp v0.5.9 // indirect
|
github.com/google/go-cmp v0.5.9 // indirect
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
github.com/google/gofuzz v1.2.0 // indirect
|
github.com/google/gofuzz v1.2.0 // indirect
|
||||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
|
github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect
|
||||||
github.com/google/s2a-go v0.1.4 // indirect
|
github.com/google/s2a-go v0.1.5 // indirect
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/uuid v1.3.1 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.11.0 // indirect
|
github.com/googleapis/gax-go/v2 v2.11.0 // indirect
|
||||||
github.com/gophercloud/gophercloud v1.0.0 // indirect
|
github.com/gophercloud/gophercloud v1.0.0 // indirect
|
||||||
github.com/gophercloud/utils v0.0.0-20210216074907-f6de111f2eae // indirect
|
github.com/gophercloud/utils v0.0.0-20210216074907-f6de111f2eae // indirect
|
||||||
github.com/gravitational/trace v1.1.16-0.20220114165159-14a9a7dd6aaf // indirect
|
github.com/gravitational/trace v1.1.16-0.20220114165159-14a9a7dd6aaf // indirect
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.14.0 // indirect
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
|
||||||
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect
|
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect
|
||||||
github.com/hashicorp/consul/sdk v0.10.0 // indirect
|
|
||||||
github.com/hashicorp/cronexpr v1.1.1 // indirect
|
github.com/hashicorp/cronexpr v1.1.1 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||||
github.com/hashicorp/go-msgpack v0.5.5 // indirect
|
|
||||||
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||||
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
|
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||||
github.com/hashicorp/go-uuid v1.0.2 // indirect
|
github.com/hashicorp/serf v0.10.1 // indirect
|
||||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
|
||||||
github.com/hashicorp/memberlist v0.3.1 // indirect
|
|
||||||
github.com/hashicorp/raft v1.3.6 // indirect
|
|
||||||
github.com/hashicorp/raft-autopilot v0.1.5 // indirect
|
|
||||||
github.com/hashicorp/serf v0.9.7 // indirect
|
|
||||||
github.com/hashicorp/yamux v0.0.0-20210826001029-26ff87cf9493 // indirect
|
|
||||||
github.com/huandu/xstrings v1.4.0 // indirect
|
github.com/huandu/xstrings v1.4.0 // indirect
|
||||||
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df // indirect
|
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df // indirect
|
||||||
github.com/imdario/mergo v0.3.12 // indirect
|
github.com/imdario/mergo v0.3.12 // indirect
|
||||||
|
@ -284,8 +270,8 @@ require (
|
||||||
github.com/mailgun/multibuf v0.1.2 // indirect
|
github.com/mailgun/multibuf v0.1.2 // indirect
|
||||||
github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51 // indirect
|
github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51 // indirect
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mattn/go-shellwords v1.0.12 // indirect
|
github.com/mattn/go-shellwords v1.0.12 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||||
|
@ -293,7 +279,6 @@ require (
|
||||||
github.com/mimuret/golang-iij-dpf v0.9.1 // indirect
|
github.com/mimuret/golang-iij-dpf v0.9.1 // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
github.com/mitchellh/go-ps v1.0.0 // indirect
|
github.com/mitchellh/go-ps v1.0.0 // indirect
|
||||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
|
||||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||||
github.com/moby/buildkit v0.8.2-0.20210401015549-df49b648c8bf // indirect
|
github.com/moby/buildkit v0.8.2-0.20210401015549-df49b648c8bf // indirect
|
||||||
github.com/moby/locker v1.0.1 // indirect
|
github.com/moby/locker v1.0.1 // indirect
|
||||||
|
@ -320,9 +305,9 @@ require (
|
||||||
github.com/opencontainers/runc v1.1.5 // indirect
|
github.com/opencontainers/runc v1.1.5 // indirect
|
||||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 // indirect
|
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 // indirect
|
||||||
github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect
|
github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect
|
||||||
github.com/outcaste-io/ristretto v0.2.1 // indirect
|
github.com/outcaste-io/ristretto v0.2.3 // indirect
|
||||||
github.com/ovh/go-ovh v1.4.1 // indirect
|
github.com/ovh/go-ovh v1.4.1 // indirect
|
||||||
github.com/philhofer/fwd v1.1.1 // indirect
|
github.com/philhofer/fwd v1.1.2 // indirect
|
||||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
|
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pquerna/otp v1.4.0 // indirect
|
github.com/pquerna/otp v1.4.0 // indirect
|
||||||
|
@ -338,8 +323,7 @@ require (
|
||||||
github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b // indirect
|
github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b // indirect
|
||||||
github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect
|
github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect
|
||||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17 // indirect
|
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17 // indirect
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
|
github.com/secure-systems-lab/go-securesystemslib v0.7.0 // indirect
|
||||||
github.com/secure-systems-lab/go-securesystemslib v0.5.0 // indirect
|
|
||||||
github.com/shopspring/decimal v1.2.0 // indirect
|
github.com/shopspring/decimal v1.2.0 // indirect
|
||||||
github.com/simplesurance/bunny-go v0.0.0-20221115111006-e11d9dc91f04 // indirect
|
github.com/simplesurance/bunny-go v0.0.0-20221115111006-e11d9dc91f04 // indirect
|
||||||
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect
|
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect
|
||||||
|
@ -348,15 +332,14 @@ require (
|
||||||
github.com/spf13/cast v1.3.1 // indirect
|
github.com/spf13/cast v1.3.1 // indirect
|
||||||
github.com/spf13/cobra v1.6.0 // indirect
|
github.com/spf13/cobra v1.6.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/stretchr/objx v0.5.0 // indirect
|
github.com/stretchr/objx v0.5.1 // indirect
|
||||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490 // indirect
|
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490 // indirect
|
||||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.490 // indirect
|
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.490 // indirect
|
||||||
github.com/theupdateframework/notary v0.6.1 // indirect
|
github.com/theupdateframework/notary v0.6.1 // indirect
|
||||||
github.com/tinylib/msgp v1.1.6 // indirect
|
github.com/tinylib/msgp v1.1.8 // indirect
|
||||||
github.com/tonistiigi/fsutil v0.0.0-20201103201449-0834f99b7b85 // indirect
|
github.com/tonistiigi/fsutil v0.0.0-20201103201449-0834f99b7b85 // indirect
|
||||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
|
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
|
||||||
github.com/transip/gotransip/v6 v6.20.0 // indirect
|
github.com/transip/gotransip/v6 v6.20.0 // indirect
|
||||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 // indirect
|
|
||||||
github.com/ultradns/ultradns-go-sdk v1.5.0-20230427130837-23c9b0c // indirect
|
github.com/ultradns/ultradns-go-sdk v1.5.0-20230427130837-23c9b0c // indirect
|
||||||
github.com/vinyldns/go-vinyldns v0.9.16 // indirect
|
github.com/vinyldns/go-vinyldns v0.9.16 // indirect
|
||||||
github.com/vultr/govultr/v2 v2.17.2 // indirect
|
github.com/vultr/govultr/v2 v2.17.2 // indirect
|
||||||
|
@ -372,16 +355,15 @@ require (
|
||||||
go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect
|
go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect
|
||||||
go.etcd.io/etcd/client/v3 v3.5.5 // indirect
|
go.etcd.io/etcd/client/v3 v3.5.5 // indirect
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.37.0 // indirect
|
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
|
||||||
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
go.uber.org/atomic v1.11.0 // indirect
|
||||||
go.uber.org/atomic v1.10.0 // indirect
|
|
||||||
go.uber.org/mock v0.3.0 // indirect
|
go.uber.org/mock v0.3.0 // indirect
|
||||||
go.uber.org/multierr v1.8.0 // indirect
|
go.uber.org/multierr v1.8.0 // indirect
|
||||||
go.uber.org/ratelimit v0.2.0 // indirect
|
go.uber.org/ratelimit v0.2.0 // indirect
|
||||||
go.uber.org/zap v1.21.0 // indirect
|
go.uber.org/zap v1.21.0 // indirect
|
||||||
go4.org/intern v0.0.0-20211027215823-ae77deb06f29 // indirect
|
go4.org/intern v0.0.0-20230525184215-6c62f75575cb // indirect
|
||||||
go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 // indirect
|
go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 // indirect
|
||||||
golang.org/x/crypto v0.14.0 // indirect
|
golang.org/x/crypto v0.14.0 // indirect
|
||||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
|
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
|
||||||
golang.org/x/oauth2 v0.10.0 // indirect
|
golang.org/x/oauth2 v0.10.0 // indirect
|
||||||
|
@ -389,7 +371,7 @@ require (
|
||||||
golang.org/x/sys v0.13.0 // indirect
|
golang.org/x/sys v0.13.0 // indirect
|
||||||
golang.org/x/term v0.13.0 // indirect
|
golang.org/x/term v0.13.0 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||||
google.golang.org/api v0.126.0 // indirect
|
google.golang.org/api v0.128.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect
|
google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||||
|
@ -401,7 +383,7 @@ require (
|
||||||
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
|
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect
|
howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect
|
||||||
inet.af/netaddr v0.0.0-20220811202034-502d2d690317 // indirect
|
inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a // indirect
|
||||||
k8s.io/klog/v2 v2.80.1 // indirect
|
k8s.io/klog/v2 v2.80.1 // indirect
|
||||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
|
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
|
||||||
nhooyr.io/websocket v1.8.7 // indirect
|
nhooyr.io/websocket v1.8.7 // indirect
|
||||||
|
|
|
@ -3,6 +3,7 @@ package integration
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -265,7 +266,8 @@ func getMD5(data string) string {
|
||||||
if _, err := digest.Write([]byte(data)); err != nil {
|
if _, err := digest.Write([]byte(data)); err != nil {
|
||||||
log.Error().Err(err).Send()
|
log.Error().Err(err).Send()
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%x", digest.Sum(nil))
|
|
||||||
|
return hex.EncodeToString(digest.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCnonce() string {
|
func getCnonce() string {
|
||||||
|
@ -273,7 +275,8 @@ func getCnonce() string {
|
||||||
if _, err := io.ReadFull(rand.Reader, b); err != nil {
|
if _, err := io.ReadFull(rand.Reader, b); err != nil {
|
||||||
log.Error().Err(err).Send()
|
log.Error().Err(err).Send()
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%x", b)[:16]
|
|
||||||
|
return hex.EncodeToString(b)[:16]
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDigestAuthorization(digestParts map[string]string) string {
|
func getDigestAuthorization(digestParts map[string]string) string {
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: ingressroutes.traefik.io
|
name: ingressroutes.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -267,20 +265,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: ingressroutetcps.traefik.io
|
name: ingressroutetcps.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -486,20 +476,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: ingressrouteudps.traefik.io
|
name: ingressrouteudps.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -591,20 +573,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: middlewares.traefik.io
|
name: middlewares.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -1493,20 +1467,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: middlewaretcps.traefik.io
|
name: middlewaretcps.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -1565,20 +1531,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: serverstransports.traefik.io
|
name: serverstransports.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -1706,20 +1664,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: serverstransporttcps.traefik.io
|
name: serverstransporttcps.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -1828,20 +1778,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: tlsoptions.traefik.io
|
name: tlsoptions.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -1935,20 +1877,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: tlsstores.traefik.io
|
name: tlsstores.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -2034,20 +1968,12 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.6.2
|
controller-gen.kubebuilder.io/version: v0.13.0
|
||||||
creationTimestamp: null
|
|
||||||
name: traefikservices.traefik.io
|
name: traefikservices.traefik.io
|
||||||
spec:
|
spec:
|
||||||
group: traefik.io
|
group: traefik.io
|
||||||
|
@ -2436,9 +2362,3 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
storage: true
|
storage: true
|
||||||
status:
|
|
||||||
acceptedNames:
|
|
||||||
kind: ""
|
|
||||||
plural: ""
|
|
||||||
conditions: []
|
|
||||||
storedVersions: []
|
|
||||||
|
|
40
integration/fixtures/retry/strip_prefix.toml
Normal file
40
integration/fixtures/retry/strip_prefix.toml
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
[global]
|
||||||
|
checkNewVersion = false
|
||||||
|
sendAnonymousUsage = false
|
||||||
|
|
||||||
|
[log]
|
||||||
|
level = "DEBUG"
|
||||||
|
|
||||||
|
[entryPoints]
|
||||||
|
[entryPoints.web]
|
||||||
|
address = ":8000"
|
||||||
|
|
||||||
|
[api]
|
||||||
|
insecure = true
|
||||||
|
|
||||||
|
[providers.file]
|
||||||
|
filename = "{{ .SelfFilename }}"
|
||||||
|
|
||||||
|
## dynamic configuration ##
|
||||||
|
|
||||||
|
[http.routers]
|
||||||
|
[http.routers.router1]
|
||||||
|
service = "service1"
|
||||||
|
middlewares = [ "retry", "strip-prefix" ]
|
||||||
|
rule = "PathPrefix(`/`)"
|
||||||
|
|
||||||
|
[http.middlewares.retry.retry]
|
||||||
|
attempts = 3
|
||||||
|
|
||||||
|
[http.middlewares.strip-prefix.stripPrefix]
|
||||||
|
prefixes = [ "/test" ]
|
||||||
|
|
||||||
|
[http.services]
|
||||||
|
[http.services.service1]
|
||||||
|
[http.services.service1.loadBalancer]
|
||||||
|
|
||||||
|
[[http.services.service1.loadBalancer.servers]]
|
||||||
|
url = "http://{{ .WhoamiIP }}:8080"
|
||||||
|
|
||||||
|
[[http.services.service1.loadBalancer.servers]]
|
||||||
|
url = "http://{{ .WhoamiIP }}:80"
|
|
@ -42,7 +42,7 @@ func (s *GRPCSuite) SetUpSuite(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *myserver) SayHello(ctx context.Context, in *helloworld.HelloRequest) (*helloworld.HelloReply, error) {
|
func (s *myserver) SayHello(ctx context.Context, in *helloworld.HelloRequest) (*helloworld.HelloReply, error) {
|
||||||
return &helloworld.HelloReply{Message: "Hello " + in.Name}, nil
|
return &helloworld.HelloReply{Message: "Hello " + in.GetName()}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *myserver) StreamExample(in *helloworld.StreamExampleRequest, server helloworld.Greeter_StreamExampleServer) error {
|
func (s *myserver) StreamExample(in *helloworld.StreamExampleRequest, server helloworld.Greeter_StreamExampleServer) error {
|
||||||
|
@ -121,7 +121,7 @@ func callHelloClientGRPC(name string, secure bool) (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return r.Message, nil
|
return r.GetMessage(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func callStreamExampleClientGRPC() (helloworld.Greeter_StreamExampleClient, func() error, error) {
|
func callStreamExampleClientGRPC() (helloworld.Greeter_StreamExampleClient, func() error, error) {
|
||||||
|
@ -351,7 +351,7 @@ func (s *GRPCSuite) TestGRPCBuffer(c *check.C) {
|
||||||
go func() {
|
go func() {
|
||||||
tr, err := client.Recv()
|
tr, err := client.Recv()
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
c.Assert(len(tr.Data), check.Equals, 512)
|
c.Assert(len(tr.GetData()), check.Equals, 512)
|
||||||
received <- true
|
received <- true
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -414,7 +414,7 @@ func (s *GRPCSuite) TestGRPCBufferWithFlushInterval(c *check.C) {
|
||||||
go func() {
|
go func() {
|
||||||
tr, err := client.Recv()
|
tr, err := client.Recv()
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
c.Assert(len(tr.Data), check.Equals, 512)
|
c.Assert(len(tr.GetData()), check.Equals, 512)
|
||||||
received <- true
|
received <- true
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package integration
|
package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
@ -86,3 +87,26 @@ func (s *RetrySuite) TestRetryWebsocket(c *check.C) {
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
c.Assert(response.StatusCode, checker.Equals, http.StatusSwitchingProtocols)
|
c.Assert(response.StatusCode, checker.Equals, http.StatusSwitchingProtocols)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *RetrySuite) TestRetryWithStripPrefix(c *check.C) {
|
||||||
|
file := s.adaptFile(c, "fixtures/retry/strip_prefix.toml", struct{ WhoamiIP string }{s.whoamiIP})
|
||||||
|
defer os.Remove(file)
|
||||||
|
|
||||||
|
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||||
|
defer display(c)
|
||||||
|
err := cmd.Start()
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
defer s.killCmd(cmd)
|
||||||
|
|
||||||
|
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("PathPrefix(`/`)"))
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
response, err := http.Get("http://127.0.0.1:8000/test")
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
body, err := io.ReadAll(response.Body)
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
c.Assert(string(body), checker.Contains, "GET / HTTP/1.1")
|
||||||
|
c.Assert(string(body), checker.Contains, "X-Forwarded-Prefix: /test")
|
||||||
|
}
|
||||||
|
|
|
@ -1467,3 +1467,31 @@ func (s *SimpleSuite) TestEncodeSemicolons(c *check.C) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SimpleSuite) TestDenyFragment(c *check.C) {
|
||||||
|
s.createComposeProject(c, "base")
|
||||||
|
|
||||||
|
s.composeUp(c)
|
||||||
|
defer s.composeDown(c)
|
||||||
|
|
||||||
|
cmd, output := s.traefikCmd(withConfigFile("fixtures/simple_default.toml"))
|
||||||
|
defer output(c)
|
||||||
|
|
||||||
|
err := cmd.Start()
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
defer s.killCmd(cmd)
|
||||||
|
|
||||||
|
// Expected a 404 as we did not configure anything
|
||||||
|
err = try.GetRequest("http://127.0.0.1:8000/", 1*time.Second, try.StatusCodeIs(http.StatusNotFound))
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
conn, err := net.Dial("tcp", "127.0.0.1:8000")
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
_, err = conn.Write([]byte("GET /#/?bar=toto;boo=titi HTTP/1.1\nHost: other.localhost\n\n"))
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
resp, err := http.ReadResponse(bufio.NewReader(conn), nil)
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
c.Assert(resp.StatusCode, checker.Equals, http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
|
@ -212,7 +212,7 @@ func TestHandler_EntryPoints(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, resp.Header.Get("Content-Type"), "application/json")
|
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
|
||||||
contents, err := io.ReadAll(resp.Body)
|
contents, err := io.ReadAll(resp.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
|
|
@ -951,7 +951,7 @@ func TestHandler_HTTP(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, resp.Header.Get("Content-Type"), "application/json")
|
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
|
||||||
contents, err := io.ReadAll(resp.Body)
|
contents, err := io.ReadAll(resp.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
|
|
@ -288,7 +288,7 @@ func TestHandler_Overview(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, resp.Header.Get("Content-Type"), "application/json")
|
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
|
||||||
contents, err := io.ReadAll(resp.Body)
|
contents, err := io.ReadAll(resp.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
|
|
@ -833,7 +833,7 @@ func TestHandler_TCP(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, resp.Header.Get("Content-Type"), "application/json")
|
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
|
||||||
|
|
||||||
contents, err := io.ReadAll(resp.Body)
|
contents, err := io.ReadAll(resp.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -143,7 +143,7 @@ func TestHandler_RawData(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, test.expected.statusCode, resp.StatusCode)
|
assert.Equal(t, test.expected.statusCode, resp.StatusCode)
|
||||||
assert.Equal(t, resp.Header.Get("Content-Type"), "application/json")
|
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
|
||||||
|
|
||||||
contents, err := io.ReadAll(resp.Body)
|
contents, err := io.ReadAll(resp.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -544,7 +544,7 @@ func TestHandler_UDP(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, resp.Header.Get("Content-Type"), "application/json")
|
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
|
||||||
|
|
||||||
contents, err := io.ReadAll(resp.Body)
|
contents, err := io.ReadAll(resp.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -61,6 +61,7 @@ type Router struct {
|
||||||
Rule string `json:"rule,omitempty" toml:"rule,omitempty" yaml:"rule,omitempty"`
|
Rule string `json:"rule,omitempty" toml:"rule,omitempty" yaml:"rule,omitempty"`
|
||||||
Priority int `json:"priority,omitempty" toml:"priority,omitempty,omitzero" yaml:"priority,omitempty" export:"true"`
|
Priority int `json:"priority,omitempty" toml:"priority,omitempty,omitzero" yaml:"priority,omitempty" export:"true"`
|
||||||
TLS *RouterTLSConfig `json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"`
|
TLS *RouterTLSConfig `json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"`
|
||||||
|
DefaultRule bool `json:"-" toml:"-" yaml:"-" label:"-" file:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +k8s:deepcopy-gen=true
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
|
@ -255,8 +255,8 @@ func (shc *ServiceHealthChecker) checkHealthGRPC(ctx context.Context, serverURL
|
||||||
return fmt.Errorf("gRPC health check failed: %w", err)
|
return fmt.Errorf("gRPC health check failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.Status != healthpb.HealthCheckResponse_SERVING {
|
if resp.GetStatus() != healthpb.HealthCheckResponse_SERVING {
|
||||||
return fmt.Errorf("received gRPC status code: %v", resp.Status)
|
return fmt.Errorf("received gRPC status code: %v", resp.GetStatus())
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -18,6 +18,8 @@ import (
|
||||||
healthpb "google.golang.org/grpc/health/grpc_health_v1"
|
healthpb "google.golang.org/grpc/health/grpc_health_v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const delta float64 = 1e-10
|
||||||
|
|
||||||
func TestNewServiceHealthChecker_durations(t *testing.T) {
|
func TestNewServiceHealthChecker_durations(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
|
@ -448,8 +450,8 @@ func TestServiceHealthChecker_Launch(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, test.expNumRemovedServers, lb.numRemovedServers, "removed servers")
|
assert.Equal(t, test.expNumRemovedServers, lb.numRemovedServers, "removed servers")
|
||||||
assert.Equal(t, test.expNumUpsertedServers, lb.numUpsertedServers, "upserted servers")
|
assert.Equal(t, test.expNumUpsertedServers, lb.numUpsertedServers, "upserted servers")
|
||||||
assert.Equal(t, test.expGaugeValue, gauge.GaugeValue, "ServerUp Gauge")
|
assert.InDelta(t, test.expGaugeValue, gauge.GaugeValue, delta, "ServerUp Gauge")
|
||||||
assert.Equal(t, serviceInfo.GetAllStatus(), map[string]string{targetURL.String(): test.targetStatus})
|
assert.Equal(t, map[string]string{targetURL.String(): test.targetStatus}, serviceInfo.GetAllStatus())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,14 +12,12 @@ import (
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/traefik/traefik/v3/pkg/types"
|
"github.com/traefik/traefik/v3/pkg/types"
|
||||||
"github.com/traefik/traefik/v3/pkg/version"
|
"github.com/traefik/traefik/v3/pkg/version"
|
||||||
|
"go.opentelemetry.io/otel"
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
|
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
|
||||||
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
|
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
|
||||||
"go.opentelemetry.io/otel/metric"
|
"go.opentelemetry.io/otel/metric"
|
||||||
"go.opentelemetry.io/otel/metric/global"
|
|
||||||
"go.opentelemetry.io/otel/metric/instrument"
|
|
||||||
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
|
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
|
||||||
"go.opentelemetry.io/otel/sdk/metric/aggregation"
|
|
||||||
"go.opentelemetry.io/otel/sdk/resource"
|
"go.opentelemetry.io/otel/sdk/resource"
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.12.0"
|
semconv "go.opentelemetry.io/otel/semconv/v1.12.0"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
|
@ -41,12 +39,11 @@ func RegisterOpenTelemetry(ctx context.Context, config *types.OpenTelemetry) Reg
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if openTelemetryGaugeCollector == nil {
|
if openTelemetryGaugeCollector == nil {
|
||||||
openTelemetryGaugeCollector = newOpenTelemetryGaugeCollector()
|
openTelemetryGaugeCollector = newOpenTelemetryGaugeCollector()
|
||||||
}
|
}
|
||||||
|
|
||||||
meter := global.Meter("github.com/traefik/traefik",
|
meter := otel.Meter("github.com/traefik/traefik",
|
||||||
metric.WithInstrumentationVersion(version.Version))
|
metric.WithInstrumentationVersion(version.Version))
|
||||||
|
|
||||||
reg := &standardRegistry{
|
reg := &standardRegistry{
|
||||||
|
@ -160,13 +157,13 @@ func newOpenTelemetryMeterProvider(ctx context.Context, config *types.OpenTeleme
|
||||||
// View to customize histogram buckets and rename a single histogram instrument.
|
// View to customize histogram buckets and rename a single histogram instrument.
|
||||||
sdkmetric.WithView(sdkmetric.NewView(
|
sdkmetric.WithView(sdkmetric.NewView(
|
||||||
sdkmetric.Instrument{Name: "traefik_*_request_duration_seconds"},
|
sdkmetric.Instrument{Name: "traefik_*_request_duration_seconds"},
|
||||||
sdkmetric.Stream{Aggregation: aggregation.ExplicitBucketHistogram{
|
sdkmetric.Stream{Aggregation: sdkmetric.AggregationExplicitBucketHistogram{
|
||||||
Boundaries: config.ExplicitBoundaries,
|
Boundaries: config.ExplicitBoundaries,
|
||||||
}},
|
}},
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
|
|
||||||
global.SetMeterProvider(meterProvider)
|
otel.SetMeterProvider(meterProvider)
|
||||||
|
|
||||||
return meterProvider, nil
|
return meterProvider, nil
|
||||||
}
|
}
|
||||||
|
@ -233,8 +230,8 @@ func newGRPCExporter(ctx context.Context, config *types.OpenTelemetry) (sdkmetri
|
||||||
|
|
||||||
func newOTLPCounterFrom(meter metric.Meter, name, desc string) *otelCounter {
|
func newOTLPCounterFrom(meter metric.Meter, name, desc string) *otelCounter {
|
||||||
c, _ := meter.Float64Counter(name,
|
c, _ := meter.Float64Counter(name,
|
||||||
instrument.WithDescription(desc),
|
metric.WithDescription(desc),
|
||||||
instrument.WithUnit("1"),
|
metric.WithUnit("1"),
|
||||||
)
|
)
|
||||||
|
|
||||||
return &otelCounter{
|
return &otelCounter{
|
||||||
|
@ -244,7 +241,7 @@ func newOTLPCounterFrom(meter metric.Meter, name, desc string) *otelCounter {
|
||||||
|
|
||||||
type otelCounter struct {
|
type otelCounter struct {
|
||||||
labelNamesValues otelLabelNamesValues
|
labelNamesValues otelLabelNamesValues
|
||||||
ip instrument.Float64Counter
|
ip metric.Float64Counter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *otelCounter) With(labelValues ...string) metrics.Counter {
|
func (c *otelCounter) With(labelValues ...string) metrics.Counter {
|
||||||
|
@ -255,7 +252,7 @@ func (c *otelCounter) With(labelValues ...string) metrics.Counter {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *otelCounter) Add(delta float64) {
|
func (c *otelCounter) Add(delta float64) {
|
||||||
c.ip.Add(context.Background(), delta, c.labelNamesValues.ToLabels()...)
|
c.ip.Add(context.Background(), delta, metric.WithAttributes(c.labelNamesValues.ToLabels()...))
|
||||||
}
|
}
|
||||||
|
|
||||||
type gaugeValue struct {
|
type gaugeValue struct {
|
||||||
|
@ -323,8 +320,8 @@ func newOTLPGaugeFrom(meter metric.Meter, name, desc string, unit string) *otelG
|
||||||
openTelemetryGaugeCollector.values[name] = make(map[string]gaugeValue)
|
openTelemetryGaugeCollector.values[name] = make(map[string]gaugeValue)
|
||||||
|
|
||||||
c, _ := meter.Float64ObservableGauge(name,
|
c, _ := meter.Float64ObservableGauge(name,
|
||||||
instrument.WithDescription(desc),
|
metric.WithDescription(desc),
|
||||||
instrument.WithUnit(unit),
|
metric.WithUnit(unit),
|
||||||
)
|
)
|
||||||
|
|
||||||
_, err := meter.RegisterCallback(func(ctx context.Context, observer metric.Observer) error {
|
_, err := meter.RegisterCallback(func(ctx context.Context, observer metric.Observer) error {
|
||||||
|
@ -337,7 +334,7 @@ func newOTLPGaugeFrom(meter metric.Meter, name, desc string, unit string) *otelG
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, value := range values {
|
for _, value := range values {
|
||||||
observer.ObserveFloat64(c, value.value, value.attributes.ToLabels()...)
|
observer.ObserveFloat64(c, value.value, metric.WithAttributes(value.attributes.ToLabels()...))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -354,7 +351,7 @@ func newOTLPGaugeFrom(meter metric.Meter, name, desc string, unit string) *otelG
|
||||||
|
|
||||||
type otelGauge struct {
|
type otelGauge struct {
|
||||||
labelNamesValues otelLabelNamesValues
|
labelNamesValues otelLabelNamesValues
|
||||||
ip instrument.Float64ObservableGauge
|
ip metric.Float64ObservableGauge
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,8 +373,8 @@ func (g *otelGauge) Set(value float64) {
|
||||||
|
|
||||||
func newOTLPHistogramFrom(meter metric.Meter, name, desc string, unit string) *otelHistogram {
|
func newOTLPHistogramFrom(meter metric.Meter, name, desc string, unit string) *otelHistogram {
|
||||||
c, _ := meter.Float64Histogram(name,
|
c, _ := meter.Float64Histogram(name,
|
||||||
instrument.WithDescription(desc),
|
metric.WithDescription(desc),
|
||||||
instrument.WithUnit(unit),
|
metric.WithUnit(unit),
|
||||||
)
|
)
|
||||||
|
|
||||||
return &otelHistogram{
|
return &otelHistogram{
|
||||||
|
@ -387,7 +384,7 @@ func newOTLPHistogramFrom(meter metric.Meter, name, desc string, unit string) *o
|
||||||
|
|
||||||
type otelHistogram struct {
|
type otelHistogram struct {
|
||||||
labelNamesValues otelLabelNamesValues
|
labelNamesValues otelLabelNamesValues
|
||||||
ip instrument.Float64Histogram
|
ip metric.Float64Histogram
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *otelHistogram) With(labelValues ...string) metrics.Histogram {
|
func (h *otelHistogram) With(labelValues ...string) metrics.Histogram {
|
||||||
|
@ -398,7 +395,7 @@ func (h *otelHistogram) With(labelValues ...string) metrics.Histogram {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *otelHistogram) Observe(incr float64) {
|
func (h *otelHistogram) Observe(incr float64) {
|
||||||
h.ip.Record(context.Background(), incr, h.labelNamesValues.ToLabels()...)
|
h.ip.Record(context.Background(), incr, metric.WithAttributes(h.labelNamesValues.ToLabels()...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// otelLabelNamesValues is the equivalent of prometheus' labelNamesValues
|
// otelLabelNamesValues is the equivalent of prometheus' labelNamesValues
|
||||||
|
|
|
@ -340,8 +340,8 @@ func TestOpenTelemetry(t *testing.T) {
|
||||||
// TODO: the len of startUnixNano is no supposed to be 20, it should be 19
|
// TODO: the len of startUnixNano is no supposed to be 20, it should be 19
|
||||||
expected = append(expected,
|
expected = append(expected,
|
||||||
`({"name":"traefik_config_reloads_total","description":"Config reloads","unit":"1","sum":{"dataPoints":\[{"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`,
|
`({"name":"traefik_config_reloads_total","description":"Config reloads","unit":"1","sum":{"dataPoints":\[{"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`,
|
||||||
`({"name":"traefik_config_last_reload_success","description":"Last config reload success","unit":"ms","gauge":{"dataPoints":\[{"startTimeUnixNano":"[\d]{20}","timeUnixNano":"[\d]{19}","asDouble":1}\]}})`,
|
`({"name":"traefik_config_last_reload_success","description":"Last config reload success","unit":"ms","gauge":{"dataPoints":\[{"timeUnixNano":"[\d]{19}","asDouble":1}\]}})`,
|
||||||
`({"name":"traefik_open_connections","description":"How many open connections exist, by entryPoint and protocol","unit":"1","gauge":{"dataPoints":\[{"attributes":\[{"key":"entrypoint","value":{"stringValue":"test"}},{"key":"protocol","value":{"stringValue":"TCP"}}\],"startTimeUnixNano":"[\d]{20}","timeUnixNano":"[\d]{19}","asDouble":1}\]}})`,
|
`({"name":"traefik_open_connections","description":"How many open connections exist, by entryPoint and protocol","unit":"1","gauge":{"dataPoints":\[{"attributes":\[{"key":"entrypoint","value":{"stringValue":"test"}},{"key":"protocol","value":{"stringValue":"TCP"}}\],"timeUnixNano":"[\d]{19}","asDouble":1}\]}})`,
|
||||||
)
|
)
|
||||||
|
|
||||||
registry.ConfigReloadsCounter().Add(1)
|
registry.ConfigReloadsCounter().Add(1)
|
||||||
|
@ -352,7 +352,7 @@ func TestOpenTelemetry(t *testing.T) {
|
||||||
assertMessage(t, *msgServer, expected)
|
assertMessage(t, *msgServer, expected)
|
||||||
|
|
||||||
expected = append(expected,
|
expected = append(expected,
|
||||||
`({"name":"traefik_tls_certs_not_after","description":"Certificate expiration timestamp","unit":"ms","gauge":{"dataPoints":\[{"attributes":\[{"key":"key","value":{"stringValue":"value"}}\],"startTimeUnixNano":"[\d]{20}","timeUnixNano":"[\d]{19}","asDouble":1}\]}})`,
|
`({"name":"traefik_tls_certs_not_after","description":"Certificate expiration timestamp","unit":"ms","gauge":{"dataPoints":\[{"attributes":\[{"key":"key","value":{"stringValue":"value"}}\],"timeUnixNano":"[\d]{19}","asDouble":1}\]}})`,
|
||||||
)
|
)
|
||||||
|
|
||||||
registry.TLSCertsNotAfterTimestampGauge().With("key", "value").Set(1)
|
registry.TLSCertsNotAfterTimestampGauge().With("key", "value").Set(1)
|
||||||
|
@ -399,7 +399,7 @@ func TestOpenTelemetry(t *testing.T) {
|
||||||
`({"name":"traefik_service_requests_total","description":"How many HTTP requests processed on a service, partitioned by status code, protocol, and method.","unit":"1","sum":{"dataPoints":\[{"attributes":\[{"key":"code","value":{"stringValue":"(?:200|404)"}},{"key":"method","value":{"stringValue":"GET"}},{"key":"service","value":{"stringValue":"ServiceReqsCounter"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1},{"attributes":\[{"key":"code","value":{"stringValue":"(?:200|404)"}},{"key":"method","value":{"stringValue":"GET"}},{"key":"service","value":{"stringValue":"ServiceReqsCounter"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`,
|
`({"name":"traefik_service_requests_total","description":"How many HTTP requests processed on a service, partitioned by status code, protocol, and method.","unit":"1","sum":{"dataPoints":\[{"attributes":\[{"key":"code","value":{"stringValue":"(?:200|404)"}},{"key":"method","value":{"stringValue":"GET"}},{"key":"service","value":{"stringValue":"ServiceReqsCounter"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1},{"attributes":\[{"key":"code","value":{"stringValue":"(?:200|404)"}},{"key":"method","value":{"stringValue":"GET"}},{"key":"service","value":{"stringValue":"ServiceReqsCounter"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`,
|
||||||
`({"name":"traefik_service_requests_tls_total","description":"How many HTTP requests with TLS processed on a service, partitioned by TLS version and TLS cipher.","unit":"1","sum":{"dataPoints":\[{"attributes":\[{"key":"service","value":{"stringValue":"test"}},{"key":"tls_cipher","value":{"stringValue":"bar"}},{"key":"tls_version","value":{"stringValue":"foo"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`,
|
`({"name":"traefik_service_requests_tls_total","description":"How many HTTP requests with TLS processed on a service, partitioned by TLS version and TLS cipher.","unit":"1","sum":{"dataPoints":\[{"attributes":\[{"key":"service","value":{"stringValue":"test"}},{"key":"tls_cipher","value":{"stringValue":"bar"}},{"key":"tls_version","value":{"stringValue":"foo"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`,
|
||||||
`({"name":"traefik_service_request_duration_seconds","description":"How long it took to process the request on a service, partitioned by status code, protocol, and method.","unit":"ms","histogram":{"dataPoints":\[{"attributes":\[{"key":"code","value":{"stringValue":"200"}},{"key":"service","value":{"stringValue":"test"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","count":"1","sum":10000,"bucketCounts":\["0","0","0","0","0","0","0","0","0","0","0","1"\],"explicitBounds":\[0.005,0.01,0.025,0.05,0.1,0.25,0.5,1,2.5,5,10\],"min":10000,"max":10000}\],"aggregationTemporality":2}})`,
|
`({"name":"traefik_service_request_duration_seconds","description":"How long it took to process the request on a service, partitioned by status code, protocol, and method.","unit":"ms","histogram":{"dataPoints":\[{"attributes":\[{"key":"code","value":{"stringValue":"200"}},{"key":"service","value":{"stringValue":"test"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","count":"1","sum":10000,"bucketCounts":\["0","0","0","0","0","0","0","0","0","0","0","1"\],"explicitBounds":\[0.005,0.01,0.025,0.05,0.1,0.25,0.5,1,2.5,5,10\],"min":10000,"max":10000}\],"aggregationTemporality":2}})`,
|
||||||
`({"name":"traefik_service_server_up","description":"service server is up, described by gauge value of 0 or 1.","unit":"1","gauge":{"dataPoints":\[{"attributes":\[{"key":"service","value":{"stringValue":"test"}},{"key":"url","value":{"stringValue":"http://127.0.0.1"}}\],"startTimeUnixNano":"[\d]{20}","timeUnixNano":"[\d]{19}","asDouble":1}\]}})`,
|
`({"name":"traefik_service_server_up","description":"service server is up, described by gauge value of 0 or 1.","unit":"1","gauge":{"dataPoints":\[{"attributes":\[{"key":"service","value":{"stringValue":"test"}},{"key":"url","value":{"stringValue":"http://127.0.0.1"}}\],"timeUnixNano":"[\d]{19}","asDouble":1}\]}})`,
|
||||||
`({"name":"traefik_service_requests_bytes_total","description":"The total size of requests in bytes received by a service, partitioned by status code, protocol, and method.","unit":"1","sum":{"dataPoints":\[{"attributes":\[{"key":"code","value":{"stringValue":"404"}},{"key":"method","value":{"stringValue":"GET"}},{"key":"service","value":{"stringValue":"ServiceReqsCounter"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`,
|
`({"name":"traefik_service_requests_bytes_total","description":"The total size of requests in bytes received by a service, partitioned by status code, protocol, and method.","unit":"1","sum":{"dataPoints":\[{"attributes":\[{"key":"code","value":{"stringValue":"404"}},{"key":"method","value":{"stringValue":"GET"}},{"key":"service","value":{"stringValue":"ServiceReqsCounter"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`,
|
||||||
`({"name":"traefik_service_responses_bytes_total","description":"The total size of responses in bytes returned by a service, partitioned by status code, protocol, and method.","unit":"1","sum":{"dataPoints":\[{"attributes":\[{"key":"code","value":{"stringValue":"404"}},{"key":"method","value":{"stringValue":"GET"}},{"key":"service","value":{"stringValue":"ServiceReqsCounter"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`,
|
`({"name":"traefik_service_responses_bytes_total","description":"The total size of responses in bytes returned by a service, partitioned by status code, protocol, and method.","unit":"1","sum":{"dataPoints":\[{"attributes":\[{"key":"code","value":{"stringValue":"404"}},{"key":"method","value":{"stringValue":"GET"}},{"key":"service","value":{"stringValue":"ServiceReqsCounter"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`,
|
||||||
)
|
)
|
||||||
|
|
|
@ -389,12 +389,12 @@ func TestPrometheus(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, label := range family.Metric[0].Label {
|
for _, label := range family.GetMetric()[0].GetLabel() {
|
||||||
val, ok := test.labels[*label.Name]
|
val, ok := test.labels[label.GetName()]
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Errorf("%q metric contains unexpected label %q", test.name, *label.Name)
|
t.Errorf("%q metric contains unexpected label %q", test.name, label.GetName())
|
||||||
} else if val != *label.Value {
|
} else if val != label.GetValue() {
|
||||||
t.Errorf("label %q in metric %q has wrong value %q, expected %q", *label.Name, test.name, *label.Value, val)
|
t.Errorf("label %q in metric %q has wrong value %q, expected %q", label.GetName(), test.name, label.GetValue(), val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
test.assert(family)
|
test.assert(family)
|
||||||
|
@ -645,7 +645,7 @@ func findMetricByLabelNamesValues(family *dto.MetricFamily, labelNamesValues ...
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, metric := range family.Metric {
|
for _, metric := range family.GetMetric() {
|
||||||
if hasMetricAllLabelPairs(metric, labelNamesValues...) {
|
if hasMetricAllLabelPairs(metric, labelNamesValues...) {
|
||||||
return metric
|
return metric
|
||||||
}
|
}
|
||||||
|
@ -665,7 +665,7 @@ func hasMetricAllLabelPairs(metric *dto.Metric, labelNamesValues ...string) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasMetricLabelPair(metric *dto.Metric, labelName, labelValue string) bool {
|
func hasMetricLabelPair(metric *dto.Metric, labelName, labelValue string) bool {
|
||||||
for _, labelPair := range metric.Label {
|
for _, labelPair := range metric.GetLabel() {
|
||||||
if labelPair.GetName() == labelName && labelPair.GetValue() == labelValue {
|
if labelPair.GetName() == labelName && labelPair.GetValue() == labelValue {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -682,12 +682,12 @@ func assertCounterValue(t *testing.T, want float64, family *dto.MetricFamily, la
|
||||||
t.Error("metric must not be nil")
|
t.Error("metric must not be nil")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if metric.Counter == nil {
|
if metric.GetCounter() == nil {
|
||||||
t.Errorf("metric %s must be a counter", family.GetName())
|
t.Errorf("metric %s must be a counter", family.GetName())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if cv := metric.Counter.GetValue(); cv != want {
|
if cv := metric.GetCounter().GetValue(); cv != want {
|
||||||
t.Errorf("metric %s has value %v, want %v", family.GetName(), cv, want)
|
t.Errorf("metric %s has value %v, want %v", family.GetName(), cv, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -696,7 +696,7 @@ func buildCounterAssert(t *testing.T, metricName string, expectedValue int) func
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
return func(family *dto.MetricFamily) {
|
return func(family *dto.MetricFamily) {
|
||||||
if cv := int(family.Metric[0].Counter.GetValue()); cv != expectedValue {
|
if cv := int(family.GetMetric()[0].GetCounter().GetValue()); cv != expectedValue {
|
||||||
t.Errorf("metric %s has value %d, want %d", metricName, cv, expectedValue)
|
t.Errorf("metric %s has value %d, want %d", metricName, cv, expectedValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -706,7 +706,7 @@ func buildGreaterThanCounterAssert(t *testing.T, metricName string, expectedMinV
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
return func(family *dto.MetricFamily) {
|
return func(family *dto.MetricFamily) {
|
||||||
if cv := int(family.Metric[0].Counter.GetValue()); cv < expectedMinValue {
|
if cv := int(family.GetMetric()[0].GetCounter().GetValue()); cv < expectedMinValue {
|
||||||
t.Errorf("metric %s has value %d, want at least %d", metricName, cv, expectedMinValue)
|
t.Errorf("metric %s has value %d, want at least %d", metricName, cv, expectedMinValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -716,7 +716,7 @@ func buildHistogramAssert(t *testing.T, metricName string, expectedSampleCount i
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
return func(family *dto.MetricFamily) {
|
return func(family *dto.MetricFamily) {
|
||||||
if sc := int(family.Metric[0].Histogram.GetSampleCount()); sc != expectedSampleCount {
|
if sc := int(family.GetMetric()[0].GetHistogram().GetSampleCount()); sc != expectedSampleCount {
|
||||||
t.Errorf("metric %s has sample count value %d, want %d", metricName, sc, expectedSampleCount)
|
t.Errorf("metric %s has sample count value %d, want %d", metricName, sc, expectedSampleCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -726,7 +726,7 @@ func buildGaugeAssert(t *testing.T, metricName string, expectedValue int) func(f
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
return func(family *dto.MetricFamily) {
|
return func(family *dto.MetricFamily) {
|
||||||
if gv := int(family.Metric[0].Gauge.GetValue()); gv != expectedValue {
|
if gv := int(family.GetMetric()[0].GetGauge().GetValue()); gv != expectedValue {
|
||||||
t.Errorf("metric %s has value %d, want %d", metricName, gv, expectedValue)
|
t.Errorf("metric %s has value %d, want %d", metricName, gv, expectedValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -736,7 +736,7 @@ func buildTimestampAssert(t *testing.T, metricName string) func(family *dto.Metr
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
return func(family *dto.MetricFamily) {
|
return func(family *dto.MetricFamily) {
|
||||||
if ts := time.Unix(int64(family.Metric[0].Gauge.GetValue()), 0); time.Since(ts) > time.Minute {
|
if ts := time.Unix(int64(family.GetMetric()[0].GetGauge().GetValue()), 0); time.Since(ts) > time.Minute {
|
||||||
t.Errorf("metric %s has wrong timestamp %v", metricName, ts)
|
t.Errorf("metric %s has wrong timestamp %v", metricName, ts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -323,7 +324,7 @@ func TestLoggerJSON(t *testing.T) {
|
||||||
ServiceURL: assertString(testServiceName),
|
ServiceURL: assertString(testServiceName),
|
||||||
ClientUsername: assertString(testUsername),
|
ClientUsername: assertString(testUsername),
|
||||||
ClientHost: assertString(testHostname),
|
ClientHost: assertString(testHostname),
|
||||||
ClientPort: assertString(fmt.Sprintf("%d", testPort)),
|
ClientPort: assertString(strconv.Itoa(testPort)),
|
||||||
ClientAddr: assertString(fmt.Sprintf("%s:%d", testHostname, testPort)),
|
ClientAddr: assertString(fmt.Sprintf("%s:%d", testHostname, testPort)),
|
||||||
"level": assertString("info"),
|
"level": assertString("info"),
|
||||||
"msg": assertString(""),
|
"msg": assertString(""),
|
||||||
|
@ -363,7 +364,7 @@ func TestLoggerJSON(t *testing.T) {
|
||||||
ServiceURL: assertString(testServiceName),
|
ServiceURL: assertString(testServiceName),
|
||||||
ClientUsername: assertString(testUsername),
|
ClientUsername: assertString(testUsername),
|
||||||
ClientHost: assertString(testHostname),
|
ClientHost: assertString(testHostname),
|
||||||
ClientPort: assertString(fmt.Sprintf("%d", testPort)),
|
ClientPort: assertString(strconv.Itoa(testPort)),
|
||||||
ClientAddr: assertString(fmt.Sprintf("%s:%d", testHostname, testPort)),
|
ClientAddr: assertString(fmt.Sprintf("%s:%d", testHostname, testPort)),
|
||||||
"level": assertString("info"),
|
"level": assertString("info"),
|
||||||
"msg": assertString(""),
|
"msg": assertString(""),
|
||||||
|
|
|
@ -137,5 +137,5 @@ func (r *digestRequest) makeAuthorization(req *http.Request, parts map[string]st
|
||||||
func generateRandom(n int) string {
|
func generateRandom(n int) string {
|
||||||
b := make([]byte, 8)
|
b := make([]byte, 8)
|
||||||
_, _ = io.ReadFull(rand.Reader, b)
|
_, _ = io.ReadFull(rand.Reader, b)
|
||||||
return fmt.Sprintf("%x", b)[:n]
|
return hex.EncodeToString(b)[:n]
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ func runBenchmark(b *testing.B, size int, req *http.Request, handler http.Handle
|
||||||
b.Fatalf("Expected 200 but got %d", code)
|
b.Fatalf("Expected 200 but got %d", code)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(b, size, len(recorder.Body.String()))
|
assert.Len(b, recorder.Body.String(), size)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateBytes(length int) []byte {
|
func generateBytes(length int) []byte {
|
||||||
|
|
|
@ -376,13 +376,13 @@ func Test_ExcludedContentTypes(t *testing.T) {
|
||||||
assert.Equal(t, "br", rw.Header().Get(contentEncoding))
|
assert.Equal(t, "br", rw.Header().Get(contentEncoding))
|
||||||
|
|
||||||
got, err := io.ReadAll(brotli.NewReader(rw.Body))
|
got, err := io.ReadAll(brotli.NewReader(rw.Body))
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, bigTestBody, got)
|
assert.Equal(t, bigTestBody, got)
|
||||||
} else {
|
} else {
|
||||||
assert.NotEqual(t, "br", rw.Header().Get("Content-Encoding"))
|
assert.NotEqual(t, "br", rw.Header().Get("Content-Encoding"))
|
||||||
|
|
||||||
got, err := io.ReadAll(rw.Body)
|
got, err := io.ReadAll(rw.Body)
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, bigTestBody, got)
|
assert.Equal(t, bigTestBody, got)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -496,13 +496,13 @@ func Test_FlushExcludedContentTypes(t *testing.T) {
|
||||||
assert.Equal(t, "br", rw.Header().Get(contentEncoding))
|
assert.Equal(t, "br", rw.Header().Get(contentEncoding))
|
||||||
|
|
||||||
got, err := io.ReadAll(brotli.NewReader(rw.Body))
|
got, err := io.ReadAll(brotli.NewReader(rw.Body))
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, bigTestBody, got)
|
assert.Equal(t, bigTestBody, got)
|
||||||
} else {
|
} else {
|
||||||
assert.NotEqual(t, "br", rw.Header().Get(contentEncoding))
|
assert.NotEqual(t, "br", rw.Header().Get(contentEncoding))
|
||||||
|
|
||||||
got, err := io.ReadAll(rw.Body)
|
got, err := io.ReadAll(rw.Body)
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, bigTestBody, got)
|
assert.Equal(t, bigTestBody, got)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -582,7 +582,7 @@ func Test1xxResponses(t *testing.T) {
|
||||||
req.Header.Add(acceptEncodingHeader, gzipValue)
|
req.Header.Add(acceptEncodingHeader, gzipValue)
|
||||||
|
|
||||||
res, err := frontendClient.Do(req)
|
res, err := frontendClient.Do(req)
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
|
|
@ -253,7 +253,7 @@ func Test1xxResponses(t *testing.T) {
|
||||||
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil)
|
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil)
|
||||||
|
|
||||||
res, err := frontendClient.Do(req)
|
res, err := frontendClient.Do(req)
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
|
64
pkg/middlewares/denyrouterrecursion/deny_router_recursion.go
Normal file
64
pkg/middlewares/denyrouterrecursion/deny_router_recursion.go
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
package denyrouterrecursion
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"hash/fnv"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/containous/alice"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/traefik/traefik/v3/pkg/logs"
|
||||||
|
)
|
||||||
|
|
||||||
|
const xTraefikRouter = "X-Traefik-Router"
|
||||||
|
|
||||||
|
type DenyRouterRecursion struct {
|
||||||
|
routerName string
|
||||||
|
routerNameHash string
|
||||||
|
next http.Handler
|
||||||
|
}
|
||||||
|
|
||||||
|
// WrapHandler Wraps router to alice.Constructor.
|
||||||
|
func WrapHandler(routerName string) alice.Constructor {
|
||||||
|
return func(next http.Handler) (http.Handler, error) {
|
||||||
|
return New(routerName, next)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new DenyRouterRecursion.
|
||||||
|
// DenyRouterRecursion middleware is an internal middleware used to avoid infinite requests loop on the same router.
|
||||||
|
func New(routerName string, next http.Handler) (*DenyRouterRecursion, error) {
|
||||||
|
if routerName == "" {
|
||||||
|
return nil, errors.New("routerName cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &DenyRouterRecursion{
|
||||||
|
routerName: routerName,
|
||||||
|
routerNameHash: makeHash(routerName),
|
||||||
|
next: next,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeHTTP implements http.Handler.
|
||||||
|
func (l *DenyRouterRecursion) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
if req.Header.Get(xTraefikRouter) == l.routerNameHash {
|
||||||
|
logger := log.With().Str(logs.MiddlewareType, "DenyRouterRecursion").Logger()
|
||||||
|
logger.Debug().Msgf("Rejecting request in provenance of the same router (%q) to stop potential infinite loop.", l.routerName)
|
||||||
|
|
||||||
|
rw.WriteHeader(http.StatusBadRequest)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set(xTraefikRouter, l.routerNameHash)
|
||||||
|
|
||||||
|
l.next.ServeHTTP(rw, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeHash(routerName string) string {
|
||||||
|
hasher := fnv.New64()
|
||||||
|
// purposely ignoring the error, as no error can be returned from the implementation.
|
||||||
|
_, _ = hasher.Write([]byte(routerName))
|
||||||
|
return strconv.FormatUint(hasher.Sum64(), 16)
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package denyrouterrecursion
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestServeHTTP(t *testing.T) {
|
||||||
|
req, err := http.NewRequest(http.MethodGet, "", nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
_, err = New("", http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {}))
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
next := 0
|
||||||
|
m, err := New("myRouter", http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
|
||||||
|
next++
|
||||||
|
}))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
m.ServeHTTP(recorder, req)
|
||||||
|
|
||||||
|
assert.Equal(t, http.StatusOK, recorder.Code)
|
||||||
|
assert.Equal(t, "995d26092d19a224", m.routerNameHash)
|
||||||
|
assert.Equal(t, m.routerNameHash, req.Header.Get(xTraefikRouter))
|
||||||
|
assert.Equal(t, 1, next)
|
||||||
|
|
||||||
|
recorder = httptest.NewRecorder()
|
||||||
|
m.ServeHTTP(recorder, req)
|
||||||
|
|
||||||
|
assert.Equal(t, 1, next)
|
||||||
|
assert.Equal(t, http.StatusBadRequest, recorder.Code)
|
||||||
|
}
|
|
@ -182,7 +182,7 @@ func Test1xxResponses(t *testing.T) {
|
||||||
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil)
|
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil)
|
||||||
|
|
||||||
res, err := frontendClient.Do(req)
|
res, err := frontendClient.Do(req)
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ import (
|
||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const delta float64 = 1e-10
|
||||||
|
|
||||||
func TestNewRateLimiter(t *testing.T) {
|
func TestNewRateLimiter(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
|
@ -131,7 +133,7 @@ func TestNewRateLimiter(t *testing.T) {
|
||||||
assert.Equal(t, test.requestHeader, hd)
|
assert.Equal(t, test.requestHeader, hd)
|
||||||
}
|
}
|
||||||
if test.expectedRTL != 0 {
|
if test.expectedRTL != 0 {
|
||||||
assert.Equal(t, test.expectedRTL, rtl.rate)
|
assert.InDelta(t, float64(test.expectedRTL), float64(rtl.rate), delta)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ func (r *retry) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
newCtx := httptrace.WithClientTrace(req.Context(), trace)
|
newCtx := httptrace.WithClientTrace(req.Context(), trace)
|
||||||
|
|
||||||
r.next.ServeHTTP(retryResponseWriter, req.WithContext(newCtx))
|
r.next.ServeHTTP(retryResponseWriter, req.Clone(newCtx))
|
||||||
|
|
||||||
if !retryResponseWriter.ShouldRetry() {
|
if !retryResponseWriter.ShouldRetry() {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -373,7 +373,7 @@ func Test1xxResponses(t *testing.T) {
|
||||||
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil)
|
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil)
|
||||||
|
|
||||||
res, err := frontendClient.Do(req)
|
res, err := frontendClient.Do(req)
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ func TestNewForwarder(t *testing.T) {
|
||||||
|
|
||||||
tags := span.Tags
|
tags := span.Tags
|
||||||
assert.Equal(t, test.expected.Tags, tags)
|
assert.Equal(t, test.expected.Tags, tags)
|
||||||
assert.True(t, len(test.expected.OperationName) <= test.spanNameLimit,
|
assert.LessOrEqual(t, len(test.expected.OperationName), test.spanNameLimit,
|
||||||
"the len of the operation name %q [len: %d] doesn't respect limit %d",
|
"the len of the operation name %q [len: %d] doesn't respect limit %d",
|
||||||
test.expected.OperationName, len(test.expected.OperationName), test.spanNameLimit)
|
test.expected.OperationName, len(test.expected.OperationName), test.spanNameLimit)
|
||||||
assert.Equal(t, test.expected.OperationName, span.OpName)
|
assert.Equal(t, test.expected.OperationName, span.OpName)
|
||||||
|
|
|
@ -309,7 +309,7 @@ func Test_addTCPRoute(t *testing.T) {
|
||||||
matchingHandler.ServeTCP(conn)
|
matchingHandler.ServeTCP(conn)
|
||||||
|
|
||||||
n, ok := conn.call[msg]
|
n, ok := conn.call[msg]
|
||||||
assert.Equal(t, n, 1)
|
assert.Equal(t, 1, n)
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
zipa "archive/zip"
|
zipa "archive/zip"
|
||||||
"context"
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -421,5 +422,5 @@ func computeHash(filepath string) (string, error) {
|
||||||
|
|
||||||
sum := hash.Sum(nil)
|
sum := hash.Sum(nil)
|
||||||
|
|
||||||
return fmt.Sprintf("%x", sum), nil
|
return hex.EncodeToString(sum), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,9 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cenkalti/backoff/v4"
|
|
||||||
"github.com/go-acme/lego/v4/challenge/http01"
|
"github.com/go-acme/lego/v4/challenge/http01"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/traefik/traefik/v3/pkg/logs"
|
"github.com/traefik/traefik/v3/pkg/logs"
|
||||||
"github.com/traefik/traefik/v3/pkg/safe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ChallengeHTTP HTTP challenge provider implements challenge.Provider.
|
// ChallengeHTTP HTTP challenge provider implements challenge.Provider.
|
||||||
|
@ -105,35 +103,18 @@ func (c *ChallengeHTTP) getTokenValue(ctx context.Context, token, domain string)
|
||||||
logger := log.Ctx(ctx)
|
logger := log.Ctx(ctx)
|
||||||
logger.Debug().Msgf("Retrieving the ACME challenge for %s (token %q)...", domain, token)
|
logger.Debug().Msgf("Retrieving the ACME challenge for %s (token %q)...", domain, token)
|
||||||
|
|
||||||
var result []byte
|
|
||||||
|
|
||||||
operation := func() error {
|
|
||||||
c.lock.RLock()
|
c.lock.RLock()
|
||||||
defer c.lock.RUnlock()
|
defer c.lock.RUnlock()
|
||||||
|
|
||||||
if _, ok := c.httpChallenges[token]; !ok {
|
if _, ok := c.httpChallenges[token]; !ok {
|
||||||
return fmt.Errorf("cannot find challenge for token %q (%s)", token, domain)
|
logger.Error().Msgf("Cannot retrieve the ACME challenge for %s (token %q)", domain, token)
|
||||||
}
|
|
||||||
|
|
||||||
var ok bool
|
|
||||||
result, ok = c.httpChallenges[token][domain]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("cannot find challenge for %s (token %q)", domain, token)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
notify := func(err error, time time.Duration) {
|
result, ok := c.httpChallenges[token][domain]
|
||||||
logger.Error().Msgf("Error getting challenge for token retrying in %s", time)
|
if !ok {
|
||||||
}
|
logger.Error().Msgf("Cannot retrieve the ACME challenge for %s (token %q)", domain, token)
|
||||||
|
return nil
|
||||||
ebo := backoff.NewExponentialBackOff()
|
|
||||||
ebo.MaxElapsedTime = 60 * time.Second
|
|
||||||
err := backoff.RetryNotify(safe.OperationWithRecover(operation), ebo, notify)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error().Err(err).Msgf("Cannot retrieve the ACME challenge for %s (token %q)", domain, token)
|
|
||||||
return []byte{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -31,6 +31,8 @@ import (
|
||||||
"github.com/traefik/traefik/v3/pkg/version"
|
"github.com/traefik/traefik/v3/pkg/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const resolverSuffix = ".acme"
|
||||||
|
|
||||||
// ocspMustStaple enables OCSP stapling as from https://github.com/go-acme/lego/issues/270.
|
// ocspMustStaple enables OCSP stapling as from https://github.com/go-acme/lego/issues/270.
|
||||||
var ocspMustStaple = false
|
var ocspMustStaple = false
|
||||||
|
|
||||||
|
@ -132,7 +134,7 @@ func (p *Provider) ListenConfiguration(config dynamic.Configuration) {
|
||||||
|
|
||||||
// Init for compatibility reason the BaseProvider implements an empty Init.
|
// Init for compatibility reason the BaseProvider implements an empty Init.
|
||||||
func (p *Provider) Init() error {
|
func (p *Provider) Init() error {
|
||||||
logger := log.With().Str(logs.ProviderName, p.ResolverName+".acme").Logger()
|
logger := log.With().Str(logs.ProviderName, p.ResolverName+resolverSuffix).Logger()
|
||||||
|
|
||||||
if len(p.Configuration.Storage) == 0 {
|
if len(p.Configuration.Storage) == 0 {
|
||||||
return errors.New("unable to initialize ACME provider with no storage location for the certificates")
|
return errors.New("unable to initialize ACME provider with no storage location for the certificates")
|
||||||
|
@ -194,7 +196,7 @@ func (p *Provider) ThrottleDuration() time.Duration {
|
||||||
// Provide allows the file provider to provide configurations to traefik
|
// Provide allows the file provider to provide configurations to traefik
|
||||||
// using the given Configuration channel.
|
// using the given Configuration channel.
|
||||||
func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error {
|
func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error {
|
||||||
logger := log.With().Str(logs.ProviderName, p.ResolverName+".acme").Str("acmeCA", p.Configuration.CAServer).
|
logger := log.With().Str(logs.ProviderName, p.ResolverName+resolverSuffix).Str("acmeCA", p.Configuration.CAServer).
|
||||||
Logger()
|
Logger()
|
||||||
ctx := logger.WithContext(context.Background())
|
ctx := logger.WithContext(context.Background())
|
||||||
|
|
||||||
|
@ -236,7 +238,7 @@ func (p *Provider) getClient() (*lego.Client, error) {
|
||||||
p.clientMutex.Lock()
|
p.clientMutex.Lock()
|
||||||
defer p.clientMutex.Unlock()
|
defer p.clientMutex.Unlock()
|
||||||
|
|
||||||
logger := log.With().Str(logs.ProviderName, p.ResolverName+".acme").Logger()
|
logger := log.With().Str(logs.ProviderName, p.ResolverName+resolverSuffix).Logger()
|
||||||
|
|
||||||
ctx := logger.WithContext(context.Background())
|
ctx := logger.WithContext(context.Background())
|
||||||
|
|
||||||
|
@ -407,7 +409,7 @@ func (p *Provider) resolveDomains(ctx context.Context, domains []string, tlsStor
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) watchNewDomains(ctx context.Context) {
|
func (p *Provider) watchNewDomains(ctx context.Context) {
|
||||||
rootLogger := log.Ctx(ctx).With().Str(logs.ProviderName, p.ResolverName+".acme").Logger()
|
rootLogger := log.Ctx(ctx).With().Str(logs.ProviderName, p.ResolverName+resolverSuffix).Str("ACME CA", p.Configuration.CAServer).Logger()
|
||||||
ctx = rootLogger.WithContext(ctx)
|
ctx = rootLogger.WithContext(ctx)
|
||||||
|
|
||||||
p.pool.GoCtx(func(ctxPool context.Context) {
|
p.pool.GoCtx(func(ctxPool context.Context) {
|
||||||
|
|
|
@ -580,7 +580,7 @@ func TestInitAccount(t *testing.T) {
|
||||||
acmeProvider := Provider{account: test.account, Configuration: &Configuration{Email: test.email, KeyType: test.keyType}}
|
acmeProvider := Provider{account: test.account, Configuration: &Configuration{Email: test.email, KeyType: test.keyType}}
|
||||||
|
|
||||||
actualAccount, err := acmeProvider.initAccount(context.Background())
|
actualAccount, err := acmeProvider.initAccount(context.Background())
|
||||||
assert.Nil(t, err, "Init account in error")
|
assert.NoError(t, err, "Init account in error")
|
||||||
assert.Equal(t, test.expectedAccount.Email, actualAccount.Email, "unexpected email account")
|
assert.Equal(t, test.expectedAccount.Email, actualAccount.Email, "unexpected email account")
|
||||||
assert.Equal(t, test.expectedAccount.KeyType, actualAccount.KeyType, "unexpected keyType account")
|
assert.Equal(t, test.expectedAccount.KeyType, actualAccount.KeyType, "unexpected keyType account")
|
||||||
})
|
})
|
||||||
|
|
|
@ -8,8 +8,8 @@ type StoredData struct {
|
||||||
|
|
||||||
// Store is a generic interface that represents a storage.
|
// Store is a generic interface that represents a storage.
|
||||||
type Store interface {
|
type Store interface {
|
||||||
GetAccount(string) (*Account, error)
|
GetAccount(resolverName string) (*Account, error)
|
||||||
SaveAccount(string, *Account) error
|
SaveAccount(resolverName string, account *Account) error
|
||||||
GetCertificates(string) ([]*CertAndStore, error)
|
GetCertificates(resolverName string) ([]*CertAndStore, error)
|
||||||
SaveCertificates(string, []*CertAndStore) error
|
SaveCertificates(resolverName string, certificates []*CertAndStore) error
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,7 +388,7 @@ func BuildTCPRouterConfiguration(ctx context.Context, configuration *dynamic.TCP
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(router.Service) == 0 {
|
if router.Service == "" {
|
||||||
if len(configuration.Services) > 1 {
|
if len(configuration.Services) > 1 {
|
||||||
delete(configuration.Routers, routerName)
|
delete(configuration.Routers, routerName)
|
||||||
loggerRouter.Error().
|
loggerRouter.Error().
|
||||||
|
@ -408,7 +408,7 @@ func BuildUDPRouterConfiguration(ctx context.Context, configuration *dynamic.UDP
|
||||||
for routerName, router := range configuration.Routers {
|
for routerName, router := range configuration.Routers {
|
||||||
loggerRouter := log.Ctx(ctx).With().Str(logs.RouterName, routerName).Logger()
|
loggerRouter := log.Ctx(ctx).With().Str(logs.RouterName, routerName).Logger()
|
||||||
|
|
||||||
if len(router.Service) > 0 {
|
if router.Service != "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,9 +454,12 @@ func BuildRouterConfiguration(ctx context.Context, configuration *dynamic.HTTPCo
|
||||||
delete(configuration.Routers, routerName)
|
delete(configuration.Routers, routerName)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flag default rule routers to add the denyRouterRecursion middleware.
|
||||||
|
router.DefaultRule = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(router.Service) == 0 {
|
if router.Service == "" {
|
||||||
if len(configuration.Services) > 1 {
|
if len(configuration.Services) > 1 {
|
||||||
delete(configuration.Routers, routerName)
|
delete(configuration.Routers, routerName)
|
||||||
loggerRouter.Error().
|
loggerRouter.Error().
|
||||||
|
|
|
@ -54,6 +54,7 @@ func TestDefaultRule(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`foo.bar`)",
|
Rule: "Host(`foo.bar`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -108,6 +109,7 @@ func TestDefaultRule(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: `Host("Test.foo.bar")`,
|
Rule: `Host("Test.foo.bar")`,
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -254,6 +256,7 @@ func TestDefaultRule(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test`)",
|
Rule: "Host(`Test`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -343,6 +346,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"dev-Test": {
|
"dev-Test": {
|
||||||
Service: "dev-Test",
|
Service: "dev-Test",
|
||||||
Rule: "Host(`dev-Test.traefik.wtf`)",
|
Rule: "Host(`dev-Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -400,6 +404,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"dev-Test": {
|
"dev-Test": {
|
||||||
Service: "dev-Test",
|
Service: "dev-Test",
|
||||||
Rule: "Host(`dev-Test.traefik.wtf`)",
|
Rule: "Host(`dev-Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -487,6 +492,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"dev-Test": {
|
"dev-Test": {
|
||||||
Service: "dev-Test",
|
Service: "dev-Test",
|
||||||
Rule: "Host(`dev-Test.traefik.wtf`)",
|
Rule: "Host(`dev-Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -566,10 +572,12 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
"Test2": {
|
"Test2": {
|
||||||
Service: "Test2",
|
Service: "Test2",
|
||||||
Rule: "Host(`Test2.traefik.wtf`)",
|
Rule: "Host(`Test2.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -643,6 +651,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -706,6 +715,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -766,6 +776,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -821,6 +832,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1103,6 +1115,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1161,6 +1174,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1209,6 +1223,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1264,6 +1279,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Services: map[string]*dynamic.Service{
|
Services: map[string]*dynamic.Service{
|
||||||
|
@ -1331,6 +1347,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{
|
Middlewares: map[string]*dynamic.Middleware{
|
||||||
|
@ -1401,6 +1418,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1478,6 +1496,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1739,6 +1758,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1792,6 +1812,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -2067,6 +2088,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -2120,6 +2142,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
Middlewares: []string{"Middleware1"},
|
Middlewares: []string{"Middleware1"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -2541,6 +2564,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -2628,6 +2652,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -2831,10 +2856,12 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
"Test-97077516270503695": {
|
"Test-97077516270503695": {
|
||||||
Service: "Test-97077516270503695",
|
Service: "Test-97077516270503695",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
|
|
@ -3,7 +3,6 @@ package consulcatalog
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/agent/connect"
|
|
||||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||||
traefiktls "github.com/traefik/traefik/v3/pkg/tls"
|
traefiktls "github.com/traefik/traefik/v3/pkg/tls"
|
||||||
)
|
)
|
||||||
|
@ -52,11 +51,11 @@ func (c *connectCert) equals(other *connectCert) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *connectCert) serversTransport(item itemData) *dynamic.ServersTransport {
|
func (c *connectCert) serversTransport(item itemData) *dynamic.ServersTransport {
|
||||||
spiffeIDService := connect.SpiffeIDService{
|
spiffeID := fmt.Sprintf("spiffe:///ns/%s/dc/%s/svc/%s",
|
||||||
Namespace: item.Namespace,
|
item.Namespace,
|
||||||
Datacenter: item.Datacenter,
|
item.Datacenter,
|
||||||
Service: item.Name,
|
item.Name,
|
||||||
}
|
)
|
||||||
|
|
||||||
return &dynamic.ServersTransport{
|
return &dynamic.ServersTransport{
|
||||||
// This ensures that the config changes whenever the verifier function changes
|
// This ensures that the config changes whenever the verifier function changes
|
||||||
|
@ -67,16 +66,16 @@ func (c *connectCert) serversTransport(item itemData) *dynamic.ServersTransport
|
||||||
Certificates: traefiktls.Certificates{
|
Certificates: traefiktls.Certificates{
|
||||||
c.getLeaf(),
|
c.getLeaf(),
|
||||||
},
|
},
|
||||||
PeerCertURI: spiffeIDService.URI().String(),
|
PeerCertURI: spiffeID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *connectCert) tcpServersTransport(item itemData) *dynamic.TCPServersTransport {
|
func (c *connectCert) tcpServersTransport(item itemData) *dynamic.TCPServersTransport {
|
||||||
spiffeIDService := connect.SpiffeIDService{
|
spiffeID := fmt.Sprintf("spiffe:///ns/%s/dc/%s/svc/%s",
|
||||||
Namespace: item.Namespace,
|
item.Namespace,
|
||||||
Datacenter: item.Datacenter,
|
item.Datacenter,
|
||||||
Service: item.Name,
|
item.Name,
|
||||||
}
|
)
|
||||||
|
|
||||||
return &dynamic.TCPServersTransport{
|
return &dynamic.TCPServersTransport{
|
||||||
TLS: &dynamic.TLSClientConfig{
|
TLS: &dynamic.TLSClientConfig{
|
||||||
|
@ -88,7 +87,7 @@ func (c *connectCert) tcpServersTransport(item itemData) *dynamic.TCPServersTran
|
||||||
Certificates: traefiktls.Certificates{
|
Certificates: traefiktls.Certificates{
|
||||||
c.getLeaf(),
|
c.getLeaf(),
|
||||||
},
|
},
|
||||||
PeerCertURI: spiffeIDService.URI().String(),
|
PeerCertURI: spiffeID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`foo.bar`)",
|
Rule: "Host(`foo.bar`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -118,6 +119,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.foo.bar`)",
|
Rule: "Host(`Test.foo.bar`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -179,6 +181,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: `Host("Test.foo.bar")`,
|
Rule: `Host("Test.foo.bar")`,
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -346,6 +349,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test`)",
|
Rule: "Host(`Test`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -568,6 +572,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -642,10 +647,12 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
"Test2": {
|
"Test2": {
|
||||||
Service: "Test2",
|
Service: "Test2",
|
||||||
Rule: "Host(`Test2.traefik.wtf`)",
|
Rule: "Host(`Test2.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -735,6 +742,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -798,6 +806,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1192,6 +1201,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1277,6 +1287,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1343,6 +1354,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1406,6 +1418,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Services: map[string]*dynamic.Service{
|
Services: map[string]*dynamic.Service{
|
||||||
|
@ -1492,6 +1505,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{
|
Middlewares: map[string]*dynamic.Middleware{
|
||||||
|
@ -1581,6 +1595,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1683,6 +1698,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -2096,6 +2112,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -2157,6 +2174,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -2419,6 +2437,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -2660,6 +2679,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -2722,6 +2742,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
Middlewares: []string{"Middleware1"},
|
Middlewares: []string{"Middleware1"},
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{
|
Middlewares: map[string]*dynamic.Middleware{
|
||||||
|
@ -3180,6 +3201,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -3354,6 +3376,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
|
|
@ -55,6 +55,7 @@ func TestDefaultRule(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`foo.bar`)",
|
Rule: "Host(`foo.bar`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -109,6 +110,7 @@ func TestDefaultRule(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.foo.bar`)",
|
Rule: "Host(`Test.foo.bar`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -165,6 +167,7 @@ func TestDefaultRule(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: `Host("Test.foo.bar")`,
|
Rule: `Host("Test.foo.bar")`,
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -317,6 +320,7 @@ func TestDefaultRule(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test`)",
|
Rule: "Host(`Test`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -514,6 +518,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -578,10 +583,12 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
"Test2": {
|
"Test2": {
|
||||||
Service: "Test2",
|
Service: "Test2",
|
||||||
Rule: "Host(`Test2.traefik.wtf`)",
|
Rule: "Host(`Test2.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -661,6 +668,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -719,6 +727,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1078,6 +1087,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1148,6 +1158,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1204,6 +1215,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1262,6 +1274,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Services: map[string]*dynamic.Service{
|
Services: map[string]*dynamic.Service{
|
||||||
|
@ -1338,6 +1351,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{
|
Middlewares: map[string]*dynamic.Middleware{
|
||||||
|
@ -1417,6 +1431,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1504,6 +1519,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1868,6 +1884,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1924,6 +1941,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -1980,6 +1998,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -2390,6 +2409,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
@ -2447,6 +2467,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
Service: "Test",
|
Service: "Test",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
Middlewares: []string{"Middleware1"},
|
Middlewares: []string{"Middleware1"},
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{
|
Middlewares: map[string]*dynamic.Middleware{
|
||||||
|
@ -2865,6 +2886,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
"Test": {
|
"Test": {
|
||||||
Service: "Service1",
|
Service: "Service1",
|
||||||
Rule: "Host(`Test.traefik.wtf`)",
|
Rule: "Host(`Test.traefik.wtf`)",
|
||||||
|
DefaultRule: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middlewares: map[string]*dynamic.Middleware{},
|
Middlewares: map[string]*dynamic.Middleware{},
|
||||||
|
|
|
@ -156,10 +156,10 @@ func TestProvideWithWatch(t *testing.T) {
|
||||||
require.NotNil(t, conf.Configuration.HTTP)
|
require.NotNil(t, conf.Configuration.HTTP)
|
||||||
numServices := len(conf.Configuration.HTTP.Services) + len(conf.Configuration.TCP.Services) + len(conf.Configuration.UDP.Services)
|
numServices := len(conf.Configuration.HTTP.Services) + len(conf.Configuration.TCP.Services) + len(conf.Configuration.UDP.Services)
|
||||||
numRouters := len(conf.Configuration.HTTP.Routers) + len(conf.Configuration.TCP.Routers) + len(conf.Configuration.UDP.Routers)
|
numRouters := len(conf.Configuration.HTTP.Routers) + len(conf.Configuration.TCP.Routers) + len(conf.Configuration.UDP.Routers)
|
||||||
assert.Equal(t, numServices, 0)
|
assert.Equal(t, 0, numServices)
|
||||||
assert.Equal(t, numRouters, 0)
|
assert.Equal(t, 0, numRouters)
|
||||||
require.NotNil(t, conf.Configuration.TLS)
|
require.NotNil(t, conf.Configuration.TLS)
|
||||||
assert.Len(t, conf.Configuration.TLS.Certificates, 0)
|
assert.Empty(t, conf.Configuration.TLS.Certificates)
|
||||||
case <-timeout:
|
case <-timeout:
|
||||||
t.Errorf("timeout while waiting for config")
|
t.Errorf("timeout while waiting for config")
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,5 +268,5 @@ func TestProvider_ProvideConfigurationOnlyOnceIfUnchanged(t *testing.T) {
|
||||||
|
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
assert.Equal(t, 1, len(configurationChan))
|
assert.Len(t, configurationChan, 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ package versioned
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
traefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1"
|
traefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1"
|
||||||
discovery "k8s.io/client-go/discovery"
|
discovery "k8s.io/client-go/discovery"
|
||||||
|
@ -40,8 +41,7 @@ type Interface interface {
|
||||||
TraefikV1alpha1() traefikv1alpha1.TraefikV1alpha1Interface
|
TraefikV1alpha1() traefikv1alpha1.TraefikV1alpha1Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clientset contains the clients for groups. Each group has exactly one
|
// Clientset contains the clients for groups.
|
||||||
// version included in a Clientset.
|
|
||||||
type Clientset struct {
|
type Clientset struct {
|
||||||
*discovery.DiscoveryClient
|
*discovery.DiscoveryClient
|
||||||
traefikV1alpha1 *traefikv1alpha1.TraefikV1alpha1Client
|
traefikV1alpha1 *traefikv1alpha1.TraefikV1alpha1Client
|
||||||
|
@ -63,22 +63,45 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||||
// NewForConfig creates a new Clientset for the given config.
|
// NewForConfig creates a new Clientset for the given config.
|
||||||
// If config's RateLimiter is not set and QPS and Burst are acceptable,
|
// If config's RateLimiter is not set and QPS and Burst are acceptable,
|
||||||
// NewForConfig will generate a rate-limiter in configShallowCopy.
|
// NewForConfig will generate a rate-limiter in configShallowCopy.
|
||||||
|
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
|
||||||
|
// where httpClient was generated with rest.HTTPClientFor(c).
|
||||||
func NewForConfig(c *rest.Config) (*Clientset, error) {
|
func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||||
configShallowCopy := *c
|
configShallowCopy := *c
|
||||||
|
|
||||||
|
if configShallowCopy.UserAgent == "" {
|
||||||
|
configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||||
|
}
|
||||||
|
|
||||||
|
// share the transport between all clients
|
||||||
|
httpClient, err := rest.HTTPClientFor(&configShallowCopy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewForConfigAndClient creates a new Clientset for the given config and http client.
|
||||||
|
// Note the http client provided takes precedence over the configured transport values.
|
||||||
|
// If config's RateLimiter is not set and QPS and Burst are acceptable,
|
||||||
|
// NewForConfigAndClient will generate a rate-limiter in configShallowCopy.
|
||||||
|
func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, error) {
|
||||||
|
configShallowCopy := *c
|
||||||
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
|
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
|
||||||
if configShallowCopy.Burst <= 0 {
|
if configShallowCopy.Burst <= 0 {
|
||||||
return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
|
return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
|
||||||
}
|
}
|
||||||
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
|
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
|
||||||
}
|
}
|
||||||
|
|
||||||
var cs Clientset
|
var cs Clientset
|
||||||
var err error
|
var err error
|
||||||
cs.traefikV1alpha1, err = traefikv1alpha1.NewForConfig(&configShallowCopy)
|
cs.traefikV1alpha1, err = traefikv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
|
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -88,11 +111,11 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||||
// NewForConfigOrDie creates a new Clientset for the given config and
|
// NewForConfigOrDie creates a new Clientset for the given config and
|
||||||
// panics if there is an error in the config.
|
// panics if there is an error in the config.
|
||||||
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||||
var cs Clientset
|
cs, err := NewForConfig(c)
|
||||||
cs.traefikV1alpha1 = traefikv1alpha1.NewForConfigOrDie(c)
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
|
}
|
||||||
return &cs
|
return cs
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Clientset for the given RESTClient.
|
// New creates a new Clientset for the given RESTClient.
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Code generated by client-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
// This package has the automatically generated clientset.
|
|
||||||
package versioned
|
|
|
@ -82,7 +82,10 @@ func (c *Clientset) Tracker() testing.ObjectTracker {
|
||||||
return c.tracker
|
return c.tracker
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ clientset.Interface = &Clientset{}
|
var (
|
||||||
|
_ clientset.Interface = &Clientset{}
|
||||||
|
_ testing.FakeClient = &Clientset{}
|
||||||
|
)
|
||||||
|
|
||||||
// TraefikV1alpha1 retrieves the TraefikV1alpha1Client
|
// TraefikV1alpha1 retrieves the TraefikV1alpha1Client
|
||||||
func (c *Clientset) TraefikV1alpha1() traefikv1alpha1.TraefikV1alpha1Interface {
|
func (c *Clientset) TraefikV1alpha1() traefikv1alpha1.TraefikV1alpha1Interface {
|
||||||
|
|
|
@ -32,7 +32,6 @@ import (
|
||||||
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
labels "k8s.io/apimachinery/pkg/labels"
|
labels "k8s.io/apimachinery/pkg/labels"
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
types "k8s.io/apimachinery/pkg/types"
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
watch "k8s.io/apimachinery/pkg/watch"
|
watch "k8s.io/apimachinery/pkg/watch"
|
||||||
testing "k8s.io/client-go/testing"
|
testing "k8s.io/client-go/testing"
|
||||||
|
@ -44,9 +43,9 @@ type FakeIngressRoutes struct {
|
||||||
ns string
|
ns string
|
||||||
}
|
}
|
||||||
|
|
||||||
var ingressroutesResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "ingressroutes"}
|
var ingressroutesResource = v1alpha1.SchemeGroupVersion.WithResource("ingressroutes")
|
||||||
|
|
||||||
var ingressroutesKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "IngressRoute"}
|
var ingressroutesKind = v1alpha1.SchemeGroupVersion.WithKind("IngressRoute")
|
||||||
|
|
||||||
// Get takes name of the ingressRoute, and returns the corresponding ingressRoute object, and an error if there is any.
|
// Get takes name of the ingressRoute, and returns the corresponding ingressRoute object, and an error if there is any.
|
||||||
func (c *FakeIngressRoutes) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IngressRoute, err error) {
|
func (c *FakeIngressRoutes) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IngressRoute, err error) {
|
||||||
|
@ -113,7 +112,7 @@ func (c *FakeIngressRoutes) Update(ctx context.Context, ingressRoute *v1alpha1.I
|
||||||
// Delete takes name of the ingressRoute and deletes it. Returns an error if one occurs.
|
// Delete takes name of the ingressRoute and deletes it. Returns an error if one occurs.
|
||||||
func (c *FakeIngressRoutes) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
func (c *FakeIngressRoutes) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||||
_, err := c.Fake.
|
_, err := c.Fake.
|
||||||
Invokes(testing.NewDeleteAction(ingressroutesResource, c.ns, name), &v1alpha1.IngressRoute{})
|
Invokes(testing.NewDeleteActionWithOptions(ingressroutesResource, c.ns, name, opts), &v1alpha1.IngressRoute{})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import (
|
||||||
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
labels "k8s.io/apimachinery/pkg/labels"
|
labels "k8s.io/apimachinery/pkg/labels"
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
types "k8s.io/apimachinery/pkg/types"
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
watch "k8s.io/apimachinery/pkg/watch"
|
watch "k8s.io/apimachinery/pkg/watch"
|
||||||
testing "k8s.io/client-go/testing"
|
testing "k8s.io/client-go/testing"
|
||||||
|
@ -44,9 +43,9 @@ type FakeIngressRouteTCPs struct {
|
||||||
ns string
|
ns string
|
||||||
}
|
}
|
||||||
|
|
||||||
var ingressroutetcpsResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "ingressroutetcps"}
|
var ingressroutetcpsResource = v1alpha1.SchemeGroupVersion.WithResource("ingressroutetcps")
|
||||||
|
|
||||||
var ingressroutetcpsKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "IngressRouteTCP"}
|
var ingressroutetcpsKind = v1alpha1.SchemeGroupVersion.WithKind("IngressRouteTCP")
|
||||||
|
|
||||||
// Get takes name of the ingressRouteTCP, and returns the corresponding ingressRouteTCP object, and an error if there is any.
|
// Get takes name of the ingressRouteTCP, and returns the corresponding ingressRouteTCP object, and an error if there is any.
|
||||||
func (c *FakeIngressRouteTCPs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IngressRouteTCP, err error) {
|
func (c *FakeIngressRouteTCPs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IngressRouteTCP, err error) {
|
||||||
|
@ -113,7 +112,7 @@ func (c *FakeIngressRouteTCPs) Update(ctx context.Context, ingressRouteTCP *v1al
|
||||||
// Delete takes name of the ingressRouteTCP and deletes it. Returns an error if one occurs.
|
// Delete takes name of the ingressRouteTCP and deletes it. Returns an error if one occurs.
|
||||||
func (c *FakeIngressRouteTCPs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
func (c *FakeIngressRouteTCPs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||||
_, err := c.Fake.
|
_, err := c.Fake.
|
||||||
Invokes(testing.NewDeleteAction(ingressroutetcpsResource, c.ns, name), &v1alpha1.IngressRouteTCP{})
|
Invokes(testing.NewDeleteActionWithOptions(ingressroutetcpsResource, c.ns, name, opts), &v1alpha1.IngressRouteTCP{})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import (
|
||||||
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
labels "k8s.io/apimachinery/pkg/labels"
|
labels "k8s.io/apimachinery/pkg/labels"
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
types "k8s.io/apimachinery/pkg/types"
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
watch "k8s.io/apimachinery/pkg/watch"
|
watch "k8s.io/apimachinery/pkg/watch"
|
||||||
testing "k8s.io/client-go/testing"
|
testing "k8s.io/client-go/testing"
|
||||||
|
@ -44,9 +43,9 @@ type FakeIngressRouteUDPs struct {
|
||||||
ns string
|
ns string
|
||||||
}
|
}
|
||||||
|
|
||||||
var ingressrouteudpsResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "ingressrouteudps"}
|
var ingressrouteudpsResource = v1alpha1.SchemeGroupVersion.WithResource("ingressrouteudps")
|
||||||
|
|
||||||
var ingressrouteudpsKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "IngressRouteUDP"}
|
var ingressrouteudpsKind = v1alpha1.SchemeGroupVersion.WithKind("IngressRouteUDP")
|
||||||
|
|
||||||
// Get takes name of the ingressRouteUDP, and returns the corresponding ingressRouteUDP object, and an error if there is any.
|
// Get takes name of the ingressRouteUDP, and returns the corresponding ingressRouteUDP object, and an error if there is any.
|
||||||
func (c *FakeIngressRouteUDPs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IngressRouteUDP, err error) {
|
func (c *FakeIngressRouteUDPs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IngressRouteUDP, err error) {
|
||||||
|
@ -113,7 +112,7 @@ func (c *FakeIngressRouteUDPs) Update(ctx context.Context, ingressRouteUDP *v1al
|
||||||
// Delete takes name of the ingressRouteUDP and deletes it. Returns an error if one occurs.
|
// Delete takes name of the ingressRouteUDP and deletes it. Returns an error if one occurs.
|
||||||
func (c *FakeIngressRouteUDPs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
func (c *FakeIngressRouteUDPs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||||
_, err := c.Fake.
|
_, err := c.Fake.
|
||||||
Invokes(testing.NewDeleteAction(ingressrouteudpsResource, c.ns, name), &v1alpha1.IngressRouteUDP{})
|
Invokes(testing.NewDeleteActionWithOptions(ingressrouteudpsResource, c.ns, name, opts), &v1alpha1.IngressRouteUDP{})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import (
|
||||||
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
labels "k8s.io/apimachinery/pkg/labels"
|
labels "k8s.io/apimachinery/pkg/labels"
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
types "k8s.io/apimachinery/pkg/types"
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
watch "k8s.io/apimachinery/pkg/watch"
|
watch "k8s.io/apimachinery/pkg/watch"
|
||||||
testing "k8s.io/client-go/testing"
|
testing "k8s.io/client-go/testing"
|
||||||
|
@ -44,9 +43,9 @@ type FakeMiddlewares struct {
|
||||||
ns string
|
ns string
|
||||||
}
|
}
|
||||||
|
|
||||||
var middlewaresResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "middlewares"}
|
var middlewaresResource = v1alpha1.SchemeGroupVersion.WithResource("middlewares")
|
||||||
|
|
||||||
var middlewaresKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "Middleware"}
|
var middlewaresKind = v1alpha1.SchemeGroupVersion.WithKind("Middleware")
|
||||||
|
|
||||||
// Get takes name of the middleware, and returns the corresponding middleware object, and an error if there is any.
|
// Get takes name of the middleware, and returns the corresponding middleware object, and an error if there is any.
|
||||||
func (c *FakeMiddlewares) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.Middleware, err error) {
|
func (c *FakeMiddlewares) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.Middleware, err error) {
|
||||||
|
@ -113,7 +112,7 @@ func (c *FakeMiddlewares) Update(ctx context.Context, middleware *v1alpha1.Middl
|
||||||
// Delete takes name of the middleware and deletes it. Returns an error if one occurs.
|
// Delete takes name of the middleware and deletes it. Returns an error if one occurs.
|
||||||
func (c *FakeMiddlewares) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
func (c *FakeMiddlewares) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||||
_, err := c.Fake.
|
_, err := c.Fake.
|
||||||
Invokes(testing.NewDeleteAction(middlewaresResource, c.ns, name), &v1alpha1.Middleware{})
|
Invokes(testing.NewDeleteActionWithOptions(middlewaresResource, c.ns, name, opts), &v1alpha1.Middleware{})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import (
|
||||||
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
labels "k8s.io/apimachinery/pkg/labels"
|
labels "k8s.io/apimachinery/pkg/labels"
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
types "k8s.io/apimachinery/pkg/types"
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
watch "k8s.io/apimachinery/pkg/watch"
|
watch "k8s.io/apimachinery/pkg/watch"
|
||||||
testing "k8s.io/client-go/testing"
|
testing "k8s.io/client-go/testing"
|
||||||
|
@ -44,9 +43,9 @@ type FakeMiddlewareTCPs struct {
|
||||||
ns string
|
ns string
|
||||||
}
|
}
|
||||||
|
|
||||||
var middlewaretcpsResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "middlewaretcps"}
|
var middlewaretcpsResource = v1alpha1.SchemeGroupVersion.WithResource("middlewaretcps")
|
||||||
|
|
||||||
var middlewaretcpsKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "MiddlewareTCP"}
|
var middlewaretcpsKind = v1alpha1.SchemeGroupVersion.WithKind("MiddlewareTCP")
|
||||||
|
|
||||||
// Get takes name of the middlewareTCP, and returns the corresponding middlewareTCP object, and an error if there is any.
|
// Get takes name of the middlewareTCP, and returns the corresponding middlewareTCP object, and an error if there is any.
|
||||||
func (c *FakeMiddlewareTCPs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.MiddlewareTCP, err error) {
|
func (c *FakeMiddlewareTCPs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.MiddlewareTCP, err error) {
|
||||||
|
@ -113,7 +112,7 @@ func (c *FakeMiddlewareTCPs) Update(ctx context.Context, middlewareTCP *v1alpha1
|
||||||
// Delete takes name of the middlewareTCP and deletes it. Returns an error if one occurs.
|
// Delete takes name of the middlewareTCP and deletes it. Returns an error if one occurs.
|
||||||
func (c *FakeMiddlewareTCPs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
func (c *FakeMiddlewareTCPs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||||
_, err := c.Fake.
|
_, err := c.Fake.
|
||||||
Invokes(testing.NewDeleteAction(middlewaretcpsResource, c.ns, name), &v1alpha1.MiddlewareTCP{})
|
Invokes(testing.NewDeleteActionWithOptions(middlewaretcpsResource, c.ns, name, opts), &v1alpha1.MiddlewareTCP{})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import (
|
||||||
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
labels "k8s.io/apimachinery/pkg/labels"
|
labels "k8s.io/apimachinery/pkg/labels"
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
types "k8s.io/apimachinery/pkg/types"
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
watch "k8s.io/apimachinery/pkg/watch"
|
watch "k8s.io/apimachinery/pkg/watch"
|
||||||
testing "k8s.io/client-go/testing"
|
testing "k8s.io/client-go/testing"
|
||||||
|
@ -44,9 +43,9 @@ type FakeServersTransports struct {
|
||||||
ns string
|
ns string
|
||||||
}
|
}
|
||||||
|
|
||||||
var serverstransportsResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "serverstransports"}
|
var serverstransportsResource = v1alpha1.SchemeGroupVersion.WithResource("serverstransports")
|
||||||
|
|
||||||
var serverstransportsKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "ServersTransport"}
|
var serverstransportsKind = v1alpha1.SchemeGroupVersion.WithKind("ServersTransport")
|
||||||
|
|
||||||
// Get takes name of the serversTransport, and returns the corresponding serversTransport object, and an error if there is any.
|
// Get takes name of the serversTransport, and returns the corresponding serversTransport object, and an error if there is any.
|
||||||
func (c *FakeServersTransports) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ServersTransport, err error) {
|
func (c *FakeServersTransports) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ServersTransport, err error) {
|
||||||
|
@ -113,7 +112,7 @@ func (c *FakeServersTransports) Update(ctx context.Context, serversTransport *v1
|
||||||
// Delete takes name of the serversTransport and deletes it. Returns an error if one occurs.
|
// Delete takes name of the serversTransport and deletes it. Returns an error if one occurs.
|
||||||
func (c *FakeServersTransports) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
func (c *FakeServersTransports) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||||
_, err := c.Fake.
|
_, err := c.Fake.
|
||||||
Invokes(testing.NewDeleteAction(serverstransportsResource, c.ns, name), &v1alpha1.ServersTransport{})
|
Invokes(testing.NewDeleteActionWithOptions(serverstransportsResource, c.ns, name, opts), &v1alpha1.ServersTransport{})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import (
|
||||||
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
labels "k8s.io/apimachinery/pkg/labels"
|
labels "k8s.io/apimachinery/pkg/labels"
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
types "k8s.io/apimachinery/pkg/types"
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
watch "k8s.io/apimachinery/pkg/watch"
|
watch "k8s.io/apimachinery/pkg/watch"
|
||||||
testing "k8s.io/client-go/testing"
|
testing "k8s.io/client-go/testing"
|
||||||
|
@ -44,9 +43,9 @@ type FakeServersTransportTCPs struct {
|
||||||
ns string
|
ns string
|
||||||
}
|
}
|
||||||
|
|
||||||
var serverstransporttcpsResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "serverstransporttcps"}
|
var serverstransporttcpsResource = v1alpha1.SchemeGroupVersion.WithResource("serverstransporttcps")
|
||||||
|
|
||||||
var serverstransporttcpsKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "ServersTransportTCP"}
|
var serverstransporttcpsKind = v1alpha1.SchemeGroupVersion.WithKind("ServersTransportTCP")
|
||||||
|
|
||||||
// Get takes name of the serversTransportTCP, and returns the corresponding serversTransportTCP object, and an error if there is any.
|
// Get takes name of the serversTransportTCP, and returns the corresponding serversTransportTCP object, and an error if there is any.
|
||||||
func (c *FakeServersTransportTCPs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ServersTransportTCP, err error) {
|
func (c *FakeServersTransportTCPs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ServersTransportTCP, err error) {
|
||||||
|
@ -113,7 +112,7 @@ func (c *FakeServersTransportTCPs) Update(ctx context.Context, serversTransportT
|
||||||
// Delete takes name of the serversTransportTCP and deletes it. Returns an error if one occurs.
|
// Delete takes name of the serversTransportTCP and deletes it. Returns an error if one occurs.
|
||||||
func (c *FakeServersTransportTCPs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
func (c *FakeServersTransportTCPs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||||
_, err := c.Fake.
|
_, err := c.Fake.
|
||||||
Invokes(testing.NewDeleteAction(serverstransporttcpsResource, c.ns, name), &v1alpha1.ServersTransportTCP{})
|
Invokes(testing.NewDeleteActionWithOptions(serverstransporttcpsResource, c.ns, name, opts), &v1alpha1.ServersTransportTCP{})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import (
|
||||||
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
labels "k8s.io/apimachinery/pkg/labels"
|
labels "k8s.io/apimachinery/pkg/labels"
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
types "k8s.io/apimachinery/pkg/types"
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
watch "k8s.io/apimachinery/pkg/watch"
|
watch "k8s.io/apimachinery/pkg/watch"
|
||||||
testing "k8s.io/client-go/testing"
|
testing "k8s.io/client-go/testing"
|
||||||
|
@ -44,9 +43,9 @@ type FakeTLSOptions struct {
|
||||||
ns string
|
ns string
|
||||||
}
|
}
|
||||||
|
|
||||||
var tlsoptionsResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "tlsoptions"}
|
var tlsoptionsResource = v1alpha1.SchemeGroupVersion.WithResource("tlsoptions")
|
||||||
|
|
||||||
var tlsoptionsKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "TLSOption"}
|
var tlsoptionsKind = v1alpha1.SchemeGroupVersion.WithKind("TLSOption")
|
||||||
|
|
||||||
// Get takes name of the tLSOption, and returns the corresponding tLSOption object, and an error if there is any.
|
// Get takes name of the tLSOption, and returns the corresponding tLSOption object, and an error if there is any.
|
||||||
func (c *FakeTLSOptions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.TLSOption, err error) {
|
func (c *FakeTLSOptions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.TLSOption, err error) {
|
||||||
|
@ -113,7 +112,7 @@ func (c *FakeTLSOptions) Update(ctx context.Context, tLSOption *v1alpha1.TLSOpti
|
||||||
// Delete takes name of the tLSOption and deletes it. Returns an error if one occurs.
|
// Delete takes name of the tLSOption and deletes it. Returns an error if one occurs.
|
||||||
func (c *FakeTLSOptions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
func (c *FakeTLSOptions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||||
_, err := c.Fake.
|
_, err := c.Fake.
|
||||||
Invokes(testing.NewDeleteAction(tlsoptionsResource, c.ns, name), &v1alpha1.TLSOption{})
|
Invokes(testing.NewDeleteActionWithOptions(tlsoptionsResource, c.ns, name, opts), &v1alpha1.TLSOption{})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import (
|
||||||
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
labels "k8s.io/apimachinery/pkg/labels"
|
labels "k8s.io/apimachinery/pkg/labels"
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
types "k8s.io/apimachinery/pkg/types"
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
watch "k8s.io/apimachinery/pkg/watch"
|
watch "k8s.io/apimachinery/pkg/watch"
|
||||||
testing "k8s.io/client-go/testing"
|
testing "k8s.io/client-go/testing"
|
||||||
|
@ -44,9 +43,9 @@ type FakeTLSStores struct {
|
||||||
ns string
|
ns string
|
||||||
}
|
}
|
||||||
|
|
||||||
var tlsstoresResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "tlsstores"}
|
var tlsstoresResource = v1alpha1.SchemeGroupVersion.WithResource("tlsstores")
|
||||||
|
|
||||||
var tlsstoresKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "TLSStore"}
|
var tlsstoresKind = v1alpha1.SchemeGroupVersion.WithKind("TLSStore")
|
||||||
|
|
||||||
// Get takes name of the tLSStore, and returns the corresponding tLSStore object, and an error if there is any.
|
// Get takes name of the tLSStore, and returns the corresponding tLSStore object, and an error if there is any.
|
||||||
func (c *FakeTLSStores) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.TLSStore, err error) {
|
func (c *FakeTLSStores) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.TLSStore, err error) {
|
||||||
|
@ -113,7 +112,7 @@ func (c *FakeTLSStores) Update(ctx context.Context, tLSStore *v1alpha1.TLSStore,
|
||||||
// Delete takes name of the tLSStore and deletes it. Returns an error if one occurs.
|
// Delete takes name of the tLSStore and deletes it. Returns an error if one occurs.
|
||||||
func (c *FakeTLSStores) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
func (c *FakeTLSStores) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||||
_, err := c.Fake.
|
_, err := c.Fake.
|
||||||
Invokes(testing.NewDeleteAction(tlsstoresResource, c.ns, name), &v1alpha1.TLSStore{})
|
Invokes(testing.NewDeleteActionWithOptions(tlsstoresResource, c.ns, name, opts), &v1alpha1.TLSStore{})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import (
|
||||||
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
labels "k8s.io/apimachinery/pkg/labels"
|
labels "k8s.io/apimachinery/pkg/labels"
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
types "k8s.io/apimachinery/pkg/types"
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
watch "k8s.io/apimachinery/pkg/watch"
|
watch "k8s.io/apimachinery/pkg/watch"
|
||||||
testing "k8s.io/client-go/testing"
|
testing "k8s.io/client-go/testing"
|
||||||
|
@ -44,9 +43,9 @@ type FakeTraefikServices struct {
|
||||||
ns string
|
ns string
|
||||||
}
|
}
|
||||||
|
|
||||||
var traefikservicesResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "traefikservices"}
|
var traefikservicesResource = v1alpha1.SchemeGroupVersion.WithResource("traefikservices")
|
||||||
|
|
||||||
var traefikservicesKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "TraefikService"}
|
var traefikservicesKind = v1alpha1.SchemeGroupVersion.WithKind("TraefikService")
|
||||||
|
|
||||||
// Get takes name of the traefikService, and returns the corresponding traefikService object, and an error if there is any.
|
// Get takes name of the traefikService, and returns the corresponding traefikService object, and an error if there is any.
|
||||||
func (c *FakeTraefikServices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.TraefikService, err error) {
|
func (c *FakeTraefikServices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.TraefikService, err error) {
|
||||||
|
@ -113,7 +112,7 @@ func (c *FakeTraefikServices) Update(ctx context.Context, traefikService *v1alph
|
||||||
// Delete takes name of the traefikService and deletes it. Returns an error if one occurs.
|
// Delete takes name of the traefikService and deletes it. Returns an error if one occurs.
|
||||||
func (c *FakeTraefikServices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
func (c *FakeTraefikServices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||||
_, err := c.Fake.
|
_, err := c.Fake.
|
||||||
Invokes(testing.NewDeleteAction(traefikservicesResource, c.ns, name), &v1alpha1.TraefikService{})
|
Invokes(testing.NewDeleteActionWithOptions(traefikservicesResource, c.ns, name, opts), &v1alpha1.TraefikService{})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@ THE SOFTWARE.
|
||||||
package v1alpha1
|
package v1alpha1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme"
|
"github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme"
|
||||||
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||||
rest "k8s.io/client-go/rest"
|
rest "k8s.io/client-go/rest"
|
||||||
|
@ -92,12 +94,28 @@ func (c *TraefikV1alpha1Client) TraefikServices(namespace string) TraefikService
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewForConfig creates a new TraefikV1alpha1Client for the given config.
|
// NewForConfig creates a new TraefikV1alpha1Client for the given config.
|
||||||
|
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
|
||||||
|
// where httpClient was generated with rest.HTTPClientFor(c).
|
||||||
func NewForConfig(c *rest.Config) (*TraefikV1alpha1Client, error) {
|
func NewForConfig(c *rest.Config) (*TraefikV1alpha1Client, error) {
|
||||||
config := *c
|
config := *c
|
||||||
if err := setConfigDefaults(&config); err != nil {
|
if err := setConfigDefaults(&config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
client, err := rest.RESTClientFor(&config)
|
httpClient, err := rest.HTTPClientFor(&config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewForConfigAndClient(&config, httpClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewForConfigAndClient creates a new TraefikV1alpha1Client for the given config and http client.
|
||||||
|
// Note the http client provided takes precedence over the configured transport values.
|
||||||
|
func NewForConfigAndClient(c *rest.Config, h *http.Client) (*TraefikV1alpha1Client, error) {
|
||||||
|
config := *c
|
||||||
|
if err := setConfigDefaults(&config); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
client, err := rest.RESTClientForConfigAndClient(&config, h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,11 @@ type sharedInformerFactory struct {
|
||||||
// startedInformers is used for tracking which informers have been started.
|
// startedInformers is used for tracking which informers have been started.
|
||||||
// This allows Start() to be called multiple times safely.
|
// This allows Start() to be called multiple times safely.
|
||||||
startedInformers map[reflect.Type]bool
|
startedInformers map[reflect.Type]bool
|
||||||
|
// wg tracks how many goroutines were started.
|
||||||
|
wg sync.WaitGroup
|
||||||
|
// shuttingDown is true when Shutdown has been called. It may still be running
|
||||||
|
// because it needs to wait for goroutines.
|
||||||
|
shuttingDown bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithCustomResyncConfig sets a custom resync period for the specified informer types.
|
// WithCustomResyncConfig sets a custom resync period for the specified informer types.
|
||||||
|
@ -115,20 +120,39 @@ func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResy
|
||||||
return factory
|
return factory
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start initializes all requested informers.
|
|
||||||
func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
|
func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
|
||||||
f.lock.Lock()
|
f.lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.lock.Unlock()
|
||||||
|
|
||||||
|
if f.shuttingDown {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for informerType, informer := range f.informers {
|
for informerType, informer := range f.informers {
|
||||||
if !f.startedInformers[informerType] {
|
if !f.startedInformers[informerType] {
|
||||||
go informer.Run(stopCh)
|
f.wg.Add(1)
|
||||||
|
// We need a new variable in each loop iteration,
|
||||||
|
// otherwise the goroutine would use the loop variable
|
||||||
|
// and that keeps changing.
|
||||||
|
informer := informer
|
||||||
|
go func() {
|
||||||
|
defer f.wg.Done()
|
||||||
|
informer.Run(stopCh)
|
||||||
|
}()
|
||||||
f.startedInformers[informerType] = true
|
f.startedInformers[informerType] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WaitForCacheSync waits for all started informers' cache were synced.
|
func (f *sharedInformerFactory) Shutdown() {
|
||||||
|
f.lock.Lock()
|
||||||
|
f.shuttingDown = true
|
||||||
|
f.lock.Unlock()
|
||||||
|
|
||||||
|
// Will return immediately if there is nothing to wait for.
|
||||||
|
f.wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool {
|
func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool {
|
||||||
informers := func() map[reflect.Type]cache.SharedIndexInformer {
|
informers := func() map[reflect.Type]cache.SharedIndexInformer {
|
||||||
f.lock.Lock()
|
f.lock.Lock()
|
||||||
|
@ -150,7 +174,7 @@ func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[ref
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// InternalInformerFor returns the SharedIndexInformer for obj using an internal
|
// InformerFor returns the SharedIndexInformer for obj using an internal
|
||||||
// client.
|
// client.
|
||||||
func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
|
func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
|
||||||
f.lock.Lock()
|
f.lock.Lock()
|
||||||
|
@ -175,11 +199,58 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal
|
||||||
|
|
||||||
// SharedInformerFactory provides shared informers for resources in all known
|
// SharedInformerFactory provides shared informers for resources in all known
|
||||||
// API group versions.
|
// API group versions.
|
||||||
|
//
|
||||||
|
// It is typically used like this:
|
||||||
|
//
|
||||||
|
// ctx, cancel := context.Background()
|
||||||
|
// defer cancel()
|
||||||
|
// factory := NewSharedInformerFactory(client, resyncPeriod)
|
||||||
|
// defer factory.WaitForStop() // Returns immediately if nothing was started.
|
||||||
|
// genericInformer := factory.ForResource(resource)
|
||||||
|
// typedInformer := factory.SomeAPIGroup().V1().SomeType()
|
||||||
|
// factory.Start(ctx.Done()) // Start processing these informers.
|
||||||
|
// synced := factory.WaitForCacheSync(ctx.Done())
|
||||||
|
// for v, ok := range synced {
|
||||||
|
// if !ok {
|
||||||
|
// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Creating informers can also be created after Start, but then
|
||||||
|
// // Start must be called again:
|
||||||
|
// anotherGenericInformer := factory.ForResource(resource)
|
||||||
|
// factory.Start(ctx.Done())
|
||||||
type SharedInformerFactory interface {
|
type SharedInformerFactory interface {
|
||||||
internalinterfaces.SharedInformerFactory
|
internalinterfaces.SharedInformerFactory
|
||||||
ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
|
|
||||||
|
// Start initializes all requested informers. They are handled in goroutines
|
||||||
|
// which run until the stop channel gets closed.
|
||||||
|
Start(stopCh <-chan struct{})
|
||||||
|
|
||||||
|
// Shutdown marks a factory as shutting down. At that point no new
|
||||||
|
// informers can be started anymore and Start will return without
|
||||||
|
// doing anything.
|
||||||
|
//
|
||||||
|
// In addition, Shutdown blocks until all goroutines have terminated. For that
|
||||||
|
// to happen, the close channel(s) that they were started with must be closed,
|
||||||
|
// either before Shutdown gets called or while it is waiting.
|
||||||
|
//
|
||||||
|
// Shutdown may be called multiple times, even concurrently. All such calls will
|
||||||
|
// block until all goroutines have terminated.
|
||||||
|
Shutdown()
|
||||||
|
|
||||||
|
// WaitForCacheSync blocks until all started informers' caches were synced
|
||||||
|
// or the stop channel gets closed.
|
||||||
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
|
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
|
||||||
|
|
||||||
|
// ForResource gives generic access to a shared informer of the matching type.
|
||||||
|
ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
|
||||||
|
|
||||||
|
// InformerFor returns the SharedIndexInformer for obj using an internal
|
||||||
|
// client.
|
||||||
|
InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer
|
||||||
|
|
||||||
Traefik() traefikio.Interface
|
Traefik() traefikio.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7067,7 +7067,7 @@ func TestCreateBasicAuthCredentials(t *testing.T) {
|
||||||
username = components[0]
|
username = components[0]
|
||||||
hashedPassword = components[1]
|
hashedPassword = components[1]
|
||||||
|
|
||||||
assert.Equal(t, username, "test2")
|
assert.Equal(t, "test2", username)
|
||||||
assert.Equal(t, hashedPassword, "$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0")
|
assert.Equal(t, "$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", hashedPassword)
|
||||||
assert.True(t, auth.CheckSecret("test2", hashedPassword))
|
assert.True(t, auth.CheckSecret("test2", hashedPassword))
|
||||||
}
|
}
|
||||||
|
|
7
pkg/provider/kubernetes/crd/traefikio/v1alpha1/types.go
Normal file
7
pkg/provider/kubernetes/crd/traefikio/v1alpha1/types.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
/*
|
||||||
|
This file is needed for kubernetes/code-generator/kube_codegen.sh script used in script/code-gen.sh.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// +genclient
|
|
@ -5500,7 +5500,7 @@ func Test_getAllowedRoutes(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
require.Len(t, conditions, 0)
|
require.Empty(t, conditions)
|
||||||
assert.Equal(t, test.wantKinds, got)
|
assert.Equal(t, test.wantKinds, got)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ type marshaler interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type unmarshaler interface {
|
type unmarshaler interface {
|
||||||
Unmarshal([]byte) error
|
Unmarshal(data []byte) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type LoadBalancerIngress interface {
|
type LoadBalancerIngress interface {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue