Small code enhancements

This commit is contained in:
Michael 2018-08-06 20:00:03 +02:00 committed by Traefiker Bot
parent 015cd7a3d0
commit 9cd47dd2aa
41 changed files with 187 additions and 85 deletions

30
.golangci.toml Normal file
View file

@ -0,0 +1,30 @@
[linters-settings]
[linters-settings.govet]
check-shadowing = true
[linters-settings.golint]
min-confidence = 0.0
[linters-settings.gocyclo]
min-complexity = 22.0
[linters-settings.maligned]
suggest-new = true
[linters-settings.goconst]
min-len = 2.0
min-occurrences = 2.0
[linters-settings.misspell]
locale = "US"
[linters]
enable-all = true
disable = [
"maligned",
"lll",
"gas",
"dupl",
"prealloc"
]

View file

@ -233,7 +233,7 @@ func (s *datastoreTransaction) Commit(object Object) error {
} }
err = s.kv.StoreConfig(s.Datastore.meta) err = s.kv.StoreConfig(s.Datastore.meta)
if err != nil { if err != nil {
return fmt.Errorf("StoreConfig error: %s", err) return fmt.Errorf("storeConfig error: %s", err)
} }
err = s.remoteLock.Unlock() err = s.remoteLock.Unlock()

View file

@ -7,7 +7,7 @@ import (
"syscall" "syscall"
) )
// ContextWithSignal create a context cancelled when SIGINT or SIGTERM are notified // ContextWithSignal creates a context canceled when SIGINT or SIGTERM are notified
func ContextWithSignal(ctx context.Context) context.Context { func ContextWithSignal(ctx context.Context) context.Context {
newCtx, cancel := context.WithCancel(ctx) newCtx, cancel := context.WithCancel(ctx)
signals := make(chan os.Signal) signals := make(chan os.Signal)

View file

@ -158,7 +158,9 @@ func runCmd(globalConfiguration *configuration.GlobalConfiguration, configFile s
http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment
roundrobin.SetDefaultWeight(0) if err := roundrobin.SetDefaultWeight(0); err != nil {
log.Error(err)
}
globalConfiguration.SetEffectiveConfiguration(configFile) globalConfiguration.SetEffectiveConfiguration(configFile)
globalConfiguration.ValidateConfiguration() globalConfiguration.ValidateConfiguration()
@ -182,8 +184,8 @@ func runCmd(globalConfiguration *configuration.GlobalConfiguration, configFile s
acmeprovider := globalConfiguration.InitACMEProvider() acmeprovider := globalConfiguration.InitACMEProvider()
if acmeprovider != nil { if acmeprovider != nil {
err := providerAggregator.AddProvider(acmeprovider)
if err != nil { if err := providerAggregator.AddProvider(acmeprovider); err != nil {
log.Errorf("Error initializing provider ACME: %v", err) log.Errorf("Error initializing provider ACME: %v", err)
acmeprovider = nil acmeprovider = nil
} }

View file

@ -79,7 +79,9 @@ func (wm *WithMiddleware) AddRoutes(systemRouter *mux.Router) {
wm.router.AddRoutes(realRouter) wm.router.AddRoutes(realRouter)
if len(wm.routerMiddlewares) > 0 { if len(wm.routerMiddlewares) > 0 {
realRouter.Walk(wrapRoute(wm.routerMiddlewares)) if err := realRouter.Walk(wrapRoute(wm.routerMiddlewares)); err != nil {
log.Error(err)
}
} }
} }

View file

@ -9,6 +9,7 @@ import (
"github.com/containous/traefik/acme" "github.com/containous/traefik/acme"
"github.com/containous/traefik/api" "github.com/containous/traefik/api"
"github.com/containous/traefik/configuration" "github.com/containous/traefik/configuration"
"github.com/containous/traefik/log"
"github.com/containous/traefik/ping" "github.com/containous/traefik/ping"
acmeprovider "github.com/containous/traefik/provider/acme" acmeprovider "github.com/containous/traefik/provider/acme"
"github.com/containous/traefik/safe" "github.com/containous/traefik/safe"
@ -104,20 +105,35 @@ func TestWithMiddleware(t *testing.T) {
router := WithMiddleware{ router := WithMiddleware{
router: MockInternalRouterFunc(func(systemRouter *mux.Router) { router: MockInternalRouterFunc(func(systemRouter *mux.Router) {
systemRouter.Handle("/test", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { systemRouter.Handle("/test", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("router"))
if _, err := w.Write([]byte("router")); err != nil {
log.Error(err)
}
})) }))
}), }),
routerMiddlewares: []negroni.Handler{ routerMiddlewares: []negroni.Handler{
negroni.HandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { negroni.HandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
rw.Write([]byte("before middleware1|")) if _, err := rw.Write([]byte("before middleware1|")); err != nil {
log.Error(err)
}
next.ServeHTTP(rw, r) next.ServeHTTP(rw, r)
rw.Write([]byte("|after middleware1"))
if _, err := rw.Write([]byte("|after middleware1")); err != nil {
log.Error(err)
}
}), }),
negroni.HandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { negroni.HandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
rw.Write([]byte("before middleware2|")) if _, err := rw.Write([]byte("before middleware2|")); err != nil {
log.Error(err)
}
next.ServeHTTP(rw, r) next.ServeHTTP(rw, r)
rw.Write([]byte("|after middleware2"))
if _, err := rw.Write([]byte("|after middleware2")); err != nil {
log.Error(err)
}
}), }),
}, },
} }

View file

@ -328,7 +328,7 @@ It is not possible to request a double wildcard certificate for a domain (for ex
Due to ACME limitation it is not possible to define wildcards in SANs (alternative domains). Thus, the wildcard domain has to be defined as a main domain. Due to ACME limitation it is not possible to define wildcards in SANs (alternative domains). Thus, the wildcard domain has to be defined as a main domain.
Most likely the root domain should receive a certificate too, so it needs to be specified as SAN and 2 `DNS-01` challenges are executed. Most likely the root domain should receive a certificate too, so it needs to be specified as SAN and 2 `DNS-01` challenges are executed.
In this case the generated DNS TXT record for both domains is the same. In this case the generated DNS TXT record for both domains is the same.
Eventhough this behaviour is [DNS RFC](https://community.letsencrypt.org/t/wildcard-issuance-two-txt-records-for-the-same-name/54528/2) compliant, it can lead to problems as all DNS providers keep DNS records cached for a certain time (TTL) and this TTL can be superior to the challenge timeout making the `DNS-01` challenge fail. Eventhough this behavior is [DNS RFC](https://community.letsencrypt.org/t/wildcard-issuance-two-txt-records-for-the-same-name/54528/2) compliant, it can lead to problems as all DNS providers keep DNS records cached for a certain time (TTL) and this TTL can be superior to the challenge timeout making the `DNS-01` challenge fail.
The Træfik ACME client library [LEGO](https://github.com/xenolf/lego) supports some but not all DNS providers to work around this issue. The Træfik ACME client library [LEGO](https://github.com/xenolf/lego) supports some but not all DNS providers to work around this issue.
The [`provider` table](/configuration/acme/#provider) indicates if they allow generating certificates for a wildcard domain and its root domain. The [`provider` table](/configuration/acme/#provider) indicates if they allow generating certificates for a wildcard domain and its root domain.

View file

@ -126,9 +126,9 @@ Træfik needs the following policy to read ECS information:
} }
``` ```
## Labels: overriding default behaviour ## Labels: overriding default behavior
Labels can be used on task containers to override default behaviour: Labels can be used on task containers to override default behavior:
| Label | Description | | Label | Description |
|------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

View file

@ -130,30 +130,34 @@ func (hc *HealthCheck) execute(ctx context.Context, backend *BackendConfig) {
func (hc *HealthCheck) checkBackend(backend *BackendConfig) { func (hc *HealthCheck) checkBackend(backend *BackendConfig) {
enabledURLs := backend.LB.Servers() enabledURLs := backend.LB.Servers()
var newDisabledURLs []*url.URL var newDisabledURLs []*url.URL
for _, url := range backend.disabledURLs { for _, disableURL := range backend.disabledURLs {
serverUpMetricValue := float64(0) serverUpMetricValue := float64(0)
if err := checkHealth(url, backend); err == nil { if err := checkHealth(disableURL, backend); err == nil {
log.Warnf("Health check up: Returning to server list. Backend: %q URL: %q", backend.name, url.String()) log.Warnf("Health check up: Returning to server list. Backend: %q URL: %q", backend.name, disableURL.String())
backend.LB.UpsertServer(url, roundrobin.Weight(1)) if err := backend.LB.UpsertServer(disableURL, roundrobin.Weight(1)); err != nil {
log.Error(err)
}
serverUpMetricValue = 1 serverUpMetricValue = 1
} else { } else {
log.Warnf("Health check still failing. Backend: %q URL: %q Reason: %s", backend.name, url.String(), err) log.Warnf("Health check still failing. Backend: %q URL: %q Reason: %s", backend.name, disableURL.String(), err)
newDisabledURLs = append(newDisabledURLs, url) newDisabledURLs = append(newDisabledURLs, disableURL)
} }
labelValues := []string{"backend", backend.name, "url", url.String()} labelValues := []string{"backend", backend.name, "url", disableURL.String()}
hc.metrics.BackendServerUpGauge().With(labelValues...).Set(serverUpMetricValue) hc.metrics.BackendServerUpGauge().With(labelValues...).Set(serverUpMetricValue)
} }
backend.disabledURLs = newDisabledURLs backend.disabledURLs = newDisabledURLs
for _, url := range enabledURLs { for _, enableURL := range enabledURLs {
serverUpMetricValue := float64(1) serverUpMetricValue := float64(1)
if err := checkHealth(url, backend); err != nil { if err := checkHealth(enableURL, backend); err != nil {
log.Warnf("Health check failed: Remove from server list. Backend: %q URL: %q Reason: %s", backend.name, url.String(), err) log.Warnf("Health check failed: Remove from server list. Backend: %q URL: %q Reason: %s", backend.name, enableURL.String(), err)
backend.LB.RemoveServer(url) if err := backend.LB.RemoveServer(enableURL); err != nil {
backend.disabledURLs = append(backend.disabledURLs, url) log.Error(err)
}
backend.disabledURLs = append(backend.disabledURLs, enableURL)
serverUpMetricValue = 0 serverUpMetricValue = 0
} }
labelValues := []string{"backend", backend.name, "url", url.String()} labelValues := []string{"backend", backend.name, "url", enableURL.String()}
hc.metrics.BackendServerUpGauge().With(labelValues...).Set(serverUpMetricValue) hc.metrics.BackendServerUpGauge().With(labelValues...).Set(serverUpMetricValue)
} }
} }

View file

@ -94,7 +94,7 @@ func TestSetBackendsConfiguration(t *testing.T) {
t.Run(test.desc, func(t *testing.T) { t.Run(test.desc, func(t *testing.T) {
t.Parallel() t.Parallel()
// The context is passed to the health check and canonically cancelled by // The context is passed to the health check and canonically canceled by
// the test server once all expected requests have been received. // the test server once all expected requests have been received.
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()

View file

@ -63,7 +63,9 @@ func (hr *Resolver) CNAMEFlatten(host string) (string, string) {
request = resolv.Record request = resolv.Record
} }
hr.cache.Add(host, strings.Join(result, ","), cacheDuration) if err := hr.cache.Add(host, strings.Join(result, ","), cacheDuration); err != nil {
log.Error(err)
}
} }
return result[0], result[len(result)-1] return result[0], result[len(result)-1]

View file

@ -12,6 +12,7 @@ import (
"time" "time"
"github.com/containous/traefik/integration/try" "github.com/containous/traefik/integration/try"
"github.com/containous/traefik/log"
"github.com/containous/traefik/middlewares/accesslog" "github.com/containous/traefik/middlewares/accesslog"
"github.com/go-check/check" "github.com/go-check/check"
checker "github.com/vdemeester/shakers" checker "github.com/vdemeester/shakers"
@ -324,13 +325,17 @@ func digestParts(resp *http.Response) map[string]string {
func getMD5(data string) string { func getMD5(data string) string {
digest := md5.New() digest := md5.New()
digest.Write([]byte(data)) if _, err := digest.Write([]byte(data)); err != nil {
log.Error(err)
}
return fmt.Sprintf("%x", digest.Sum(nil)) return fmt.Sprintf("%x", digest.Sum(nil))
} }
func getCnonce() string { func getCnonce() string {
b := make([]byte, 8) b := make([]byte, 8)
io.ReadFull(rand.Reader, b) if _, err := io.ReadFull(rand.Reader, b); err != nil {
log.Error(err)
}
return fmt.Sprintf("%x", b)[:16] return fmt.Sprintf("%x", b)[:16]
} }

View file

@ -530,7 +530,8 @@ func (s *ConsulCatalogSuite) TestRetryWithConsulServer(c *check.C) {
// Scale consul to 1 // Scale consul to 1
s.composeProject.Scale(c, "consul", 1) s.composeProject.Scale(c, "consul", 1)
s.waitToElectConsulLeader() err = s.waitToElectConsulLeader()
c.Assert(err, checker.IsNil)
whoami := s.composeProject.Container(c, "whoami1") whoami := s.composeProject.Container(c, "whoami1")
// Register service // Register service
@ -576,7 +577,8 @@ func (s *ConsulCatalogSuite) TestServiceWithMultipleHealthCheck(c *check.C) {
// Scale consul to 1 // Scale consul to 1
s.composeProject.Scale(c, "consul", 1) s.composeProject.Scale(c, "consul", 1)
s.waitToElectConsulLeader() err = s.waitToElectConsulLeader()
c.Assert(err, checker.IsNil)
whoami := s.composeProject.Container(c, "whoami1") whoami := s.composeProject.Container(c, "whoami1")
// Register service // Register service

View file

@ -404,7 +404,8 @@ func (s *Etcd3Suite) TestCommandStoreConfig(c *check.C) {
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
// wait for traefik finish without error // wait for traefik finish without error
cmd.Wait() err = cmd.Wait()
c.Assert(err, checker.IsNil)
// CHECK // CHECK
checkmap := map[string]string{ checkmap := map[string]string{

View file

@ -411,8 +411,9 @@ func (s *EtcdSuite) TestCommandStoreConfig(c *check.C) {
err := cmd.Start() err := cmd.Start()
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
// wait for Træfik finish without error // wait for traefik finish without error
cmd.Wait() err = cmd.Wait()
c.Assert(err, checker.IsNil)
// CHECK // CHECK
checkmap := map[string]string{ checkmap := map[string]string{

View file

@ -93,7 +93,9 @@ func (s *handler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
auth.Minttl = 1 auth.Minttl = 1
m.Ns = append(m.Ns, auth) m.Ns = append(m.Ns, auth)
w.WriteMsg(m) if err := w.WriteMsg(m); err != nil {
log.Fatalf("Failed to write message %v", err)
}
} }
func startFakeDNSServer() *dns.Server { func startFakeDNSServer() *dns.Server {

View file

@ -13,6 +13,7 @@ import (
"github.com/containous/traefik/integration/helloworld" "github.com/containous/traefik/integration/helloworld"
"github.com/containous/traefik/integration/try" "github.com/containous/traefik/integration/try"
"github.com/containous/traefik/log"
"github.com/go-check/check" "github.com/go-check/check"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
@ -47,7 +48,11 @@ func (s *myserver) StreamExample(in *helloworld.StreamExampleRequest, server hel
for i := range data { for i := range data {
data[i] = randCharset[rand.Intn(len(randCharset))] data[i] = randCharset[rand.Intn(len(randCharset))]
} }
server.Send(&helloworld.StreamExampleReply{Data: string(data)})
if err := server.Send(&helloworld.StreamExampleReply{Data: string(data)}); err != nil {
log.Error(err)
}
<-s.stopStreamExample <-s.stopStreamExample
return nil return nil
} }

View file

@ -708,7 +708,10 @@ func modifyCertificateConfFileContent(c *check.C, certFileName, confFileName, en
defer func() { defer func() {
f.Close() f.Close()
}() }()
f.Truncate(0)
err = f.Truncate(0)
c.Assert(err, checker.IsNil)
// If certificate file is not provided, just truncate the configuration file // If certificate file is not provided, just truncate the configuration file
if len(certFileName) > 0 { if len(certFileName) > 0 {
tlsConf := types.Configuration{ tlsConf := types.Configuration{

View file

@ -26,10 +26,10 @@ const (
DataTableKey key = "LogDataTable" DataTableKey key = "LogDataTable"
// CommonFormat is the common logging format (CLF) // CommonFormat is the common logging format (CLF)
CommonFormat = "common" CommonFormat string = "common"
// JSONFormat is the JSON logging format // JSONFormat is the JSON logging format
JSONFormat = "json" JSONFormat string = "json"
) )
type logHandlerParams struct { type logHandlerParams struct {

View file

@ -15,6 +15,7 @@ import (
"time" "time"
"github.com/containous/flaeg/parse" "github.com/containous/flaeg/parse"
"github.com/containous/traefik/log"
"github.com/containous/traefik/types" "github.com/containous/traefik/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -626,7 +627,10 @@ func doLogging(t *testing.T, config *types.AccessLog) {
} }
func logWriterTestHandlerFunc(rw http.ResponseWriter, r *http.Request) { func logWriterTestHandlerFunc(rw http.ResponseWriter, r *http.Request) {
rw.Write([]byte(testContent)) if _, err := rw.Write([]byte(testContent)); err != nil {
log.Error(err)
}
rw.WriteHeader(testStatus) rw.WriteHeader(testStatus)
logDataTable := GetLogDataTable(r) logDataTable := GetLogDataTable(r)

View file

@ -90,7 +90,10 @@ func Forward(config *types.Forward, w http.ResponseWriter, r *http.Request, next
tracing.LogResponseCode(tracing.GetSpan(r), forwardResponse.StatusCode) tracing.LogResponseCode(tracing.GetSpan(r), forwardResponse.StatusCode)
w.WriteHeader(forwardResponse.StatusCode) w.WriteHeader(forwardResponse.StatusCode)
w.Write(body)
if _, err = w.Write(body); err != nil {
log.Error(err)
}
return return
} }

View file

@ -3,6 +3,7 @@ package middlewares
import ( import (
"net/http" "net/http"
"github.com/containous/traefik/log"
"github.com/containous/traefik/middlewares/tracing" "github.com/containous/traefik/middlewares/tracing"
"github.com/vulcand/oxy/cbreaker" "github.com/vulcand/oxy/cbreaker"
) )
@ -27,7 +28,10 @@ func NewCircuitBreakerOptions(expression string) cbreaker.CircuitBreakerOption {
tracing.LogEventf(r, "blocked by circuit-breaker (%q)", expression) tracing.LogEventf(r, "blocked by circuit-breaker (%q)", expression)
w.WriteHeader(http.StatusServiceUnavailable) w.WriteHeader(http.StatusServiceUnavailable)
w.Write([]byte(http.StatusText(http.StatusServiceUnavailable)))
if _, err := w.Write([]byte(http.StatusText(http.StatusServiceUnavailable))); err != nil {
log.Error(err)
}
})) }))
} }

View file

@ -29,7 +29,8 @@ func TestShouldCompressWhenNoContentEncodingHeader(t *testing.T) {
baseBody := generateBytes(gziphandler.DefaultMinSize) baseBody := generateBytes(gziphandler.DefaultMinSize)
next := func(rw http.ResponseWriter, r *http.Request) { next := func(rw http.ResponseWriter, r *http.Request) {
rw.Write(baseBody) _, err := rw.Write(baseBody)
assert.NoError(t, err)
} }
rw := httptest.NewRecorder() rw := httptest.NewRecorder()

View file

@ -103,7 +103,10 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, req *http.Request, next http.
utils.CopyHeaders(w.Header(), recorderErrorPage.Header()) utils.CopyHeaders(w.Header(), recorderErrorPage.Header())
w.WriteHeader(recorder.GetCode()) w.WriteHeader(recorder.GetCode())
w.Write(recorderErrorPage.GetBody().Bytes())
if _, err = w.Write(recorderErrorPage.GetBody().Bytes()); err != nil {
log.Error(err)
}
return return
} }
} }

View file

@ -218,7 +218,8 @@ func TestHandlerOldWay(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
errorPageHandler.FallbackURL = "http://localhost" errorPageHandler.FallbackURL = "http://localhost"
errorPageHandler.PostLoad(test.errorPageForwarder) err = errorPageHandler.PostLoad(test.errorPageForwarder)
require.NoError(t, err)
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(test.backendCode) w.WriteHeader(test.backendCode)

View file

@ -49,7 +49,8 @@ func TestModifyResponseHeaders(t *testing.T) {
res := httptest.NewRecorder() res := httptest.NewRecorder()
res.HeaderMap.Add("X-Custom-Response-Header", "test_response") res.HeaderMap.Add("X-Custom-Response-Header", "test_response")
header.ModifyResponseHeaders(res.Result()) err := header.ModifyResponseHeaders(res.Result())
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, res.Code, "Status not OK") assert.Equal(t, http.StatusOK, res.Code, "Status not OK")
assert.Equal(t, "test_response", res.Header().Get("X-Custom-Response-Header"), "Did not get expected header") assert.Equal(t, "test_response", res.Header().Get("X-Custom-Response-Header"), "Did not get expected header")
@ -57,7 +58,8 @@ func TestModifyResponseHeaders(t *testing.T) {
res = httptest.NewRecorder() res = httptest.NewRecorder()
res.HeaderMap.Add("X-Custom-Response-Header", "") res.HeaderMap.Add("X-Custom-Response-Header", "")
header.ModifyResponseHeaders(res.Result()) err = header.ModifyResponseHeaders(res.Result())
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, res.Code, "Status not OK") assert.Equal(t, http.StatusOK, res.Code, "Status not OK")
assert.Equal(t, "", res.Header().Get("X-Custom-Response-Header"), "Did not get expected header") assert.Equal(t, "", res.Header().Get("X-Custom-Response-Header"), "Did not get expected header")
@ -65,7 +67,8 @@ func TestModifyResponseHeaders(t *testing.T) {
res = httptest.NewRecorder() res = httptest.NewRecorder()
res.HeaderMap.Add("X-Custom-Response-Header", "test_override") res.HeaderMap.Add("X-Custom-Response-Header", "test_override")
header.ModifyResponseHeaders(res.Result()) err = header.ModifyResponseHeaders(res.Result())
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, res.Code, "Status not OK") assert.Equal(t, http.StatusOK, res.Code, "Status not OK")
assert.Equal(t, "test_override", res.Header().Get("X-Custom-Response-Header"), "Did not get expected header") assert.Equal(t, "test_override", res.Header().Get("X-Custom-Response-Header"), "Did not get expected header")

View file

@ -6,6 +6,7 @@ import (
"testing" "testing"
"github.com/containous/traefik/testhelpers" "github.com/containous/traefik/testhelpers"
"github.com/stretchr/testify/assert"
"github.com/vulcand/oxy/forward" "github.com/vulcand/oxy/forward"
"github.com/vulcand/oxy/roundrobin" "github.com/vulcand/oxy/roundrobin"
) )
@ -91,11 +92,13 @@ func TestRetry(t *testing.T) {
// See: https://stackoverflow.com/questions/528538/non-routable-ip-address/18436928#18436928 // See: https://stackoverflow.com/questions/528538/non-routable-ip-address/18436928#18436928
// We only use the port specification here because the URL is used as identifier // We only use the port specification here because the URL is used as identifier
// in the load balancer and using the exact same URL would not add a new server. // in the load balancer and using the exact same URL would not add a new server.
loadBalancer.UpsertServer(testhelpers.MustParseURL("http://192.0.2.0:" + string(basePort+i))) err = loadBalancer.UpsertServer(testhelpers.MustParseURL("http://192.0.2.0:" + string(basePort+i)))
assert.NoError(t, err)
} }
// add the functioning server to the end of the load balancer list // add the functioning server to the end of the load balancer list
loadBalancer.UpsertServer(testhelpers.MustParseURL(backendServer.URL)) err = loadBalancer.UpsertServer(testhelpers.MustParseURL(backendServer.URL))
assert.NoError(t, err)
retryListener := &countingRetryListener{} retryListener := &countingRetryListener{}
retry := NewRetry(tc.maxRequestAttempts, loadBalancer, retryListener) retry := NewRetry(tc.maxRequestAttempts, loadBalancer, retryListener)

View file

@ -188,7 +188,7 @@ func (s *LocalStore) SetHTTPChallengeToken(token, domain string, keyAuth []byte)
s.storedData.HTTPChallenges[token] = map[string][]byte{} s.storedData.HTTPChallenges[token] = map[string][]byte{}
} }
s.storedData.HTTPChallenges[token][domain] = []byte(keyAuth) s.storedData.HTTPChallenges[token][domain] = keyAuth
return nil return nil
} }

View file

@ -76,7 +76,7 @@ func (p *Provider) BuildConfiguration() (*types.Configuration, error) {
return p.loadFileConfig(p.TraefikFile, false) return p.loadFileConfig(p.TraefikFile, false)
} }
return nil, errors.New("Error using file configuration backend, no filename defined") return nil, errors.New("error using file configuration backend, no filename defined")
} }
func (p *Provider) addWatcher(pool *safe.Pool, directory string, configurationChan chan<- types.ConfigMessage, callback func(chan<- types.ConfigMessage, fsnotify.Event)) error { func (p *Provider) addWatcher(pool *safe.Pool, directory string, configurationChan chan<- types.ConfigMessage, callback func(chan<- types.ConfigMessage, fsnotify.Event)) error {

View file

@ -241,11 +241,15 @@ func TestProvideWithWatch(t *testing.T) {
} }
if len(test.fileContent) > 0 { if len(test.fileContent) > 0 {
ioutil.WriteFile(provider.Filename, []byte(test.fileContent), 0755) if err := ioutil.WriteFile(provider.Filename, []byte(test.fileContent), 0755); err != nil {
t.Error(err)
}
} }
if len(test.traefikFileContent) > 0 { if len(test.traefikFileContent) > 0 {
ioutil.WriteFile(provider.TraefikFile, []byte(test.traefikFileContent), 0755) if err := ioutil.WriteFile(provider.TraefikFile, []byte(test.traefikFileContent), 0755); err != nil {
t.Error(err)
}
} }
if len(test.directoryContent) > 0 { if len(test.directoryContent) > 0 {

View file

@ -241,7 +241,7 @@ func (c *clientImpl) newResourceEventHandler(events chan<- interface{}) cache.Re
// eventHandlerFunc will pass the obj on to the events channel or drop it. // eventHandlerFunc will pass the obj on to the events channel or drop it.
// This is so passing the events along won't block in the case of high volume. // This is so passing the events along won't block in the case of high volume.
// The events are only used for signalling anyway so dropping a few is ok. // The events are only used for signaling anyway so dropping a few is ok.
func eventHandlerFunc(events chan<- interface{}, obj interface{}) { func eventHandlerFunc(events chan<- interface{}, obj interface{}) {
select { select {
case events <- obj: case events <- obj:

View file

@ -44,7 +44,7 @@ func newKvClientMock(kvPairs []*store.KVPair, err error) *Mock {
} }
func (s *Mock) Put(key string, value []byte, opts *store.WriteOptions) error { func (s *Mock) Put(key string, value []byte, opts *store.WriteOptions) error {
return errors.New("Put not supported") return errors.New("put not supported")
} }
func (s *Mock) Get(key string, options *store.ReadOptions) (*store.KVPair, error) { func (s *Mock) Get(key string, options *store.ReadOptions) (*store.KVPair, error) {
@ -60,7 +60,7 @@ func (s *Mock) Get(key string, options *store.ReadOptions) (*store.KVPair, error
} }
func (s *Mock) Delete(key string) error { func (s *Mock) Delete(key string) error {
return errors.New("Delete not supported") return errors.New("delete not supported")
} }
// Exists mock // Exists mock
@ -78,7 +78,7 @@ func (s *Mock) Exists(key string, options *store.ReadOptions) (bool, error) {
// Watch mock // Watch mock
func (s *Mock) Watch(key string, stopCh <-chan struct{}, options *store.ReadOptions) (<-chan *store.KVPair, error) { func (s *Mock) Watch(key string, stopCh <-chan struct{}, options *store.ReadOptions) (<-chan *store.KVPair, error) {
return nil, errors.New("Watch not supported") return nil, errors.New("watch not supported")
} }
// WatchTree mock // WatchTree mock

View file

@ -5,6 +5,7 @@ import (
"time" "time"
"github.com/abronan/valkeyrie/store" "github.com/abronan/valkeyrie/store"
"github.com/containous/traefik/log"
"github.com/containous/traefik/types" "github.com/containous/traefik/types"
) )
@ -22,7 +23,9 @@ func TestKvWatchTree(t *testing.T) {
configChan := make(chan types.ConfigMessage) configChan := make(chan types.ConfigMessage)
go func() { go func() {
provider.watchKv(configChan, "prefix", make(chan bool, 1)) if err := provider.watchKv(configChan, "prefix", make(chan bool, 1)); err != nil {
log.Error(err)
}
}() }()
select { select {

View file

@ -95,12 +95,6 @@ func containerNetwork() func(*marathon.Application) {
} }
} }
func hostNetwork() func(*marathon.Application) {
return func(app *marathon.Application) {
app.SetNetwork("host", marathon.HostNetworkMode)
}
}
func ipAddrPerTask(port int) func(*marathon.Application) { func ipAddrPerTask(port int) func(*marathon.Application) {
return func(app *marathon.Application) { return func(app *marathon.Application) {
p := marathon.Port{ p := marathon.Port{

View file

@ -109,7 +109,7 @@ func (p *Provider) longPoll(client rancher.Client, updateConfiguration func(stri
// Holds the connection until there is either a change in the metadata // Holds the connection until there is either a change in the metadata
// repository or `p.RefreshSeconds` has elapsed. Long polling should be // repository or `p.RefreshSeconds` has elapsed. Long polling should be
// favoured for the most accurate configuration updates. // favored for the most accurate configuration updates.
safe.Go(func() { safe.Go(func() {
client.OnChange(p.RefreshSeconds, updateConfiguration) client.OnChange(p.RefreshSeconds, updateConfiguration)
}) })

View file

@ -343,7 +343,7 @@ func (s *Server) AddListener(listener func(types.Configuration)) {
s.configurationListeners = append(s.configurationListeners, listener) s.configurationListeners = append(s.configurationListeners, listener)
} }
// getCertificate allows to customize tlsConfig.GetCertificate behaviour to get the certificates inserted dynamically // getCertificate allows to customize tlsConfig.GetCertificate behavior to get the certificates inserted dynamically
func (s *serverEntryPoint) getCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) { func (s *serverEntryPoint) getCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
domainToCheck := types.CanonicalDomain(clientHello.ServerName) domainToCheck := types.CanonicalDomain(clientHello.ServerName)
@ -498,7 +498,7 @@ func (s *Server) startServer(serverEntryPoint *serverEntryPoint) {
} }
func (s *Server) setupServerEntryPoint(newServerEntryPointName string, newServerEntryPoint *serverEntryPoint) *serverEntryPoint { func (s *Server) setupServerEntryPoint(newServerEntryPointName string, newServerEntryPoint *serverEntryPoint) *serverEntryPoint {
serverMiddlewares, err := s.buildServerEntryPointMiddlewares(newServerEntryPointName, newServerEntryPoint) serverMiddlewares, err := s.buildServerEntryPointMiddlewares(newServerEntryPointName)
if err != nil { if err != nil {
log.Fatal("Error preparing server: ", err) log.Fatal("Error preparing server: ", err)
} }

View file

@ -165,7 +165,7 @@ func (s *Server) loadFrontendConfig(
if backendsHandlers[entryPointName+providerName+frontendHash] == nil { if backendsHandlers[entryPointName+providerName+frontendHash] == nil {
log.Debugf("Creating backend %s", frontend.Backend) log.Debugf("Creating backend %s", frontend.Backend)
handlers, responseModifier, postConfig, err := s.buildMiddlewares(frontendName, frontend, config.Backends, entryPointName, entryPoint, providerName) handlers, responseModifier, postConfig, err := s.buildMiddlewares(frontendName, frontend, config.Backends, entryPointName, providerName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -566,11 +566,15 @@ func (s *Server) buildServerEntryPoints() map[string]*serverEntryPoint {
if entryPoint.Configuration.TLS.DefaultCertificate != nil { if entryPoint.Configuration.TLS.DefaultCertificate != nil {
cert, err := tls.LoadX509KeyPair(entryPoint.Configuration.TLS.DefaultCertificate.CertFile.String(), entryPoint.Configuration.TLS.DefaultCertificate.KeyFile.String()) cert, err := tls.LoadX509KeyPair(entryPoint.Configuration.TLS.DefaultCertificate.CertFile.String(), entryPoint.Configuration.TLS.DefaultCertificate.KeyFile.String())
if err != nil { if err != nil {
log.Error(err)
continue
} }
serverEntryPoints[entryPointName].certs.DefaultCertificate = &cert serverEntryPoints[entryPointName].certs.DefaultCertificate = &cert
} else { } else {
cert, err := generate.DefaultCertificate() cert, err := generate.DefaultCertificate()
if err != nil { if err != nil {
log.Error(err)
continue
} }
serverEntryPoints[entryPointName].certs.DefaultCertificate = cert serverEntryPoints[entryPointName].certs.DefaultCertificate = cert
} }

View file

@ -228,7 +228,7 @@ func (s *Server) getRoundTripper(entryPointName string, passTLSCert bool, tls *t
// For the settings that can't be configured in Traefik it uses the default http.Transport settings. // For the settings that can't be configured in Traefik it uses the default http.Transport settings.
// An exception to this is the MaxIdleConns setting as we only provide the option MaxIdleConnsPerHost // An exception to this is the MaxIdleConns setting as we only provide the option MaxIdleConnsPerHost
// in Traefik at this point in time. Setting this value to the default of 100 could lead to confusing // in Traefik at this point in time. Setting this value to the default of 100 could lead to confusing
// behaviour and backwards compatibility issues. // behavior and backwards compatibility issues.
func createHTTPTransport(globalConfiguration configuration.GlobalConfiguration) (*http.Transport, error) { func createHTTPTransport(globalConfiguration configuration.GlobalConfiguration) (*http.Transport, error) {
dialer := &net.Dialer{ dialer := &net.Dialer{
Timeout: configuration.DefaultDialTimeout, Timeout: configuration.DefaultDialTimeout,

View file

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"github.com/containous/traefik/configuration"
"github.com/containous/traefik/log" "github.com/containous/traefik/log"
"github.com/containous/traefik/middlewares" "github.com/containous/traefik/middlewares"
"github.com/containous/traefik/middlewares/accesslog" "github.com/containous/traefik/middlewares/accesslog"
@ -22,9 +21,7 @@ type handlerPostConfig func(backendsHandlers map[string]http.Handler) error
type modifyResponse func(*http.Response) error type modifyResponse func(*http.Response) error
func (s *Server) buildMiddlewares(frontendName string, frontend *types.Frontend, func (s *Server) buildMiddlewares(frontendName string, frontend *types.Frontend,
backends map[string]*types.Backend, backends map[string]*types.Backend, entryPointName string, providerName string) ([]negroni.Handler, modifyResponse, handlerPostConfig, error) {
entryPointName string, entryPoint *configuration.EntryPoint,
providerName string) ([]negroni.Handler, modifyResponse, handlerPostConfig, error) {
var middle []negroni.Handler var middle []negroni.Handler
var postConfig handlerPostConfig var postConfig handlerPostConfig
@ -109,7 +106,7 @@ func (s *Server) buildMiddlewares(frontendName string, frontend *types.Frontend,
return middle, buildModifyResponse(secureMiddleware, headerMiddleware), postConfig, nil return middle, buildModifyResponse(secureMiddleware, headerMiddleware), postConfig, nil
} }
func (s *Server) buildServerEntryPointMiddlewares(serverEntryPointName string, serverEntryPoint *serverEntryPoint) ([]negroni.Handler, error) { func (s *Server) buildServerEntryPointMiddlewares(serverEntryPointName string) ([]negroni.Handler, error) {
serverMiddlewares := []negroni.Handler{middlewares.NegroniRecoverHandler()} serverMiddlewares := []negroni.Handler{middlewares.NegroniRecoverHandler()}
if s.tracingMiddleware.IsEnabled() { if s.tracingMiddleware.IsEnabled() {

View file

@ -35,16 +35,16 @@ func TestPrepareServerTimeouts(t *testing.T) {
WriteTimeout: parse.Duration(14 * time.Second), WriteTimeout: parse.Duration(14 * time.Second),
}, },
}, },
expectedIdleTimeout: time.Duration(10 * time.Second), expectedIdleTimeout: 10 * time.Second,
expectedReadTimeout: time.Duration(12 * time.Second), expectedReadTimeout: 12 * time.Second,
expectedWriteTimeout: time.Duration(14 * time.Second), expectedWriteTimeout: 14 * time.Second,
}, },
{ {
desc: "using defaults", desc: "using defaults",
globalConfig: configuration.GlobalConfiguration{}, globalConfig: configuration.GlobalConfiguration{},
expectedIdleTimeout: time.Duration(180 * time.Second), expectedIdleTimeout: 180 * time.Second,
expectedReadTimeout: time.Duration(0 * time.Second), expectedReadTimeout: 0 * time.Second,
expectedWriteTimeout: time.Duration(0 * time.Second), expectedWriteTimeout: 0 * time.Second,
}, },
} }
@ -106,7 +106,7 @@ func TestListenProvidersSkipsSameConfigurationForProvider(t *testing.T) {
case config := <-server.configurationValidatedChan: case config := <-server.configurationValidatedChan:
// set the current configuration // set the current configuration
// this is usually done in the processing part of the published configuration // this is usually done in the processing part of the published configuration
// so we have to emulate the behaviour here // so we have to emulate the behavior here
currentConfigurations := server.currentConfigurations.Get().(types.Configurations) currentConfigurations := server.currentConfigurations.Get().(types.Configurations)
currentConfigurations[config.ProviderName] = config.Configuration currentConfigurations[config.ProviderName] = config.Configuration
server.currentConfigurations.Set(currentConfigurations) server.currentConfigurations.Set(currentConfigurations)

View file

@ -41,7 +41,10 @@ func (v Handler) AddRoutes(router *mux.Router) {
Version: Version, Version: Version,
Codename: Codename, Codename: Codename,
} }
templatesRenderer.JSON(response, http.StatusOK, v)
if err := templatesRenderer.JSON(response, http.StatusOK, v); err != nil {
log.Error(err)
}
}) })
} }