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:
parent
994e135368
commit
cbccdd51c5
26 changed files with 125 additions and 128 deletions
|
@ -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) {
|
||||||
|
|
26
acme/acme.go
26
acme/acme.go
|
@ -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
|
||||||
|
|
|
@ -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.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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{
|
||||||
|
|
|
@ -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{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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],
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue