1
0
Fork 0

API: expose runtime representation

Co-authored-by: Julien Salleyron <julien.salleyron@gmail.com>
Co-authored-by: Jean-Baptiste Doumenjou <jb.doumenjou@gmail.com>
This commit is contained in:
mpl 2019-05-16 10:58:06 +02:00 committed by Traefiker Bot
parent 5cd9396dae
commit f6df556eb0
50 changed files with 2250 additions and 1158 deletions

View file

@ -3,6 +3,7 @@ package tcp
import (
"context"
"crypto/tls"
"fmt"
"net/http"
"github.com/containous/traefik/pkg/config"
@ -14,14 +15,14 @@ import (
)
// NewManager Creates a new Manager
func NewManager(routers map[string]*config.TCPRouter,
func NewManager(conf *config.RuntimeConfiguration,
serviceManager *tcpservice.Manager,
httpHandlers map[string]http.Handler,
httpsHandlers map[string]http.Handler,
tlsConfig *tls.Config,
) *Manager {
return &Manager{
configs: routers,
configs: conf.TCPRouters,
serviceManager: serviceManager,
httpHandlers: httpHandlers,
httpsHandlers: httpsHandlers,
@ -31,7 +32,7 @@ func NewManager(routers map[string]*config.TCPRouter,
// Manager is a route/router manager
type Manager struct {
configs map[string]*config.TCPRouter
configs map[string]*config.TCPRouterInfo
serviceManager *tcpservice.Manager
httpHandlers map[string]http.Handler
httpsHandlers map[string]http.Handler
@ -60,7 +61,7 @@ func (m *Manager) BuildHandlers(rootCtx context.Context, entryPoints []string) m
return entryPointHandlers
}
func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string]*config.TCPRouter, handlerHTTP http.Handler, handlerHTTPS http.Handler) (*tcp.Router, error) {
func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string]*config.TCPRouterInfo, handlerHTTP http.Handler, handlerHTTPS http.Handler) (*tcp.Router, error) {
router := &tcp.Router{}
router.HTTPHandler(handlerHTTP)
router.HTTPSHandler(handlerHTTPS, m.tlsConfig)
@ -71,18 +72,21 @@ func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string
handler, err := m.serviceManager.BuildTCP(ctxRouter, routerConfig.Service)
if err != nil {
routerConfig.Err = err.Error()
logger.Error(err)
continue
}
domains, err := rules.ParseHostSNI(routerConfig.Rule)
if err != nil {
logger.Debugf("Unknown rule %s", routerConfig.Rule)
routerErr := fmt.Errorf("unknown rule %s", routerConfig.Rule)
routerConfig.Err = routerErr.Error()
logger.Debug(routerErr)
continue
}
for _, domain := range domains {
logger.Debugf("Add route %s on TCP", domain)
logger.Debugf("Adding route %s on TCP", domain)
switch {
case routerConfig.TLS != nil:
if routerConfig.TLS.Passthrough {
@ -101,8 +105,17 @@ func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string
return router, nil
}
func (m *Manager) filteredRouters(ctx context.Context, entryPoints []string) map[string]map[string]*config.TCPRouter {
entryPointsRouters := make(map[string]map[string]*config.TCPRouter)
func contains(entryPoints []string, entryPointName string) bool {
for _, name := range entryPoints {
if name == entryPointName {
return true
}
}
return false
}
func (m *Manager) filteredRouters(ctx context.Context, entryPoints []string) map[string]map[string]*config.TCPRouterInfo {
entryPointsRouters := make(map[string]map[string]*config.TCPRouterInfo)
for rtName, rt := range m.configs {
eps := rt.EntryPoints
@ -118,7 +131,7 @@ func (m *Manager) filteredRouters(ctx context.Context, entryPoints []string) map
}
if _, ok := entryPointsRouters[entryPointName]; !ok {
entryPointsRouters[entryPointName] = make(map[string]*config.TCPRouter)
entryPointsRouters[entryPointName] = make(map[string]*config.TCPRouterInfo)
}
entryPointsRouters[entryPointName][rtName] = rt
@ -127,12 +140,3 @@ func (m *Manager) filteredRouters(ctx context.Context, entryPoints []string) map
return entryPointsRouters
}
func contains(entryPoints []string, entryPointName string) bool {
for _, name := range entryPoints {
if name == entryPointName {
return true
}
}
return false
}

View file

@ -0,0 +1,223 @@
package tcp
import (
"context"
"testing"
"github.com/containous/traefik/pkg/config"
"github.com/containous/traefik/pkg/server/service/tcp"
"github.com/stretchr/testify/assert"
)
func TestRuntimeConfiguration(t *testing.T) {
testCases := []struct {
desc string
serviceConfig map[string]*config.TCPServiceInfo
routerConfig map[string]*config.TCPRouterInfo
expectedError int
}{
{
desc: "No error",
serviceConfig: map[string]*config.TCPServiceInfo{
"foo-service": {
TCPService: &config.TCPService{
LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{
{
Port: "8085",
Address: "127.0.0.1:8085",
},
{
Address: "127.0.0.1:8086",
Port: "8086",
},
},
Method: "wrr",
},
},
},
},
routerConfig: map[string]*config.TCPRouterInfo{
"foo": {
TCPRouter: &config.TCPRouter{
EntryPoints: []string{"web"},
Service: "foo-service",
Rule: "HostSNI(`bar.foo`)",
},
},
"bar": {
TCPRouter: &config.TCPRouter{
EntryPoints: []string{"web"},
Service: "foo-service",
Rule: "HostSNI(`foo.bar`)",
},
},
},
expectedError: 0,
},
{
desc: "One router with wrong rule",
serviceConfig: map[string]*config.TCPServiceInfo{
"foo-service": {
TCPService: &config.TCPService{
LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{
{
Address: "127.0.0.1:80",
},
},
Method: "wrr",
},
},
},
},
routerConfig: map[string]*config.TCPRouterInfo{
"foo": {
TCPRouter: &config.TCPRouter{
EntryPoints: []string{"web"},
Service: "foo-service",
Rule: "WrongRule(`bar.foo`)",
},
},
"bar": {
TCPRouter: &config.TCPRouter{
EntryPoints: []string{"web"},
Service: "foo-service",
Rule: "HostSNI(`foo.bar`)",
},
},
},
expectedError: 1,
},
{
desc: "All router with wrong rule",
serviceConfig: map[string]*config.TCPServiceInfo{
"foo-service": {
TCPService: &config.TCPService{
LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{
{
Address: "127.0.0.1:80",
Weight: 1,
},
},
Method: "wrr",
},
},
},
},
routerConfig: map[string]*config.TCPRouterInfo{
"foo": {
TCPRouter: &config.TCPRouter{
EntryPoints: []string{"web"},
Service: "foo-service",
Rule: "WrongRule(`bar.foo`)",
},
},
"bar": {
TCPRouter: &config.TCPRouter{
EntryPoints: []string{"web"},
Service: "foo-service",
Rule: "WrongRule(`foo.bar`)",
},
},
},
expectedError: 2,
},
{
desc: "Router with unknown service",
serviceConfig: map[string]*config.TCPServiceInfo{
"foo-service": {
TCPService: &config.TCPService{
LoadBalancer: &config.TCPLoadBalancerService{
Servers: []config.TCPServer{
{
Address: "127.0.0.1:80",
Weight: 1,
},
},
Method: "wrr",
},
},
},
},
routerConfig: map[string]*config.TCPRouterInfo{
"foo": {
TCPRouter: &config.TCPRouter{
EntryPoints: []string{"web"},
Service: "wrong-service",
Rule: "HostSNI(`bar.foo`)",
},
},
"bar": {
TCPRouter: &config.TCPRouter{
EntryPoints: []string{"web"},
Service: "foo-service",
Rule: "HostSNI(`foo.bar`)",
},
},
},
expectedError: 1,
},
{
desc: "Router with broken service",
serviceConfig: map[string]*config.TCPServiceInfo{
"foo-service": {
TCPService: &config.TCPService{
LoadBalancer: nil,
},
},
},
routerConfig: map[string]*config.TCPRouterInfo{
"bar": {
TCPRouter: &config.TCPRouter{
EntryPoints: []string{"web"},
Service: "foo-service",
Rule: "HostSNI(`foo.bar`)",
},
},
},
expectedError: 2,
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
entryPoints := []string{"web"}
conf := &config.RuntimeConfiguration{
TCPServices: test.serviceConfig,
TCPRouters: test.routerConfig,
}
serviceManager := tcp.NewManager(conf)
routerManager := NewManager(conf, serviceManager,
nil, nil, nil)
_ = routerManager.BuildHandlers(context.Background(), entryPoints)
// even though conf was passed by argument to the manager builders above,
// it's ok to use it as the result we check, because everything worth checking
// can be accessed by pointers in it.
var allErrors int
for _, v := range conf.TCPServices {
if v.Err != nil {
allErrors++
}
}
for _, v := range conf.TCPRouters {
if v.Err != "" {
allErrors++
}
}
assert.Equal(t, test.expectedError, allErrors)
})
}
}