Merge v2.10 into v3.0

This commit is contained in:
romain 2023-11-29 12:20:57 +01:00
commit e29a142f6a
118 changed files with 1324 additions and 1290 deletions

View file

@ -7,7 +7,7 @@ on:
env: env:
GO_VERSION: '1.21' GO_VERSION: '1.21'
GOLANGCI_LINT_VERSION: v1.54.1 GOLANGCI_LINT_VERSION: v1.55.2
MISSSPELL_VERSION: v0.4.0 MISSSPELL_VERSION: v0.4.0
IN_DOCKER: "" IN_DOCKER: ""

View file

@ -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

View file

@ -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)

View file

@ -1,3 +1,23 @@
## [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) ## [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) [All Commits](https://github.com/traefik/traefik/compare/v3.0.0-beta3...v3.0.0-beta4)

View file

@ -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]

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 youre 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

View file

@ -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 PRs in the past 6 months. - The contributor has opened and successfully run medium to large PRs in the past 6 months.
- The contributor has participated in multiple code reviews of other PRs, - The contributor has participated in multiple code reviews of other PRs,
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 PRs,
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 cant 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.

View file

@ -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.

View file

@ -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"

View file

@ -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:

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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`

View file

@ -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.

View file

@ -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_

View file

@ -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_

View file

@ -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_

View file

@ -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=""_

View file

@ -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_

View file

@ -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: []

View file

@ -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: []

View file

@ -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: []

View file

@ -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: []

View file

@ -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: []

View file

@ -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: []

View file

@ -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: []

View file

@ -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: []

View file

@ -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: []

View file

@ -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: []

View file

@ -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: []

113
go.mod
View file

@ -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
@ -87,14 +86,14 @@ require (
go.opentelemetry.io/otel/sdk v1.19.0 go.opentelemetry.io/otel/sdk v1.19.0
go.opentelemetry.io/otel/sdk/metric v1.19.0 go.opentelemetry.io/otel/sdk/metric v1.19.0
go.opentelemetry.io/otel/trace v1.19.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,16 +218,15 @@ 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
@ -239,22 +234,13 @@ require (
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.16.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
@ -374,13 +357,13 @@ require (
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect
go.uber.org/atomic v1.10.0 // indirect go.uber.org/atomic v1.11.0 // indirect
go.uber.org/mock v0.3.0 // indirect go.uber.org/mock v0.3.0 // indirect
go.uber.org/multierr v1.8.0 // indirect go.uber.org/multierr v1.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
@ -388,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
@ -400,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

454
go.sum

File diff suppressed because it is too large Load diff

View file

@ -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 {

View file

@ -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: []

View 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"

View file

@ -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
}() }()

View file

@ -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")
}

View file

@ -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)
}

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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())
}) })
} }
} }

View file

@ -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)
} }
} }

View file

@ -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(""),

View file

@ -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]
} }

View file

@ -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 {

View file

@ -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)
} }
}) })

View file

@ -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()

View file

@ -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()

View 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)
}

View file

@ -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)
}

View file

@ -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()

View file

@ -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)
} }
}) })
} }

View file

@ -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

View file

@ -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()

View file

@ -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)

View file

@ -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)
}) })
} }

View file

@ -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
} }

View file

@ -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

View file

@ -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) {

View file

@ -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")
}) })

View file

@ -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
} }

View file

@ -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().

View file

@ -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{},

View file

@ -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,
}, },
} }
} }

View file

@ -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{},

View file

@ -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{},

View file

@ -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")
} }

View file

@ -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)
} }

View file

@ -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.

View file

@ -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

View file

@ -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 {

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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))
} }

View 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

View file

@ -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)
}) })
} }

View file

@ -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 {

View file

@ -324,7 +324,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
portString := pa.Backend.Service.Port.Name portString := pa.Backend.Service.Port.Name
if len(pa.Backend.Service.Port.Name) == 0 { if len(pa.Backend.Service.Port.Name) == 0 {
portString = fmt.Sprint(pa.Backend.Service.Port.Number) portString = strconv.Itoa(int(pa.Backend.Service.Port.Number))
} }
serviceName := provider.Normalize(ingress.Namespace + "-" + pa.Backend.Service.Name + "-" + portString) serviceName := provider.Normalize(ingress.Namespace + "-" + pa.Backend.Service.Name + "-" + portString)

View file

@ -47,6 +47,7 @@ func Test_defaultRule(t *testing.T) {
"Test": { "Test": {
Service: "Test", Service: "Test",
Rule: "Host(`example.com`)", Rule: "Host(`example.com`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -101,6 +102,7 @@ func Test_defaultRule(t *testing.T) {
"Test": { "Test": {
Service: "Test", Service: "Test",
Rule: `Host("Test.example.com")`, Rule: `Host("Test.example.com")`,
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -198,6 +200,7 @@ func Test_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{},
@ -272,6 +275,7 @@ func Test_buildConfig(t *testing.T) {
"dev-Test": { "dev-Test": {
Service: "dev-Test", Service: "dev-Test",
Rule: "Host(`dev-Test.traefik.test`)", Rule: "Host(`dev-Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -330,10 +334,12 @@ func Test_buildConfig(t *testing.T) {
"Test1": { "Test1": {
Service: "Test1", Service: "Test1",
Rule: "Host(`Test1.traefik.test`)", Rule: "Host(`Test1.traefik.test`)",
DefaultRule: true,
}, },
"Test2": { "Test2": {
Service: "Test2", Service: "Test2",
Rule: "Host(`Test2.traefik.test`)", Rule: "Host(`Test2.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -407,6 +413,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Test", Service: "Test",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -470,6 +477,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Test", Service: "Test",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -530,6 +538,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Test", Service: "Test",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -585,6 +594,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Service1", Service: "Service1",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -868,6 +878,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Service1", Service: "Service1",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -926,6 +937,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Service1", Service: "Service1",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -974,6 +986,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Service1", Service: "Service1",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -1029,6 +1042,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Test", Service: "Test",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
@ -1097,6 +1111,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Test", Service: "Test",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{ Middlewares: map[string]*dynamic.Middleware{
@ -1168,6 +1183,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Test", Service: "Test",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -1348,6 +1364,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Test", Service: "Test",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -1401,6 +1418,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Service1", Service: "Service1",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -1645,6 +1663,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Test", Service: "Test",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -1699,6 +1718,7 @@ func Test_buildConfig(t *testing.T) {
Service: "Test", Service: "Test",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
Middlewares: []string{"Middleware1"}, Middlewares: []string{"Middleware1"},
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{ Middlewares: map[string]*dynamic.Middleware{
@ -2095,6 +2115,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Service1", Service: "Service1",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -2182,6 +2203,7 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Service1", Service: "Service1",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},
@ -2384,10 +2406,12 @@ func Test_buildConfig(t *testing.T) {
"Test": { "Test": {
Service: "Test", Service: "Test",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
"Test-1234154071633021619": { "Test-1234154071633021619": {
Service: "Test-1234154071633021619", Service: "Test-1234154071633021619",
Rule: "Host(`Test.traefik.test`)", Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
}, },
}, },
Middlewares: map[string]*dynamic.Middleware{}, Middlewares: map[string]*dynamic.Middleware{},

View file

@ -517,7 +517,7 @@ func TestDo_staticConfiguration(t *testing.T) {
} }
config.EntryPoints = static.EntryPoints{ config.EntryPoints = static.EntryPoints{
"foobar": { "foobar": &static.EntryPoint{
Address: "foo Address", Address: "foo Address",
Transport: &static.EntryPointsTransport{ Transport: &static.EntryPointsTransport{
LifeCycle: &static.LifeCycle{ LifeCycle: &static.LifeCycle{

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