1
0
Fork 0

Add a new protocol

Co-authored-by: Gérald Croës <gerald@containo.us>
This commit is contained in:
Julien Salleyron 2019-03-14 09:30:04 +01:00 committed by Traefiker Bot
parent 0ca2149408
commit 4a68d29ce2
231 changed files with 6895 additions and 4395 deletions

View file

@ -14,7 +14,7 @@ import (
var _ Store = (*LocalStore)(nil)
// LocalStore Store implementation for local file
// LocalStore Stores implementation for local file
type LocalStore struct {
filename string
storedData *StoredData

View file

@ -47,7 +47,6 @@ type Configuration struct {
EntryPoint string `description:"EntryPoint to use."`
KeyType string `description:"KeyType used for generating certificate private key. Allow value 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'. Default to 'RSA4096'"`
OnHostRule bool `description:"Enable certificate generation on frontends Host rules."`
OnDemand bool `description:"Enable on demand certificate generation. This will request a certificate from Let's Encrypt during the first TLS handshake for a hostname that does not yet have a certificate."` // Deprecated
DNSChallenge *DNSChallenge `description:"Activate DNS-01 Challenge"`
HTTPChallenge *HTTPChallenge `description:"Activate HTTP-01 Challenge"`
TLSChallenge *TLSChallenge `description:"Activate TLS-ALPN-01 Challenge"`
@ -89,7 +88,7 @@ type Provider struct {
client *lego.Client
certsChan chan *Certificate
configurationChan chan<- config.Message
certificateStore *traefiktls.CertificateStore
tlsManager *traefiktls.Manager
clientMutex sync.Mutex
configFromListenerChan chan config.Configuration
pool *safe.Pool
@ -97,16 +96,16 @@ type Provider struct {
resolvingDomainsMutex sync.RWMutex
}
// SetTLSManager sets the tls manager to use
func (p *Provider) SetTLSManager(tlsManager *traefiktls.Manager) {
p.tlsManager = tlsManager
}
// SetConfigListenerChan initializes the configFromListenerChan
func (p *Provider) SetConfigListenerChan(configFromListenerChan chan config.Configuration) {
p.configFromListenerChan = configFromListenerChan
}
// SetCertificateStore allow to initialize certificate store
func (p *Provider) SetCertificateStore(certificateStore *traefiktls.CertificateStore) {
p.certificateStore = certificateStore
}
// ListenConfiguration sets a new Configuration into the configFromListenerChan
func (p *Provider) ListenConfiguration(config config.Configuration) {
p.configFromListenerChan <- config
@ -128,6 +127,7 @@ func (p *Provider) ListenRequest(domain string) (*tls.Certificate, error) {
// Init for compatibility reason the BaseProvider implements an empty Init
func (p *Provider) Init() error {
ctx := log.With(context.Background(), log.Str(log.ProviderName, "acme"))
logger := log.FromContext(ctx)
@ -137,9 +137,10 @@ func (p *Provider) Init() error {
legolog.Logger = fmtlog.New(ioutil.Discard, "", 0)
}
if p.Store == nil {
return errors.New("no store found for the ACME provider")
if len(p.Configuration.Storage) == 0 {
return errors.New("unable to initialize ACME provider with no storage location for the certificates")
}
p.Store = NewLocalStore(p.Configuration.Storage)
var err error
p.account, err = p.Store.GetAccount()
@ -352,40 +353,56 @@ func (p *Provider) initAccount(ctx context.Context) (*Account, error) {
return p.account, nil
}
func (p *Provider) resolveDomains(ctx context.Context, domains []string) {
if len(domains) == 0 {
log.FromContext(ctx).Debug("No domain parsed in provider ACME")
return
}
log.FromContext(ctx).Debugf("Try to challenge certificate for domain %v founded in HostSNI rule", domains)
var domain types.Domain
if len(domains) > 0 {
domain = types.Domain{Main: domains[0]}
if len(domains) > 1 {
domain.SANs = domains[1:]
}
safe.Go(func() {
if _, err := p.resolveCertificate(ctx, domain, false); err != nil {
log.FromContext(ctx).Errorf("Unable to obtain ACME certificate for domains %q: %v", strings.Join(domains, ","), err)
}
})
}
}
func (p *Provider) watchNewDomains(ctx context.Context) {
p.pool.Go(func(stop chan bool) {
for {
select {
case config := <-p.configFromListenerChan:
for routerName, route := range config.Routers {
logger := log.FromContext(ctx).WithField(log.RouterName, routerName)
if config.TCP != nil {
for routerName, route := range config.TCP.Routers {
ctxRouter := log.With(ctx, log.Str(log.RouterName, routerName), log.Str(log.Rule, route.Rule))
domains, err := rules.ParseHostSNI(route.Rule)
if err != nil {
log.FromContext(ctxRouter).Errorf("Error parsing domains in provider ACME: %v", err)
continue
}
p.resolveDomains(ctxRouter, domains)
}
}
for routerName, route := range config.HTTP.Routers {
ctxRouter := log.With(ctx, log.Str(log.RouterName, routerName), log.Str(log.Rule, route.Rule))
domains, err := rules.ParseDomains(route.Rule)
if err != nil {
logger.Errorf("Error parsing domains in provider ACME: %v", err)
log.FromContext(ctxRouter).Errorf("Error parsing domains in provider ACME: %v", err)
continue
}
if len(domains) == 0 {
logger.Debugf("No domain parsed in rule %q in provider ACME", route.Rule)
continue
}
logger.Debugf("Try to challenge certificate for domain %v founded in Host rule", domains)
var domain types.Domain
if len(domains) > 0 {
domain = types.Domain{Main: domains[0]}
if len(domains) > 1 {
domain.SANs = domains[1:]
}
safe.Go(func() {
if _, err := p.resolveCertificate(ctx, domain, false); err != nil {
logger.Errorf("Unable to obtain ACME certificate for domains %q detected thanks to rule %q : %v", strings.Join(domains, ","), route.Rule, err)
}
})
}
p.resolveDomains(ctxRouter, domains)
}
case <-stop:
return
@ -635,16 +652,18 @@ func (p *Provider) refreshCertificates() {
conf := config.Message{
ProviderName: "ACME",
Configuration: &config.Configuration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
TLS: []*traefiktls.Configuration{},
HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
},
TLS: []*traefiktls.Configuration{},
},
}
for _, cert := range p.certificates {
cert := &traefiktls.Certificate{CertFile: traefiktls.FileOrContent(cert.Certificate), KeyFile: traefiktls.FileOrContent(cert.Key)}
conf.Configuration.TLS = append(conf.Configuration.TLS, &traefiktls.Configuration{Certificate: cert, EntryPoints: []string{p.EntryPoint}})
conf.Configuration.TLS = append(conf.Configuration.TLS, &traefiktls.Configuration{Certificate: cert})
}
p.configurationChan <- conf
}
@ -695,7 +714,7 @@ func (p *Provider) getUncheckedDomains(ctx context.Context, domainsToCheck []str
log.FromContext(ctx).Debugf("Looking for provided certificate(s) to validate %q...", domainsToCheck)
allDomains := p.certificateStore.GetAllDomains()
allDomains := p.tlsManager.GetStore("default").GetAllDomains()
// Get ACME certificates
for _, cert := range p.certificates {

View file

@ -6,13 +6,13 @@ import (
"testing"
"github.com/containous/traefik/safe"
traefiktls "github.com/containous/traefik/tls"
"github.com/containous/traefik/types"
"github.com/stretchr/testify/assert"
"github.com/xenolf/lego/certcrypto"
)
func TestGetUncheckedCertificates(t *testing.T) {
t.Skip("Needs TLS Manager")
wildcardMap := make(map[string]*tls.Certificate)
wildcardMap["*.traefik.wtf"] = &tls.Certificate{}
@ -164,9 +164,9 @@ func TestGetUncheckedCertificates(t *testing.T) {
}
acmeProvider := Provider{
certificateStore: &traefiktls.CertificateStore{
DynamicCerts: test.dynamicCerts,
},
// certificateStore: &traefiktls.CertificateStore{
// DynamicCerts: test.dynamicCerts,
// },
certificates: test.acmeCertificates,
resolvingDomains: test.resolvingDomains,
}

View file

@ -1,6 +1,6 @@
package acme
// StoredData represents the data managed by the Store
// StoredData represents the data managed by Store
type StoredData struct {
Account *Account
Certificates []*Certificate
@ -8,7 +8,7 @@ type StoredData struct {
TLSChallenges map[string]*Certificate
}
// Store is a generic interface to represents a storage
// Store is a generic interface that represents a storage
type Store interface {
GetAccount() (*Account, error)
SaveAccount(*Account) error

View file

@ -7,12 +7,14 @@ import (
"github.com/containous/traefik/config/static"
"github.com/containous/traefik/log"
"github.com/containous/traefik/provider"
"github.com/containous/traefik/provider/file"
"github.com/containous/traefik/safe"
)
// ProviderAggregator aggregates providers.
type ProviderAggregator struct {
providers []provider.Provider
fileProvider *file.Provider
providers []provider.Provider
}
// NewProviderAggregator returns an aggregate of all the providers configured in the static configuration.
@ -55,7 +57,12 @@ func (p *ProviderAggregator) AddProvider(provider provider.Provider) error {
if err != nil {
return err
}
p.providers = append(p.providers, provider)
if fileProvider, ok := provider.(*file.Provider); ok {
p.fileProvider = fileProvider
} else {
p.providers = append(p.providers, provider)
}
return nil
}
@ -66,19 +73,29 @@ func (p ProviderAggregator) Init() error {
// Provide calls the provide method of every providers
func (p ProviderAggregator) Provide(configurationChan chan<- config.Message, pool *safe.Pool) error {
if p.fileProvider != nil {
launchProvider(configurationChan, pool, p.fileProvider)
}
for _, prd := range p.providers {
jsonConf, err := json.Marshal(prd)
if err != nil {
log.WithoutContext().Debugf("Cannot marshal the provider configuration %T: %v", prd, err)
}
log.WithoutContext().Infof("Starting provider %T %s", prd, jsonConf)
currentProvider := prd
safe.Go(func() {
err := currentProvider.Provide(configurationChan, pool)
if err != nil {
log.WithoutContext().Errorf("Cannot start the provider %T: %v", prd, err)
}
launchProvider(configurationChan, pool, prd)
})
}
return nil
}
func launchProvider(configurationChan chan<- config.Message, pool *safe.Pool, prd provider.Provider) {
jsonConf, err := json.Marshal(prd)
if err != nil {
log.WithoutContext().Debugf("Cannot marshal the provider configuration %T: %v", prd, err)
}
log.WithoutContext().Infof("Starting provider %T %s", prd, jsonConf)
currentProvider := prd
err = currentProvider.Provide(configurationChan, pool)
if err != nil {
log.WithoutContext().Errorf("Cannot start the provider %T: %v", prd, err)
}
}

View file

@ -9,6 +9,7 @@ import (
"github.com/Masterminds/sprig"
"github.com/containous/traefik/config"
"github.com/containous/traefik/log"
"github.com/containous/traefik/tls"
"github.com/containous/traefik/types"
)
@ -79,7 +80,20 @@ func (p *BaseProvider) CreateConfiguration(tmplContent string, funcMap template.
// DecodeConfiguration Decodes a *types.Configuration from a content.
func (p *BaseProvider) DecodeConfiguration(content string) (*config.Configuration, error) {
configuration := new(config.Configuration)
configuration := &config.Configuration{
HTTP: &config.HTTPConfiguration{
Routers: make(map[string]*config.Router),
Middlewares: make(map[string]*config.Middleware),
Services: make(map[string]*config.Service),
},
TCP: &config.TCPConfiguration{
Routers: make(map[string]*config.TCPRouter),
Services: make(map[string]*config.TCPService),
},
TLS: make([]*tls.Configuration, 0),
TLSStores: make(map[string]tls.Store),
TLSOptions: make(map[string]tls.TLS),
}
if _, err := toml.Decode(content, configuration); err != nil {
return nil, err
}

View file

@ -19,9 +19,15 @@ func Merge(ctx context.Context, configurations map[string]*config.Configuration)
logger := log.FromContext(ctx)
configuration := &config.Configuration{
Routers: make(map[string]*config.Router),
Middlewares: make(map[string]*config.Middleware),
Services: make(map[string]*config.Service),
HTTP: &config.HTTPConfiguration{
Routers: make(map[string]*config.Router),
Middlewares: make(map[string]*config.Middleware),
Services: make(map[string]*config.Service),
},
TCP: &config.TCPConfiguration{
Routers: make(map[string]*config.TCPRouter),
Services: make(map[string]*config.TCPService),
},
}
servicesToDelete := map[string]struct{}{}
@ -41,23 +47,23 @@ func Merge(ctx context.Context, configurations map[string]*config.Configuration)
for _, root := range sortedKeys {
conf := configurations[root]
for serviceName, service := range conf.Services {
for serviceName, service := range conf.HTTP.Services {
services[serviceName] = append(services[serviceName], root)
if !AddService(configuration, serviceName, service) {
if !AddService(configuration.HTTP, serviceName, service) {
servicesToDelete[serviceName] = struct{}{}
}
}
for routerName, router := range conf.Routers {
for routerName, router := range conf.HTTP.Routers {
routers[routerName] = append(routers[routerName], root)
if !AddRouter(configuration, routerName, router) {
if !AddRouter(configuration.HTTP, routerName, router) {
routersToDelete[routerName] = struct{}{}
}
}
for middlewareName, middleware := range conf.Middlewares {
for middlewareName, middleware := range conf.HTTP.Middlewares {
middlewares[middlewareName] = append(middlewares[middlewareName], root)
if !AddMiddleware(configuration, middlewareName, middleware) {
if !AddMiddleware(configuration.HTTP, middlewareName, middleware) {
middlewaresToDelete[middlewareName] = struct{}{}
}
}
@ -66,26 +72,26 @@ func Merge(ctx context.Context, configurations map[string]*config.Configuration)
for serviceName := range servicesToDelete {
logger.WithField(log.ServiceName, serviceName).
Errorf("Service defined multiple times with different configurations in %v", services[serviceName])
delete(configuration.Services, serviceName)
delete(configuration.HTTP.Services, serviceName)
}
for routerName := range routersToDelete {
logger.WithField(log.RouterName, routerName).
Errorf("Router defined multiple times with different configurations in %v", routers[routerName])
delete(configuration.Routers, routerName)
delete(configuration.HTTP.Routers, routerName)
}
for middlewareName := range middlewaresToDelete {
logger.WithField(log.MiddlewareName, middlewareName).
Errorf("Middleware defined multiple times with different configurations in %v", middlewares[middlewareName])
delete(configuration.Middlewares, middlewareName)
delete(configuration.HTTP.Middlewares, middlewareName)
}
return configuration
}
// AddService Adds a service to a configurations.
func AddService(configuration *config.Configuration, serviceName string, service *config.Service) bool {
func AddService(configuration *config.HTTPConfiguration, serviceName string, service *config.Service) bool {
if _, ok := configuration.Services[serviceName]; !ok {
configuration.Services[serviceName] = service
return true
@ -100,7 +106,7 @@ func AddService(configuration *config.Configuration, serviceName string, service
}
// AddRouter Adds a router to a configurations.
func AddRouter(configuration *config.Configuration, routerName string, router *config.Router) bool {
func AddRouter(configuration *config.HTTPConfiguration, routerName string, router *config.Router) bool {
if _, ok := configuration.Routers[routerName]; !ok {
configuration.Routers[routerName] = router
return true
@ -110,7 +116,7 @@ func AddRouter(configuration *config.Configuration, routerName string, router *c
}
// AddMiddleware Adds a middleware to a configurations.
func AddMiddleware(configuration *config.Configuration, middlewareName string, middleware *config.Middleware) bool {
func AddMiddleware(configuration *config.HTTPConfiguration, middlewareName string, middleware *config.Middleware) bool {
if _, ok := configuration.Middlewares[middlewareName]; !ok {
configuration.Middlewares[middlewareName] = middleware
return true
@ -132,7 +138,7 @@ func MakeDefaultRuleTemplate(defaultRule string, funcMap template.FuncMap) (*tem
}
// BuildRouterConfiguration Builds a router configuration.
func BuildRouterConfiguration(ctx context.Context, configuration *config.Configuration, defaultRouterName string, defaultRuleTpl *template.Template, model interface{}) {
func BuildRouterConfiguration(ctx context.Context, configuration *config.HTTPConfiguration, defaultRouterName string, defaultRuleTpl *template.Template, model interface{}) {
logger := log.FromContext(ctx)
if len(configuration.Routers) == 0 {

View file

@ -33,7 +33,7 @@ func (p *Provider) buildConfiguration(ctx context.Context, containersInspected [
continue
}
err = p.buildServiceConfiguration(ctxContainer, container, confFromLabel)
err = p.buildServiceConfiguration(ctxContainer, container, confFromLabel.HTTP)
if err != nil {
logger.Error(err)
continue
@ -49,7 +49,7 @@ func (p *Provider) buildConfiguration(ctx context.Context, containersInspected [
Labels: container.Labels,
}
provider.BuildRouterConfiguration(ctx, confFromLabel, serviceName, p.defaultRuleTpl, model)
provider.BuildRouterConfiguration(ctx, confFromLabel.HTTP, serviceName, p.defaultRuleTpl, model)
configurations[containerName] = confFromLabel
}
@ -57,7 +57,7 @@ func (p *Provider) buildConfiguration(ctx context.Context, containersInspected [
return provider.Merge(ctx, configurations)
}
func (p *Provider) buildServiceConfiguration(ctx context.Context, container dockerData, configuration *config.Configuration) error {
func (p *Provider) buildServiceConfiguration(ctx context.Context, container dockerData, configuration *config.HTTPConfiguration) error {
serviceName := getServiceName(container)
if len(configuration.Services) == 0 {

View file

@ -19,7 +19,7 @@ func TestDefaultRule(t *testing.T) {
desc string
containers []dockerData
defaultRule string
expected *config.Configuration
expected *config.HTTPConfiguration
}{
{
desc: "default rule with no variable",
@ -42,7 +42,7 @@ func TestDefaultRule(t *testing.T) {
},
},
defaultRule: "Host(`foo.bar`)",
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Test",
@ -87,7 +87,7 @@ func TestDefaultRule(t *testing.T) {
},
},
defaultRule: "Host(`{{ .Name }}.foo.bar`)",
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Test",
@ -134,7 +134,7 @@ func TestDefaultRule(t *testing.T) {
},
},
defaultRule: `Host("{{ .Name }}.{{ index .Labels "traefik.domain" }}")`,
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Test",
@ -179,7 +179,7 @@ func TestDefaultRule(t *testing.T) {
},
},
defaultRule: `Host("{{ .Toto }}")`,
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{
@ -219,7 +219,7 @@ func TestDefaultRule(t *testing.T) {
},
},
defaultRule: ``,
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{
@ -259,7 +259,7 @@ func TestDefaultRule(t *testing.T) {
},
},
defaultRule: DefaultTemplateRule,
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Test",
@ -307,7 +307,7 @@ func TestDefaultRule(t *testing.T) {
configuration := p.buildConfiguration(context.Background(), test.containers)
assert.Equal(t, test.expected, configuration)
assert.Equal(t, test.expected, configuration.HTTP)
})
}
}
@ -317,7 +317,7 @@ func Test_buildConfiguration(t *testing.T) {
desc string
containers []dockerData
constraints types.Constraints
expected *config.Configuration
expected *config.HTTPConfiguration
}{
{
desc: "one container no label",
@ -339,7 +339,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Test",
@ -399,7 +399,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Test",
@ -477,7 +477,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Test",
@ -512,7 +512,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.services.Service1.loadbalancer.method": "drr",
"traefik.http.services.Service1.loadbalancer.method": "drr",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -527,7 +527,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Service1",
@ -558,9 +558,9 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.services.Service1.loadbalancer.method": "wrr",
"traefik.routers.Router1.rule": "Host(`foo.com`)",
"traefik.routers.Router1.service": "Service1",
"traefik.http.services.Service1.loadbalancer.method": "wrr",
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
"traefik.http.routers.Router1.service": "Service1",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -575,7 +575,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Router1": {
Service: "Service1",
@ -606,7 +606,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.routers.Router1.rule": "Host(`foo.com`)",
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -621,7 +621,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{
"Test": {
@ -652,8 +652,8 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.routers.Router1.rule": "Host(`foo.com`)",
"traefik.services.Service1.loadbalancer.method": "wrr",
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
"traefik.http.services.Service1.loadbalancer.method": "wrr",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -668,7 +668,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Router1": {
Service: "Service1",
@ -699,9 +699,9 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.routers.Router1.rule": "Host(`foo.com`)",
"traefik.services.Service1.loadbalancer.method": "wrr",
"traefik.services.Service2.loadbalancer.method": "wrr",
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
"traefik.http.services.Service1.loadbalancer.method": "wrr",
"traefik.http.services.Service2.loadbalancer.method": "wrr",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -716,7 +716,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{
@ -755,7 +755,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.services.Service1.loadbalancer.method": "drr",
"traefik.http.services.Service1.loadbalancer.method": "drr",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -774,7 +774,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.services.Service1.loadbalancer.method": "wrr",
"traefik.http.services.Service1.loadbalancer.method": "wrr",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -789,7 +789,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Service1",
@ -808,7 +808,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.services.Service1.loadbalancer.method": "drr",
"traefik.http.services.Service1.loadbalancer.method": "drr",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -827,7 +827,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.services.Service1.loadbalancer.method": "wrr",
"traefik.http.services.Service1.loadbalancer.method": "wrr",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -846,7 +846,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.services.Service1.loadbalancer.method": "foo",
"traefik.http.services.Service1.loadbalancer.method": "foo",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -861,7 +861,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Service1",
@ -880,7 +880,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.services.Service1.loadbalancer.method": "drr",
"traefik.http.services.Service1.loadbalancer.method": "drr",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -899,7 +899,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.services.Service1.loadbalancer.method": "drr",
"traefik.http.services.Service1.loadbalancer.method": "drr",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -914,7 +914,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Service1",
@ -949,7 +949,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.middlewares.Middleware1.maxconn.amount": "42",
"traefik.http.middlewares.Middleware1.maxconn.amount": "42",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -964,7 +964,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Test",
@ -1003,7 +1003,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.middlewares.Middleware1.maxconn.amount": "42",
"traefik.http.middlewares.Middleware1.maxconn.amount": "42",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1022,7 +1022,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.middlewares.Middleware1.maxconn.amount": "42",
"traefik.http.middlewares.Middleware1.maxconn.amount": "42",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1037,7 +1037,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Test",
@ -1080,7 +1080,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.middlewares.Middleware1.maxconn.amount": "42",
"traefik.http.middlewares.Middleware1.maxconn.amount": "42",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1099,7 +1099,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.middlewares.Middleware1.maxconn.amount": "41",
"traefik.http.middlewares.Middleware1.maxconn.amount": "41",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1114,7 +1114,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Test",
@ -1150,7 +1150,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.middlewares.Middleware1.maxconn.amount": "42",
"traefik.http.middlewares.Middleware1.maxconn.amount": "42",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1169,7 +1169,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.middlewares.Middleware1.maxconn.amount": "41",
"traefik.http.middlewares.Middleware1.maxconn.amount": "41",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1188,7 +1188,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.middlewares.Middleware1.maxconn.amount": "40",
"traefik.http.middlewares.Middleware1.maxconn.amount": "40",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1203,7 +1203,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Test",
@ -1243,7 +1243,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.routers.Router1.rule": "Host(`foo.com`)",
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1262,7 +1262,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.routers.Router1.rule": "Host(`bar.com`)",
"traefik.http.routers.Router1.rule": "Host(`bar.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1277,7 +1277,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{
@ -1308,7 +1308,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.routers.Router1.rule": "Host(`foo.com`)",
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1327,7 +1327,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.routers.Router1.rule": "Host(`bar.com`)",
"traefik.http.routers.Router1.rule": "Host(`bar.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1346,7 +1346,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.routers.Router1.rule": "Host(`foobar.com`)",
"traefik.http.routers.Router1.rule": "Host(`foobar.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1361,7 +1361,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{
@ -1396,7 +1396,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.routers.Router1.rule": "Host(`foo.com`)",
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1415,7 +1415,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.routers.Router1.rule": "Host(`foo.com`)",
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1430,7 +1430,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Router1": {
Service: "Test",
@ -1465,7 +1465,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.routers.Router1.rule": "Host(`foo.com`)",
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1483,7 +1483,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test2",
Name: "Test",
Labels: map[string]string{
"traefik.routers.Router1.rule": "Host(`foo.com`)",
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1498,7 +1498,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{
@ -1551,7 +1551,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Test",
@ -1582,8 +1582,8 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.services.Service1.LoadBalancer.server.scheme": "h2c",
"traefik.services.Service1.LoadBalancer.server.port": "8080",
"traefik.http.services.Service1.LoadBalancer.server.scheme": "h2c",
"traefik.http.services.Service1.LoadBalancer.server.port": "8080",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1598,7 +1598,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Service1",
@ -1629,8 +1629,8 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.services.Service1.LoadBalancer.server.port": "",
"traefik.services.Service2.LoadBalancer.server.port": "8080",
"traefik.http.services.Service1.LoadBalancer.server.port": "",
"traefik.http.services.Service2.LoadBalancer.server.port": "8080",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1645,7 +1645,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{
@ -1694,7 +1694,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
@ -1707,7 +1707,7 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.middlewares.Middleware1.maxconn.amount": "42",
"traefik.http.middlewares.Middleware1.maxconn.amount": "42",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{},
@ -1720,7 +1720,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
@ -1748,7 +1748,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
@ -1775,7 +1775,7 @@ func Test_buildConfiguration(t *testing.T) {
Health: "not_healthy",
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
@ -1810,7 +1810,7 @@ func Test_buildConfiguration(t *testing.T) {
Regex: "bar",
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
@ -1845,7 +1845,7 @@ func Test_buildConfiguration(t *testing.T) {
Regex: "foo",
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Test",
@ -1876,8 +1876,8 @@ func Test_buildConfiguration(t *testing.T) {
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.middlewares.Middleware1.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
"traefik.routers.Test.middlewares": "Middleware1",
"traefik.http.middlewares.Middleware1.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
"traefik.http.routers.Test.middlewares": "Middleware1",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
@ -1892,7 +1892,7 @@ func Test_buildConfiguration(t *testing.T) {
},
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Test": {
Service: "Test",
@ -1951,7 +1951,7 @@ func Test_buildConfiguration(t *testing.T) {
configuration := p.buildConfiguration(context.Background(), test.containers)
assert.Equal(t, test.expected, configuration)
assert.Equal(t, test.expected, configuration.HTTP)
})
}
}

View file

@ -205,13 +205,6 @@ func (p *Provider) loadFileConfig(filename string, parseTemplate bool) (*config.
}
configuration.TLS = tlsConfigs
if configuration == nil || configuration.Routers == nil && configuration.Middlewares == nil && configuration.Services == nil && configuration.TLS == nil {
configuration = &config.Configuration{
Routers: make(map[string]*config.Router),
Middlewares: make(map[string]*config.Middleware),
Services: make(map[string]*config.Service),
}
}
return configuration, nil
}
@ -226,9 +219,15 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st
if configuration == nil {
configuration = &config.Configuration{
Routers: make(map[string]*config.Router),
Middlewares: make(map[string]*config.Middleware),
Services: make(map[string]*config.Service),
HTTP: &config.HTTPConfiguration{
Routers: make(map[string]*config.Router),
Middlewares: make(map[string]*config.Middleware),
Services: make(map[string]*config.Service),
},
TCP: &config.TCPConfiguration{
Routers: make(map[string]*config.TCPRouter),
Services: make(map[string]*config.TCPService),
},
}
}
@ -252,33 +251,49 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st
return configuration, err
}
for name, conf := range c.Routers {
if _, exists := configuration.Routers[name]; exists {
logger.WithField(log.RouterName, name).Warn("Router already configured, skipping")
for name, conf := range c.HTTP.Routers {
if _, exists := configuration.HTTP.Routers[name]; exists {
logger.WithField(log.RouterName, name).Warn("HTTP router already configured, skipping")
} else {
configuration.Routers[name] = conf
configuration.HTTP.Routers[name] = conf
}
}
for name, conf := range c.Middlewares {
if _, exists := configuration.Middlewares[name]; exists {
logger.WithField(log.MiddlewareName, name).Warn("Middleware already configured, skipping")
for name, conf := range c.HTTP.Middlewares {
if _, exists := configuration.HTTP.Middlewares[name]; exists {
logger.WithField(log.MiddlewareName, name).Warn("HTTP middleware already configured, skipping")
} else {
configuration.Middlewares[name] = conf
configuration.HTTP.Middlewares[name] = conf
}
}
for name, conf := range c.Services {
if _, exists := configuration.Services[name]; exists {
logger.WithField(log.ServiceName, name).Warn("Service already configured, skipping")
for name, conf := range c.HTTP.Services {
if _, exists := configuration.HTTP.Services[name]; exists {
logger.WithField(log.ServiceName, name).Warn("HTTP service already configured, skipping")
} else {
configuration.Services[name] = conf
configuration.HTTP.Services[name] = conf
}
}
for name, conf := range c.TCP.Routers {
if _, exists := configuration.TCP.Routers[name]; exists {
logger.WithField(log.RouterName, name).Warn("TCP router already configured, skipping")
} else {
configuration.TCP.Routers[name] = conf
}
}
for name, conf := range c.TCP.Services {
if _, exists := configuration.TCP.Services[name]; exists {
logger.WithField(log.ServiceName, name).Warn("TCP service already configured, skipping")
} else {
configuration.TCP.Services[name] = conf
}
}
for _, conf := range c.TLS {
if _, exists := configTLSMaps[conf]; exists {
logger.Warnf("TLS Configuration %v already configured, skipping", conf)
logger.Warnf("TLS configuration %v already configured, skipping", conf)
} else {
configTLSMaps[conf] = struct{}{}
}

View file

@ -42,8 +42,8 @@ func TestProvideWithoutWatch(t *testing.T) {
timeout := time.After(time.Second)
select {
case conf := <-configChan:
assert.Len(t, conf.Configuration.Services, test.expectedNumService)
assert.Len(t, conf.Configuration.Routers, test.expectedNumRouter)
assert.Len(t, conf.Configuration.HTTP.Services, test.expectedNumService)
assert.Len(t, conf.Configuration.HTTP.Routers, test.expectedNumRouter)
assert.Len(t, conf.Configuration.TLS, test.expectedNumTLSConf)
case <-timeout:
t.Errorf("timeout while waiting for config")
@ -67,8 +67,8 @@ func TestProvideWithWatch(t *testing.T) {
timeout := time.After(time.Second)
select {
case conf := <-configChan:
assert.Len(t, conf.Configuration.Services, 0)
assert.Len(t, conf.Configuration.Routers, 0)
assert.Len(t, conf.Configuration.HTTP.Services, 0)
assert.Len(t, conf.Configuration.HTTP.Routers, 0)
assert.Len(t, conf.Configuration.TLS, 0)
case <-timeout:
t.Errorf("timeout while waiting for config")
@ -98,8 +98,8 @@ func TestProvideWithWatch(t *testing.T) {
select {
case conf := <-configChan:
numUpdates++
numServices = len(conf.Configuration.Services)
numRouters = len(conf.Configuration.Routers)
numServices = len(conf.Configuration.HTTP.Services)
numRouters = len(conf.Configuration.HTTP.Routers)
numTLSConfs = len(conf.Configuration.TLS)
t.Logf("received update #%d: services %d/%d, routers %d/%d, TLS configs %d/%d", numUpdates, numServices, test.expectedNumService, numRouters, test.expectedNumRouter, numTLSConfs, test.expectedNumTLSConf)
@ -156,9 +156,9 @@ func getTestCases() []ProvideTestCase {
{
desc: "template file",
fileContent: `
[routers]
[http.routers]
{{ range $i, $e := until 20 }}
[routers.router{{ $e }}]
[http.routers.router{{ $e }}]
service = "application"
{{ end }}
`,
@ -179,17 +179,17 @@ func getTestCases() []ProvideTestCase {
desc: "template in directory",
directoryContent: []string{
`
[routers]
[http.routers]
{{ range $i, $e := until 20 }}
[routers.router{{ $e }}]
[http.routers.router{{ $e }}]
service = "application"
{{ end }}
`,
`
[services]
[http.services]
{{ range $i, $e := until 20 }}
[services.application-{{ $e }}]
[[services.application-{{ $e }}.servers]]
[http.services.application-{{ $e }}]
[[http.services.application-{{ $e }}.servers]]
url="http://127.0.0.1"
weight = 1
{{ end }}
@ -202,7 +202,7 @@ func getTestCases() []ProvideTestCase {
desc: "simple traefik file",
traefikFileContent: `
debug=true
[file]
[providers.file]
` + createRoutersConfiguration(2) + createServicesConfiguration(3) + createTLS(4),
expectedNumRouter: 2,
expectedNumService: 3,
@ -212,7 +212,7 @@ func getTestCases() []ProvideTestCase {
desc: "simple traefik file with templating",
traefikFileContent: `
temp="{{ getTag \"test\" }}"
[file]
[providers.file]
` + createRoutersConfiguration(2) + createServicesConfiguration(3) + createTLS(4),
expectedNumRouter: 2,
expectedNumService: 3,
@ -300,10 +300,10 @@ func createTempDir(t *testing.T, dir string) string {
// createRoutersConfiguration Helper
func createRoutersConfiguration(n int) string {
conf := "[routers]\n"
conf := "[http.routers]\n"
for i := 1; i <= n; i++ {
conf += fmt.Sprintf(`
[routers."router%[1]d"]
[http.routers."router%[1]d"]
service = "application-%[1]d"
`, i)
}
@ -312,11 +312,11 @@ func createRoutersConfiguration(n int) string {
// createServicesConfiguration Helper
func createServicesConfiguration(n int) string {
conf := "[services]\n"
conf := "[http.services]\n"
for i := 1; i <= n; i++ {
conf += fmt.Sprintf(`
[services.application-%[1]d.loadbalancer]
[[services.application-%[1]d.loadbalancer.servers]]
[http.services.application-%[1]d.loadbalancer]
[[http.services.application-%[1]d.loadbalancer.servers]]
url = "http://172.17.0.%[1]d:80"
weight = 1
`, i)

View file

@ -250,9 +250,12 @@ func loadService(client Client, namespace string, backend v1beta1.IngressBackend
func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Client) *config.Configuration {
conf := &config.Configuration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
HTTP: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
},
TCP: &config.TCPConfiguration{},
}
ingresses := client.GetIngresses()
@ -272,7 +275,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
if len(ingress.Spec.Rules) == 0 {
if ingress.Spec.Backend != nil {
if _, ok := conf.Services["default-backend"]; ok {
if _, ok := conf.HTTP.Services["default-backend"]; ok {
log.FromContext(ctx).Error("The default backend already exists.")
continue
}
@ -286,13 +289,13 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
continue
}
conf.Routers["/"] = &config.Router{
conf.HTTP.Routers["/"] = &config.Router{
Rule: "PathPrefix(`/`)",
Priority: math.MinInt32,
Service: "default-backend",
}
conf.Services["default-backend"] = service
conf.HTTP.Services["default-backend"] = service
}
}
for _, rule := range ingress.Spec.Rules {
@ -327,12 +330,12 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
rules = append(rules, "PathPrefix(`"+p.Path+"`)")
}
conf.Routers[strings.Replace(rule.Host, ".", "-", -1)+p.Path] = &config.Router{
conf.HTTP.Routers[strings.Replace(rule.Host, ".", "-", -1)+p.Path] = &config.Router{
Rule: strings.Join(rules, " && "),
Service: serviceName,
}
conf.Services[serviceName] = service
conf.HTTP.Services[serviceName] = service
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -7,9 +7,12 @@ import (
// DecodeConfiguration Converts the labels to a configuration.
func DecodeConfiguration(labels map[string]string) (*config.Configuration, error) {
conf := &config.Configuration{}
conf := &config.Configuration{
HTTP: &config.HTTPConfiguration{},
TCP: &config.TCPConfiguration{},
}
err := Decode(labels, conf, "traefik.services", "traefik.routers", "traefik.middlewares")
err := Decode(labels, conf, "traefik.http", "traefik.tcp")
if err != nil {
return nil, err
}

File diff suppressed because it is too large Load diff

View file

@ -39,7 +39,7 @@ func (p *Provider) buildConfiguration(ctx context.Context, applications *maratho
continue
}
err = p.buildServiceConfiguration(ctxApp, app, extraConf, confFromLabel)
err = p.buildServiceConfiguration(ctxApp, app, extraConf, confFromLabel.HTTP)
if err != nil {
logger.Error(err)
continue
@ -55,7 +55,7 @@ func (p *Provider) buildConfiguration(ctx context.Context, applications *maratho
serviceName := getServiceName(app)
provider.BuildRouterConfiguration(ctxApp, confFromLabel, serviceName, p.defaultRuleTpl, model)
provider.BuildRouterConfiguration(ctxApp, confFromLabel.HTTP, serviceName, p.defaultRuleTpl, model)
configurations[app.ID] = confFromLabel
}
@ -67,7 +67,7 @@ func getServiceName(app marathon.Application) string {
return strings.Replace(strings.TrimPrefix(app.ID, "/"), "/", "_", -1)
}
func (p *Provider) buildServiceConfiguration(ctx context.Context, app marathon.Application, extraConf configuration, conf *config.Configuration) error {
func (p *Provider) buildServiceConfiguration(ctx context.Context, app marathon.Application, extraConf configuration, conf *config.HTTPConfiguration) error {
appName := getServiceName(app)
appCtx := log.With(ctx, log.Str("ApplicationID", appName))

View file

@ -34,7 +34,7 @@ func TestBuildConfiguration(t *testing.T) {
constraints types.Constraints
filterMarathonConstraints bool
defaultRule string
expected *config.Configuration
expected *config.HTTPConfiguration
}{
{
desc: "simple application",
@ -44,7 +44,7 @@ func TestBuildConfiguration(t *testing.T) {
appPorts(80),
withTasks(localhostTask(taskPorts(80))),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"app": {
Service: "app",
@ -74,7 +74,7 @@ func TestBuildConfiguration(t *testing.T) {
appPorts(80),
withTasks(localhostTask(taskPorts(80), taskState(taskStateStaging))),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
@ -88,7 +88,7 @@ func TestBuildConfiguration(t *testing.T) {
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"app": {
Service: "app",
@ -116,11 +116,11 @@ func TestBuildConfiguration(t *testing.T) {
application(
appID("/app"),
appPorts(80),
withLabel("traefik.middlewares.Middleware1.basicauth.users", "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withLabel("traefik.routers.app.middlewares", "Middleware1"),
withLabel("traefik.http.middlewares.Middleware1.basicauth.users", "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withLabel("traefik.http.routers.app.middlewares", "Middleware1"),
withTasks(localhostTask(taskPorts(80))),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"app": {
Service: "app",
@ -159,18 +159,18 @@ func TestBuildConfiguration(t *testing.T) {
appID("/foo-v000"),
withTasks(localhostTask(taskPorts(8080))),
withLabel("traefik.services.Service1.LoadBalancer.server.port", "index:0"),
withLabel("traefik.routers.Router1.rule", "Host(`app.marathon.localhost`)"),
withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "index:0"),
withLabel("traefik.http.routers.Router1.rule", "Host(`app.marathon.localhost`)"),
),
application(
appID("/foo-v001"),
withTasks(localhostTask(taskPorts(8081))),
withLabel("traefik.services.Service1.LoadBalancer.server.port", "index:0"),
withLabel("traefik.routers.Router1.rule", "Host(`app.marathon.localhost`)"),
withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "index:0"),
withLabel("traefik.http.routers.Router1.rule", "Host(`app.marathon.localhost`)"),
),
),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Router1": {
Service: "Service1",
@ -204,19 +204,19 @@ func TestBuildConfiguration(t *testing.T) {
withTasks(localhostTask(taskPorts(8080))),
withTasks(localhostTask(taskPorts(8081))),
withLabel("traefik.services.Service1.LoadBalancer.server.port", "index:0"),
withLabel("traefik.routers.Router1.rule", "Host(`app.marathon.localhost`)"),
withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "index:0"),
withLabel("traefik.http.routers.Router1.rule", "Host(`app.marathon.localhost`)"),
),
application(
appID("/foo-v001"),
withTasks(localhostTask(taskPorts(8082))),
withTasks(localhostTask(taskPorts(8083))),
withLabel("traefik.services.Service1.LoadBalancer.server.port", "index:0"),
withLabel("traefik.routers.Router1.rule", "Host(`app.marathon.localhost`)"),
withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "index:0"),
withLabel("traefik.http.routers.Router1.rule", "Host(`app.marathon.localhost`)"),
),
),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Router1": {
Service: "Service1",
@ -262,7 +262,7 @@ func TestBuildConfiguration(t *testing.T) {
withTasks(localhostTask(taskPorts(8081))),
),
),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"foo": {
Service: "foo",
@ -306,7 +306,7 @@ func TestBuildConfiguration(t *testing.T) {
appPorts(80),
withTasks(localhostTask(taskPorts(80)), localhostTask(taskPorts(81))),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"app": {
Service: "app",
@ -341,9 +341,9 @@ func TestBuildConfiguration(t *testing.T) {
appID("/app"),
appPorts(80),
withTasks(localhostTask(taskPorts(80))),
withLabel("traefik.services.Service1.loadbalancer.method", "drr"),
withLabel("traefik.http.services.Service1.loadbalancer.method", "drr"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"app": {
Service: "Service1",
@ -372,11 +372,11 @@ func TestBuildConfiguration(t *testing.T) {
appID("/app"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.services.Service1.loadbalancer.method", "wrr"),
withLabel("traefik.routers.Router1.rule", "Host(`foo.com`)"),
withLabel("traefik.routers.Router1.service", "Service1"),
withLabel("traefik.http.services.Service1.loadbalancer.method", "wrr"),
withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"),
withLabel("traefik.http.routers.Router1.service", "Service1"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Router1": {
Service: "Service1",
@ -407,9 +407,9 @@ func TestBuildConfiguration(t *testing.T) {
appID("/app"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.routers.Router1.rule", "Host(`foo.com`)"),
withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{
"app": {
@ -440,10 +440,10 @@ func TestBuildConfiguration(t *testing.T) {
appID("/app"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.routers.Router1.rule", "Host(`foo.com`)"),
withLabel("traefik.services.Service1.loadbalancer.method", "wrr"),
withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"),
withLabel("traefik.http.services.Service1.loadbalancer.method", "wrr"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Router1": {
Service: "Service1",
@ -474,11 +474,11 @@ func TestBuildConfiguration(t *testing.T) {
appID("/app"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.routers.Router1.rule", "Host(`foo.com`)"),
withLabel("traefik.services.Service1.loadbalancer.method", "wrr"),
withLabel("traefik.services.Service2.loadbalancer.method", "wrr"),
withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"),
withLabel("traefik.http.services.Service1.loadbalancer.method", "wrr"),
withLabel("traefik.http.services.Service2.loadbalancer.method", "wrr"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{
@ -516,15 +516,15 @@ func TestBuildConfiguration(t *testing.T) {
appID("/app"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.services.Service1.loadbalancer.method", "wrr"),
withLabel("traefik.http.services.Service1.loadbalancer.method", "wrr"),
),
application(
appID("/app2"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.services.Service1.loadbalancer.method", "drr"),
withLabel("traefik.http.services.Service1.loadbalancer.method", "drr"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"app": {
Service: "Service1",
@ -546,15 +546,15 @@ func TestBuildConfiguration(t *testing.T) {
appID("/app"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.middlewares.Middleware1.maxconn.amount", "42"),
withLabel("traefik.http.middlewares.Middleware1.maxconn.amount", "42"),
),
application(
appID("/app2"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.middlewares.Middleware1.maxconn.amount", "42"),
withLabel("traefik.http.middlewares.Middleware1.maxconn.amount", "42"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"app": {
Service: "app",
@ -608,15 +608,15 @@ func TestBuildConfiguration(t *testing.T) {
appID("/app"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.middlewares.Middleware1.maxconn.amount", "42"),
withLabel("traefik.http.middlewares.Middleware1.maxconn.amount", "42"),
),
application(
appID("/app2"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.middlewares.Middleware1.maxconn.amount", "41"),
withLabel("traefik.http.middlewares.Middleware1.maxconn.amount", "41"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"app": {
Service: "app",
@ -663,15 +663,15 @@ func TestBuildConfiguration(t *testing.T) {
appID("/app"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.routers.Router1.rule", "Host(`foo.com`)"),
withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"),
),
application(
appID("/app2"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.routers.Router1.rule", "Host(`bar.com`)"),
withLabel("traefik.http.routers.Router1.rule", "Host(`bar.com`)"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{
@ -709,17 +709,17 @@ func TestBuildConfiguration(t *testing.T) {
appID("/app"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.routers.Router1.rule", "Host(`foo.com`)"),
withLabel("traefik.services.Service1.LoadBalancer.method", "wrr"),
withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"),
withLabel("traefik.http.services.Service1.LoadBalancer.method", "wrr"),
),
application(
appID("/app2"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.routers.Router1.rule", "Host(`foo.com`)"),
withLabel("traefik.services.Service1.LoadBalancer.method", "wrr"),
withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"),
withLabel("traefik.http.services.Service1.LoadBalancer.method", "wrr"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"Router1": {
Service: "Service1",
@ -754,15 +754,15 @@ func TestBuildConfiguration(t *testing.T) {
appID("/app"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.routers.Router1.rule", "Host(`foo.com`)"),
withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"),
),
application(
appID("/app2"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.routers.Router1.rule", "Host(`foo.com`)"),
withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{
@ -802,7 +802,7 @@ func TestBuildConfiguration(t *testing.T) {
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.wrong.label", "tchouk"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"app": {
Service: "app",
@ -833,10 +833,10 @@ func TestBuildConfiguration(t *testing.T) {
appID("/app"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.services.Service1.LoadBalancer.server.scheme", "h2c"),
withLabel("traefik.services.Service1.LoadBalancer.server.port", "90"),
withLabel("traefik.http.services.Service1.LoadBalancer.server.scheme", "h2c"),
withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "90"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"app": {
Service: "Service1",
@ -867,10 +867,10 @@ func TestBuildConfiguration(t *testing.T) {
appID("/app"),
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
withLabel("traefik.services.Service1.LoadBalancer.server.port", ""),
withLabel("traefik.services.Service2.LoadBalancer.server.port", "8080"),
withLabel("traefik.http.services.Service1.LoadBalancer.server.port", ""),
withLabel("traefik.http.services.Service2.LoadBalancer.server.port", "8080"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{
@ -909,7 +909,7 @@ func TestBuildConfiguration(t *testing.T) {
appPorts(80, 81),
withTasks(localhostTask()),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
@ -922,9 +922,9 @@ func TestBuildConfiguration(t *testing.T) {
appID("/app"),
appPorts(80, 81),
withTasks(localhostTask()),
withLabel("traefik.middlewares.Middleware1.basicauth.users", "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
withLabel("traefik.http.middlewares.Middleware1.basicauth.users", "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
@ -939,7 +939,7 @@ func TestBuildConfiguration(t *testing.T) {
withTasks(localhostTask()),
withLabel("traefik.enable", "false"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
@ -954,7 +954,7 @@ func TestBuildConfiguration(t *testing.T) {
withTasks(localhostTask()),
withLabel("traefik.enable", "false"),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
@ -976,7 +976,7 @@ func TestBuildConfiguration(t *testing.T) {
Regex: "bar",
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
@ -999,7 +999,7 @@ func TestBuildConfiguration(t *testing.T) {
Regex: "rack_id:CLUSTER:rack-2",
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{},
Middlewares: map[string]*config.Middleware{},
Services: map[string]*config.Service{},
@ -1022,7 +1022,7 @@ func TestBuildConfiguration(t *testing.T) {
Regex: "rack_id:CLUSTER:rack-1",
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"app": {
Service: "app",
@ -1063,7 +1063,7 @@ func TestBuildConfiguration(t *testing.T) {
Regex: "bar",
},
},
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"app": {
Service: "app",
@ -1096,7 +1096,7 @@ func TestBuildConfiguration(t *testing.T) {
appPorts(80, 81),
withTasks(localhostTask(taskPorts(80, 81))),
)),
expected: &config.Configuration{
expected: &config.HTTPConfiguration{
Routers: map[string]*config.Router{
"a_b_app": {
Service: "a_b_app",
@ -1145,7 +1145,7 @@ func TestBuildConfiguration(t *testing.T) {
actualConfig := p.buildConfiguration(context.Background(), test.applications)
assert.NotNil(t, actualConfig)
assert.Equal(t, test.expected, actualConfig)
assert.Equal(t, test.expected, actualConfig.HTTP)
})
}
}

View file

@ -43,7 +43,7 @@ func (p *Provider) Append(systemRouter *mux.Router) {
return
}
configuration := new(config.Configuration)
configuration := new(config.HTTPConfiguration)
body, _ := ioutil.ReadAll(request.Body)
if err := json.Unmarshal(body, configuration); err != nil {
@ -52,7 +52,9 @@ func (p *Provider) Append(systemRouter *mux.Router) {
return
}
p.configurationChan <- config.Message{ProviderName: "rest", Configuration: configuration}
p.configurationChan <- config.Message{ProviderName: "rest", Configuration: &config.Configuration{
HTTP: configuration,
}}
if err := templatesRenderer.JSON(response, http.StatusOK, configuration); err != nil {
log.WithoutContext().Error(err)
}