Merge v2.4 into master
This commit is contained in:
commit
d211437d6c
80 changed files with 430 additions and 100 deletions
|
@ -8,13 +8,15 @@ import (
|
|||
"github.com/traefik/traefik/v2/pkg/log"
|
||||
"github.com/traefik/traefik/v2/pkg/provider"
|
||||
"github.com/traefik/traefik/v2/pkg/provider/file"
|
||||
"github.com/traefik/traefik/v2/pkg/provider/traefik"
|
||||
"github.com/traefik/traefik/v2/pkg/safe"
|
||||
)
|
||||
|
||||
// ProviderAggregator aggregates providers.
|
||||
type ProviderAggregator struct {
|
||||
fileProvider *file.Provider
|
||||
providers []provider.Provider
|
||||
internalProvider provider.Provider
|
||||
fileProvider provider.Provider
|
||||
providers []provider.Provider
|
||||
}
|
||||
|
||||
// NewProviderAggregator returns an aggregate of all the providers configured in the static configuration.
|
||||
|
@ -98,11 +100,15 @@ func (p *ProviderAggregator) AddProvider(provider provider.Provider) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if fileProvider, ok := provider.(*file.Provider); ok {
|
||||
p.fileProvider = fileProvider
|
||||
} else {
|
||||
switch provider.(type) {
|
||||
case *file.Provider:
|
||||
p.fileProvider = provider
|
||||
case *traefik.Provider:
|
||||
p.internalProvider = provider
|
||||
default:
|
||||
p.providers = append(p.providers, provider)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -113,6 +119,10 @@ func (p ProviderAggregator) Init() error {
|
|||
|
||||
// Provide calls the provide method of every providers.
|
||||
func (p ProviderAggregator) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error {
|
||||
if p.internalProvider != nil {
|
||||
launchProvider(configurationChan, pool, p.internalProvider)
|
||||
}
|
||||
|
||||
if p.fileProvider != nil {
|
||||
launchProvider(configurationChan, pool, p.fileProvider)
|
||||
}
|
||||
|
@ -123,6 +133,7 @@ func (p ProviderAggregator) Provide(configurationChan chan<- dynamic.Message, po
|
|||
launchProvider(configurationChan, pool, prd)
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
79
pkg/provider/aggregator/aggregator_test.go
Normal file
79
pkg/provider/aggregator/aggregator_test.go
Normal file
|
@ -0,0 +1,79 @@
|
|||
package aggregator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v2/pkg/provider"
|
||||
"github.com/traefik/traefik/v2/pkg/safe"
|
||||
)
|
||||
|
||||
func TestProviderAggregator_Provide(t *testing.T) {
|
||||
aggregator := ProviderAggregator{
|
||||
internalProvider: &providerMock{"internal"},
|
||||
fileProvider: &providerMock{"file"},
|
||||
providers: []provider.Provider{
|
||||
&providerMock{"salad"},
|
||||
&providerMock{"tomato"},
|
||||
&providerMock{"onion"},
|
||||
},
|
||||
}
|
||||
|
||||
cfgCh := make(chan dynamic.Message)
|
||||
errCh := make(chan error)
|
||||
pool := safe.NewPool(context.Background())
|
||||
|
||||
t.Cleanup(pool.Stop)
|
||||
|
||||
go func() {
|
||||
errCh <- aggregator.Provide(cfgCh, pool)
|
||||
}()
|
||||
|
||||
// Make sure the internal provider is always called first, followed by the file provider.
|
||||
requireReceivedMessageFromProviders(t, cfgCh, []string{"internal"})
|
||||
requireReceivedMessageFromProviders(t, cfgCh, []string{"file"})
|
||||
|
||||
// Check if all providers have been called, the order doesn't matter.
|
||||
requireReceivedMessageFromProviders(t, cfgCh, []string{"salad", "tomato", "onion"})
|
||||
|
||||
require.NoError(t, <-errCh)
|
||||
}
|
||||
|
||||
// requireReceivedMessageFromProviders makes sure the given providers have emitted a message on the given message channel.
|
||||
// Providers order is not enforced.
|
||||
func requireReceivedMessageFromProviders(t *testing.T, cfgCh <-chan dynamic.Message, names []string) {
|
||||
t.Helper()
|
||||
|
||||
var msg dynamic.Message
|
||||
var receivedMessagesFrom []string
|
||||
|
||||
for range names {
|
||||
select {
|
||||
case <-time.After(10 * time.Millisecond):
|
||||
case msg = <-cfgCh:
|
||||
receivedMessagesFrom = append(receivedMessagesFrom, msg.ProviderName)
|
||||
}
|
||||
}
|
||||
|
||||
require.ElementsMatch(t, names, receivedMessagesFrom)
|
||||
}
|
||||
|
||||
type providerMock struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (p *providerMock) Init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *providerMock) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error {
|
||||
configurationChan <- dynamic.Message{
|
||||
ProviderName: p.Name,
|
||||
Configuration: &dynamic.Configuration{},
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -42,7 +42,7 @@ type Provider struct {
|
|||
Constraints string `description:"Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container." json:"constraints,omitempty" toml:"constraints,omitempty" yaml:"constraints,omitempty" export:"true"`
|
||||
Endpoint *EndpointConfig `description:"Consul endpoint settings" json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty" export:"true"`
|
||||
Prefix string `description:"Prefix for consul service tags. Default 'traefik'" json:"prefix,omitempty" toml:"prefix,omitempty" yaml:"prefix,omitempty" export:"true"`
|
||||
RefreshInterval ptypes.Duration `description:"Interval for check Consul API. Default 100ms" json:"refreshInterval,omitempty" toml:"refreshInterval,omitempty" yaml:"refreshInterval,omitempty" export:"true"`
|
||||
RefreshInterval ptypes.Duration `description:"Interval for check Consul API. Default 15s" json:"refreshInterval,omitempty" toml:"refreshInterval,omitempty" yaml:"refreshInterval,omitempty" export:"true"`
|
||||
RequireConsistent bool `description:"Forces the read to be fully consistent." json:"requireConsistent,omitempty" toml:"requireConsistent,omitempty" yaml:"requireConsistent,omitempty" export:"true"`
|
||||
Stale bool `description:"Use stale consistency for catalog reads." json:"stale,omitempty" toml:"stale,omitempty" yaml:"stale,omitempty" export:"true"`
|
||||
Cache bool `description:"Use local agent caching for catalog reads." json:"cache,omitempty" toml:"cache,omitempty" yaml:"cache,omitempty" export:"true"`
|
||||
|
|
|
@ -56,7 +56,7 @@ func (reh *resourceEventHandler) OnDelete(obj interface{}) {
|
|||
type Client interface {
|
||||
WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error)
|
||||
GetIngresses() []*networkingv1beta1.Ingress
|
||||
GetIngressClass() (*networkingv1beta1.IngressClass, error)
|
||||
GetIngressClasses() ([]*networkingv1beta1.IngressClass, error)
|
||||
GetService(namespace, name string) (*corev1.Service, bool, error)
|
||||
GetSecret(namespace, name string) (*corev1.Secret, bool, error)
|
||||
GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error)
|
||||
|
@ -393,9 +393,9 @@ func (c *clientWrapper) GetSecret(namespace, name string) (*corev1.Secret, bool,
|
|||
return secret, exist, err
|
||||
}
|
||||
|
||||
func (c *clientWrapper) GetIngressClass() (*networkingv1beta1.IngressClass, error) {
|
||||
func (c *clientWrapper) GetIngressClasses() ([]*networkingv1beta1.IngressClass, error) {
|
||||
if c.clusterFactory == nil {
|
||||
return nil, errors.New("failed to find ingressClass: factory not loaded")
|
||||
return nil, errors.New("cluster factory not loaded")
|
||||
}
|
||||
|
||||
ingressClasses, err := c.clusterFactory.Networking().V1beta1().IngressClasses().Lister().List(labels.Everything())
|
||||
|
@ -403,13 +403,14 @@ func (c *clientWrapper) GetIngressClass() (*networkingv1beta1.IngressClass, erro
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var ics []*networkingv1beta1.IngressClass
|
||||
for _, ic := range ingressClasses {
|
||||
if ic.Spec.Controller == traefikDefaultIngressClassController {
|
||||
return ic, nil
|
||||
ics = append(ics, ic)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
return ics, nil
|
||||
}
|
||||
|
||||
// lookupNamespace returns the lookup namespace key for the given namespace.
|
||||
|
|
|
@ -14,11 +14,11 @@ import (
|
|||
var _ Client = (*clientMock)(nil)
|
||||
|
||||
type clientMock struct {
|
||||
ingresses []*networkingv1beta1.Ingress
|
||||
services []*corev1.Service
|
||||
secrets []*corev1.Secret
|
||||
endpoints []*corev1.Endpoints
|
||||
ingressClass *networkingv1beta1.IngressClass
|
||||
ingresses []*networkingv1beta1.Ingress
|
||||
services []*corev1.Service
|
||||
secrets []*corev1.Secret
|
||||
endpoints []*corev1.Endpoints
|
||||
ingressClasses []*networkingv1beta1.IngressClass
|
||||
|
||||
serverVersion *version.Version
|
||||
|
||||
|
@ -59,7 +59,7 @@ func newClientMock(serverVersion string, paths ...string) clientMock {
|
|||
}
|
||||
c.ingresses = append(c.ingresses, ing)
|
||||
case *networkingv1beta1.IngressClass:
|
||||
c.ingressClass = o
|
||||
c.ingressClasses = append(c.ingressClasses, o)
|
||||
default:
|
||||
panic(fmt.Sprintf("Unknown runtime object %+v %T", o, o))
|
||||
}
|
||||
|
@ -117,8 +117,8 @@ func (c clientMock) GetSecret(namespace, name string) (*corev1.Secret, bool, err
|
|||
return nil, false, nil
|
||||
}
|
||||
|
||||
func (c clientMock) GetIngressClass() (*networkingv1beta1.IngressClass, error) {
|
||||
return c.ingressClass, nil
|
||||
func (c clientMock) GetIngressClasses() ([]*networkingv1beta1.IngressClass, error) {
|
||||
return c.ingressClasses, nil
|
||||
}
|
||||
|
||||
func (c clientMock) WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error) {
|
||||
|
|
|
@ -8,7 +8,7 @@ spec:
|
|||
ports:
|
||||
- name: tchouk
|
||||
port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
||||
---
|
||||
kind: Service
|
||||
|
@ -21,4 +21,4 @@ spec:
|
|||
ports:
|
||||
- name: tchouk
|
||||
port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,7 +7,7 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
||||
---
|
||||
kind: Service
|
||||
|
@ -19,4 +19,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -8,7 +8,7 @@ spec:
|
|||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
clusterIp: "fc00:f853:ccd:e793::1"
|
||||
clusterIP: "fc00:f853:ccd:e793::1"
|
||||
type: ClusterIP
|
||||
|
||||
---
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -8,4 +8,4 @@ spec:
|
|||
ports:
|
||||
- port: 443
|
||||
targetPort: 8443
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -9,4 +9,4 @@ spec:
|
|||
- name: https
|
||||
protocol: ""
|
||||
port: 8443
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -9,4 +9,4 @@ spec:
|
|||
- name: https-foo
|
||||
protocol: ""
|
||||
port: 8443
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -8,4 +8,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -17,4 +17,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -8,5 +8,5 @@ spec:
|
|||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
type: ClusterIP
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -10,5 +10,5 @@ spec:
|
|||
port: 8082
|
||||
- name: tchouk
|
||||
port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
||||
|
|
|
@ -10,5 +10,5 @@ spec:
|
|||
port: 8082
|
||||
- name: tchouk
|
||||
port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 8080
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
type: ExternalName
|
||||
externalName: traefik.wtf
|
||||
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -10,5 +10,5 @@ spec:
|
|||
port: 8082
|
||||
- name: tchouk
|
||||
port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
||||
---
|
||||
kind: Service
|
||||
|
@ -19,4 +19,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 8082
|
||||
clusterIp: 10.1.0.1
|
||||
clusterIP: 10.1.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -8,4 +8,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -10,5 +10,5 @@ spec:
|
|||
port: 8082
|
||||
- name: tchouk
|
||||
port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -8,7 +8,7 @@ spec:
|
|||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
type: ClusterIP
|
||||
|
||||
---
|
||||
|
@ -22,5 +22,5 @@ spec:
|
|||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
clusterIp: 10.0.0.2
|
||||
clusterIP: 10.0.0.2
|
||||
type: ClusterIP
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
kind: Endpoints
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: service1
|
||||
namespace: testing
|
||||
|
||||
subsets:
|
||||
- addresses:
|
||||
- ip: 10.10.0.1
|
||||
ports:
|
||||
- port: 8080
|
|
@ -0,0 +1,30 @@
|
|||
kind: Ingress
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: ""
|
||||
namespace: testing
|
||||
spec:
|
||||
ingressClassName: traefik-lb
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /bar
|
||||
backend:
|
||||
serviceName: service1
|
||||
servicePort: 80
|
||||
|
||||
---
|
||||
kind: Ingress
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: ""
|
||||
namespace: testing
|
||||
spec:
|
||||
ingressClassName: traefik-lb2
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /foo
|
||||
backend:
|
||||
serviceName: service1
|
||||
servicePort: 80
|
|
@ -0,0 +1,14 @@
|
|||
apiVersion: networking.k8s.io/v1beta1
|
||||
kind: IngressClass
|
||||
metadata:
|
||||
name: traefik-lb2
|
||||
spec:
|
||||
controller: traefik.io/ingress-controller
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
kind: IngressClass
|
||||
metadata:
|
||||
name: traefik-lb
|
||||
spec:
|
||||
controller: traefik.io/ingress-controller
|
|
@ -0,0 +1,10 @@
|
|||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: service1
|
||||
namespace: testing
|
||||
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIP: 10.0.0.1
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIp: 10.0.0.1
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
|
@ -190,15 +190,15 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
|
|||
return conf
|
||||
}
|
||||
|
||||
var ingressClass *networkingv1beta1.IngressClass
|
||||
var ingressClasses []*networkingv1beta1.IngressClass
|
||||
|
||||
if supportsIngressClass(serverVersion) {
|
||||
ic, err := client.GetIngressClass()
|
||||
ics, err := client.GetIngressClasses()
|
||||
if err != nil {
|
||||
log.FromContext(ctx).Warnf("Failed to find an ingress class: %v", err)
|
||||
log.FromContext(ctx).Warnf("Failed to list ingress classes: %v", err)
|
||||
}
|
||||
|
||||
ingressClass = ic
|
||||
ingressClasses = ics
|
||||
}
|
||||
|
||||
ingresses := client.GetIngresses()
|
||||
|
@ -207,7 +207,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
|
|||
for _, ingress := range ingresses {
|
||||
ctx = log.With(ctx, log.Str("ingress", ingress.Name), log.Str("namespace", ingress.Namespace))
|
||||
|
||||
if !p.shouldProcessIngress(p.IngressClass, ingress, ingressClass) {
|
||||
if !p.shouldProcessIngress(ingress, ingressClasses) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -351,14 +351,20 @@ func (p *Provider) updateIngressStatus(ing *networkingv1beta1.Ingress, k8sClient
|
|||
return k8sClient.UpdateIngressStatus(ing, service.Status.LoadBalancer.Ingress)
|
||||
}
|
||||
|
||||
func (p *Provider) shouldProcessIngress(providerIngressClass string, ingress *networkingv1beta1.Ingress, ingressClass *networkingv1beta1.IngressClass) bool {
|
||||
func (p *Provider) shouldProcessIngress(ingress *networkingv1beta1.Ingress, ingressClasses []*networkingv1beta1.IngressClass) bool {
|
||||
// configuration through the new kubernetes ingressClass
|
||||
if ingress.Spec.IngressClassName != nil {
|
||||
return ingressClass != nil && ingressClass.ObjectMeta.Name == *ingress.Spec.IngressClassName
|
||||
for _, ic := range ingressClasses {
|
||||
if *ingress.Spec.IngressClassName == ic.ObjectMeta.Name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return providerIngressClass == ingress.Annotations[annotationKubernetesIngressClass] ||
|
||||
len(providerIngressClass) == 0 && ingress.Annotations[annotationKubernetesIngressClass] == traefikDefaultIngressClass
|
||||
return p.IngressClass == ingress.Annotations[annotationKubernetesIngressClass] ||
|
||||
len(p.IngressClass) == 0 && ingress.Annotations[annotationKubernetesIngressClass] == traefikDefaultIngressClass
|
||||
}
|
||||
|
||||
func buildHostRule(host string) string {
|
||||
|
|
|
@ -1061,6 +1061,38 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "v18 Ingress with multiple ingressClasses",
|
||||
serverVersion: "v1.18",
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"testing-foo": {
|
||||
Rule: "PathPrefix(`/foo`)",
|
||||
Service: "testing-service1-80",
|
||||
},
|
||||
"testing-bar": {
|
||||
Rule: "PathPrefix(`/bar`)",
|
||||
Service: "testing-service1-80",
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:8080",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "v18 Ingress with no pathType",
|
||||
serverVersion: "v1.18",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue