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:
GO_VERSION: '1.21'
GOLANGCI_LINT_VERSION: v1.54.1
GOLANGCI_LINT_VERSION: v1.55.2
MISSSPELL_VERSION: v0.4.0
IN_DOCKER: ""

View file

@ -87,8 +87,6 @@ linters-settings:
pkg: "sigs.k8s.io/gateway-api/apis/v1alpha2"
# Traefik Kubernetes rewrites:
- alias: containousv1alpha1
pkg: "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1"
- alias: traefikv1alpha1
pkg: "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
- alias: traefikclientset
@ -151,6 +149,19 @@ linters-settings:
- github.com/mailgun/minheap
- github.com/mailgun/multibuf
- 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:
enable-all: true

View file

@ -25,7 +25,7 @@ global_job_config:
- export "PATH=${GOPATH}/bin:${PATH}"
- mkdir -vp "${SEMAPHORE_GIT_DIR}" "${GOPATH}/bin"
- 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"
- checkout
- 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)
[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.
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
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
.PHONY: 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
.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
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.
You can also find more information on our process to review pull requests and manage issues [in this document](docs/content/contributing/maintainers.md).
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](https://github.com/traefik/contributors-guide/blob/master/issue_triage.md).
## Contributing

View file

@ -13,7 +13,7 @@ RUN mkdir -p /usr/local/bin \
| tar -xzC /usr/local/bin --transform 's#^.+/##x'
# 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
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"
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
Spread the Love & Tell Us about It
Spread the Love & Tell Us About It
{: .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:
**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)
Note: the document is a work in progress.
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,
and firmly standing against the elitist closed approach.
Being part of the core team should be accessible to anyone motivated
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.
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.
Before a contributor becomes a maintainer, they should meet the following requirements:
## 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,
but must have achieved several.
- The contributor showed a consistent pattern of helpful, non-threatening, and friendly behavior towards other community members in the past.
- 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 participated in multiple code reviews of other PRs,
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
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
There are lots of areas where you can contribute to the project,
but we can suggest you start with activities such as:
As a maintainer, you are granted a vote for the following:
- PR reviewing.
- 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).
- [PR review](https://github.com/traefik/contributors-guide/blob/master/pr_guidelines.md).
## 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
- 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.
You can reach Traefik core developers directly,
which offers the possibility to discuss issues, pull requests, enhancements more efficiently
Maintainers can discuss issues, pull requests, enhancements more efficiently
and get the feedback almost immediately.
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.
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.
- Every decision made on the discord server among maintainers is documented so it's visible to the rest of the community.
- At 2:15pm CET every Monday and Thursday we review all the created issues that have been reported,
assign them the appropriate *[labels](maintainers.md#labels)*
and prioritize them based on the severity of the problem.
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.
For that purpose, we use the Traefik Maintainers Discord server
where you are invited once you have become an official maintainer.
- Maintainers express their opinions on issues and reviews.
It is fine to have different point of views.
We encourage active and open conversations which goals are to improve Traefik.
- When discussing issues and proposals, maintainers should share as much information as possible to help solve the issue.
## 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.
- 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?
- 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
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 with the community in general.
- Has the maintainer shown a consistent pattern of helpful,
non-threatening,
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 -
if anyone tries to communicate with you directly,
ask politely to move the conversation to a public communication channel.
- Stay away from defensive comments.
- Please try to express your thoughts clearly enough
and note that some of us are not native English speakers.
Try to rephrase your sentences, avoiding mental shortcuts;
none of us is able to predict your 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.
none of us is able to predict anyone's thoughts.
- Be proactive.
- Emoji are fine,
but if you express yourself clearly enough they are not necessary.
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
## The Team
## Active Maintainers
* 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)
* Timo Reimann [@timoreimann](https://github.com/timoreimann)
* Ludovic Fernandez [@ldez](https://github.com/ldez)
* Julien Salleyron [@juliens](https://github.com/juliens)
* Nicolas Mengin [@nmengin](https://github.com/nmengin)
* Marco Jantke [@mjantke](https://github.com/mjeri)
* Michaël Matur [@mmatur](https://github.com/mmatur)
* Gérald Croës [@geraldcroes](https://github.com/geraldcroes)
* 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)
* Harold Ozouf [@jspdown](https://github.com/jspdown)
* 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
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.
Please read the [maintainer's guidelines](maintainers-guidelines.md).

View file

@ -11,8 +11,8 @@ Help Us Help You!
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.
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).
To help us (and other community members) quickly and effortlessly understand what you need,
The process of sorting and checking the issues is a daunting task, and requires a lot of work.
To help maintainers (and other community members) quickly and effortlessly understand what you need,
be sure to follow the guidelines below.
!!! 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
We wish we could review every pull request right away.
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).
We wish we could review every pull request right away, but because it's a time consuming operation, it's not always possible.
The PRs we are able to handle fastest are:
The PRs we are able to handle the fastest are:
* Documentation updates.
* 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.
* Pass the validation check.
* Pass all tests.
* Receive 3 approving reviews maintainers.
* Receive 3 approving reviews from maintainers.
## 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,
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.
* 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:

View file

@ -9,7 +9,7 @@ _You_ Made It
{: .subtitle}
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.
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?"
If you want to:
- Propose and idea, request a feature a report a bug,
read the page [Submitting Issues](./submitting-issues.md).
- Propose an idea, request a feature, or report a bug,
then read [Submitting Issues](./submitting-issues.md).
- 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,
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,
read the related page [Documentation](./documentation.md).
then read the page about [Documentation](./documentation.md).
- Understand how do we learn about Traefik usage,
read the [Data Collection](./data-collection.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,
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)
The BasicAuth middleware restricts access to your services to known users.
The BasicAuth middleware grants access to services to authorized users only.
## Configuration Examples

View file

@ -10,7 +10,7 @@ Adding Digest Authentication
![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

View file

@ -21,7 +21,7 @@ The Errors middleware returns a custom page in lieu of the default, according to
```yaml tab="Docker & Swarm"
# Dynamic Custom Error Page for 5XX Status Code
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.query=/{status}.html"
```
@ -34,7 +34,10 @@ metadata:
spec:
errors:
status:
- "500-599"
- "500"
- "501"
- "503"
- "505-599"
query: /{status}.html
service:
name: whoami
@ -42,20 +45,23 @@ spec:
```
```yaml tab="Consul Catalog"
# Dynamic Custom Error Page for 5XX Status Code
- "traefik.http.middlewares.test-errors.errors.status=500-599"
# Dynamic Custom Error Page for 5XX Status Code excluding 502 and 504
- "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.query=/{status}.html"
```
```yaml tab="File (YAML)"
# Custom Error Page for 5XX
# Dynamic Custom Error Page for 5XX Status Code excluding 502 and 504
http:
middlewares:
test-errors:
errors:
status:
- "500-599"
- "500"
- "501"
- "503"
- "505-599"
service: serviceError
query: "/{status}.html"
@ -64,10 +70,10 @@ http:
```
```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.test-errors.errors]
status = ["500-599"]
status = ["500","501","503","505-599"]
service = "serviceError"
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 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 ""
You can define either a status code as a number (`500`),
as multiple comma-separated numbers (`500,502`),
as ranges by separating two codes with a dash (`500-599`),
or a combination of the two (`404,418,500-599`).
as ranges by separating two codes with a dash (`505-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`

View file

@ -227,4 +227,12 @@ The following metric is produced :
```bash
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`
_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`
_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`
_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`
_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`
_Optional, Default=15_

View file

@ -1,11 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: ingressroutes.traefik.io
spec:
group: traefik.io
@ -267,20 +265,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: ingressroutetcps.traefik.io
spec:
group: traefik.io
@ -486,20 +476,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: ingressrouteudps.traefik.io
spec:
group: traefik.io
@ -591,20 +573,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: middlewares.traefik.io
spec:
group: traefik.io
@ -1493,20 +1467,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: middlewaretcps.traefik.io
spec:
group: traefik.io
@ -1565,20 +1531,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: serverstransports.traefik.io
spec:
group: traefik.io
@ -1706,20 +1664,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: serverstransporttcps.traefik.io
spec:
group: traefik.io
@ -1828,20 +1778,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: tlsoptions.traefik.io
spec:
group: traefik.io
@ -1935,20 +1877,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: tlsstores.traefik.io
spec:
group: traefik.io
@ -2034,20 +1968,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: traefikservices.traefik.io
spec:
group: traefik.io
@ -2436,9 +2362,3 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View file

@ -1,11 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: ingressroutes.traefik.io
spec:
group: traefik.io
@ -267,9 +265,3 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View file

@ -1,11 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: ingressroutetcps.traefik.io
spec:
group: traefik.io
@ -211,9 +209,3 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View file

@ -1,11 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: ingressrouteudps.traefik.io
spec:
group: traefik.io
@ -97,9 +95,3 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View file

@ -1,11 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: middlewares.traefik.io
spec:
group: traefik.io
@ -894,9 +892,3 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View file

@ -1,11 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: middlewaretcps.traefik.io
spec:
group: traefik.io
@ -64,9 +62,3 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View file

@ -1,11 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: serverstransports.traefik.io
spec:
group: traefik.io
@ -133,9 +131,3 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View file

@ -1,11 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: serverstransporttcps.traefik.io
spec:
group: traefik.io
@ -114,9 +112,3 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View file

@ -1,11 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: tlsoptions.traefik.io
spec:
group: traefik.io
@ -99,9 +97,3 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View file

@ -1,11 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: tlsstores.traefik.io
spec:
group: traefik.io
@ -91,9 +89,3 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View file

@ -1,11 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: traefikservices.traefik.io
spec:
group: traefik.io
@ -394,9 +392,3 @@ spec:
type: object
served: 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/Masterminds/sprig/v3 v3.2.3
github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000
github.com/andybalholm/brotli v1.0.4
github.com/aws/aws-sdk-go v1.44.47
github.com/andybalholm/brotli v1.0.6
github.com/aws/aws-sdk-go v1.44.327
github.com/cenkalti/backoff/v4 v4.2.1
github.com/compose-spec/compose-go v1.0.3
github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
github.com/davecgh/go-spew v1.1.1
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
github.com/docker/cli v20.10.11+incompatible
github.com/docker/compose/v2 v2.0.1
github.com/docker/docker v20.10.21+incompatible
@ -26,9 +26,8 @@ require (
github.com/google/go-github/v28 v28.1.1
github.com/gorilla/mux v1.8.0
github.com/gorilla/websocket v1.5.0
github.com/hashicorp/consul v1.10.12
github.com/hashicorp/consul/api v1.14.0
github.com/hashicorp/go-hclog v1.2.0
github.com/hashicorp/consul/api v1.26.1
github.com/hashicorp/go-hclog v1.5.0
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/go-retryablehttp v0.7.4
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/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d
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/etcdv3 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/patrickmn/go-cache v2.1.0+incompatible
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_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/sirupsen/logrus v1.9.3
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/metric v1.19.0
go.opentelemetry.io/otel/trace v1.19.0
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db
golang.org/x/mod v0.11.0
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
golang.org/x/mod v0.12.0
golang.org/x/net v0.17.0
golang.org/x/text v0.13.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
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/yaml.v3 v3.0.1
k8s.io/api v0.26.3
@ -107,7 +106,7 @@ 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
github.com/AdamSLevy/jsonrpc2/v14 v14.1.0 // 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/AzureAD/microsoft-authentication-library-for-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/remoteconfig/state v0.45.0-rc.1 // indirect
github.com/DataDog/datadog-go v4.8.2+incompatible // indirect
github.com/DataDog/datadog-go/v5 v5.1.1 // indirect
github.com/DataDog/go-libddwaf v1.2.0 // indirect
github.com/DataDog/go-tuf v0.3.0--fix-localmeta-fork // indirect
github.com/DataDog/sketches-go v1.2.1 // indirect
github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.0 // indirect
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.0-devel.0.20230725154044-2549ba9058df // indirect
github.com/DataDog/datadog-go/v5 v5.3.0 // indirect
github.com/DataDog/go-libddwaf v1.5.0 // indirect
github.com/DataDog/go-tuf v1.0.2-0.5.2 // indirect
github.com/DataDog/sketches-go v1.4.2 // indirect
github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
github.com/Masterminds/goutils v1.1.1 // 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/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/agl/ed25519 v0.0.0-20170116200512-5312a6153412 // indirect
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 // 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/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/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/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/internal/configsources v1.1.35 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.29 // 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.34 // 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/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/ssooidc v1.14.13 // 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/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
github.com/buger/goterm v1.0.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/cloudflare/cloudflare-go v0.70.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-metrics v0.0.1 // 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-sysinfo v1.1.1 // 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/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/fvbommel/sortorder v1.0.1 // 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/groupcache v0.0.0-20210331224755-41bb18bfe9da // 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/go-cmp v0.5.9 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
github.com/google/s2a-go v0.1.4 // indirect
github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect
github.com/google/s2a-go v0.1.5 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
github.com/googleapis/gax-go/v2 v2.11.0 // indirect
github.com/gophercloud/gophercloud v1.0.0 // 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/grpc-gateway/v2 v2.16.0 // 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/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-msgpack v0.5.5 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
github.com/hashicorp/go-uuid v1.0.2 // 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/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/serf v0.10.1 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df // 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/timetools v0.0.0-20141028012446-7e6055773c51 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // 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/mitchellh/go-homedir v1.1.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/moby/buildkit v0.8.2-0.20210401015549-df49b648c8bf // indirect
github.com/moby/locker v1.0.1 // indirect
@ -320,9 +305,9 @@ require (
github.com/opencontainers/runc v1.1.5 // 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/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/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/errors v0.9.1 // 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/santhosh-tekuri/jsonschema v1.2.4 // 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.5.0 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.7.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/simplesurance/bunny-go v0.0.0-20221115111006-e11d9dc91f04 // 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/cobra v1.6.0 // 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/dnspod v1.0.490 // 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/units v0.0.0-20180711220420-6950e57a87ea // 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/vinyldns/go-vinyldns v0.9.16 // indirect
github.com/vultr/govultr/v2 v2.17.2 // indirect
@ -374,13 +357,13 @@ require (
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.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/multierr v1.8.0 // indirect
go.uber.org/ratelimit v0.2.0 // indirect
go.uber.org/zap v1.21.0 // indirect
go4.org/intern v0.0.0-20211027215823-ae77deb06f29 // indirect
go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 // indirect
go4.org/intern v0.0.0-20230525184215-6c62f75575cb // 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/lint v0.0.0-20210508222113-6edffad5e616 // 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/term v0.13.0 // 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/genproto 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/yaml.v2 v2.4.0 // 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/kube-openapi v0.0.0-20221012153701-172d655c2280 // 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 (
"crypto/md5"
"crypto/rand"
"encoding/hex"
"encoding/json"
"fmt"
"io"
@ -265,7 +266,8 @@ func getMD5(data string) string {
if _, err := digest.Write([]byte(data)); err != nil {
log.Error().Err(err).Send()
}
return fmt.Sprintf("%x", digest.Sum(nil))
return hex.EncodeToString(digest.Sum(nil))
}
func getCnonce() string {
@ -273,7 +275,8 @@ func getCnonce() string {
if _, err := io.ReadFull(rand.Reader, b); err != nil {
log.Error().Err(err).Send()
}
return fmt.Sprintf("%x", b)[:16]
return hex.EncodeToString(b)[:16]
}
func getDigestAuthorization(digestParts map[string]string) string {

View file

@ -1,11 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: ingressroutes.traefik.io
spec:
group: traefik.io
@ -267,20 +265,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: ingressroutetcps.traefik.io
spec:
group: traefik.io
@ -486,20 +476,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: ingressrouteudps.traefik.io
spec:
group: traefik.io
@ -591,20 +573,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: middlewares.traefik.io
spec:
group: traefik.io
@ -1493,20 +1467,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: middlewaretcps.traefik.io
spec:
group: traefik.io
@ -1565,20 +1531,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: serverstransports.traefik.io
spec:
group: traefik.io
@ -1706,20 +1664,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: serverstransporttcps.traefik.io
spec:
group: traefik.io
@ -1828,20 +1778,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: tlsoptions.traefik.io
spec:
group: traefik.io
@ -1935,20 +1877,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: tlsstores.traefik.io
spec:
group: traefik.io
@ -2034,20 +1968,12 @@ spec:
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.13.0
name: traefikservices.traefik.io
spec:
group: traefik.io
@ -2436,9 +2362,3 @@ spec:
type: object
served: 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) {
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 {
@ -121,7 +121,7 @@ func callHelloClientGRPC(name string, secure bool) (string, error) {
if err != nil {
return "", err
}
return r.Message, nil
return r.GetMessage(), nil
}
func callStreamExampleClientGRPC() (helloworld.Greeter_StreamExampleClient, func() error, error) {
@ -351,7 +351,7 @@ func (s *GRPCSuite) TestGRPCBuffer(c *check.C) {
go func() {
tr, err := client.Recv()
c.Assert(err, check.IsNil)
c.Assert(len(tr.Data), check.Equals, 512)
c.Assert(len(tr.GetData()), check.Equals, 512)
received <- true
}()
@ -414,7 +414,7 @@ func (s *GRPCSuite) TestGRPCBufferWithFlushInterval(c *check.C) {
go func() {
tr, err := client.Recv()
c.Assert(err, check.IsNil)
c.Assert(len(tr.Data), check.Equals, 512)
c.Assert(len(tr.GetData()), check.Equals, 512)
received <- true
}()

View file

@ -1,6 +1,7 @@
package integration
import (
"io"
"net/http"
"os"
"time"
@ -86,3 +87,26 @@ func (s *RetrySuite) TestRetryWebsocket(c *check.C) {
c.Assert(err, checker.IsNil)
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
}
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)
require.NoError(t, err)

View file

@ -951,7 +951,7 @@ func TestHandler_HTTP(t *testing.T) {
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)
require.NoError(t, err)

View file

@ -288,7 +288,7 @@ func TestHandler_Overview(t *testing.T) {
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)
require.NoError(t, err)

View file

@ -833,7 +833,7 @@ func TestHandler_TCP(t *testing.T) {
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)
require.NoError(t, err)

View file

@ -143,7 +143,7 @@ func TestHandler_RawData(t *testing.T) {
require.NoError(t, err)
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)
require.NoError(t, err)

View file

@ -544,7 +544,7 @@ func TestHandler_UDP(t *testing.T) {
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)
require.NoError(t, err)

View file

@ -61,6 +61,7 @@ type Router struct {
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"`
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

View file

@ -255,8 +255,8 @@ func (shc *ServiceHealthChecker) checkHealthGRPC(ctx context.Context, serverURL
return fmt.Errorf("gRPC health check failed: %w", err)
}
if resp.Status != healthpb.HealthCheckResponse_SERVING {
return fmt.Errorf("received gRPC status code: %v", resp.Status)
if resp.GetStatus() != healthpb.HealthCheckResponse_SERVING {
return fmt.Errorf("received gRPC status code: %v", resp.GetStatus())
}
return nil

View file

@ -18,6 +18,8 @@ import (
healthpb "google.golang.org/grpc/health/grpc_health_v1"
)
const delta float64 = 1e-10
func TestNewServiceHealthChecker_durations(t *testing.T) {
testCases := []struct {
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.expNumUpsertedServers, lb.numUpsertedServers, "upserted servers")
assert.Equal(t, test.expGaugeValue, gauge.GaugeValue, "ServerUp Gauge")
assert.Equal(t, serviceInfo.GetAllStatus(), map[string]string{targetURL.String(): test.targetStatus})
assert.InDelta(t, test.expGaugeValue, gauge.GaugeValue, delta, "ServerUp Gauge")
assert.Equal(t, map[string]string{targetURL.String(): test.targetStatus}, serviceInfo.GetAllStatus())
})
}
}

View file

@ -389,12 +389,12 @@ func TestPrometheus(t *testing.T) {
return
}
for _, label := range family.Metric[0].Label {
val, ok := test.labels[*label.Name]
for _, label := range family.GetMetric()[0].GetLabel() {
val, ok := test.labels[label.GetName()]
if !ok {
t.Errorf("%q metric contains unexpected label %q", test.name, *label.Name)
} else if val != *label.Value {
t.Errorf("label %q in metric %q has wrong value %q, expected %q", *label.Name, test.name, *label.Value, val)
t.Errorf("%q metric contains unexpected label %q", test.name, label.GetName())
} else if val != label.GetValue() {
t.Errorf("label %q in metric %q has wrong value %q, expected %q", label.GetName(), test.name, label.GetValue(), val)
}
}
test.assert(family)
@ -645,7 +645,7 @@ func findMetricByLabelNamesValues(family *dto.MetricFamily, labelNamesValues ...
return nil
}
for _, metric := range family.Metric {
for _, metric := range family.GetMetric() {
if hasMetricAllLabelPairs(metric, labelNamesValues...) {
return metric
}
@ -665,7 +665,7 @@ func hasMetricAllLabelPairs(metric *dto.Metric, labelNamesValues ...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 {
return true
}
@ -682,12 +682,12 @@ func assertCounterValue(t *testing.T, want float64, family *dto.MetricFamily, la
t.Error("metric must not be nil")
return
}
if metric.Counter == nil {
if metric.GetCounter() == nil {
t.Errorf("metric %s must be a counter", family.GetName())
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)
}
}
@ -696,7 +696,7 @@ func buildCounterAssert(t *testing.T, metricName string, expectedValue int) func
t.Helper()
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)
}
}
@ -706,7 +706,7 @@ func buildGreaterThanCounterAssert(t *testing.T, metricName string, expectedMinV
t.Helper()
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)
}
}
@ -716,7 +716,7 @@ func buildHistogramAssert(t *testing.T, metricName string, expectedSampleCount i
t.Helper()
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)
}
}
@ -726,7 +726,7 @@ func buildGaugeAssert(t *testing.T, metricName string, expectedValue int) func(f
t.Helper()
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)
}
}
@ -736,7 +736,7 @@ func buildTimestampAssert(t *testing.T, metricName string) func(family *dto.Metr
t.Helper()
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)
}
}

View file

@ -14,6 +14,7 @@ import (
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"testing"
"time"
@ -323,7 +324,7 @@ func TestLoggerJSON(t *testing.T) {
ServiceURL: assertString(testServiceName),
ClientUsername: assertString(testUsername),
ClientHost: assertString(testHostname),
ClientPort: assertString(fmt.Sprintf("%d", testPort)),
ClientPort: assertString(strconv.Itoa(testPort)),
ClientAddr: assertString(fmt.Sprintf("%s:%d", testHostname, testPort)),
"level": assertString("info"),
"msg": assertString(""),
@ -363,7 +364,7 @@ func TestLoggerJSON(t *testing.T) {
ServiceURL: assertString(testServiceName),
ClientUsername: assertString(testUsername),
ClientHost: assertString(testHostname),
ClientPort: assertString(fmt.Sprintf("%d", testPort)),
ClientPort: assertString(strconv.Itoa(testPort)),
ClientAddr: assertString(fmt.Sprintf("%s:%d", testHostname, testPort)),
"level": assertString("info"),
"msg": assertString(""),

View file

@ -137,5 +137,5 @@ func (r *digestRequest) makeAuthorization(req *http.Request, parts map[string]st
func generateRandom(n int) string {
b := make([]byte, 8)
_, _ = 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)
}
assert.Equal(b, size, len(recorder.Body.String()))
assert.Len(b, recorder.Body.String(), size)
}
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))
got, err := io.ReadAll(brotli.NewReader(rw.Body))
assert.Nil(t, err)
assert.NoError(t, err)
assert.Equal(t, bigTestBody, got)
} else {
assert.NotEqual(t, "br", rw.Header().Get("Content-Encoding"))
got, err := io.ReadAll(rw.Body)
assert.Nil(t, err)
assert.NoError(t, err)
assert.Equal(t, bigTestBody, got)
}
})
@ -496,13 +496,13 @@ func Test_FlushExcludedContentTypes(t *testing.T) {
assert.Equal(t, "br", rw.Header().Get(contentEncoding))
got, err := io.ReadAll(brotli.NewReader(rw.Body))
assert.Nil(t, err)
assert.NoError(t, err)
assert.Equal(t, bigTestBody, got)
} else {
assert.NotEqual(t, "br", rw.Header().Get(contentEncoding))
got, err := io.ReadAll(rw.Body)
assert.Nil(t, err)
assert.NoError(t, err)
assert.Equal(t, bigTestBody, got)
}
})

View file

@ -582,7 +582,7 @@ func Test1xxResponses(t *testing.T) {
req.Header.Add(acceptEncodingHeader, gzipValue)
res, err := frontendClient.Do(req)
assert.Nil(t, err)
assert.NoError(t, err)
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)
res, err := frontendClient.Do(req)
assert.Nil(t, err)
assert.NoError(t, err)
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)
res, err := frontendClient.Do(req)
assert.Nil(t, err)
assert.NoError(t, err)
defer res.Body.Close()

View file

@ -18,6 +18,8 @@ import (
"golang.org/x/time/rate"
)
const delta float64 = 1e-10
func TestNewRateLimiter(t *testing.T) {
testCases := []struct {
desc string
@ -131,7 +133,7 @@ func TestNewRateLimiter(t *testing.T) {
assert.Equal(t, test.requestHeader, hd)
}
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)
r.next.ServeHTTP(retryResponseWriter, req.WithContext(newCtx))
r.next.ServeHTTP(retryResponseWriter, req.Clone(newCtx))
if !retryResponseWriter.ShouldRetry() {
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)
res, err := frontendClient.Do(req)
assert.Nil(t, err)
assert.NoError(t, err)
defer res.Body.Close()

View file

@ -123,7 +123,7 @@ func TestNewForwarder(t *testing.T) {
tags := span.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",
test.expected.OperationName, len(test.expected.OperationName), test.spanNameLimit)
assert.Equal(t, test.expected.OperationName, span.OpName)

View file

@ -309,7 +309,7 @@ func Test_addTCPRoute(t *testing.T) {
matchingHandler.ServeTCP(conn)
n, ok := conn.call[msg]
assert.Equal(t, n, 1)
assert.Equal(t, 1, n)
assert.True(t, ok)
})
}

View file

@ -4,6 +4,7 @@ import (
zipa "archive/zip"
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
@ -421,5 +422,5 @@ func computeHash(filepath string) (string, error) {
sum := hash.Sum(nil)
return fmt.Sprintf("%x", sum), nil
return hex.EncodeToString(sum), nil
}

View file

@ -11,11 +11,9 @@ import (
"sync"
"time"
"github.com/cenkalti/backoff/v4"
"github.com/go-acme/lego/v4/challenge/http01"
"github.com/rs/zerolog/log"
"github.com/traefik/traefik/v3/pkg/logs"
"github.com/traefik/traefik/v3/pkg/safe"
)
// 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.Debug().Msgf("Retrieving the ACME challenge for %s (token %q)...", domain, token)
var result []byte
operation := func() error {
c.lock.RLock()
defer c.lock.RUnlock()
if _, ok := c.httpChallenges[token]; !ok {
return fmt.Errorf("cannot find challenge for token %q (%s)", token, domain)
}
var ok bool
result, ok = c.httpChallenges[token][domain]
if !ok {
return fmt.Errorf("cannot find challenge for %s (token %q)", domain, token)
}
c.lock.RLock()
defer c.lock.RUnlock()
if _, ok := c.httpChallenges[token]; !ok {
logger.Error().Msgf("Cannot retrieve the ACME challenge for %s (token %q)", domain, token)
return nil
}
notify := func(err error, time time.Duration) {
logger.Error().Msgf("Error getting challenge for token retrying in %s", time)
}
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{}
result, ok := c.httpChallenges[token][domain]
if !ok {
logger.Error().Msgf("Cannot retrieve the ACME challenge for %s (token %q)", domain, token)
return nil
}
return result

View file

@ -31,6 +31,8 @@ import (
"github.com/traefik/traefik/v3/pkg/version"
)
const resolverSuffix = ".acme"
// ocspMustStaple enables OCSP stapling as from https://github.com/go-acme/lego/issues/270.
var ocspMustStaple = false
@ -132,7 +134,7 @@ func (p *Provider) ListenConfiguration(config dynamic.Configuration) {
// Init for compatibility reason the BaseProvider implements an empty Init.
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 {
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
// using the given Configuration channel.
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()
ctx := logger.WithContext(context.Background())
@ -236,7 +238,7 @@ func (p *Provider) getClient() (*lego.Client, error) {
p.clientMutex.Lock()
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())
@ -407,7 +409,7 @@ func (p *Provider) resolveDomains(ctx context.Context, domains []string, tlsStor
}
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)
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}}
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.KeyType, actualAccount.KeyType, "unexpected keyType account")
})

View file

@ -8,8 +8,8 @@ type StoredData struct {
// Store is a generic interface that represents a storage.
type Store interface {
GetAccount(string) (*Account, error)
SaveAccount(string, *Account) error
GetCertificates(string) ([]*CertAndStore, error)
SaveCertificates(string, []*CertAndStore) error
GetAccount(resolverName string) (*Account, error)
SaveAccount(resolverName string, account *Account) error
GetCertificates(resolverName string) ([]*CertAndStore, error)
SaveCertificates(resolverName string, certificates []*CertAndStore) error
}

View file

@ -388,7 +388,7 @@ func BuildTCPRouterConfiguration(ctx context.Context, configuration *dynamic.TCP
continue
}
if len(router.Service) == 0 {
if router.Service == "" {
if len(configuration.Services) > 1 {
delete(configuration.Routers, routerName)
loggerRouter.Error().
@ -408,7 +408,7 @@ func BuildUDPRouterConfiguration(ctx context.Context, configuration *dynamic.UDP
for routerName, router := range configuration.Routers {
loggerRouter := log.Ctx(ctx).With().Str(logs.RouterName, routerName).Logger()
if len(router.Service) > 0 {
if router.Service != "" {
continue
}
@ -454,9 +454,12 @@ func BuildRouterConfiguration(ctx context.Context, configuration *dynamic.HTTPCo
delete(configuration.Routers, routerName)
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 {
delete(configuration.Routers, routerName)
loggerRouter.Error().

View file

@ -52,8 +52,9 @@ func TestDefaultRule(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`foo.bar`)",
Service: "Test",
Rule: "Host(`foo.bar`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -106,8 +107,9 @@ func TestDefaultRule(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: `Host("Test.foo.bar")`,
Service: "Test",
Rule: `Host("Test.foo.bar")`,
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -252,8 +254,9 @@ func TestDefaultRule(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test`)",
Service: "Test",
Rule: "Host(`Test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -341,8 +344,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"dev-Test": {
Service: "dev-Test",
Rule: "Host(`dev-Test.traefik.wtf`)",
Service: "dev-Test",
Rule: "Host(`dev-Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -398,8 +402,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"dev-Test": {
Service: "dev-Test",
Rule: "Host(`dev-Test.traefik.wtf`)",
Service: "dev-Test",
Rule: "Host(`dev-Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -485,8 +490,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"dev-Test": {
Service: "dev-Test",
Rule: "Host(`dev-Test.traefik.wtf`)",
Service: "dev-Test",
Rule: "Host(`dev-Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -564,12 +570,14 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
"Test2": {
Service: "Test2",
Rule: "Host(`Test2.traefik.wtf`)",
Service: "Test2",
Rule: "Host(`Test2.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -641,8 +649,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -704,8 +713,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -764,8 +774,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -819,8 +830,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1101,8 +1113,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1159,8 +1172,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1207,8 +1221,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1262,8 +1277,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Services: map[string]*dynamic.Service{
@ -1329,8 +1345,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{
@ -1399,8 +1416,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1476,8 +1494,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1737,8 +1756,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1790,8 +1810,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -2065,8 +2086,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -2120,6 +2142,7 @@ func Test_buildConfiguration(t *testing.T) {
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
Middlewares: []string{"Middleware1"},
},
},
@ -2539,8 +2562,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -2626,8 +2650,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -2829,12 +2854,14 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
"Test-97077516270503695": {
Service: "Test-97077516270503695",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test-97077516270503695",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},

View file

@ -3,7 +3,6 @@ package consulcatalog
import (
"fmt"
"github.com/hashicorp/consul/agent/connect"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
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 {
spiffeIDService := connect.SpiffeIDService{
Namespace: item.Namespace,
Datacenter: item.Datacenter,
Service: item.Name,
}
spiffeID := fmt.Sprintf("spiffe:///ns/%s/dc/%s/svc/%s",
item.Namespace,
item.Datacenter,
item.Name,
)
return &dynamic.ServersTransport{
// 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{
c.getLeaf(),
},
PeerCertURI: spiffeIDService.URI().String(),
PeerCertURI: spiffeID,
}
}
func (c *connectCert) tcpServersTransport(item itemData) *dynamic.TCPServersTransport {
spiffeIDService := connect.SpiffeIDService{
Namespace: item.Namespace,
Datacenter: item.Datacenter,
Service: item.Name,
}
spiffeID := fmt.Sprintf("spiffe:///ns/%s/dc/%s/svc/%s",
item.Namespace,
item.Datacenter,
item.Name,
)
return &dynamic.TCPServersTransport{
TLS: &dynamic.TLSClientConfig{
@ -88,7 +87,7 @@ func (c *connectCert) tcpServersTransport(item itemData) *dynamic.TCPServersTran
Certificates: traefiktls.Certificates{
c.getLeaf(),
},
PeerCertURI: spiffeIDService.URI().String(),
PeerCertURI: spiffeID,
},
}
}

View file

@ -57,8 +57,9 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`foo.bar`)",
Service: "Test",
Rule: "Host(`foo.bar`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -116,8 +117,9 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.foo.bar`)",
Service: "Test",
Rule: "Host(`Test.foo.bar`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -177,8 +179,9 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: `Host("Test.foo.bar")`,
Service: "Test",
Rule: `Host("Test.foo.bar")`,
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -344,8 +347,9 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test`)",
Service: "Test",
Rule: "Host(`Test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -566,8 +570,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -640,12 +645,14 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
"Test2": {
Service: "Test2",
Rule: "Host(`Test2.traefik.wtf`)",
Service: "Test2",
Rule: "Host(`Test2.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -733,8 +740,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -796,8 +804,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1190,8 +1199,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1275,8 +1285,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1341,8 +1352,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1404,8 +1416,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Services: map[string]*dynamic.Service{
@ -1490,8 +1503,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{
@ -1579,8 +1593,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1681,8 +1696,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -2094,8 +2110,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -2155,8 +2172,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -2417,8 +2435,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -2658,8 +2677,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -2722,6 +2742,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Middlewares: []string{"Middleware1"},
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{
@ -3178,8 +3199,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -3352,8 +3374,9 @@ func TestDynConfBuilder_build(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},

View file

@ -53,8 +53,9 @@ func TestDefaultRule(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`foo.bar`)",
Service: "Test",
Rule: "Host(`foo.bar`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -107,8 +108,9 @@ func TestDefaultRule(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.foo.bar`)",
Service: "Test",
Rule: "Host(`Test.foo.bar`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -163,8 +165,9 @@ func TestDefaultRule(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: `Host("Test.foo.bar")`,
Service: "Test",
Rule: `Host("Test.foo.bar")`,
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -315,8 +318,9 @@ func TestDefaultRule(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test`)",
Service: "Test",
Rule: "Host(`Test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -512,8 +516,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -576,12 +581,14 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
"Test2": {
Service: "Test2",
Rule: "Host(`Test2.traefik.wtf`)",
Service: "Test2",
Rule: "Host(`Test2.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -659,8 +666,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -717,8 +725,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1076,8 +1085,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1146,8 +1156,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1202,8 +1213,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1260,8 +1272,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Services: map[string]*dynamic.Service{
@ -1336,8 +1349,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{
@ -1415,8 +1429,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1502,8 +1517,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1866,8 +1882,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1922,8 +1939,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1978,8 +1996,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -2388,8 +2407,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -2447,6 +2467,7 @@ func Test_buildConfiguration(t *testing.T) {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
Middlewares: []string{"Middleware1"},
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{
@ -2863,8 +2884,9 @@ func Test_buildConfiguration(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
Service: "Service1",
Rule: "Host(`Test.traefik.wtf`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},

View file

@ -156,10 +156,10 @@ func TestProvideWithWatch(t *testing.T) {
require.NotNil(t, conf.Configuration.HTTP)
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)
assert.Equal(t, numServices, 0)
assert.Equal(t, numRouters, 0)
assert.Equal(t, 0, numServices)
assert.Equal(t, 0, numRouters)
require.NotNil(t, conf.Configuration.TLS)
assert.Len(t, conf.Configuration.TLS.Certificates, 0)
assert.Empty(t, conf.Configuration.TLS.Certificates)
case <-timeout:
t.Errorf("timeout while waiting for config")
}

View file

@ -268,5 +268,5 @@ func TestProvider_ProvideConfigurationOnlyOnceIfUnchanged(t *testing.T) {
time.Sleep(time.Second)
assert.Equal(t, 1, len(configurationChan))
assert.Len(t, configurationChan, 1)
}

View file

@ -28,6 +28,7 @@ package versioned
import (
"fmt"
"net/http"
traefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1"
discovery "k8s.io/client-go/discovery"
@ -40,8 +41,7 @@ type Interface interface {
TraefikV1alpha1() traefikv1alpha1.TraefikV1alpha1Interface
}
// Clientset contains the clients for groups. Each group has exactly one
// version included in a Clientset.
// Clientset contains the clients for groups.
type Clientset struct {
*discovery.DiscoveryClient
traefikV1alpha1 *traefikv1alpha1.TraefikV1alpha1Client
@ -63,22 +63,45 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface {
// NewForConfig creates a new Clientset for the given config.
// If config's RateLimiter is not set and QPS and Burst are acceptable,
// 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) {
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.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")
}
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
}
var cs Clientset
var err error
cs.traefikV1alpha1, err = traefikv1alpha1.NewForConfig(&configShallowCopy)
cs.traefikV1alpha1, err = traefikv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient)
if err != nil {
return nil, err
}
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient)
if err != nil {
return nil, err
}
@ -88,11 +111,11 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
// NewForConfigOrDie creates a new Clientset for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *Clientset {
var cs Clientset
cs.traefikV1alpha1 = traefikv1alpha1.NewForConfigOrDie(c)
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
return &cs
cs, err := NewForConfig(c)
if err != nil {
panic(err)
}
return cs
}
// 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
}
var _ clientset.Interface = &Clientset{}
var (
_ clientset.Interface = &Clientset{}
_ testing.FakeClient = &Clientset{}
)
// TraefikV1alpha1 retrieves the TraefikV1alpha1Client
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"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@ -44,9 +43,9 @@ type FakeIngressRoutes struct {
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.
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.
func (c *FakeIngressRoutes) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(ingressroutesResource, c.ns, name), &v1alpha1.IngressRoute{})
Invokes(testing.NewDeleteActionWithOptions(ingressroutesResource, c.ns, name, opts), &v1alpha1.IngressRoute{})
return err
}

View file

@ -32,7 +32,6 @@ import (
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@ -44,9 +43,9 @@ type FakeIngressRouteTCPs struct {
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.
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.
func (c *FakeIngressRouteTCPs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(ingressroutetcpsResource, c.ns, name), &v1alpha1.IngressRouteTCP{})
Invokes(testing.NewDeleteActionWithOptions(ingressroutetcpsResource, c.ns, name, opts), &v1alpha1.IngressRouteTCP{})
return err
}

View file

@ -32,7 +32,6 @@ import (
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@ -44,9 +43,9 @@ type FakeIngressRouteUDPs struct {
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.
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.
func (c *FakeIngressRouteUDPs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(ingressrouteudpsResource, c.ns, name), &v1alpha1.IngressRouteUDP{})
Invokes(testing.NewDeleteActionWithOptions(ingressrouteudpsResource, c.ns, name, opts), &v1alpha1.IngressRouteUDP{})
return err
}

View file

@ -32,7 +32,6 @@ import (
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@ -44,9 +43,9 @@ type FakeMiddlewares struct {
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.
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.
func (c *FakeMiddlewares) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(middlewaresResource, c.ns, name), &v1alpha1.Middleware{})
Invokes(testing.NewDeleteActionWithOptions(middlewaresResource, c.ns, name, opts), &v1alpha1.Middleware{})
return err
}

View file

@ -32,7 +32,6 @@ import (
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@ -44,9 +43,9 @@ type FakeMiddlewareTCPs struct {
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.
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.
func (c *FakeMiddlewareTCPs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(middlewaretcpsResource, c.ns, name), &v1alpha1.MiddlewareTCP{})
Invokes(testing.NewDeleteActionWithOptions(middlewaretcpsResource, c.ns, name, opts), &v1alpha1.MiddlewareTCP{})
return err
}

View file

@ -32,7 +32,6 @@ import (
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@ -44,9 +43,9 @@ type FakeServersTransports struct {
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.
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.
func (c *FakeServersTransports) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(serverstransportsResource, c.ns, name), &v1alpha1.ServersTransport{})
Invokes(testing.NewDeleteActionWithOptions(serverstransportsResource, c.ns, name, opts), &v1alpha1.ServersTransport{})
return err
}

View file

@ -32,7 +32,6 @@ import (
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@ -44,9 +43,9 @@ type FakeServersTransportTCPs struct {
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.
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.
func (c *FakeServersTransportTCPs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(serverstransporttcpsResource, c.ns, name), &v1alpha1.ServersTransportTCP{})
Invokes(testing.NewDeleteActionWithOptions(serverstransporttcpsResource, c.ns, name, opts), &v1alpha1.ServersTransportTCP{})
return err
}

View file

@ -32,7 +32,6 @@ import (
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@ -44,9 +43,9 @@ type FakeTLSOptions struct {
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.
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.
func (c *FakeTLSOptions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(tlsoptionsResource, c.ns, name), &v1alpha1.TLSOption{})
Invokes(testing.NewDeleteActionWithOptions(tlsoptionsResource, c.ns, name, opts), &v1alpha1.TLSOption{})
return err
}

View file

@ -32,7 +32,6 @@ import (
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@ -44,9 +43,9 @@ type FakeTLSStores struct {
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.
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.
func (c *FakeTLSStores) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(tlsstoresResource, c.ns, name), &v1alpha1.TLSStore{})
Invokes(testing.NewDeleteActionWithOptions(tlsstoresResource, c.ns, name, opts), &v1alpha1.TLSStore{})
return err
}

View file

@ -32,7 +32,6 @@ import (
v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@ -44,9 +43,9 @@ type FakeTraefikServices struct {
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.
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.
func (c *FakeTraefikServices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(traefikservicesResource, c.ns, name), &v1alpha1.TraefikService{})
Invokes(testing.NewDeleteActionWithOptions(traefikservicesResource, c.ns, name, opts), &v1alpha1.TraefikService{})
return err
}

View file

@ -27,6 +27,8 @@ THE SOFTWARE.
package v1alpha1
import (
"net/http"
"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"
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 is equivalent to NewForConfigAndClient(c, httpClient),
// where httpClient was generated with rest.HTTPClientFor(c).
func NewForConfig(c *rest.Config) (*TraefikV1alpha1Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
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 {
return nil, err
}

View file

@ -55,6 +55,11 @@ type sharedInformerFactory struct {
// startedInformers is used for tracking which informers have been started.
// This allows Start() to be called multiple times safely.
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.
@ -115,20 +120,39 @@ func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResy
return factory
}
// Start initializes all requested informers.
func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
f.lock.Lock()
defer f.lock.Unlock()
if f.shuttingDown {
return
}
for informerType, informer := range f.informers {
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
}
}
}
// 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 {
informers := func() map[reflect.Type]cache.SharedIndexInformer {
f.lock.Lock()
@ -150,7 +174,7 @@ func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[ref
return res
}
// InternalInformerFor returns the SharedIndexInformer for obj using an internal
// InformerFor returns the SharedIndexInformer for obj using an internal
// client.
func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
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
// 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 {
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
// 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
}

View file

@ -7067,7 +7067,7 @@ func TestCreateBasicAuthCredentials(t *testing.T) {
username = components[0]
hashedPassword = components[1]
assert.Equal(t, username, "test2")
assert.Equal(t, hashedPassword, "$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0")
assert.Equal(t, "test2", username)
assert.Equal(t, "$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", 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
}
require.Len(t, conditions, 0)
require.Empty(t, conditions)
assert.Equal(t, test.wantKinds, got)
})
}

View file

@ -12,7 +12,7 @@ type marshaler interface {
}
type unmarshaler interface {
Unmarshal([]byte) error
Unmarshal(data []byte) error
}
type LoadBalancerIngress interface {

View file

@ -324,7 +324,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
portString := pa.Backend.Service.Port.Name
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)

View file

@ -45,8 +45,9 @@ func Test_defaultRule(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`example.com`)",
Service: "Test",
Rule: "Host(`example.com`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -99,8 +100,9 @@ func Test_defaultRule(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: `Host("Test.example.com")`,
Service: "Test",
Rule: `Host("Test.example.com")`,
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -196,8 +198,9 @@ func Test_defaultRule(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test`)",
Service: "Test",
Rule: "Host(`Test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -270,8 +273,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"dev-Test": {
Service: "dev-Test",
Rule: "Host(`dev-Test.traefik.test`)",
Service: "dev-Test",
Rule: "Host(`dev-Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -328,12 +332,14 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test1": {
Service: "Test1",
Rule: "Host(`Test1.traefik.test`)",
Service: "Test1",
Rule: "Host(`Test1.traefik.test`)",
DefaultRule: true,
},
"Test2": {
Service: "Test2",
Rule: "Host(`Test2.traefik.test`)",
Service: "Test2",
Rule: "Host(`Test2.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -405,8 +411,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -468,8 +475,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -528,8 +536,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -583,8 +592,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.test`)",
Service: "Service1",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -866,8 +876,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.test`)",
Service: "Service1",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -924,8 +935,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.test`)",
Service: "Service1",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -972,8 +984,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.test`)",
Service: "Service1",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1027,8 +1040,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Services: map[string]*dynamic.Service{
@ -1095,8 +1109,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{
@ -1166,8 +1181,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1346,8 +1362,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1399,8 +1416,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.test`)",
Service: "Service1",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1643,8 +1661,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -1699,6 +1718,7 @@ func Test_buildConfig(t *testing.T) {
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
Middlewares: []string{"Middleware1"},
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{
@ -2093,8 +2113,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.test`)",
Service: "Service1",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -2180,8 +2201,9 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Service1",
Rule: "Host(`Test.traefik.test`)",
Service: "Service1",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},
@ -2382,12 +2404,14 @@ func Test_buildConfig(t *testing.T) {
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
Service: "Test",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
"Test-1234154071633021619": {
Service: "Test-1234154071633021619",
Rule: "Host(`Test.traefik.test`)",
Service: "Test-1234154071633021619",
Rule: "Host(`Test.traefik.test`)",
DefaultRule: true,
},
},
Middlewares: map[string]*dynamic.Middleware{},

View file

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

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