1
0
Fork 0

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

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

View file

@ -267,7 +267,7 @@ func TestListenProvidersThrottleProviderConfigReload(t *testing.T) {
providerAggregator := aggregator.ProviderAggregator{}
err := providerAggregator.AddProvider(pvd)
assert.Nil(t, err)
assert.NoError(t, err)
watcher := NewConfigurationWatcher(routinesPool, providerAggregator, []string{}, "")
@ -342,7 +342,7 @@ func TestListenProvidersSkipsSameConfigurationForProvider(t *testing.T) {
// give some time so that the configuration can be processed
time.Sleep(100 * time.Millisecond)
assert.Equal(t, configurationReloads, 1, "Same configuration should not be published multiple times")
assert.Equal(t, 1, configurationReloads, "Same configuration should not be published multiple times")
}
func TestListenProvidersDoesNotSkipFlappingConfiguration(t *testing.T) {
@ -450,7 +450,7 @@ func TestListenProvidersIgnoreSameConfig(t *testing.T) {
providerAggregator := aggregator.ProviderAggregator{}
err := providerAggregator.AddProvider(pvd)
assert.Nil(t, err)
assert.NoError(t, err)
watcher := NewConfigurationWatcher(routinesPool, providerAggregator, []string{"defaultEP"}, "")
@ -593,7 +593,7 @@ func TestListenProvidersIgnoreIntermediateConfigs(t *testing.T) {
providerAggregator := aggregator.ProviderAggregator{}
err := providerAggregator.AddProvider(pvd)
assert.Nil(t, err)
assert.NoError(t, err)
watcher := NewConfigurationWatcher(routinesPool, providerAggregator, []string{"defaultEP"}, "")

View file

@ -12,6 +12,7 @@ import (
"github.com/traefik/traefik/v3/pkg/logs"
"github.com/traefik/traefik/v3/pkg/metrics"
"github.com/traefik/traefik/v3/pkg/middlewares/accesslog"
"github.com/traefik/traefik/v3/pkg/middlewares/denyrouterrecursion"
metricsMiddle "github.com/traefik/traefik/v3/pkg/middlewares/metrics"
"github.com/traefik/traefik/v3/pkg/middlewares/recovery"
"github.com/traefik/traefik/v3/pkg/middlewares/tracing"
@ -207,6 +208,10 @@ func (m *Manager) buildHTTPHandler(ctx context.Context, router *runtime.RouterIn
chain = chain.Append(metricsMiddle.WrapRouterHandler(ctx, m.metricsRegistry, routerName, provider.GetQualifiedName(ctx, router.Service)))
}
if router.DefaultRule {
chain = chain.Append(denyrouterrecursion.WrapHandler(routerName))
}
return chain.Extend(*mHandler).Append(tHandler).Then(sHandler)
}

View file

@ -620,12 +620,12 @@ func Test_Routing(t *testing.T) {
err := check.checkRouter(epListener.Addr().String(), timeout)
if check.expectedError != "" {
require.NotNil(t, err, check.desc)
require.Error(t, err, check.desc)
assert.Contains(t, err.Error(), check.expectedError, check.desc)
continue
}
assert.Nil(t, err, check.desc)
assert.NoError(t, err, check.desc)
}
epListener.Close()

View file

@ -517,7 +517,7 @@ func (c *connectionTracker) Close() {
}
type stoppable interface {
Shutdown(context.Context) error
Shutdown(ctx context.Context) error
Close() error
}
@ -553,6 +553,7 @@ func createHTTPServer(ctx context.Context, ln net.Listener, configuration *stati
return nil, err
}
handler = denyFragment(handler)
if configuration.HTTP.EncodeQuerySemicolons {
handler = encodeQuerySemicolons(handler)
} else {
@ -640,3 +641,20 @@ func encodeQuerySemicolons(h http.Handler) http.Handler {
}
})
}
// When go receives an HTTP request, it assumes the absence of fragment URL.
// However, it is still possible to send a fragment in the request.
// In this case, Traefik will encode the '#' character, altering the request's intended meaning.
// To avoid this behavior, the following function rejects requests that include a fragment in the URL.
func denyFragment(h http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if strings.Contains(req.URL.RawPath, "#") {
log.Debug().Msgf("Rejecting request because it contains a fragment in the URL path: %s", req.URL.RawPath)
rw.WriteHeader(http.StatusBadRequest)
return
}
h.ServeHTTP(rw, req)
})
}

