Remove BaseProvider

This commit is contained in:
Ludovic Fernandez 2019-03-27 15:02:06 +01:00 committed by Traefiker Bot
parent 7932e317c8
commit 2916f540c1
10 changed files with 107 additions and 181 deletions

View file

@ -171,7 +171,6 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
// default Kubernetes // default Kubernetes
var defaultKubernetes ingress.Provider var defaultKubernetes ingress.Provider
defaultKubernetes.Watch = true
defaultProviders := static.Providers{ defaultProviders := static.Providers{
File: &defaultFile, File: &defaultFile,

View file

@ -25,7 +25,6 @@ import (
) )
func TestDo_globalConfiguration(t *testing.T) { func TestDo_globalConfiguration(t *testing.T) {
config := &static.Configuration{} config := &static.Configuration{}
sendAnonymousUsage := true sendAnonymousUsage := true
@ -148,9 +147,15 @@ func TestDo_globalConfiguration(t *testing.T) {
} }
config.Providers.File = &file.Provider{ config.Providers.File = &file.Provider{
BaseProvider: provider.BaseProvider{ Directory: "file Directory",
Watch: true, Watch: true,
Filename: "file Filename", Filename: "file Filename",
DebugLogGeneratedTemplate: true,
TraefikFile: "",
}
config.Providers.Docker = &docker.Provider{
Constrainer: provider.Constrainer{
Constraints: types.Constraints{ Constraints: types.Constraints{
{ {
Key: "file Constraints Key 1", Key: "file Constraints Key 1",
@ -163,20 +168,8 @@ func TestDo_globalConfiguration(t *testing.T) {
MustMatch: true, MustMatch: true,
}, },
}, },
Trace: true,
DebugLogGeneratedTemplate: true,
},
Directory: "file Directory",
}
config.Providers.Docker = &docker.Provider{
BaseProvider: provider.BaseProvider{
Watch: true,
Filename: "myfilename",
Constraints: nil,
Trace: true,
DebugLogGeneratedTemplate: true,
}, },
Watch: true,
Endpoint: "MyEndPoint", Endpoint: "MyEndPoint",
DefaultRule: "PathPrefix(`/`)", DefaultRule: "PathPrefix(`/`)",
TLS: &types.ClientTLS{ TLS: &types.ClientTLS{
@ -194,24 +187,6 @@ func TestDo_globalConfiguration(t *testing.T) {
} }
config.Providers.Kubernetes = &ingress.Provider{ config.Providers.Kubernetes = &ingress.Provider{
BaseProvider: provider.BaseProvider{
Watch: true,
Filename: "myFileName",
Constraints: types.Constraints{
{
Key: "k8s Constraints Key 1",
Regex: "k8s Constraints Regex 2",
MustMatch: true,
},
{
Key: "k8s Constraints Key 1",
Regex: "k8s Constraints Regex 2",
MustMatch: true,
},
},
Trace: true,
DebugLogGeneratedTemplate: true,
},
Endpoint: "MyEndpoint", Endpoint: "MyEndpoint",
Token: "MyToken", Token: "MyToken",
CertAuthFilePath: "MyCertAuthPath", CertAuthFilePath: "MyCertAuthPath",
@ -222,24 +197,6 @@ func TestDo_globalConfiguration(t *testing.T) {
} }
config.Providers.KubernetesCRD = &crd.Provider{ config.Providers.KubernetesCRD = &crd.Provider{
BaseProvider: provider.BaseProvider{
Watch: true,
Filename: "myFileName",
Constraints: types.Constraints{
{
Key: "k8s Constraints Key 1",
Regex: "k8s Constraints Regex 2",
MustMatch: true,
},
{
Key: "k8s Constraints Key 1",
Regex: "k8s Constraints Regex 2",
MustMatch: true,
},
},
Trace: true,
DebugLogGeneratedTemplate: true,
},
Endpoint: "MyEndpoint", Endpoint: "MyEndpoint",
Token: "MyToken", Token: "MyToken",
CertAuthFilePath: "MyCertAuthPath", CertAuthFilePath: "MyCertAuthPath",

View file

@ -1,105 +0,0 @@
package provider
import (
"bytes"
"strings"
"text/template"
"github.com/BurntSushi/toml"
"github.com/Masterminds/sprig"
"github.com/containous/traefik/pkg/config"
"github.com/containous/traefik/pkg/log"
"github.com/containous/traefik/pkg/tls"
"github.com/containous/traefik/pkg/types"
)
// BaseProvider should be inherited by providers.
type BaseProvider struct {
Watch bool `description:"Watch provider" export:"true"`
Filename string `description:"Override default configuration template. For advanced users :)" export:"true"`
Constraints types.Constraints `description:"Filter services by constraint, matching with Traefik tags." export:"true"`
Trace bool `description:"Display additional provider logs (if available)." export:"true"`
DebugLogGeneratedTemplate bool `description:"Enable debug logging of generated configuration template." export:"true"`
}
// Init for compatibility reason the BaseProvider implements an empty Init.
func (p *BaseProvider) Init() error {
return nil
}
// MatchConstraints must match with EVERY single constraint
// returns first constraint that do not match or nil.
func (p *BaseProvider) MatchConstraints(tags []string) (bool, *types.Constraint) {
// if there is no tags and no constraints, filtering is disabled
if len(tags) == 0 && len(p.Constraints) == 0 {
return true, nil
}
for _, constraint := range p.Constraints {
// xor: if ok and constraint.MustMatch are equal, then no tag is currently matching with the constraint
if ok := constraint.MatchConstraintWithAtLeastOneTag(tags); ok != constraint.MustMatch {
return false, constraint
}
}
// If no constraint or every constraints matching
return true, nil
}
// CreateConfiguration creates a provider configuration from content using templating.
func (p *BaseProvider) CreateConfiguration(tmplContent string, funcMap template.FuncMap, templateObjects interface{}) (*config.Configuration, error) {
var defaultFuncMap = sprig.TxtFuncMap()
// tolower is deprecated in favor of sprig's lower function
defaultFuncMap["tolower"] = strings.ToLower
defaultFuncMap["normalize"] = Normalize
defaultFuncMap["split"] = split
for funcID, funcElement := range funcMap {
defaultFuncMap[funcID] = funcElement
}
tmpl := template.New(p.Filename).Funcs(defaultFuncMap)
_, err := tmpl.Parse(tmplContent)
if err != nil {
return nil, err
}
var buffer bytes.Buffer
err = tmpl.Execute(&buffer, templateObjects)
if err != nil {
return nil, err
}
var renderedTemplate = buffer.String()
if p.DebugLogGeneratedTemplate {
log.Debugf("Template content: %s", tmplContent)
log.Debugf("Rendering results: %s", renderedTemplate)
}
return p.DecodeConfiguration(renderedTemplate)
}
// DecodeConfiguration Decodes a *types.Configuration from a content.
func (p *BaseProvider) DecodeConfiguration(content string) (*config.Configuration, error) {
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
}
return configuration, nil
}
func split(sep, s string) []string {
return strings.Split(s, sep)
}

View file

@ -0,0 +1,27 @@
package provider
import "github.com/containous/traefik/pkg/types"
// Constrainer Filter services by constraint, matching with Traefik tags.
type Constrainer struct {
Constraints types.Constraints `description:"Filter services by constraint, matching with Traefik tags." export:"true"`
}
// MatchConstraints must match with EVERY single constraint
// returns first constraint that do not match or nil.
func (c *Constrainer) MatchConstraints(tags []string) (bool, *types.Constraint) {
// if there is no tags and no constraints, filtering is disabled
if len(tags) == 0 && len(c.Constraints) == 0 {
return true, nil
}
for _, constraint := range c.Constraints {
// xor: if ok and constraint.MustMatch are equal, then no tag is currently matching with the constraint
if ok := constraint.MatchConstraintWithAtLeastOneTag(tags); ok != constraint.MustMatch {
return false, constraint
}
}
// If no constraint or every constraints matching
return true, nil
}

View file

@ -41,7 +41,8 @@ var _ provider.Provider = (*Provider)(nil)
// Provider holds configurations of the provider. // Provider holds configurations of the provider.
type Provider struct { type Provider struct {
provider.BaseProvider `mapstructure:",squash" export:"true"` provider.Constrainer `mapstructure:",squash" export:"true"`
Watch bool `description:"Watch provider" export:"true"`
Endpoint string `description:"Docker server endpoint. Can be a tcp or a unix socket endpoint"` Endpoint string `description:"Docker server endpoint. Can be a tcp or a unix socket endpoint"`
DefaultRule string `description:"Default rule"` DefaultRule string `description:"Default rule"`
TLS *types.ClientTLS `description:"Enable Docker TLS support" export:"true"` TLS *types.ClientTLS `description:"Enable Docker TLS support" export:"true"`
@ -61,7 +62,7 @@ func (p *Provider) Init() error {
} }
p.defaultRuleTpl = defaultRuleTpl p.defaultRuleTpl = defaultRuleTpl
return p.BaseProvider.Init() return nil
} }
// dockerData holds the need data to the provider. // dockerData holds the need data to the provider.

View file

@ -1,6 +1,7 @@
package file package file
import ( import (
"bytes"
"context" "context"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
@ -10,6 +11,8 @@ import (
"strings" "strings"
"text/template" "text/template"
"github.com/BurntSushi/toml"
"github.com/Masterminds/sprig"
"github.com/containous/traefik/pkg/config" "github.com/containous/traefik/pkg/config"
"github.com/containous/traefik/pkg/log" "github.com/containous/traefik/pkg/log"
"github.com/containous/traefik/pkg/provider" "github.com/containous/traefik/pkg/provider"
@ -25,14 +28,16 @@ var _ provider.Provider = (*Provider)(nil)
// Provider holds configurations of the provider. // Provider holds configurations of the provider.
type Provider struct { type Provider struct {
provider.BaseProvider `mapstructure:",squash" export:"true"` Directory string `description:"Load configuration from one or more .toml files in a directory" export:"true"`
Directory string `description:"Load configuration from one or more .toml files in a directory" export:"true"` Watch bool `description:"Watch provider" export:"true"`
TraefikFile string Filename string `description:"Override default configuration template. For advanced users :)" export:"true"`
DebugLogGeneratedTemplate bool `description:"Enable debug logging of generated configuration template." export:"true"`
TraefikFile string
} }
// Init the provider // Init the provider
func (p *Provider) Init() error { func (p *Provider) Init() error {
return p.BaseProvider.Init() return nil
} }
// Provide allows the file provider to provide configurations to traefik // Provide allows the file provider to provide configurations to traefik
@ -305,3 +310,55 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st
} }
return configuration, nil return configuration, nil
} }
// CreateConfiguration creates a provider configuration from content using templating.
func (p *Provider) CreateConfiguration(tmplContent string, funcMap template.FuncMap, templateObjects interface{}) (*config.Configuration, error) {
var defaultFuncMap = sprig.TxtFuncMap()
defaultFuncMap["normalize"] = provider.Normalize
defaultFuncMap["split"] = strings.Split
for funcID, funcElement := range funcMap {
defaultFuncMap[funcID] = funcElement
}
tmpl := template.New(p.Filename).Funcs(defaultFuncMap)
_, err := tmpl.Parse(tmplContent)
if err != nil {
return nil, err
}
var buffer bytes.Buffer
err = tmpl.Execute(&buffer, templateObjects)
if err != nil {
return nil, err
}
var renderedTemplate = buffer.String()
if p.DebugLogGeneratedTemplate {
log.Debugf("Template content: %s", tmplContent)
log.Debugf("Rendering results: %s", renderedTemplate)
}
return p.DecodeConfiguration(renderedTemplate)
}
// DecodeConfiguration Decodes a *types.Configuration from a content.
func (p *Provider) DecodeConfiguration(content string) (*config.Configuration, error) {
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
}
return configuration, nil
}

View file

@ -16,7 +16,6 @@ import (
"github.com/containous/traefik/pkg/config" "github.com/containous/traefik/pkg/config"
"github.com/containous/traefik/pkg/job" "github.com/containous/traefik/pkg/job"
"github.com/containous/traefik/pkg/log" "github.com/containous/traefik/pkg/log"
"github.com/containous/traefik/pkg/provider"
"github.com/containous/traefik/pkg/provider/kubernetes/crd/traefik/v1alpha1" "github.com/containous/traefik/pkg/provider/kubernetes/crd/traefik/v1alpha1"
"github.com/containous/traefik/pkg/provider/kubernetes/k8s" "github.com/containous/traefik/pkg/provider/kubernetes/k8s"
"github.com/containous/traefik/pkg/safe" "github.com/containous/traefik/pkg/safe"
@ -33,7 +32,6 @@ const (
// Provider holds configurations of the provider. // Provider holds configurations of the provider.
type Provider struct { type Provider struct {
provider.BaseProvider `mapstructure:",squash" export:"true"`
Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)"` Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)"`
Token string `description:"Kubernetes bearer token (not needed for in-cluster client)"` Token string `description:"Kubernetes bearer token (not needed for in-cluster client)"`
CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)"` CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)"`
@ -78,7 +76,7 @@ func (p *Provider) newK8sClient(ctx context.Context, labelSelector string) (*cli
// Init the provider. // Init the provider.
func (p *Provider) Init() error { func (p *Provider) Init() error {
return p.BaseProvider.Init() return nil
} }
// Provide allows the k8s provider to provide configurations to traefik // Provide allows the k8s provider to provide configurations to traefik

View file

@ -16,7 +16,6 @@ import (
"github.com/containous/traefik/pkg/config" "github.com/containous/traefik/pkg/config"
"github.com/containous/traefik/pkg/job" "github.com/containous/traefik/pkg/job"
"github.com/containous/traefik/pkg/log" "github.com/containous/traefik/pkg/log"
"github.com/containous/traefik/pkg/provider"
"github.com/containous/traefik/pkg/provider/kubernetes/k8s" "github.com/containous/traefik/pkg/provider/kubernetes/k8s"
"github.com/containous/traefik/pkg/safe" "github.com/containous/traefik/pkg/safe"
"github.com/containous/traefik/pkg/tls" "github.com/containous/traefik/pkg/tls"
@ -34,7 +33,6 @@ const (
// Provider holds configurations of the provider. // Provider holds configurations of the provider.
type Provider struct { type Provider struct {
provider.BaseProvider `mapstructure:",squash" export:"true"`
Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)"` Endpoint string `description:"Kubernetes server endpoint (required for external cluster client)"`
Token string `description:"Kubernetes bearer token (not needed for in-cluster client)"` Token string `description:"Kubernetes bearer token (not needed for in-cluster client)"`
CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)"` CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)"`
@ -90,7 +88,7 @@ func (p *Provider) newK8sClient(ctx context.Context, ingressLabelSelector string
// Init the provider. // Init the provider.
func (p *Provider) Init() error { func (p *Provider) Init() error {
return p.BaseProvider.Init() return nil
} }
// Provide allows the k8s provider to provide configurations to traefik // Provide allows the k8s provider to provide configurations to traefik

View file

@ -4,7 +4,6 @@ import (
"math" "math"
"testing" "testing"
"github.com/containous/traefik/pkg/provider"
"github.com/gambol99/go-marathon" "github.com/gambol99/go-marathon"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -24,7 +23,6 @@ func TestGetConfiguration(t *testing.T) {
Labels: &map[string]string{}, Labels: &map[string]string{},
}, },
p: Provider{ p: Provider{
BaseProvider: provider.BaseProvider{},
ExposedByDefault: false, ExposedByDefault: false,
FilterMarathonConstraints: false, FilterMarathonConstraints: false,
}, },
@ -45,7 +43,6 @@ func TestGetConfiguration(t *testing.T) {
}, },
}, },
p: Provider{ p: Provider{
BaseProvider: provider.BaseProvider{},
ExposedByDefault: false, ExposedByDefault: false,
FilterMarathonConstraints: false, FilterMarathonConstraints: false,
}, },
@ -66,7 +63,6 @@ func TestGetConfiguration(t *testing.T) {
}, },
}, },
p: Provider{ p: Provider{
BaseProvider: provider.BaseProvider{},
ExposedByDefault: false, ExposedByDefault: false,
FilterMarathonConstraints: false, FilterMarathonConstraints: false,
}, },
@ -87,7 +83,6 @@ func TestGetConfiguration(t *testing.T) {
Labels: &map[string]string{}, Labels: &map[string]string{},
}, },
p: Provider{ p: Provider{
BaseProvider: provider.BaseProvider{},
ExposedByDefault: false, ExposedByDefault: false,
FilterMarathonConstraints: true, FilterMarathonConstraints: true,
}, },
@ -108,7 +103,6 @@ func TestGetConfiguration(t *testing.T) {
Labels: &map[string]string{}, Labels: &map[string]string{},
}, },
p: Provider{ p: Provider{
BaseProvider: provider.BaseProvider{},
ExposedByDefault: true, ExposedByDefault: true,
FilterMarathonConstraints: false, FilterMarathonConstraints: false,
}, },
@ -129,7 +123,6 @@ func TestGetConfiguration(t *testing.T) {
}, },
}, },
p: Provider{ p: Provider{
BaseProvider: provider.BaseProvider{},
ExposedByDefault: true, ExposedByDefault: true,
FilterMarathonConstraints: false, FilterMarathonConstraints: false,
}, },
@ -150,7 +143,6 @@ func TestGetConfiguration(t *testing.T) {
}, },
}, },
p: Provider{ p: Provider{
BaseProvider: provider.BaseProvider{},
ExposedByDefault: true, ExposedByDefault: true,
FilterMarathonConstraints: false, FilterMarathonConstraints: false,
}, },

View file

@ -46,7 +46,9 @@ var _ provider.Provider = (*Provider)(nil)
// Provider holds configuration of the provider. // Provider holds configuration of the provider.
type Provider struct { type Provider struct {
provider.BaseProvider provider.Constrainer `mapstructure:",squash" export:"true"`
Trace bool `description:"Display additional provider logs." export:"true"`
Watch bool `description:"Watch provider" export:"true"`
Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon" export:"true"` Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon" export:"true"`
DefaultRule string `description:"Default rule"` DefaultRule string `description:"Default rule"`
ExposedByDefault bool `description:"Expose Marathon apps by default" export:"true"` ExposedByDefault bool `description:"Expose Marathon apps by default" export:"true"`
@ -89,7 +91,7 @@ func (p *Provider) Init() error {
} }
p.defaultRuleTpl = defaultRuleTpl p.defaultRuleTpl = defaultRuleTpl
return p.BaseProvider.Init() return nil
} }
// Provide allows the marathon provider to provide configurations to traefik // Provide allows the marathon provider to provide configurations to traefik