Adds Docker provider support
Co-authored-by: Julien Salleyron <julien@containo.us>
This commit is contained in:
parent
8735263930
commit
b54c956c5e
78 changed files with 3476 additions and 5587 deletions
|
@ -58,19 +58,20 @@ func (b *Builder) BuildChain(ctx context.Context, middlewares []string) *alice.C
|
|||
for _, middlewareName := range middlewares {
|
||||
middlewareName := internal.GetQualifiedName(ctx, middlewareName)
|
||||
constructorContext := internal.AddProviderInContext(ctx, middlewareName)
|
||||
|
||||
chain = chain.Append(func(next http.Handler) (http.Handler, error) {
|
||||
if _, ok := b.configs[middlewareName]; !ok {
|
||||
return nil, fmt.Errorf("middleware %q does not exist", middlewareName)
|
||||
}
|
||||
|
||||
var err error
|
||||
if constructorContext, err = checkRecursivity(constructorContext, middlewareName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, ok := b.configs[middlewareName]; !ok {
|
||||
return nil, fmt.Errorf("middleware %q does not exist", middlewareName)
|
||||
}
|
||||
|
||||
constructor, err := b.buildConstructor(constructorContext, middlewareName, *b.configs[middlewareName])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error while instanciation of %s: %v", middlewareName, err)
|
||||
return nil, fmt.Errorf("error during instanciation of %s: %v", middlewareName, err)
|
||||
}
|
||||
return constructor(next)
|
||||
})
|
||||
|
@ -314,6 +315,10 @@ func (b *Builder) buildConstructor(ctx context.Context, middlewareName string, c
|
|||
}
|
||||
}
|
||||
|
||||
if middleware == nil {
|
||||
return nil, fmt.Errorf("middleware %q does not exist", middlewareName)
|
||||
}
|
||||
|
||||
return tracing.Wrap(ctx, middleware), nil
|
||||
}
|
||||
|
||||
|
|
|
@ -2,18 +2,18 @@ package middleware
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/containous/traefik/config"
|
||||
"github.com/containous/traefik/server/internal"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMiddlewaresRegistry_BuildMiddlewareCircuitBreaker(t *testing.T) {
|
||||
func TestBuilder_buildConstructorCircuitBreaker(t *testing.T) {
|
||||
testConfig := map[string]*config.Middleware{
|
||||
"empty": {
|
||||
CircuitBreaker: &config.CircuitBreaker{
|
||||
|
@ -65,7 +65,7 @@ func TestMiddlewaresRegistry_BuildMiddlewareCircuitBreaker(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestMiddlewaresRegistry_BuildChainNilConfig(t *testing.T) {
|
||||
func TestBuilder_BuildChainNilConfig(t *testing.T) {
|
||||
testConfig := map[string]*config.Middleware{
|
||||
"empty": {},
|
||||
}
|
||||
|
@ -73,10 +73,21 @@ func TestMiddlewaresRegistry_BuildChainNilConfig(t *testing.T) {
|
|||
|
||||
chain := middlewaresBuilder.BuildChain(context.Background(), []string{"empty"})
|
||||
_, err := chain.Then(nil)
|
||||
require.NoError(t, err)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestMiddlewaresRegistry_BuildMiddlewareAddPrefix(t *testing.T) {
|
||||
func TestBuilder_BuildChainNonExistentChain(t *testing.T) {
|
||||
testConfig := map[string]*config.Middleware{
|
||||
"foobar": {},
|
||||
}
|
||||
middlewaresBuilder := NewBuilder(testConfig, nil)
|
||||
|
||||
chain := middlewaresBuilder.BuildChain(context.Background(), []string{"empty"})
|
||||
_, err := chain.Then(nil)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestBuilder_buildConstructorAddPrefix(t *testing.T) {
|
||||
testConfig := map[string]*config.Middleware{
|
||||
"empty": {
|
||||
AddPrefix: &config.AddPrefix{
|
||||
|
@ -98,7 +109,7 @@ func TestMiddlewaresRegistry_BuildMiddlewareAddPrefix(t *testing.T) {
|
|||
expectedError bool
|
||||
}{
|
||||
{
|
||||
desc: "Should not create an emty AddPrefix middleware when given an empty prefix",
|
||||
desc: "Should not create an empty AddPrefix middleware when given an empty prefix",
|
||||
middlewareID: "empty",
|
||||
expectedError: true,
|
||||
}, {
|
||||
|
@ -128,7 +139,7 @@ func TestMiddlewaresRegistry_BuildMiddlewareAddPrefix(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestChainWithContext(t *testing.T) {
|
||||
func TestBuild_BuildChainWithContext(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
buildChain []string
|
||||
|
|
|
@ -57,7 +57,16 @@ func (m *Manager) BuildHandlers(rootCtx context.Context, entryPoints []string) m
|
|||
log.FromContext(ctx).Error(err)
|
||||
continue
|
||||
}
|
||||
entryPointHandlers[entryPointName] = handler
|
||||
|
||||
handlerWithAccessLog, err := alice.New(func(next http.Handler) (http.Handler, error) {
|
||||
return accesslog.NewFieldHandler(next, log.EntryPointName, entryPointName, accesslog.AddOriginFields), nil
|
||||
}).Then(handler)
|
||||
if err != nil {
|
||||
log.FromContext(ctx).Error(err)
|
||||
entryPointHandlers[entryPointName] = handler
|
||||
} else {
|
||||
entryPointHandlers[entryPointName] = handlerWithAccessLog
|
||||
}
|
||||
}
|
||||
|
||||
m.serviceManager.LaunchHealthCheck()
|
||||
|
@ -171,13 +180,9 @@ func (m *Manager) buildHandler(ctx context.Context, router *config.Router, route
|
|||
|
||||
mHandler := m.middlewaresBuilder.BuildChain(ctx, router.Middlewares)
|
||||
|
||||
alHandler := func(next http.Handler) (http.Handler, error) {
|
||||
return accesslog.NewFieldHandler(next, accesslog.ServiceName, router.Service, accesslog.AddServiceFields), nil
|
||||
}
|
||||
|
||||
tHandler := func(next http.Handler) (http.Handler, error) {
|
||||
return tracing.NewForwarder(ctx, routerName, router.Service, next), nil
|
||||
}
|
||||
|
||||
return alice.New().Append(alHandler).Extend(*mHandler).Append(tHandler).Then(sHandler)
|
||||
return alice.New().Extend(*mHandler).Append(tHandler).Then(sHandler)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// loadConfiguration manages dynamically frontends, backends and TLS configurations
|
||||
// loadConfiguration manages dynamically routers, middlewares, servers and TLS configurations
|
||||
func (s *Server) loadConfiguration(configMsg config.Message) {
|
||||
logger := log.FromContext(log.With(context.Background(), log.Str(log.ProviderName, configMsg.ProviderName)))
|
||||
|
||||
|
|
|
@ -9,10 +9,12 @@ import (
|
|||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/containous/alice"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/config"
|
||||
"github.com/containous/traefik/healthcheck"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/middlewares/accesslog"
|
||||
"github.com/containous/traefik/middlewares/emptybackendhandler"
|
||||
"github.com/containous/traefik/old/middlewares/pipelining"
|
||||
"github.com/containous/traefik/server/cookie"
|
||||
|
@ -84,14 +86,16 @@ func (m *Manager) getLoadBalancerServiceHandler(
|
|||
return nil, err
|
||||
}
|
||||
|
||||
fwd = pipelining.NewPipelining(fwd)
|
||||
alHandler := func(next http.Handler) (http.Handler, error) {
|
||||
return accesslog.NewFieldHandler(next, accesslog.ServiceName, serviceName, accesslog.AddServiceFields), nil
|
||||
}
|
||||
|
||||
rr, err := roundrobin.New(fwd)
|
||||
handler, err := alice.New().Append(alHandler).Then(pipelining.NewPipelining(fwd))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
balancer, err := m.getLoadBalancer(ctx, serviceName, service, fwd, rr)
|
||||
balancer, err := m.getLoadBalancer(ctx, serviceName, service, handler)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -181,7 +185,7 @@ func buildHealthCheckOptions(ctx context.Context, lb healthcheck.BalancerHandler
|
|||
}
|
||||
}
|
||||
|
||||
func (m *Manager) getLoadBalancer(ctx context.Context, serviceName string, service *config.LoadBalancerService, fwd http.Handler, rr balancerHandler) (healthcheck.BalancerHandler, error) {
|
||||
func (m *Manager) getLoadBalancer(ctx context.Context, serviceName string, service *config.LoadBalancerService, fwd http.Handler) (healthcheck.BalancerHandler, error) {
|
||||
logger := log.FromContext(ctx)
|
||||
|
||||
var stickySession *roundrobin.StickySession
|
||||
|
@ -192,10 +196,13 @@ func (m *Manager) getLoadBalancer(ctx context.Context, serviceName string, servi
|
|||
}
|
||||
|
||||
var lb healthcheck.BalancerHandler
|
||||
var err error
|
||||
|
||||
if service.Method == "drr" {
|
||||
logger.Debug("Creating drr load-balancer")
|
||||
rr, err := roundrobin.New(fwd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if stickySession != nil {
|
||||
logger.Debugf("Sticky session cookie name: %v", cookieName)
|
||||
|
@ -220,12 +227,17 @@ func (m *Manager) getLoadBalancer(ctx context.Context, serviceName string, servi
|
|||
if stickySession != nil {
|
||||
logger.Debugf("Sticky session cookie name: %v", cookieName)
|
||||
|
||||
var err error
|
||||
lb, err = roundrobin.New(fwd, roundrobin.EnableStickySession(stickySession))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
lb = rr
|
||||
var err error
|
||||
lb, err = roundrobin.New(fwd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,8 @@ package service
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/containous/traefik/config"
|
||||
|
@ -13,41 +11,8 @@ import (
|
|||
"github.com/containous/traefik/testhelpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/vulcand/oxy/roundrobin"
|
||||
)
|
||||
|
||||
type MockRR struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (*MockRR) Servers() []*url.URL {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (*MockRR) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (*MockRR) ServerWeight(u *url.URL) (int, bool) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (*MockRR) RemoveServer(u *url.URL) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (m *MockRR) UpsertServer(u *url.URL, options ...roundrobin.ServerOption) error {
|
||||
return m.err
|
||||
}
|
||||
|
||||
func (*MockRR) NextServer() (*url.URL, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (*MockRR) Next() http.Handler {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
type MockForwarder struct{}
|
||||
|
||||
func (MockForwarder) ServeHTTP(http.ResponseWriter, *http.Request) {
|
||||
|
@ -62,7 +27,6 @@ func TestGetLoadBalancer(t *testing.T) {
|
|||
serviceName string
|
||||
service *config.LoadBalancerService
|
||||
fwd http.Handler
|
||||
rr balancerHandler
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
|
@ -77,22 +41,6 @@ func TestGetLoadBalancer(t *testing.T) {
|
|||
},
|
||||
},
|
||||
fwd: &MockForwarder{},
|
||||
rr: &MockRR{},
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
desc: "Fails when the server upsert fails",
|
||||
serviceName: "test",
|
||||
service: &config.LoadBalancerService{
|
||||
Servers: []config.Server{
|
||||
{
|
||||
URL: "http://foo",
|
||||
Weight: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
fwd: &MockForwarder{},
|
||||
rr: &MockRR{err: errors.New("upsert fails")},
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
|
@ -100,7 +48,6 @@ func TestGetLoadBalancer(t *testing.T) {
|
|||
serviceName: "test",
|
||||
service: &config.LoadBalancerService{},
|
||||
fwd: &MockForwarder{},
|
||||
rr: &MockRR{},
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
|
@ -110,7 +57,6 @@ func TestGetLoadBalancer(t *testing.T) {
|
|||
Stickiness: &config.Stickiness{},
|
||||
},
|
||||
fwd: &MockForwarder{},
|
||||
rr: &MockRR{},
|
||||
expectError: false,
|
||||
},
|
||||
}
|
||||
|
@ -120,7 +66,7 @@ func TestGetLoadBalancer(t *testing.T) {
|
|||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
handler, err := sm.getLoadBalancer(context.Background(), test.serviceName, test.service, test.fwd, test.rr)
|
||||
handler, err := sm.getLoadBalancer(context.Background(), test.serviceName, test.service, test.fwd)
|
||||
if test.expectError {
|
||||
require.Error(t, err)
|
||||
assert.Nil(t, handler)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue