refactor: Logs & errors review.

- log & error: remove format if not necessary, add if necessary.
- add constants for k8s annotations.
- fix typos
This commit is contained in:
Fernandez Ludovic 2017-05-26 17:03:14 +02:00 committed by Ludovic Fernandez
parent 994e135368
commit cbccdd51c5
26 changed files with 125 additions and 128 deletions

View file

@ -6,7 +6,7 @@ import (
"crypto/rsa" "crypto/rsa"
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
"errors" "fmt"
"reflect" "reflect"
"sort" "sort"
"strings" "strings"
@ -178,7 +178,7 @@ func (dc *DomainsCertificates) renewCertificates(acmeCert *Certificate, domain D
return nil return nil
} }
} }
return errors.New("Certificate to renew not found for domain " + domain.Main) return fmt.Errorf("Certificate to renew not found for domain %s", domain.Main)
} }
func (dc *DomainsCertificates) addCertificateForDomains(acmeCert *Certificate, domain Domain) (*DomainsCertificate, error) { func (dc *DomainsCertificates) addCertificateForDomains(acmeCert *Certificate, domain Domain) (*DomainsCertificate, error) {

View file

@ -106,7 +106,7 @@ func (a *ACME) init() error {
a.defaultCertificate = cert a.defaultCertificate = cert
// TODO: to remove in the futurs // TODO: to remove in the futurs
if len(a.StorageFile) > 0 && len(a.Storage) == 0 { if len(a.StorageFile) > 0 && len(a.Storage) == 0 {
log.Warnf("ACME.StorageFile is deprecated, use ACME.Storage instead") log.Warn("ACME.StorageFile is deprecated, use ACME.Storage instead")
a.Storage = a.StorageFile a.Storage = a.StorageFile
} }
a.jobs = channels.NewInfiniteChannel() a.jobs = channels.NewInfiniteChannel()
@ -155,8 +155,8 @@ func (a *ACME) CreateClusterConfig(leadership *cluster.Leadership, tlsConfig *tl
ticker := time.NewTicker(24 * time.Hour) ticker := time.NewTicker(24 * time.Hour)
leadership.Pool.AddGoCtx(func(ctx context.Context) { leadership.Pool.AddGoCtx(func(ctx context.Context) {
log.Infof("Starting ACME renew job...") log.Info("Starting ACME renew job...")
defer log.Infof("Stopped ACME renew job...") defer log.Info("Stopped ACME renew job...")
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -196,7 +196,7 @@ func (a *ACME) CreateClusterConfig(leadership *cluster.Leadership, tlsConfig *tl
} }
if needRegister { if needRegister {
// New users will need to register; be sure to save it // New users will need to register; be sure to save it
log.Debugf("Register...") log.Debug("Register...")
reg, err := a.client.Register() reg, err := a.client.Register()
if err != nil { if err != nil {
return err return err
@ -205,7 +205,7 @@ func (a *ACME) CreateClusterConfig(leadership *cluster.Leadership, tlsConfig *tl
} }
// The client has a URL to the current Let's Encrypt Subscriber // The client has a URL to the current Let's Encrypt Subscriber
// Agreement. The user will need to agree to it. // Agreement. The user will need to agree to it.
log.Debugf("AgreeToTOS...") log.Debug("AgreeToTOS...")
err = a.client.AgreeToTOS() err = a.client.AgreeToTOS()
if err != nil { if err != nil {
// Let's Encrypt Subscriber Agreement renew ? // Let's Encrypt Subscriber Agreement renew ?
@ -254,7 +254,7 @@ func (a *ACME) CreateLocalConfig(tlsConfig *tls.Config, checkOnDemandDomain func
var account *Account var account *Account
if fileInfo, fileErr := os.Stat(a.Storage); fileErr == nil && fileInfo.Size() != 0 { if fileInfo, fileErr := os.Stat(a.Storage); fileErr == nil && fileInfo.Size() != 0 {
log.Infof("Loading ACME Account...") log.Info("Loading ACME Account...")
// load account // load account
object, err := localStore.Load() object, err := localStore.Load()
if err != nil { if err != nil {
@ -262,7 +262,7 @@ func (a *ACME) CreateLocalConfig(tlsConfig *tls.Config, checkOnDemandDomain func
} }
account = object.(*Account) account = object.(*Account)
} else { } else {
log.Infof("Generating ACME Account...") log.Info("Generating ACME Account...")
account, err = NewAccount(a.Email) account, err = NewAccount(a.Email)
if err != nil { if err != nil {
return err return err
@ -277,7 +277,7 @@ func (a *ACME) CreateLocalConfig(tlsConfig *tls.Config, checkOnDemandDomain func
if needRegister { if needRegister {
// New users will need to register; be sure to save it // New users will need to register; be sure to save it
log.Infof("Register...") log.Info("Register...")
reg, err := a.client.Register() reg, err := a.client.Register()
if err != nil { if err != nil {
return err return err
@ -287,7 +287,7 @@ func (a *ACME) CreateLocalConfig(tlsConfig *tls.Config, checkOnDemandDomain func
// The client has a URL to the current Let's Encrypt Subscriber // The client has a URL to the current Let's Encrypt Subscriber
// Agreement. The user will need to agree to it. // Agreement. The user will need to agree to it.
log.Debugf("AgreeToTOS...") log.Debug("AgreeToTOS...")
err = a.client.AgreeToTOS() err = a.client.AgreeToTOS()
if err != nil { if err != nil {
// Let's Encrypt Subscriber Agreement renew ? // Let's Encrypt Subscriber Agreement renew ?
@ -356,7 +356,7 @@ func (a *ACME) getCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificat
func (a *ACME) retrieveCertificates() { func (a *ACME) retrieveCertificates() {
a.jobs.In() <- func() { a.jobs.In() <- func() {
log.Infof("Retrieving ACME certificates...") log.Info("Retrieving ACME certificates...")
for _, domain := range a.Domains { for _, domain := range a.Domains {
// check if cert isn't already loaded // check if cert isn't already loaded
account := a.store.Get().(*Account) account := a.store.Get().(*Account)
@ -387,13 +387,13 @@ func (a *ACME) retrieveCertificates() {
} }
} }
} }
log.Infof("Retrieved ACME certificates") log.Info("Retrieved ACME certificates")
} }
} }
func (a *ACME) renewCertificates() { func (a *ACME) renewCertificates() {
a.jobs.In() <- func() { a.jobs.In() <- func() {
log.Debugf("Testing certificate renew...") log.Debug("Testing certificate renew...")
account := a.store.Get().(*Account) account := a.store.Get().(*Account)
for _, certificateResource := range account.DomainsCertificate.Certs { for _, certificateResource := range account.DomainsCertificate.Certs {
if certificateResource.needRenew() { if certificateResource.needRenew() {
@ -453,7 +453,7 @@ func dnsOverrideDelay(delay int) error {
} }
func (a *ACME) buildACMEClient(account *Account) (*acme.Client, error) { func (a *ACME) buildACMEClient(account *Account) (*acme.Client, error) {
log.Debugf("Building ACME client...") log.Debug("Building ACME client...")
caServer := "https://acme-v01.api.letsencrypt.org/directory" caServer := "https://acme-v01.api.letsencrypt.org/directory"
if len(a.CAServer) > 0 { if len(a.CAServer) > 0 {
caServer = a.CAServer caServer = a.CAServer

View file

@ -222,14 +222,14 @@ func TestNoPreCheckOverride(t *testing.T) {
t.Errorf("Error in dnsOverrideDelay :%v", err) t.Errorf("Error in dnsOverrideDelay :%v", err)
} }
if acme.PreCheckDNS != nil { if acme.PreCheckDNS != nil {
t.Errorf("Unexpected change to acme.PreCheckDNS when leaving DNS verification as is.") t.Error("Unexpected change to acme.PreCheckDNS when leaving DNS verification as is.")
} }
} }
func TestSillyPreCheckOverride(t *testing.T) { func TestSillyPreCheckOverride(t *testing.T) {
err := dnsOverrideDelay(-5) err := dnsOverrideDelay(-5)
if err == nil { if err == nil {
t.Errorf("Missing expected error in dnsOverrideDelay!") t.Error("Missing expected error in dnsOverrideDelay!")
} }
} }
@ -240,7 +240,7 @@ func TestPreCheckOverride(t *testing.T) {
t.Errorf("Error in dnsOverrideDelay :%v", err) t.Errorf("Error in dnsOverrideDelay :%v", err)
} }
if acme.PreCheckDNS == nil { if acme.PreCheckDNS == nil {
t.Errorf("No change to acme.PreCheckDNS when meant to be adding enforcing override function.") t.Error("No change to acme.PreCheckDNS when meant to be adding enforcing override function.")
} }
} }
@ -271,9 +271,9 @@ cijFkALeQp/qyeXdFld2v9gUN3eCgljgcl0QweRoIc=---`)
t.Errorf("Error in buildACMEClient: %v", err) t.Errorf("Error in buildACMEClient: %v", err)
} }
if client == nil { if client == nil {
t.Errorf("No client from buildACMEClient!") t.Error("No client from buildACMEClient!")
} }
if acme.PreCheckDNS == nil { if acme.PreCheckDNS == nil {
t.Errorf("No change to acme.PreCheckDNS when meant to be adding enforcing override function.") t.Error("No change to acme.PreCheckDNS when meant to be adding enforcing override function.")
} }
} }

View file

@ -97,7 +97,6 @@ func (d *Datastore) watchChanges() error {
if err != nil { if err != nil {
return err return err
} }
// log.Debugf("Datastore object change received: %+v", d.meta)
if d.listener != nil { if d.listener != nil {
err := d.listener(d.meta.object) err := d.listener(d.meta.object)
if err != nil { if err != nil {
@ -119,7 +118,7 @@ func (d *Datastore) watchChanges() error {
} }
func (d *Datastore) reload() error { func (d *Datastore) reload() error {
log.Debugf("Datastore reload") log.Debug("Datastore reload")
d.localLock.Lock() d.localLock.Lock()
err := d.kv.LoadConfig(d.meta) err := d.kv.LoadConfig(d.meta)
if err != nil { if err != nil {

View file

@ -118,7 +118,7 @@ func newBugCmd(traefikConfiguration interface{}, traefikPointersConfiguration in
body := bug.String() body := bug.String()
URL := bugtracker + "?body=" + url.QueryEscape(body) URL := bugtracker + "?body=" + url.QueryEscape(body)
if err := openBrowser(URL); err != nil { if err := openBrowser(URL); err != nil {
fmt.Print("Please file a new issue at " + bugtracker + " using this template:\n\n") fmt.Printf("Please file a new issue at %s using this template:\n\n", bugtracker)
fmt.Print(body) fmt.Print(body)
} }

View file

@ -30,7 +30,7 @@ func newVersionCmd() *flaeg.Command {
if err := getVersionPrint(os.Stdout); err != nil { if err := getVersionPrint(os.Stdout); err != nil {
return err return err
} }
fmt.Printf("\n") fmt.Print("\n")
return nil return nil
}, },

View file

@ -98,7 +98,7 @@ func (hc *HealthCheck) execute(ctx context.Context, backendID string, backend *B
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
log.Debugf("Stopping all current Healthcheck goroutines") log.Debug("Stopping all current Healthcheck goroutines")
return return
case <-ticker.C: case <-ticker.C:
log.Debugf("Refreshing healthcheck for currentBackend %s ", backendID) log.Debugf("Refreshing healthcheck for currentBackend %s ", backendID)

View file

@ -12,8 +12,7 @@ import (
const commonLogTimeFormat = "02/Jan/2006:15:04:05 -0700" const commonLogTimeFormat = "02/Jan/2006:15:04:05 -0700"
// CommonLogFormatter provides formatting in the Traefik common log format // CommonLogFormatter provides formatting in the Traefik common log format
type CommonLogFormatter struct { type CommonLogFormatter struct{}
}
//Format formats the log entry in the Traefik common log format //Format formats the log entry in the Traefik common log format
func (f *CommonLogFormatter) Format(entry *logrus.Entry) ([]byte, error) { func (f *CommonLogFormatter) Format(entry *logrus.Entry) ([]byte, error) {

View file

@ -70,10 +70,10 @@ func TestLogger(t *testing.T) {
if logdata, err := ioutil.ReadFile(logfilePath); err != nil { if logdata, err := ioutil.ReadFile(logfilePath); err != nil {
fmt.Printf("%s\n%s\n", string(logdata), err.Error()) fmt.Printf("%s\n%s\n", string(logdata), err.Error())
assert.Nil(t, err) assert.NoError(t, err)
} else if tokens, err := shellwords.Parse(string(logdata)); err != nil { } else if tokens, err := shellwords.Parse(string(logdata)); err != nil {
fmt.Printf("%s\n", err.Error()) fmt.Printf("%s\n", err.Error())
assert.Nil(t, err) assert.NoError(t, err)
} else if assert.Equal(t, 14, len(tokens), printLogdata(logdata)) { } else if assert.Equal(t, 14, len(tokens), printLogdata(logdata)) {
assert.Equal(t, testHostname, tokens[0], printLogdata(logdata)) assert.Equal(t, testHostname, tokens[0], printLogdata(logdata))
assert.Equal(t, testUsername, tokens[2], printLogdata(logdata)) assert.Equal(t, testUsername, tokens[2], printLogdata(logdata))

View file

@ -33,10 +33,10 @@ func NewAuthenticator(authConfig *types.Auth) (*Authenticator, error) {
basicAuth := auth.NewBasicAuthenticator("traefik", authenticator.secretBasic) basicAuth := auth.NewBasicAuthenticator("traefik", authenticator.secretBasic)
authenticator.handler = negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { authenticator.handler = negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
if username := basicAuth.CheckAuth(r); username == "" { if username := basicAuth.CheckAuth(r); username == "" {
log.Debugf("Basic auth failed...") log.Debug("Basic auth failed...")
basicAuth.RequireAuth(w, r) basicAuth.RequireAuth(w, r)
} else { } else {
log.Debugf("Basic auth success...") log.Debug("Basic auth success...")
if authConfig.HeaderField != "" { if authConfig.HeaderField != "" {
r.Header[authConfig.HeaderField] = []string{username} r.Header[authConfig.HeaderField] = []string{username}
} }
@ -51,10 +51,10 @@ func NewAuthenticator(authConfig *types.Auth) (*Authenticator, error) {
digestAuth := auth.NewDigestAuthenticator("traefik", authenticator.secretDigest) digestAuth := auth.NewDigestAuthenticator("traefik", authenticator.secretDigest)
authenticator.handler = negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { authenticator.handler = negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
if username, _ := digestAuth.CheckAuth(r); username == "" { if username, _ := digestAuth.CheckAuth(r); username == "" {
log.Debugf("Digest auth failed...") log.Debug("Digest auth failed...")
digestAuth.RequireAuth(w, r) digestAuth.RequireAuth(w, r)
} else { } else {
log.Debugf("Digest auth success...") log.Debug("Digest auth success...")
if authConfig.HeaderField != "" { if authConfig.HeaderField != "" {
r.Header[authConfig.HeaderField] = []string{username} r.Header[authConfig.HeaderField] = []string{username}
} }

View file

@ -7,6 +7,7 @@ import (
"github.com/codegangsta/negroni" "github.com/codegangsta/negroni"
"github.com/containous/traefik/log" "github.com/containous/traefik/log"
"github.com/pkg/errors"
) )
// IPWhitelister is a middleware that provides Checks of the Requesting IP against a set of Whitelists // IPWhitelister is a middleware that provides Checks of the Requesting IP against a set of Whitelists
@ -20,7 +21,7 @@ func NewIPWhitelister(whitelistStrings []string) (*IPWhitelister, error) {
whitelister := IPWhitelister{} whitelister := IPWhitelister{}
if len(whitelistStrings) == 0 { if len(whitelistStrings) == 0 {
return nil, fmt.Errorf("no whitelists provided") return nil, errors.New("no whitelists provided")
} }
for _, whitelistString := range whitelistStrings { for _, whitelistString := range whitelistStrings {

View file

@ -9,7 +9,6 @@ import (
"time" "time"
"github.com/BurntSushi/ty/fun" "github.com/BurntSushi/ty/fun"
"github.com/Sirupsen/logrus"
"github.com/cenk/backoff" "github.com/cenk/backoff"
"github.com/containous/traefik/job" "github.com/containous/traefik/job"
"github.com/containous/traefik/log" "github.com/containous/traefik/log"
@ -96,7 +95,7 @@ func (p *CatalogProvider) watchServices(stopCh <-chan struct{}) <-chan map[strin
data, catalogMeta, err := catalog.Services(catalogOptions) data, catalogMeta, err := catalog.Services(catalogOptions)
if err != nil { if err != nil {
log.WithError(err).Errorf("Failed to list services") log.WithError(err).Error("Failed to list services")
return return
} }
@ -105,7 +104,7 @@ func (p *CatalogProvider) watchServices(stopCh <-chan struct{}) <-chan map[strin
// (intentionally there is no interest in the received data). // (intentionally there is no interest in the received data).
_, healthMeta, err := health.State("passing", healthOptions) _, healthMeta, err := health.State("passing", healthOptions)
if err != nil { if err != nil {
log.WithError(err).Errorf("Failed to retrieve health checks") log.WithError(err).Error("Failed to retrieve health checks")
return return
} }
@ -133,7 +132,7 @@ func (p *CatalogProvider) healthyNodes(service string) (catalogUpdate, error) {
opts := &api.QueryOptions{} opts := &api.QueryOptions{}
data, _, err := health.Service(service, "", true, opts) data, _, err := health.Service(service, "", true, opts)
if err != nil { if err != nil {
log.WithError(err).Errorf("Failed to fetch details of " + service) log.WithError(err).Errorf("Failed to fetch details of %s", service)
return catalogUpdate{}, err return catalogUpdate{}, err
} }
@ -285,9 +284,7 @@ func (p *CatalogProvider) getNodes(index map[string][]string) ([]catalogUpdate,
name := strings.ToLower(service) name := strings.ToLower(service)
if !strings.Contains(name, " ") && !visited[name] { if !strings.Contains(name, " ") && !visited[name] {
visited[name] = true visited[name] = true
log.WithFields(logrus.Fields{ log.WithField("service", name).Debug("Fetching service")
"service": name,
}).Debug("Fetching service")
healthy, err := p.healthyNodes(name) healthy, err := p.healthyNodes(name)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -2,7 +2,7 @@ package docker
import ( import (
"context" "context"
"errors" "fmt"
"math" "math"
"net" "net"
"net/http" "net/http"
@ -705,7 +705,7 @@ func getLabel(container dockerData, label string) (string, error) {
return value, nil return value, nil
} }
} }
return "", errors.New("Label not found:" + label) return "", fmt.Errorf("label not found: %s", label)
} }
func getLabels(container dockerData, labels []string) (map[string]string, error) { func getLabels(container dockerData, labels []string) (map[string]string, error) {
@ -715,7 +715,7 @@ func getLabels(container dockerData, labels []string) (map[string]string, error)
foundLabel, err := getLabel(container, label) foundLabel, err := getLabel(container, label)
// Error out only if one of them is defined. // Error out only if one of them is defined.
if err != nil { if err != nil {
globalErr = errors.New("Label not found: " + label) globalErr = fmt.Errorf("label not found: %s", label)
continue continue
} }
foundLabels[label] = foundLabel foundLabels[label] = foundLabel

View file

@ -469,7 +469,7 @@ func TestDockerGetLabel(t *testing.T) {
}{ }{
{ {
container: containerJSON(), container: containerJSON(),
expected: "Label not found:", expected: "label not found:",
}, },
{ {
container: containerJSON(labels(map[string]string{ container: containerJSON(labels(map[string]string{
@ -507,7 +507,7 @@ func TestDockerGetLabels(t *testing.T) {
{ {
container: containerJSON(), container: containerJSON(),
expectedLabels: map[string]string{}, expectedLabels: map[string]string{},
expectedError: "Label not found:", expectedError: "label not found:",
}, },
{ {
container: containerJSON(labels(map[string]string{ container: containerJSON(labels(map[string]string{
@ -516,7 +516,7 @@ func TestDockerGetLabels(t *testing.T) {
expectedLabels: map[string]string{ expectedLabels: map[string]string{
"foo": "fooz", "foo": "fooz",
}, },
expectedError: "Label not found: bar", expectedError: "label not found: bar",
}, },
{ {
container: containerJSON(labels(map[string]string{ container: containerJSON(labels(map[string]string{

View file

@ -415,7 +415,7 @@ func TestSwarmGetLabel(t *testing.T) {
}{ }{
{ {
service: swarmService(), service: swarmService(),
expected: "Label not found:", expected: "label not found:",
networks: map[string]*docker.NetworkResource{}, networks: map[string]*docker.NetworkResource{},
}, },
{ {
@ -439,7 +439,7 @@ func TestSwarmGetLabel(t *testing.T) {
} }
} else { } else {
if label != "bar" { if label != "bar" {
t.Errorf("expected label 'bar', got %s", label) t.Errorf("expected label 'bar', got '%s'", label)
} }
} }
}) })
@ -456,7 +456,7 @@ func TestSwarmGetLabels(t *testing.T) {
{ {
service: swarmService(), service: swarmService(),
expectedLabels: map[string]string{}, expectedLabels: map[string]string{},
expectedError: "Label not found:", expectedError: "label not found:",
networks: map[string]*docker.NetworkResource{}, networks: map[string]*docker.NetworkResource{},
}, },
{ {
@ -466,7 +466,7 @@ func TestSwarmGetLabels(t *testing.T) {
expectedLabels: map[string]string{ expectedLabels: map[string]string{
"foo": "fooz", "foo": "fooz",
}, },
expectedError: "Label not found: bar", expectedError: "label not found: bar",
networks: map[string]*docker.NetworkResource{}, networks: map[string]*docker.NetworkResource{},
}, },
{ {

View file

@ -40,7 +40,7 @@ type dynamoClient struct {
// createClient configures aws credentials and creates a dynamoClient // createClient configures aws credentials and creates a dynamoClient
func (p *Provider) createClient() (*dynamoClient, error) { func (p *Provider) createClient() (*dynamoClient, error) {
log.Infof("Creating Provider client...") log.Info("Creating Provider client...")
sess := session.New() sess := session.New()
if p.Region == "" { if p.Region == "" {
return nil, errors.New("no Region provided for Provider") return nil, errors.New("no Region provided for Provider")
@ -105,14 +105,14 @@ func (p *Provider) loadDynamoConfig(client *dynamoClient) (*types.Configuration,
// verify the type of each item by checking to see if it has // verify the type of each item by checking to see if it has
// the corresponding type, backend or frontend map // the corresponding type, backend or frontend map
if backend, exists := item["backend"]; exists { if backend, exists := item["backend"]; exists {
log.Debugf("Unmarshaling backend from Provider...") log.Debug("Unmarshaling backend from Provider...")
tmpBackend := &types.Backend{} tmpBackend := &types.Backend{}
err = dynamodbattribute.Unmarshal(backend, tmpBackend) err = dynamodbattribute.Unmarshal(backend, tmpBackend)
if err != nil { if err != nil {
log.Errorf(err.Error()) log.Errorf(err.Error())
} else { } else {
backends[*item["name"].S] = tmpBackend backends[*item["name"].S] = tmpBackend
log.Debugf("Backend from Provider unmarshalled successfully") log.Debug("Backend from Provider unmarshalled successfully")
} }
} else if frontend, exists := item["frontend"]; exists { } else if frontend, exists := item["frontend"]; exists {
log.Debugf("Unmarshaling frontend from Provider...") log.Debugf("Unmarshaling frontend from Provider...")
@ -122,7 +122,7 @@ func (p *Provider) loadDynamoConfig(client *dynamoClient) (*types.Configuration,
log.Errorf(err.Error()) log.Errorf(err.Error())
} else { } else {
frontends[*item["name"].S] = tmpFrontend frontends[*item["name"].S] = tmpFrontend
log.Debugf("Frontend from Provider unmarshalled successfully") log.Debug("Frontend from Provider unmarshalled successfully")
} }
} else { } else {
log.Warnf("Error in format of Provider Item: %v", item) log.Warnf("Error in format of Provider Item: %v", item)
@ -176,7 +176,7 @@ func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *s
reload := time.NewTicker(time.Second * time.Duration(p.RefreshSeconds)) reload := time.NewTicker(time.Second * time.Duration(p.RefreshSeconds))
defer reload.Stop() defer reload.Stop()
for { for {
log.Debugf("Watching Provider...") log.Debug("Watching Provider...")
select { select {
case <-reload.C: case <-reload.C:
configuration, err := p.loadDynamoConfig(aws) configuration, err := p.loadDynamoConfig(aws)

View file

@ -29,6 +29,10 @@ const (
annotationFrontendRuleType = "traefik.frontend.rule.type" annotationFrontendRuleType = "traefik.frontend.rule.type"
ruleTypePathPrefix = "PathPrefix" ruleTypePathPrefix = "PathPrefix"
annotationKubernetesIngressClass = "kubernetes.io/ingress.class"
annotationKubernetesAuthRealm = "ingress.kubernetes.io/auth-realm"
annotationKubernetesAuthType = "ingress.kubernetes.io/auth-type"
annotationKubernetesAuthSecret = "ingress.kubernetes.io/auth-secret"
annotationKubernetesWhitelistSourceRange = "ingress.kubernetes.io/whitelist-source-range" annotationKubernetesWhitelistSourceRange = "ingress.kubernetes.io/whitelist-source-range"
) )
@ -127,11 +131,11 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
ingresses := k8sClient.GetIngresses(p.Namespaces) ingresses := k8sClient.GetIngresses(p.Namespaces)
templateObjects := types.Configuration{ templateObjects := types.Configuration{
map[string]*types.Backend{}, Backends: map[string]*types.Backend{},
map[string]*types.Frontend{}, Frontends: map[string]*types.Frontend{},
} }
for _, i := range ingresses { for _, i := range ingresses {
ingressClass := i.Annotations["kubernetes.io/ingress.class"] ingressClass := i.Annotations[annotationKubernetesIngressClass]
if !shouldProcessIngress(ingressClass) { if !shouldProcessIngress(ingressClass) {
continue continue
@ -139,7 +143,7 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
for _, r := range i.Spec.Rules { for _, r := range i.Spec.Rules {
if r.HTTP == nil { if r.HTTP == nil {
log.Warnf("Error in ingress: HTTP is nil") log.Warn("Error in ingress: HTTP is nil")
continue continue
} }
for _, pa := range r.HTTP.Paths { for _, pa := range r.HTTP.Paths {
@ -166,7 +170,7 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
default: default:
log.Warnf("Unknown value '%s' for traefik.frontend.passHostHeader, falling back to %s", passHostHeaderAnnotation, PassHostHeader) log.Warnf("Unknown value '%s' for traefik.frontend.passHostHeader, falling back to %s", passHostHeaderAnnotation, PassHostHeader)
} }
if realm := i.Annotations["ingress.kubernetes.io/auth-realm"]; realm != "" && realm != traefikDefaultRealm { if realm := i.Annotations[annotationKubernetesAuthRealm]; realm != "" && realm != traefikDefaultRealm {
return nil, errors.New("no realm customization supported") return nil, errors.New("no realm customization supported")
} }
@ -291,14 +295,14 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
} }
func handleBasicAuthConfig(i *v1beta1.Ingress, k8sClient Client) ([]string, error) { func handleBasicAuthConfig(i *v1beta1.Ingress, k8sClient Client) ([]string, error) {
authType, exists := i.Annotations["ingress.kubernetes.io/auth-type"] authType, exists := i.Annotations[annotationKubernetesAuthType]
if !exists { if !exists {
return nil, nil return nil, nil
} }
if strings.ToLower(authType) != "basic" { if strings.ToLower(authType) != "basic" {
return nil, fmt.Errorf("unsupported auth-type: %q", authType) return nil, fmt.Errorf("unsupported auth-type: %q", authType)
} }
authSecret := i.Annotations["ingress.kubernetes.io/auth-secret"] authSecret := i.Annotations[annotationKubernetesAuthSecret]
if authSecret == "" { if authSecret == "" {
return nil, errors.New("auth-secret annotation must be set") return nil, errors.New("auth-secret annotation must be set")
} }

View file

@ -108,7 +108,7 @@ func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *s
case <-stop: case <-stop:
return return
case event := <-update: case event := <-update:
log.Debug("Provider event receveived", event) log.Debug("Provider event received", event)
configuration := p.loadMarathonConfig() configuration := p.loadMarathonConfig()
if configuration != nil { if configuration != nil {
configurationChan <- types.ConfigMessage{ configurationChan <- types.ConfigMessage{

View file

@ -112,11 +112,11 @@ func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *s
} }
notify := func(err error, time time.Duration) { notify := func(err error, time time.Duration) {
log.Errorf("mesos connection error %+v, retrying in %s", err, time) log.Errorf("Mesos connection error %+v, retrying in %s", err, time)
} }
err := backoff.RetryNotify(safe.OperationWithRecover(operation), job.NewBackOff(backoff.NewExponentialBackOff()), notify) err := backoff.RetryNotify(safe.OperationWithRecover(operation), job.NewBackOff(backoff.NewExponentialBackOff()), notify)
if err != nil { if err != nil {
log.Errorf("Cannot connect to mesos server %+v", err) log.Errorf("Cannot connect to Mesos server %+v", err)
} }
return nil return nil
} }
@ -141,7 +141,7 @@ func (p *Provider) loadMesosConfig() *types.Configuration {
t := records.NewRecordGenerator(time.Duration(p.StateTimeoutSecond) * time.Second) t := records.NewRecordGenerator(time.Duration(p.StateTimeoutSecond) * time.Second)
sj, err := t.FindMaster(p.Masters...) sj, err := t.FindMaster(p.Masters...)
if err != nil { if err != nil {
log.Errorf("Failed to create a client for mesos, error: %s", err) log.Errorf("Failed to create a client for Mesos, error: %s", err)
return nil return nil
} }
tasks := p.taskRecords(sj) tasks := p.taskRecords(sj)
@ -197,11 +197,11 @@ func labels(task state.Task, key string) string {
func mesosTaskFilter(task state.Task, exposedByDefaultFlag bool) bool { func mesosTaskFilter(task state.Task, exposedByDefaultFlag bool) bool {
if len(task.DiscoveryInfo.Ports.DiscoveryPorts) == 0 { if len(task.DiscoveryInfo.Ports.DiscoveryPorts) == 0 {
log.Debugf("Filtering mesos task without port %s", task.Name) log.Debugf("Filtering Mesos task without port %s", task.Name)
return false return false
} }
if !isMesosApplicationEnabled(task, exposedByDefaultFlag) { if !isMesosApplicationEnabled(task, exposedByDefaultFlag) {
log.Debugf("Filtering disabled mesos task %s", task.DiscoveryInfo.Name) log.Debugf("Filtering disabled Mesos task %s", task.DiscoveryInfo.Name)
return false return false
} }
@ -209,20 +209,20 @@ func mesosTaskFilter(task state.Task, exposedByDefaultFlag bool) bool {
portIndexLabel := labels(task, "traefik.portIndex") portIndexLabel := labels(task, "traefik.portIndex")
portValueLabel := labels(task, "traefik.port") portValueLabel := labels(task, "traefik.port")
if portIndexLabel != "" && portValueLabel != "" { if portIndexLabel != "" && portValueLabel != "" {
log.Debugf("Filtering mesos task %s specifying both traefik.portIndex and traefik.port labels", task.Name) log.Debugf("Filtering Mesos task %s specifying both traefik.portIndex and traefik.port labels", task.Name)
return false return false
} }
if portIndexLabel != "" { if portIndexLabel != "" {
index, err := strconv.Atoi(labels(task, "traefik.portIndex")) index, err := strconv.Atoi(labels(task, "traefik.portIndex"))
if err != nil || index < 0 || index > len(task.DiscoveryInfo.Ports.DiscoveryPorts)-1 { if err != nil || index < 0 || index > len(task.DiscoveryInfo.Ports.DiscoveryPorts)-1 {
log.Debugf("Filtering mesos task %s with unexpected value for traefik.portIndex label", task.Name) log.Debugf("Filtering Mesos task %s with unexpected value for traefik.portIndex label", task.Name)
return false return false
} }
} }
if portValueLabel != "" { if portValueLabel != "" {
port, err := strconv.Atoi(labels(task, "traefik.port")) port, err := strconv.Atoi(labels(task, "traefik.port"))
if err != nil { if err != nil {
log.Debugf("Filtering mesos task %s with unexpected value for traefik.port label", task.Name) log.Debugf("Filtering Mesos task %s with unexpected value for traefik.port label", task.Name)
return false return false
} }
@ -235,14 +235,14 @@ func mesosTaskFilter(task state.Task, exposedByDefaultFlag bool) bool {
} }
if !foundPort { if !foundPort {
log.Debugf("Filtering mesos task %s without a matching port for traefik.port label", task.Name) log.Debugf("Filtering Mesos task %s without a matching port for traefik.port label", task.Name)
return false return false
} }
} }
//filter healthchecks //filter healthchecks
if task.Statuses != nil && len(task.Statuses) > 0 && task.Statuses[0].Healthy != nil && !*task.Statuses[0].Healthy { if task.Statuses != nil && len(task.Statuses) > 0 && task.Statuses[0].Healthy != nil && !*task.Statuses[0].Healthy {
log.Debugf("Filtering mesos task %s with bad healthcheck", task.DiscoveryInfo.Name) log.Debugf("Filtering Mesos task %s with bad healthcheck", task.DiscoveryInfo.Name)
return false return false
} }
@ -274,7 +274,7 @@ func (p *Provider) getLabel(task state.Task, label string) (string, error) {
func (p *Provider) getPort(task state.Task, applications []state.Task) string { func (p *Provider) getPort(task state.Task, applications []state.Task) string {
application, err := getMesos(task, applications) application, err := getMesos(task, applications)
if err != nil { if err != nil {
log.Errorf("Unable to get mesos application from task %s", task.DiscoveryInfo.Name) log.Errorf("Unable to get Mesos application from task %s", task.DiscoveryInfo.Name)
return "" return ""
} }
@ -296,7 +296,7 @@ func (p *Provider) getPort(task state.Task, applications []state.Task) string {
func (p *Provider) getWeight(task state.Task, applications []state.Task) string { func (p *Provider) getWeight(task state.Task, applications []state.Task) string {
application, errApp := getMesos(task, applications) application, errApp := getMesos(task, applications)
if errApp != nil { if errApp != nil {
log.Errorf("Unable to get mesos application from task %s", task.DiscoveryInfo.Name) log.Errorf("Unable to get Mesos application from task %s", task.DiscoveryInfo.Name)
return "0" return "0"
} }
@ -316,7 +316,7 @@ func (p *Provider) getDomain(task state.Task) string {
func (p *Provider) getProtocol(task state.Task, applications []state.Task) string { func (p *Provider) getProtocol(task state.Task, applications []state.Task) string {
application, errApp := getMesos(task, applications) application, errApp := getMesos(task, applications)
if errApp != nil { if errApp != nil {
log.Errorf("Unable to get mesos application from task %s", task.DiscoveryInfo.Name) log.Errorf("Unable to get Mesos application from task %s", task.DiscoveryInfo.Name)
return "http" return "http"
} }
if label, err := p.getLabel(application, "traefik.protocol"); err == nil { if label, err := p.getLabel(application, "traefik.protocol"); err == nil {
@ -358,7 +358,7 @@ func (p *Provider) getFrontendRule(task state.Task) string {
func (p *Provider) getBackend(task state.Task, applications []state.Task) string { func (p *Provider) getBackend(task state.Task, applications []state.Task) string {
application, errApp := getMesos(task, applications) application, errApp := getMesos(task, applications)
if errApp != nil { if errApp != nil {
log.Errorf("Unable to get mesos application from task %s", task.DiscoveryInfo.Name) log.Errorf("Unable to get Mesos application from task %s", task.DiscoveryInfo.Name)
return "" return ""
} }
return p.getFrontendBackend(application) return p.getFrontendBackend(application)
@ -392,9 +392,9 @@ func detectMasters(zk string, masters []string) <-chan []string {
if zk != "" { if zk != "" {
log.Debugf("Starting master detector for ZK ", zk) log.Debugf("Starting master detector for ZK ", zk)
if md, err := detector.New(zk); err != nil { if md, err := detector.New(zk); err != nil {
log.Errorf("failed to create master detector: %v", err) log.Errorf("Failed to create master detector: %v", err)
} else if err := md.Detect(detect.NewMasters(masters, changed)); err != nil { } else if err := md.Detect(detect.NewMasters(masters, changed)); err != nil {
log.Errorf("failed to initialize master detector: %v", err) log.Errorf("Failed to initialize master detector: %v", err)
} }
} else { } else {
changed <- masters changed <- masters

View file

@ -141,7 +141,7 @@ func TestGetConfiguration(t *testing.T) {
t.Fatalf("Shouldn't have error out, got %v", err) t.Fatalf("Shouldn't have error out, got %v", err)
} }
if configuration == nil { if configuration == nil {
t.Fatalf("Configuration should not be nil, but was") t.Fatal("Configuration should not be nil, but was")
} }
} }
@ -203,15 +203,15 @@ func TestGetConfigurationReturnsCorrectMaxConnConfiguration(t *testing.T) {
t.Fatalf("Shouldn't have error out, got %v", err) t.Fatalf("Shouldn't have error out, got %v", err)
} }
if configuration == nil { if configuration == nil {
t.Fatalf("Configuration should not be nil, but was") t.Fatal("Configuration should not be nil, but was")
} }
if configuration.Backends["backend1"].MaxConn.Amount != 10 { if configuration.Backends["backend1"].MaxConn.Amount != 10 {
t.Fatalf("Configuration did not parse MaxConn.Amount properly") t.Fatal("Configuration did not parse MaxConn.Amount properly")
} }
if configuration.Backends["backend1"].MaxConn.ExtractorFunc != "request.host" { if configuration.Backends["backend1"].MaxConn.ExtractorFunc != "request.host" {
t.Fatalf("Configuration did not parse MaxConn.ExtractorFunc properly") t.Fatal("Configuration did not parse MaxConn.ExtractorFunc properly")
} }
} }
@ -224,7 +224,7 @@ func TestNilClientTLS(t *testing.T) {
} }
_, err := provider.TLS.CreateTLSConfig() _, err := provider.TLS.CreateTLSConfig()
if err != nil { if err != nil {
t.Fatalf("CreateTLSConfig should assume that consumer does not want a TLS configuration if input is nil") t.Fatal("CreateTLSConfig should assume that consumer does not want a TLS configuration if input is nil")
} }
} }
@ -371,12 +371,12 @@ func TestDefaultFuncMap(t *testing.T) {
t.Fatalf("Shouldn't have error out, got %v", err) t.Fatalf("Shouldn't have error out, got %v", err)
} }
if configuration == nil { if configuration == nil {
t.Fatalf("Configuration should not be nil, but was") t.Fatal("Configuration should not be nil, but was")
} }
if _, ok := configuration.Backends["backend1"]; !ok { if _, ok := configuration.Backends["backend1"]; !ok {
t.Fatalf("backend1 should exists, but it not") t.Fatal("backend1 should exists, but it not")
} }
if _, ok := configuration.Frontends["frontend-1"]; !ok { if _, ok := configuration.Frontends["frontend-1"]; !ok {
t.Fatalf("Frontend frontend-1 should exists, but it not") t.Fatal("Frontend frontend-1 should exists, but it not")
} }
} }

View file

@ -27,5 +27,4 @@ func (oxylogger *OxyLogger) Errorf(format string, args ...interface{}) {
func notFoundHandler(w http.ResponseWriter, r *http.Request) { func notFoundHandler(w http.ResponseWriter, r *http.Request) {
http.NotFound(w, r) http.NotFound(w, r)
//templatesRenderer.HTML(w, http.StatusNotFound, "notFound", nil)
} }

View file

@ -88,7 +88,7 @@ func (dep *DefaultEntryPoints) String() string {
func (dep *DefaultEntryPoints) Set(value string) error { func (dep *DefaultEntryPoints) Set(value string) error {
entrypoints := strings.Split(value, ",") entrypoints := strings.Split(value, ",")
if len(entrypoints) == 0 { if len(entrypoints) == 0 {
return errors.New("Bad DefaultEntryPoints format: " + value) return fmt.Errorf("bad DefaultEntryPoints format: %s", value)
} }
for _, entrypoint := range entrypoints { for _, entrypoint := range entrypoints {
*dep = append(*dep, entrypoint) *dep = append(*dep, entrypoint)
@ -127,7 +127,7 @@ func (ep *EntryPoints) Set(value string) error {
regex := regexp.MustCompile("(?:Name:(?P<Name>\\S*))\\s*(?:Address:(?P<Address>\\S*))?\\s*(?:TLS:(?P<TLS>\\S*))?\\s*((?P<TLSACME>TLS))?\\s*(?:CA:(?P<CA>\\S*))?\\s*(?:Redirect.EntryPoint:(?P<RedirectEntryPoint>\\S*))?\\s*(?:Redirect.Regex:(?P<RedirectRegex>\\S*))?\\s*(?:Redirect.Replacement:(?P<RedirectReplacement>\\S*))?\\s*(?:Compress:(?P<Compress>\\S*))?") regex := regexp.MustCompile("(?:Name:(?P<Name>\\S*))\\s*(?:Address:(?P<Address>\\S*))?\\s*(?:TLS:(?P<TLS>\\S*))?\\s*((?P<TLSACME>TLS))?\\s*(?:CA:(?P<CA>\\S*))?\\s*(?:Redirect.EntryPoint:(?P<RedirectEntryPoint>\\S*))?\\s*(?:Redirect.Regex:(?P<RedirectRegex>\\S*))?\\s*(?:Redirect.Replacement:(?P<RedirectReplacement>\\S*))?\\s*(?:Compress:(?P<Compress>\\S*))?")
match := regex.FindAllStringSubmatch(value, -1) match := regex.FindAllStringSubmatch(value, -1)
if match == nil { if match == nil {
return errors.New("Bad EntryPoints format: " + value) return fmt.Errorf("bad EntryPoints format: %s", value)
} }
matchResult := match[0] matchResult := match[0]
result := make(map[string]string) result := make(map[string]string)
@ -269,10 +269,10 @@ func (certs *Certificates) CreateTLSConfig() (*tls.Config, error) {
if errKey == nil { if errKey == nil {
isAPath = true isAPath = true
} else { } else {
return nil, fmt.Errorf("bad TLS Certificate KeyFile format, expected a path") return nil, errors.New("bad TLS Certificate KeyFile format, expected a path")
} }
} else if errKey == nil { } else if errKey == nil {
return nil, fmt.Errorf("bad TLS Certificate KeyFile format, expected a path") return nil, errors.New("bad TLS Certificate KeyFile format, expected a path")
} }
cert := tls.Certificate{} cert := tls.Certificate{}
@ -314,7 +314,7 @@ func (certs *Certificates) Set(value string) error {
for _, certificate := range certificates { for _, certificate := range certificates {
files := strings.Split(certificate, ",") files := strings.Split(certificate, ",")
if len(files) != 2 { if len(files) != 2 {
return errors.New("Bad certificates format: " + value) return fmt.Errorf("bad certificates format: %s", value)
} }
*certs = append(*certs, Certificate{ *certs = append(*certs, Certificate{
CertFile: files[0], CertFile: files[0],

View file

@ -167,12 +167,12 @@ func (r *Rules) parseRules(expression string, onRule func(functionName string, f
// get function // get function
parsedFunctions := strings.FieldsFunc(rule, f) parsedFunctions := strings.FieldsFunc(rule, f)
if len(parsedFunctions) == 0 { if len(parsedFunctions) == 0 {
return errors.New("Error parsing rule: '" + rule + "'") return fmt.Errorf("error parsing rule: '%s'", rule)
} }
functionName := strings.TrimSpace(parsedFunctions[0]) functionName := strings.TrimSpace(parsedFunctions[0])
parsedFunction, ok := functions[functionName] parsedFunction, ok := functions[functionName]
if !ok { if !ok {
return errors.New("Error parsing rule: '" + rule + "'. Unknown function: '" + parsedFunctions[0] + "'") return fmt.Errorf("error parsing rule: '%s'. Unknown function: '%s'", rule, parsedFunctions[0])
} }
parsedFunctions = append(parsedFunctions[:0], parsedFunctions[1:]...) parsedFunctions = append(parsedFunctions[:0], parsedFunctions[1:]...)
fargs := func(c rune) bool { fargs := func(c rune) bool {
@ -181,7 +181,7 @@ func (r *Rules) parseRules(expression string, onRule func(functionName string, f
// get function // get function
parsedArgs := strings.FieldsFunc(strings.Join(parsedFunctions, ":"), fargs) parsedArgs := strings.FieldsFunc(strings.Join(parsedFunctions, ":"), fargs)
if len(parsedArgs) == 0 { if len(parsedArgs) == 0 {
return errors.New("Error parsing args from rule: '" + rule + "'") return fmt.Errorf("error parsing args from rule: '%s'", rule)
} }
for i := range parsedArgs { for i := range parsedArgs {
@ -215,12 +215,12 @@ func (r *Rules) Parse(expression string) (*mux.Route, error) {
} }
} else { } else {
return errors.New("Method not found: '" + functionName + "'") return fmt.Errorf("Method not found: '%s'", functionName)
} }
return nil return nil
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("Error parsing rule: %v", err) return nil, fmt.Errorf("error parsing rule: %v", err)
} }
return resultRoute, nil return resultRoute, nil
} }
@ -235,7 +235,7 @@ func (r *Rules) ParseDomains(expression string) ([]string, error) {
return nil return nil
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("Error parsing domains: %v", err) return nil, fmt.Errorf("error parsing domains: %v", err)
} }
return fun.Map(types.CanonicalDomain, domains).([]string), nil return fun.Map(types.CanonicalDomain, domains).([]string), nil
} }

View file

@ -19,15 +19,14 @@ func TestParseOneRule(t *testing.T) {
routeResult, err := rules.Parse(expression) routeResult, err := rules.Parse(expression)
if err != nil { if err != nil {
t.Fatal("Error while building route for Host:foo.bar") t.Fatalf("Error while building route for Host:foo.bar: %s", err)
} }
request, err := http.NewRequest("GET", "http://foo.bar", nil) request, err := http.NewRequest("GET", "http://foo.bar", nil)
routeMatch := routeResult.Match(request, &mux.RouteMatch{Route: routeResult}) routeMatch := routeResult.Match(request, &mux.RouteMatch{Route: routeResult})
if routeMatch == false { if !routeMatch {
t.Log(err) t.Fatalf("Rule Host:foo.bar don't match: %s", err)
t.Fatal("Rule Host:foo.bar don't match")
} }
} }
@ -41,23 +40,21 @@ func TestParseTwoRules(t *testing.T) {
routeResult, err := rules.Parse(expression) routeResult, err := rules.Parse(expression)
if err != nil { if err != nil {
t.Fatal("Error while building route for Host:foo.bar;Path:/FOObar") t.Fatalf("Error while building route for Host:foo.bar;Path:/FOObar: %s", err)
} }
request, err := http.NewRequest("GET", "http://foo.bar/foobar", nil) request, err := http.NewRequest("GET", "http://foo.bar/foobar", nil)
routeMatch := routeResult.Match(request, &mux.RouteMatch{Route: routeResult}) routeMatch := routeResult.Match(request, &mux.RouteMatch{Route: routeResult})
if routeMatch == true { if routeMatch {
t.Log(err) t.Fatalf("Rule Host:foo.bar;Path:/FOObar don't match: %s", err)
t.Fatal("Rule Host:foo.bar;Path:/FOObar don't match")
} }
request, err = http.NewRequest("GET", "http://foo.bar/FOObar", nil) request, err = http.NewRequest("GET", "http://foo.bar/FOObar", nil)
routeMatch = routeResult.Match(request, &mux.RouteMatch{Route: routeResult}) routeMatch = routeResult.Match(request, &mux.RouteMatch{Route: routeResult})
if routeMatch == false { if !routeMatch {
t.Log(err) t.Fatalf("Rule Host:foo.bar;Path:/FOObar don't match: %s", err)
t.Fatal("Rule Host:foo.bar;Path:/FOObar don't match")
} }
} }
@ -92,7 +89,7 @@ func TestPriorites(t *testing.T) {
rules := &Rules{route: &serverRoute{route: router.NewRoute()}} rules := &Rules{route: &serverRoute{route: router.NewRoute()}}
routeFoo, err := rules.Parse("PathPrefix:/foo") routeFoo, err := rules.Parse("PathPrefix:/foo")
if err != nil { if err != nil {
t.Fatal("Error while building route for PathPrefix:/foo") t.Fatalf("Error while building route for PathPrefix:/foo: %s", err)
} }
fooHandler := &fakeHandler{name: "fooHandler"} fooHandler := &fakeHandler{name: "fooHandler"}
routeFoo.Handler(fooHandler) routeFoo.Handler(fooHandler)
@ -100,40 +97,40 @@ func TestPriorites(t *testing.T) {
if !router.Match(&http.Request{URL: &url.URL{ if !router.Match(&http.Request{URL: &url.URL{
Path: "/foo", Path: "/foo",
}}, &mux.RouteMatch{}) { }}, &mux.RouteMatch{}) {
t.Fatalf("Error matching route") t.Fatal("Error matching route")
} }
if router.Match(&http.Request{URL: &url.URL{ if router.Match(&http.Request{URL: &url.URL{
Path: "/fo", Path: "/fo",
}}, &mux.RouteMatch{}) { }}, &mux.RouteMatch{}) {
t.Fatalf("Error matching route") t.Fatal("Error matching route")
} }
multipleRules := &Rules{route: &serverRoute{route: router.NewRoute()}} multipleRules := &Rules{route: &serverRoute{route: router.NewRoute()}}
routeFoobar, err := multipleRules.Parse("PathPrefix:/foobar") routeFoobar, err := multipleRules.Parse("PathPrefix:/foobar")
if err != nil { if err != nil {
t.Fatal("Error while building route for PathPrefix:/foobar") t.Fatalf("Error while building route for PathPrefix:/foobar: %s", err)
} }
foobarHandler := &fakeHandler{name: "foobarHandler"} foobarHandler := &fakeHandler{name: "foobarHandler"}
routeFoobar.Handler(foobarHandler) routeFoobar.Handler(foobarHandler)
if !router.Match(&http.Request{URL: &url.URL{ if !router.Match(&http.Request{URL: &url.URL{
Path: "/foo", Path: "/foo",
}}, &mux.RouteMatch{}) { }}, &mux.RouteMatch{}) {
t.Fatalf("Error matching route") t.Fatal("Error matching route")
} }
fooMatcher := &mux.RouteMatch{} fooMatcher := &mux.RouteMatch{}
if !router.Match(&http.Request{URL: &url.URL{ if !router.Match(&http.Request{URL: &url.URL{
Path: "/foobar", Path: "/foobar",
}}, fooMatcher) { }}, fooMatcher) {
t.Fatalf("Error matching route") t.Fatal("Error matching route")
} }
if fooMatcher.Handler == foobarHandler { if fooMatcher.Handler == foobarHandler {
t.Fatalf("Error matching priority") t.Fatal("Error matching priority")
} }
if fooMatcher.Handler != fooHandler { if fooMatcher.Handler != fooHandler {
t.Fatalf("Error matching priority") t.Fatal("Error matching priority")
} }
routeFoo.Priority(1) routeFoo.Priority(1)
@ -144,15 +141,15 @@ func TestPriorites(t *testing.T) {
if !router.Match(&http.Request{URL: &url.URL{ if !router.Match(&http.Request{URL: &url.URL{
Path: "/foobar", Path: "/foobar",
}}, foobarMatcher) { }}, foobarMatcher) {
t.Fatalf("Error matching route") t.Fatal("Error matching route")
} }
if foobarMatcher.Handler != foobarHandler { if foobarMatcher.Handler != foobarHandler {
t.Fatalf("Error matching priority") t.Fatal("Error matching priority")
} }
if foobarMatcher.Handler == fooHandler { if foobarMatcher.Handler == fooHandler {
t.Fatalf("Error matching priority") t.Fatal("Error matching priority")
} }
} }
@ -160,6 +157,4 @@ type fakeHandler struct {
name string name string
} }
func (h *fakeHandler) ServeHTTP(http.ResponseWriter, *http.Request) { func (h *fakeHandler) ServeHTTP(http.ResponseWriter, *http.Request) {}
}

View file

@ -91,7 +91,7 @@ func NewServer(globalConfiguration GlobalConfiguration) *Server {
var err error var err error
server.accessLoggerMiddleware, err = accesslog.NewLogHandler(globalConfiguration.AccessLogsFile) server.accessLoggerMiddleware, err = accesslog.NewLogHandler(globalConfiguration.AccessLogsFile)
if err != nil { if err != nil {
log.Warn("Unable to create log handler: %s", err) log.Warnf("Unable to create log handler: %s", err)
} }
return server return server
} }
@ -147,7 +147,7 @@ func (server *Server) Close() {
if ctx.Err() == context.Canceled { if ctx.Err() == context.Canceled {
return return
} else if ctx.Err() == context.DeadlineExceeded { } else if ctx.Err() == context.DeadlineExceeded {
log.Warnf("Timeout while stopping traefik, killing instance ✝") log.Warn("Timeout while stopping traefik, killing instance ✝")
os.Exit(1) os.Exit(1)
} }
}(ctx) }(ctx)
@ -736,6 +736,7 @@ func (server *Server) loadConfig(configurations configs, globalConfiguration Glo
negroni.Use(metricsMiddlewareBackend) negroni.Use(metricsMiddlewareBackend)
} }
} }
ipWhitelistMiddleware, err := configureIPWhitelistMiddleware(frontend.WhitelistSourceRange) ipWhitelistMiddleware, err := configureIPWhitelistMiddleware(frontend.WhitelistSourceRange)
if err != nil { if err != nil {
log.Fatalf("Error creating IP Whitelister: %s", err) log.Fatalf("Error creating IP Whitelister: %s", err)
@ -761,6 +762,7 @@ func (server *Server) loadConfig(configurations configs, globalConfiguration Glo
negroni.Use(authMiddleware) negroni.Use(authMiddleware)
} }
} }
if configuration.Backends[frontend.Backend].CircuitBreaker != nil { if configuration.Backends[frontend.Backend].CircuitBreaker != nil {
log.Debugf("Creating circuit breaker %s", configuration.Backends[frontend.Backend].CircuitBreaker.Expression) log.Debugf("Creating circuit breaker %s", configuration.Backends[frontend.Backend].CircuitBreaker.Expression)
cbreaker, err := middlewares.NewCircuitBreaker(lb, configuration.Backends[frontend.Backend].CircuitBreaker.Expression, cbreaker.Logger(oxyLogger)) cbreaker, err := middlewares.NewCircuitBreaker(lb, configuration.Backends[frontend.Backend].CircuitBreaker.Expression, cbreaker.Logger(oxyLogger))

View file

@ -126,7 +126,8 @@ func (provider *WebProvider) Provide(configurationChan chan<- types.ConfigMessag
systemRouter.Methods("GET").Path(provider.Path).HandlerFunc(func(response http.ResponseWriter, request *http.Request) { systemRouter.Methods("GET").Path(provider.Path).HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
http.Redirect(response, request, provider.Path+"dashboard/", 302) http.Redirect(response, request, provider.Path+"dashboard/", 302)
}) })
systemRouter.Methods("GET").PathPrefix(provider.Path + "dashboard/").Handler(http.StripPrefix(provider.Path+"dashboard/", http.FileServer(&assetfs.AssetFS{Asset: autogen.Asset, AssetInfo: autogen.AssetInfo, AssetDir: autogen.AssetDir, Prefix: "static"}))) systemRouter.Methods("GET").PathPrefix(provider.Path + "dashboard/").
Handler(http.StripPrefix(provider.Path+"dashboard/", http.FileServer(&assetfs.AssetFS{Asset: autogen.Asset, AssetInfo: autogen.AssetInfo, AssetDir: autogen.AssetDir, Prefix: "static"})))
// expvars // expvars
if provider.server.globalConfiguration.Debug { if provider.server.globalConfiguration.Debug {