View file

@ -98,7 +98,7 @@ func TestHijack(t *testing.T) {
var mirrorRequest bool
err := mirror.AddMirror(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
hijacker, ok := rw.(http.Hijacker)
assert.Equal(t, true, ok)
assert.True(t, ok)
_, _, err := hijacker.Hijack()
assert.Error(t, err)
@ -109,7 +109,7 @@ func TestHijack(t *testing.T) {
mirror.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest(http.MethodGet, "/", nil))
pool.Stop()
assert.Equal(t, true, mirrorRequest)
assert.True(t, mirrorRequest)
}
func TestFlush(t *testing.T) {
@ -122,7 +122,7 @@ func TestFlush(t *testing.T) {
var mirrorRequest bool
err := mirror.AddMirror(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
hijacker, ok := rw.(http.Flusher)
assert.Equal(t, true, ok)
assert.True(t, ok)
hijacker.Flush()
@ -133,7 +133,7 @@ func TestFlush(t *testing.T) {
mirror.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest(http.MethodGet, "/", nil))
pool.Stop()
assert.Equal(t, true, mirrorRequest)
assert.True(t, mirrorRequest)
}
func TestMirroringWithBody(t *testing.T) {
@ -233,7 +233,7 @@ func TestCloneRequest(t *testing.T) {
_, expectedBytes, err := newReusableRequest(req, 2)
assert.Error(t, err)
assert.Equal(t, bb[:3], expectedBytes)
assert.Equal(t, expectedBytes, bb[:3])
})
t.Run("valid case with maxBodySize", func(t *testing.T) {
@ -258,7 +258,7 @@ func TestCloneRequest(t *testing.T) {
rr, expectedBytes, err := newReusableRequest(req, 20)
assert.NoError(t, err)
assert.Nil(t, expectedBytes)
assert.Len(t, rr.body, 0)
assert.Empty(t, rr.body)
})
t.Run("no request given", func(t *testing.T) {

View file

@ -256,8 +256,8 @@ func TestSticky(t *testing.T) {
assert.Equal(t, 0, recorder.save["first"])
assert.Equal(t, 3, recorder.save["second"])
assert.Equal(t, true, recorder.cookies["test"].HttpOnly)
assert.Equal(t, true, recorder.cookies["test"].Secure)
assert.True(t, recorder.cookies["test"].HttpOnly)
assert.True(t, recorder.cookies["test"].Secure)
assert.Equal(t, http.SameSiteNoneMode, recorder.cookies["test"].SameSite)
}

View file

@ -51,7 +51,7 @@ func TestWebSocketTCPClose(t *testing.T) {
serverErr := <-errChan
var wsErr *gorillawebsocket.CloseError
require.True(t, errors.As(serverErr, &wsErr))
require.ErrorAs(t, serverErr, &wsErr)
assert.Equal(t, 1006, wsErr.Code)
}

View file

@ -2,6 +2,7 @@ package service
import (
"context"
"encoding/hex"
"errors"
"fmt"
"hash/fnv"
@ -287,7 +288,7 @@ func (m *Manager) getLoadBalancerServiceHandler(ctx context.Context, serviceName
hasher := fnv.New64a()
_, _ = hasher.Write([]byte(server.URL)) // this will never return an error.
proxyName := fmt.Sprintf("%x", hasher.Sum(nil))
proxyName := hex.EncodeToString(hasher.Sum(nil))
target, err := url.Parse(server.URL)
if err != nil {

View file

@ -393,7 +393,7 @@ func Test1xxResponses(t *testing.T) {
}
handler, err := sm.getLoadBalancerServiceHandler(context.Background(), "foobar", info)
assert.Nil(t, err)
assert.NoError(t, err)
frontend := httptest.NewServer(handler)
t.Cleanup(frontend.Close)
@ -439,7 +439,7 @@ func Test1xxResponses(t *testing.T) {
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, frontend.URL, nil)
res, err := frontendClient.Do(req)
assert.Nil(t, err)
assert.NoError(t, err)
defer res.Body.Close()

View file

@ -173,7 +173,7 @@ func TestManager_Get(t *testing.T) {
}
require.NoError(t, err)
assert.Equal(t, config.MinVersion, test.expectedMinVersion)
assert.Equal(t, test.expectedMinVersion, config.MinVersion)
})
}
}
@ -317,10 +317,10 @@ func TestClientAuth(t *testing.T) {
if test.expectedRawSubject != nil {
subjects := config.ClientCAs.Subjects()
assert.Len(t, subjects, 1)
assert.Equal(t, subjects[0], test.expectedRawSubject)
assert.Equal(t, test.expectedRawSubject, subjects[0])
}
assert.Equal(t, config.ClientAuth, test.expectedClientAuth)
assert.Equal(t, test.expectedClientAuth, config.ClientAuth)
})
}
}
@ -330,9 +330,9 @@ func TestManager_Get_DefaultValues(t *testing.T) {
// Ensures we won't break things for Traefik users when updating Go
config, _ := tlsManager.Get("default", "default")
assert.Equal(t, config.MinVersion, uint16(tls.VersionTLS12))
assert.Equal(t, config.NextProtos, []string{"h2", "http/1.1", "acme-tls/1"})
assert.Equal(t, config.CipherSuites, []uint16{
assert.Equal(t, uint16(tls.VersionTLS12), config.MinVersion)
assert.Equal(t, []string{"h2", "http/1.1", "acme-tls/1"}, config.NextProtos)
assert.Equal(t, []uint16{
tls.TLS_RSA_WITH_AES_128_CBC_SHA,
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
@ -350,5 +350,5 @@ func TestManager_Get_DefaultValues(t *testing.T) {
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
})
}, config.CipherSuites)
}

View file

@ -48,7 +48,7 @@ func (c *Config) Setup(serviceName string) (opentracing.Tracer, io.Closer, error
logger := log.With().Str(logs.TracingProviderName, Name).Logger()
opts := []datadog.StartOption{
datadog.WithServiceName(serviceName),
datadog.WithService(serviceName),
datadog.WithDebugMode(c.Debug),
datadog.WithPropagator(datadog.NewPropagator(&datadog.PropagatorConfig{
TraceHeader: c.TraceIDHeaderName,

View file

@ -2,7 +2,7 @@ package tracing
import (
"crypto/sha256"
"fmt"
"encoding/hex"
"strings"
"github.com/rs/zerolog/log"
@ -61,5 +61,5 @@ func computeHash(name string) string {
log.Error().Str("OperationName", name).Err(err).Msgf("Failed to create Span name hash for %s", name)
}
return fmt.Sprintf("%x", hash.Sum(nil))[:TraceNameHashLength]
return hex.EncodeToString(hash.Sum(nil))[:TraceNameHashLength]
}

View file

@ -129,7 +129,7 @@ func TestTruncateString(t *testing.T) {
actual := truncateString(test.text, test.limit)
assert.Equal(t, test.expected, actual)
assert.True(t, len(actual) <= test.limit)
assert.LessOrEqual(t, len(actual), test.limit)
})
}
}

View file

@ -220,10 +220,10 @@ func testTimeout(t *testing.T, withRead bool) {
time.Sleep(10 * time.Millisecond)
assert.Equal(t, 10, len(ln.conns))
assert.Len(t, ln.conns, 10)
time.Sleep(ln.timeout + time.Second)
assert.Equal(t, 0, len(ln.conns))
assert.Empty(t, ln.conns)
}
func TestShutdown(t *testing.T) {