Split runtime.go
This commit is contained in:
parent
6be390c795
commit
51f7d9a07f
6 changed files with 692 additions and 660 deletions
|
@ -1,10 +1,8 @@
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||||
"github.com/containous/traefik/v2/pkg/log"
|
"github.com/containous/traefik/v2/pkg/log"
|
||||||
|
@ -171,255 +169,6 @@ func contains(entryPoints []string, entryPointName string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRoutersByEntryPoints returns all the http routers by entry points name and routers name
|
|
||||||
func (c *Configuration) GetRoutersByEntryPoints(ctx context.Context, entryPoints []string, tls bool) map[string]map[string]*RouterInfo {
|
|
||||||
entryPointsRouters := make(map[string]map[string]*RouterInfo)
|
|
||||||
|
|
||||||
for rtName, rt := range c.Routers {
|
|
||||||
if (tls && rt.TLS == nil) || (!tls && rt.TLS != nil) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
eps := rt.EntryPoints
|
|
||||||
if len(eps) == 0 {
|
|
||||||
eps = entryPoints
|
|
||||||
}
|
|
||||||
for _, entryPointName := range eps {
|
|
||||||
if !contains(entryPoints, entryPointName) {
|
|
||||||
log.FromContext(log.With(ctx, log.Str(log.EntryPointName, entryPointName))).
|
|
||||||
Errorf("entryPoint %q doesn't exist", entryPointName)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := entryPointsRouters[entryPointName]; !ok {
|
|
||||||
entryPointsRouters[entryPointName] = make(map[string]*RouterInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
entryPointsRouters[entryPointName][rtName] = rt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return entryPointsRouters
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTCPRoutersByEntryPoints returns all the tcp routers by entry points name and routers name
|
|
||||||
func (c *Configuration) GetTCPRoutersByEntryPoints(ctx context.Context, entryPoints []string) map[string]map[string]*TCPRouterInfo {
|
|
||||||
entryPointsRouters := make(map[string]map[string]*TCPRouterInfo)
|
|
||||||
|
|
||||||
for rtName, rt := range c.TCPRouters {
|
|
||||||
eps := rt.EntryPoints
|
|
||||||
if len(eps) == 0 {
|
|
||||||
eps = entryPoints
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, entryPointName := range eps {
|
|
||||||
if !contains(entryPoints, entryPointName) {
|
|
||||||
log.FromContext(log.With(ctx, log.Str(log.EntryPointName, entryPointName))).
|
|
||||||
Errorf("entryPoint %q doesn't exist", entryPointName)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := entryPointsRouters[entryPointName]; !ok {
|
|
||||||
entryPointsRouters[entryPointName] = make(map[string]*TCPRouterInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
entryPointsRouters[entryPointName][rtName] = rt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return entryPointsRouters
|
|
||||||
}
|
|
||||||
|
|
||||||
// RouterInfo holds information about a currently running HTTP router
|
|
||||||
type RouterInfo struct {
|
|
||||||
*dynamic.Router // dynamic configuration
|
|
||||||
// Err contains all the errors that occurred during router's creation.
|
|
||||||
Err []string `json:"error,omitempty"`
|
|
||||||
// Status reports whether the router is disabled, in a warning state, or all good (enabled).
|
|
||||||
// If not in "enabled" state, the reason for it should be in the list of Err.
|
|
||||||
// It is the caller's responsibility to set the initial status.
|
|
||||||
Status string `json:"status,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddError adds err to r.Err, if it does not already exist.
|
|
||||||
// If critical is set, r is marked as disabled.
|
|
||||||
func (r *RouterInfo) AddError(err error, critical bool) {
|
|
||||||
for _, value := range r.Err {
|
|
||||||
if value == err.Error() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Err = append(r.Err, err.Error())
|
|
||||||
if critical {
|
|
||||||
r.Status = StatusDisabled
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// only set it to "warning" if not already in a worse state
|
|
||||||
if r.Status != StatusDisabled {
|
|
||||||
r.Status = StatusWarning
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TCPRouterInfo holds information about a currently running TCP router
|
|
||||||
type TCPRouterInfo struct {
|
|
||||||
*dynamic.TCPRouter // dynamic configuration
|
|
||||||
Err []string `json:"error,omitempty"` // initialization error
|
|
||||||
// Status reports whether the router is disabled, in a warning state, or all good (enabled).
|
|
||||||
// If not in "enabled" state, the reason for it should be in the list of Err.
|
|
||||||
// It is the caller's responsibility to set the initial status.
|
|
||||||
Status string `json:"status,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddError adds err to r.Err, if it does not already exist.
|
|
||||||
// If critical is set, r is marked as disabled.
|
|
||||||
func (r *TCPRouterInfo) AddError(err error, critical bool) {
|
|
||||||
for _, value := range r.Err {
|
|
||||||
if value == err.Error() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Err = append(r.Err, err.Error())
|
|
||||||
if critical {
|
|
||||||
r.Status = StatusDisabled
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// only set it to "warning" if not already in a worse state
|
|
||||||
if r.Status != StatusDisabled {
|
|
||||||
r.Status = StatusWarning
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MiddlewareInfo holds information about a currently running middleware
|
|
||||||
type MiddlewareInfo struct {
|
|
||||||
*dynamic.Middleware // dynamic configuration
|
|
||||||
// Err contains all the errors that occurred during service creation.
|
|
||||||
Err []string `json:"error,omitempty"`
|
|
||||||
Status string `json:"status,omitempty"`
|
|
||||||
UsedBy []string `json:"usedBy,omitempty"` // list of routers and services using that middleware
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddError adds err to s.Err, if it does not already exist.
|
|
||||||
// If critical is set, m is marked as disabled.
|
|
||||||
func (m *MiddlewareInfo) AddError(err error, critical bool) {
|
|
||||||
for _, value := range m.Err {
|
|
||||||
if value == err.Error() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Err = append(m.Err, err.Error())
|
|
||||||
if critical {
|
|
||||||
m.Status = StatusDisabled
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// only set it to "warning" if not already in a worse state
|
|
||||||
if m.Status != StatusDisabled {
|
|
||||||
m.Status = StatusWarning
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServiceInfo holds information about a currently running service
|
|
||||||
type ServiceInfo struct {
|
|
||||||
*dynamic.Service // dynamic configuration
|
|
||||||
// Err contains all the errors that occurred during service creation.
|
|
||||||
Err []string `json:"error,omitempty"`
|
|
||||||
// Status reports whether the service is disabled, in a warning state, or all good (enabled).
|
|
||||||
// If not in "enabled" state, the reason for it should be in the list of Err.
|
|
||||||
// It is the caller's responsibility to set the initial status.
|
|
||||||
Status string `json:"status,omitempty"`
|
|
||||||
UsedBy []string `json:"usedBy,omitempty"` // list of routers using that service
|
|
||||||
|
|
||||||
serverStatusMu sync.RWMutex
|
|
||||||
serverStatus map[string]string // keyed by server URL
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddError adds err to s.Err, if it does not already exist.
|
|
||||||
// If critical is set, s is marked as disabled.
|
|
||||||
func (s *ServiceInfo) AddError(err error, critical bool) {
|
|
||||||
for _, value := range s.Err {
|
|
||||||
if value == err.Error() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s.Err = append(s.Err, err.Error())
|
|
||||||
if critical {
|
|
||||||
s.Status = StatusDisabled
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// only set it to "warning" if not already in a worse state
|
|
||||||
if s.Status != StatusDisabled {
|
|
||||||
s.Status = StatusWarning
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateServerStatus sets the status of the server in the ServiceInfo.
|
|
||||||
// It is the responsibility of the caller to check that s is not nil.
|
|
||||||
func (s *ServiceInfo) UpdateServerStatus(server string, status string) {
|
|
||||||
s.serverStatusMu.Lock()
|
|
||||||
defer s.serverStatusMu.Unlock()
|
|
||||||
|
|
||||||
if s.serverStatus == nil {
|
|
||||||
s.serverStatus = make(map[string]string)
|
|
||||||
}
|
|
||||||
s.serverStatus[server] = status
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAllStatus returns all the statuses of all the servers in ServiceInfo.
|
|
||||||
// It is the responsibility of the caller to check that s is not nil
|
|
||||||
func (s *ServiceInfo) GetAllStatus() map[string]string {
|
|
||||||
s.serverStatusMu.RLock()
|
|
||||||
defer s.serverStatusMu.RUnlock()
|
|
||||||
|
|
||||||
if len(s.serverStatus) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
allStatus := make(map[string]string, len(s.serverStatus))
|
|
||||||
for k, v := range s.serverStatus {
|
|
||||||
allStatus[k] = v
|
|
||||||
}
|
|
||||||
return allStatus
|
|
||||||
}
|
|
||||||
|
|
||||||
// TCPServiceInfo holds information about a currently running TCP service
|
|
||||||
type TCPServiceInfo struct {
|
|
||||||
*dynamic.TCPService // dynamic configuration
|
|
||||||
Err []string `json:"error,omitempty"` // initialization error
|
|
||||||
// Status reports whether the service is disabled, in a warning state, or all good (enabled).
|
|
||||||
// If not in "enabled" state, the reason for it should be in the list of Err.
|
|
||||||
// It is the caller's responsibility to set the initial status.
|
|
||||||
Status string `json:"status,omitempty"`
|
|
||||||
UsedBy []string `json:"usedBy,omitempty"` // list of routers using that service
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddError adds err to s.Err, if it does not already exist.
|
|
||||||
// If critical is set, s is marked as disabled.
|
|
||||||
func (s *TCPServiceInfo) AddError(err error, critical bool) {
|
|
||||||
for _, value := range s.Err {
|
|
||||||
if value == err.Error() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s.Err = append(s.Err, err.Error())
|
|
||||||
if critical {
|
|
||||||
s.Status = StatusDisabled
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// only set it to "warning" if not already in a worse state
|
|
||||||
if s.Status != StatusDisabled {
|
|
||||||
s.Status = StatusWarning
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getProviderName(elementName string) string {
|
func getProviderName(elementName string) string {
|
||||||
parts := strings.Split(elementName, "@")
|
parts := strings.Split(elementName, "@")
|
||||||
if len(parts) > 1 {
|
if len(parts) > 1 {
|
||||||
|
|
167
pkg/config/runtime/runtime_http.go
Normal file
167
pkg/config/runtime/runtime_http.go
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||||
|
"github.com/containous/traefik/v2/pkg/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetRoutersByEntryPoints returns all the http routers by entry points name and routers name
|
||||||
|
func (c *Configuration) GetRoutersByEntryPoints(ctx context.Context, entryPoints []string, tls bool) map[string]map[string]*RouterInfo {
|
||||||
|
entryPointsRouters := make(map[string]map[string]*RouterInfo)
|
||||||
|
|
||||||
|
for rtName, rt := range c.Routers {
|
||||||
|
if (tls && rt.TLS == nil) || (!tls && rt.TLS != nil) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
eps := rt.EntryPoints
|
||||||
|
if len(eps) == 0 {
|
||||||
|
eps = entryPoints
|
||||||
|
}
|
||||||
|
for _, entryPointName := range eps {
|
||||||
|
if !contains(entryPoints, entryPointName) {
|
||||||
|
log.FromContext(log.With(ctx, log.Str(log.EntryPointName, entryPointName))).
|
||||||
|
Errorf("entryPoint %q doesn't exist", entryPointName)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := entryPointsRouters[entryPointName]; !ok {
|
||||||
|
entryPointsRouters[entryPointName] = make(map[string]*RouterInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
entryPointsRouters[entryPointName][rtName] = rt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return entryPointsRouters
|
||||||
|
}
|
||||||
|
|
||||||
|
// RouterInfo holds information about a currently running HTTP router
|
||||||
|
type RouterInfo struct {
|
||||||
|
*dynamic.Router // dynamic configuration
|
||||||
|
// Err contains all the errors that occurred during router's creation.
|
||||||
|
Err []string `json:"error,omitempty"`
|
||||||
|
// Status reports whether the router is disabled, in a warning state, or all good (enabled).
|
||||||
|
// If not in "enabled" state, the reason for it should be in the list of Err.
|
||||||
|
// It is the caller's responsibility to set the initial status.
|
||||||
|
Status string `json:"status,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddError adds err to r.Err, if it does not already exist.
|
||||||
|
// If critical is set, r is marked as disabled.
|
||||||
|
func (r *RouterInfo) AddError(err error, critical bool) {
|
||||||
|
for _, value := range r.Err {
|
||||||
|
if value == err.Error() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Err = append(r.Err, err.Error())
|
||||||
|
if critical {
|
||||||
|
r.Status = StatusDisabled
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// only set it to "warning" if not already in a worse state
|
||||||
|
if r.Status != StatusDisabled {
|
||||||
|
r.Status = StatusWarning
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MiddlewareInfo holds information about a currently running middleware
|
||||||
|
type MiddlewareInfo struct {
|
||||||
|
*dynamic.Middleware // dynamic configuration
|
||||||
|
// Err contains all the errors that occurred during service creation.
|
||||||
|
Err []string `json:"error,omitempty"`
|
||||||
|
Status string `json:"status,omitempty"`
|
||||||
|
UsedBy []string `json:"usedBy,omitempty"` // list of routers and services using that middleware
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddError adds err to s.Err, if it does not already exist.
|
||||||
|
// If critical is set, m is marked as disabled.
|
||||||
|
func (m *MiddlewareInfo) AddError(err error, critical bool) {
|
||||||
|
for _, value := range m.Err {
|
||||||
|
if value == err.Error() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Err = append(m.Err, err.Error())
|
||||||
|
if critical {
|
||||||
|
m.Status = StatusDisabled
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// only set it to "warning" if not already in a worse state
|
||||||
|
if m.Status != StatusDisabled {
|
||||||
|
m.Status = StatusWarning
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceInfo holds information about a currently running service
|
||||||
|
type ServiceInfo struct {
|
||||||
|
*dynamic.Service // dynamic configuration
|
||||||
|
// Err contains all the errors that occurred during service creation.
|
||||||
|
Err []string `json:"error,omitempty"`
|
||||||
|
// Status reports whether the service is disabled, in a warning state, or all good (enabled).
|
||||||
|
// If not in "enabled" state, the reason for it should be in the list of Err.
|
||||||
|
// It is the caller's responsibility to set the initial status.
|
||||||
|
Status string `json:"status,omitempty"`
|
||||||
|
UsedBy []string `json:"usedBy,omitempty"` // list of routers using that service
|
||||||
|
|
||||||
|
serverStatusMu sync.RWMutex
|
||||||
|
serverStatus map[string]string // keyed by server URL
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddError adds err to s.Err, if it does not already exist.
|
||||||
|
// If critical is set, s is marked as disabled.
|
||||||
|
func (s *ServiceInfo) AddError(err error, critical bool) {
|
||||||
|
for _, value := range s.Err {
|
||||||
|
if value == err.Error() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Err = append(s.Err, err.Error())
|
||||||
|
if critical {
|
||||||
|
s.Status = StatusDisabled
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// only set it to "warning" if not already in a worse state
|
||||||
|
if s.Status != StatusDisabled {
|
||||||
|
s.Status = StatusWarning
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateServerStatus sets the status of the server in the ServiceInfo.
|
||||||
|
// It is the responsibility of the caller to check that s is not nil.
|
||||||
|
func (s *ServiceInfo) UpdateServerStatus(server string, status string) {
|
||||||
|
s.serverStatusMu.Lock()
|
||||||
|
defer s.serverStatusMu.Unlock()
|
||||||
|
|
||||||
|
if s.serverStatus == nil {
|
||||||
|
s.serverStatus = make(map[string]string)
|
||||||
|
}
|
||||||
|
s.serverStatus[server] = status
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllStatus returns all the statuses of all the servers in ServiceInfo.
|
||||||
|
// It is the responsibility of the caller to check that s is not nil
|
||||||
|
func (s *ServiceInfo) GetAllStatus() map[string]string {
|
||||||
|
s.serverStatusMu.RLock()
|
||||||
|
defer s.serverStatusMu.RUnlock()
|
||||||
|
|
||||||
|
if len(s.serverStatus) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
allStatus := make(map[string]string, len(s.serverStatus))
|
||||||
|
for k, v := range s.serverStatus {
|
||||||
|
allStatus[k] = v
|
||||||
|
}
|
||||||
|
return allStatus
|
||||||
|
}
|
213
pkg/config/runtime/runtime_http_test.go
Normal file
213
pkg/config/runtime/runtime_http_test.go
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetRoutersByEntryPoints(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
conf dynamic.Configuration
|
||||||
|
entryPoints []string
|
||||||
|
expected map[string]map[string]*RouterInfo
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "Empty Configuration without entrypoint",
|
||||||
|
conf: dynamic.Configuration{},
|
||||||
|
entryPoints: []string{""},
|
||||||
|
expected: map[string]map[string]*RouterInfo{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "Empty Configuration with unknown entrypoints",
|
||||||
|
conf: dynamic.Configuration{},
|
||||||
|
entryPoints: []string{"foo"},
|
||||||
|
expected: map[string]map[string]*RouterInfo{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "Valid configuration with an unknown entrypoint",
|
||||||
|
conf: dynamic.Configuration{
|
||||||
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.Router{
|
||||||
|
"foo": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foo`)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TCP: &dynamic.TCPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.TCPRouter{
|
||||||
|
"foo": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foo`)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
entryPoints: []string{"foo"},
|
||||||
|
expected: map[string]map[string]*RouterInfo{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "Valid configuration with a known entrypoint",
|
||||||
|
conf: dynamic.Configuration{
|
||||||
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.Router{
|
||||||
|
"foo": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foo`)",
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
EntryPoints: []string{"webs"},
|
||||||
|
Service: "bar-service@myprovider",
|
||||||
|
Rule: "Host(`foo.bar`)",
|
||||||
|
},
|
||||||
|
"foobar": {
|
||||||
|
EntryPoints: []string{"web", "webs"},
|
||||||
|
Service: "foobar-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foobar`)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TCP: &dynamic.TCPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.TCPRouter{
|
||||||
|
"foo": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foo`)",
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
EntryPoints: []string{"webs"},
|
||||||
|
Service: "bar-service@myprovider",
|
||||||
|
Rule: "HostSNI(`foo.bar`)",
|
||||||
|
},
|
||||||
|
"foobar": {
|
||||||
|
EntryPoints: []string{"web", "webs"},
|
||||||
|
Service: "foobar-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foobar`)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
entryPoints: []string{"web"},
|
||||||
|
expected: map[string]map[string]*RouterInfo{
|
||||||
|
"web": {
|
||||||
|
"foo": {
|
||||||
|
Router: &dynamic.Router{
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foo`)",
|
||||||
|
},
|
||||||
|
Status: "enabled",
|
||||||
|
},
|
||||||
|
"foobar": {
|
||||||
|
Router: &dynamic.Router{
|
||||||
|
EntryPoints: []string{"web", "webs"},
|
||||||
|
Service: "foobar-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foobar`)",
|
||||||
|
},
|
||||||
|
Status: "enabled",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "Valid configuration with multiple known entrypoints",
|
||||||
|
conf: dynamic.Configuration{
|
||||||
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.Router{
|
||||||
|
"foo": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foo`)",
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
EntryPoints: []string{"webs"},
|
||||||
|
Service: "bar-service@myprovider",
|
||||||
|
Rule: "Host(`foo.bar`)",
|
||||||
|
},
|
||||||
|
"foobar": {
|
||||||
|
EntryPoints: []string{"web", "webs"},
|
||||||
|
Service: "foobar-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foobar`)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TCP: &dynamic.TCPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.TCPRouter{
|
||||||
|
"foo": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foo`)",
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
EntryPoints: []string{"webs"},
|
||||||
|
Service: "bar-service@myprovider",
|
||||||
|
Rule: "HostSNI(`foo.bar`)",
|
||||||
|
},
|
||||||
|
"foobar": {
|
||||||
|
EntryPoints: []string{"web", "webs"},
|
||||||
|
Service: "foobar-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foobar`)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
entryPoints: []string{"web", "webs"},
|
||||||
|
expected: map[string]map[string]*RouterInfo{
|
||||||
|
"web": {
|
||||||
|
"foo": {
|
||||||
|
Router: &dynamic.Router{
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foo`)",
|
||||||
|
},
|
||||||
|
Status: "enabled",
|
||||||
|
},
|
||||||
|
"foobar": {
|
||||||
|
Router: &dynamic.Router{
|
||||||
|
EntryPoints: []string{"web", "webs"},
|
||||||
|
Service: "foobar-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foobar`)",
|
||||||
|
},
|
||||||
|
Status: "enabled",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"webs": {
|
||||||
|
"bar": {
|
||||||
|
Router: &dynamic.Router{
|
||||||
|
|
||||||
|
EntryPoints: []string{"webs"},
|
||||||
|
Service: "bar-service@myprovider",
|
||||||
|
Rule: "Host(`foo.bar`)",
|
||||||
|
},
|
||||||
|
Status: "enabled",
|
||||||
|
},
|
||||||
|
"foobar": {
|
||||||
|
Router: &dynamic.Router{
|
||||||
|
EntryPoints: []string{"web", "webs"},
|
||||||
|
Service: "foobar-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foobar`)",
|
||||||
|
},
|
||||||
|
Status: "enabled",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
runtimeConfig := NewConfig(test.conf)
|
||||||
|
actual := runtimeConfig.GetRoutersByEntryPoints(context.Background(), test.entryPoints, false)
|
||||||
|
assert.Equal(t, test.expected, actual)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
99
pkg/config/runtime/runtime_tcp.go
Normal file
99
pkg/config/runtime/runtime_tcp.go
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||||
|
"github.com/containous/traefik/v2/pkg/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetTCPRoutersByEntryPoints returns all the tcp routers by entry points name and routers name
|
||||||
|
func (c *Configuration) GetTCPRoutersByEntryPoints(ctx context.Context, entryPoints []string) map[string]map[string]*TCPRouterInfo {
|
||||||
|
entryPointsRouters := make(map[string]map[string]*TCPRouterInfo)
|
||||||
|
|
||||||
|
for rtName, rt := range c.TCPRouters {
|
||||||
|
eps := rt.EntryPoints
|
||||||
|
if len(eps) == 0 {
|
||||||
|
eps = entryPoints
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entryPointName := range eps {
|
||||||
|
if !contains(entryPoints, entryPointName) {
|
||||||
|
log.FromContext(log.With(ctx, log.Str(log.EntryPointName, entryPointName))).
|
||||||
|
Errorf("entryPoint %q doesn't exist", entryPointName)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := entryPointsRouters[entryPointName]; !ok {
|
||||||
|
entryPointsRouters[entryPointName] = make(map[string]*TCPRouterInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
entryPointsRouters[entryPointName][rtName] = rt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return entryPointsRouters
|
||||||
|
}
|
||||||
|
|
||||||
|
// TCPRouterInfo holds information about a currently running TCP router
|
||||||
|
type TCPRouterInfo struct {
|
||||||
|
*dynamic.TCPRouter // dynamic configuration
|
||||||
|
Err []string `json:"error,omitempty"` // initialization error
|
||||||
|
// Status reports whether the router is disabled, in a warning state, or all good (enabled).
|
||||||
|
// If not in "enabled" state, the reason for it should be in the list of Err.
|
||||||
|
// It is the caller's responsibility to set the initial status.
|
||||||
|
Status string `json:"status,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddError adds err to r.Err, if it does not already exist.
|
||||||
|
// If critical is set, r is marked as disabled.
|
||||||
|
func (r *TCPRouterInfo) AddError(err error, critical bool) {
|
||||||
|
for _, value := range r.Err {
|
||||||
|
if value == err.Error() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Err = append(r.Err, err.Error())
|
||||||
|
if critical {
|
||||||
|
r.Status = StatusDisabled
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// only set it to "warning" if not already in a worse state
|
||||||
|
if r.Status != StatusDisabled {
|
||||||
|
r.Status = StatusWarning
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TCPServiceInfo holds information about a currently running TCP service
|
||||||
|
type TCPServiceInfo struct {
|
||||||
|
*dynamic.TCPService // dynamic configuration
|
||||||
|
Err []string `json:"error,omitempty"` // initialization error
|
||||||
|
// Status reports whether the service is disabled, in a warning state, or all good (enabled).
|
||||||
|
// If not in "enabled" state, the reason for it should be in the list of Err.
|
||||||
|
// It is the caller's responsibility to set the initial status.
|
||||||
|
Status string `json:"status,omitempty"`
|
||||||
|
UsedBy []string `json:"usedBy,omitempty"` // list of routers using that service
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddError adds err to s.Err, if it does not already exist.
|
||||||
|
// If critical is set, s is marked as disabled.
|
||||||
|
func (s *TCPServiceInfo) AddError(err error, critical bool) {
|
||||||
|
for _, value := range s.Err {
|
||||||
|
if value == err.Error() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Err = append(s.Err, err.Error())
|
||||||
|
if critical {
|
||||||
|
s.Status = StatusDisabled
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// only set it to "warning" if not already in a worse state
|
||||||
|
if s.Status != StatusDisabled {
|
||||||
|
s.Status = StatusWarning
|
||||||
|
}
|
||||||
|
}
|
213
pkg/config/runtime/runtime_tcp_test.go
Normal file
213
pkg/config/runtime/runtime_tcp_test.go
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetTCPRoutersByEntryPoints(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
conf dynamic.Configuration
|
||||||
|
entryPoints []string
|
||||||
|
expected map[string]map[string]*TCPRouterInfo
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "Empty Configuration without entrypoint",
|
||||||
|
conf: dynamic.Configuration{},
|
||||||
|
entryPoints: []string{""},
|
||||||
|
expected: map[string]map[string]*TCPRouterInfo{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "Empty Configuration with unknown entrypoints",
|
||||||
|
conf: dynamic.Configuration{},
|
||||||
|
entryPoints: []string{"foo"},
|
||||||
|
expected: map[string]map[string]*TCPRouterInfo{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "Valid configuration with an unknown entrypoint",
|
||||||
|
conf: dynamic.Configuration{
|
||||||
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.Router{
|
||||||
|
"foo": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foo`)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TCP: &dynamic.TCPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.TCPRouter{
|
||||||
|
"foo": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foo`)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
entryPoints: []string{"foo"},
|
||||||
|
expected: map[string]map[string]*TCPRouterInfo{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "Valid configuration with a known entrypoint",
|
||||||
|
conf: dynamic.Configuration{
|
||||||
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.Router{
|
||||||
|
"foo": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foo`)",
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
EntryPoints: []string{"webs"},
|
||||||
|
Service: "bar-service@myprovider",
|
||||||
|
Rule: "Host(`foo.bar`)",
|
||||||
|
},
|
||||||
|
"foobar": {
|
||||||
|
EntryPoints: []string{"web", "webs"},
|
||||||
|
Service: "foobar-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foobar`)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TCP: &dynamic.TCPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.TCPRouter{
|
||||||
|
"foo": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foo`)",
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
EntryPoints: []string{"webs"},
|
||||||
|
Service: "bar-service@myprovider",
|
||||||
|
Rule: "HostSNI(`foo.bar`)",
|
||||||
|
},
|
||||||
|
"foobar": {
|
||||||
|
EntryPoints: []string{"web", "webs"},
|
||||||
|
Service: "foobar-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foobar`)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
entryPoints: []string{"web"},
|
||||||
|
expected: map[string]map[string]*TCPRouterInfo{
|
||||||
|
"web": {
|
||||||
|
"foo": {
|
||||||
|
TCPRouter: &dynamic.TCPRouter{
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foo`)",
|
||||||
|
},
|
||||||
|
Status: "enabled",
|
||||||
|
},
|
||||||
|
"foobar": {
|
||||||
|
TCPRouter: &dynamic.TCPRouter{
|
||||||
|
EntryPoints: []string{"web", "webs"},
|
||||||
|
Service: "foobar-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foobar`)",
|
||||||
|
},
|
||||||
|
Status: "enabled",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "Valid configuration with multiple known entrypoints",
|
||||||
|
conf: dynamic.Configuration{
|
||||||
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.Router{
|
||||||
|
"foo": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foo`)",
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
EntryPoints: []string{"webs"},
|
||||||
|
Service: "bar-service@myprovider",
|
||||||
|
Rule: "Host(`foo.bar`)",
|
||||||
|
},
|
||||||
|
"foobar": {
|
||||||
|
EntryPoints: []string{"web", "webs"},
|
||||||
|
Service: "foobar-service@myprovider",
|
||||||
|
Rule: "Host(`bar.foobar`)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TCP: &dynamic.TCPConfiguration{
|
||||||
|
Routers: map[string]*dynamic.TCPRouter{
|
||||||
|
"foo": {
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foo`)",
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
EntryPoints: []string{"webs"},
|
||||||
|
Service: "bar-service@myprovider",
|
||||||
|
Rule: "HostSNI(`foo.bar`)",
|
||||||
|
},
|
||||||
|
"foobar": {
|
||||||
|
EntryPoints: []string{"web", "webs"},
|
||||||
|
Service: "foobar-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foobar`)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
entryPoints: []string{"web", "webs"},
|
||||||
|
expected: map[string]map[string]*TCPRouterInfo{
|
||||||
|
"web": {
|
||||||
|
"foo": {
|
||||||
|
TCPRouter: &dynamic.TCPRouter{
|
||||||
|
EntryPoints: []string{"web"},
|
||||||
|
Service: "foo-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foo`)",
|
||||||
|
},
|
||||||
|
Status: "enabled",
|
||||||
|
},
|
||||||
|
"foobar": {
|
||||||
|
TCPRouter: &dynamic.TCPRouter{
|
||||||
|
EntryPoints: []string{"web", "webs"},
|
||||||
|
Service: "foobar-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foobar`)",
|
||||||
|
},
|
||||||
|
Status: "enabled",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"webs": {
|
||||||
|
"bar": {
|
||||||
|
TCPRouter: &dynamic.TCPRouter{
|
||||||
|
|
||||||
|
EntryPoints: []string{"webs"},
|
||||||
|
Service: "bar-service@myprovider",
|
||||||
|
Rule: "HostSNI(`foo.bar`)",
|
||||||
|
},
|
||||||
|
Status: "enabled",
|
||||||
|
},
|
||||||
|
"foobar": {
|
||||||
|
TCPRouter: &dynamic.TCPRouter{
|
||||||
|
EntryPoints: []string{"web", "webs"},
|
||||||
|
Service: "foobar-service@myprovider",
|
||||||
|
Rule: "HostSNI(`bar.foobar`)",
|
||||||
|
},
|
||||||
|
Status: "enabled",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
runtimeConfig := NewConfig(test.conf)
|
||||||
|
actual := runtimeConfig.GetTCPRoutersByEntryPoints(context.Background(), test.entryPoints)
|
||||||
|
assert.Equal(t, test.expected, actual)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package runtime_test
|
package runtime_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||||
|
@ -690,411 +689,3 @@ func TestPopulateUsedBy(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetTCPRoutersByEntryPoints(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
desc string
|
|
||||||
conf dynamic.Configuration
|
|
||||||
entryPoints []string
|
|
||||||
expected map[string]map[string]*runtime.TCPRouterInfo
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
desc: "Empty Configuration without entrypoint",
|
|
||||||
conf: dynamic.Configuration{},
|
|
||||||
entryPoints: []string{""},
|
|
||||||
expected: map[string]map[string]*runtime.TCPRouterInfo{},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "Empty Configuration with unknown entrypoints",
|
|
||||||
conf: dynamic.Configuration{},
|
|
||||||
entryPoints: []string{"foo"},
|
|
||||||
expected: map[string]map[string]*runtime.TCPRouterInfo{},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "Valid configuration with an unknown entrypoint",
|
|
||||||
conf: dynamic.Configuration{
|
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
|
||||||
Routers: map[string]*dynamic.Router{
|
|
||||||
"foo": {
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foo`)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TCP: &dynamic.TCPConfiguration{
|
|
||||||
Routers: map[string]*dynamic.TCPRouter{
|
|
||||||
"foo": {
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foo`)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
entryPoints: []string{"foo"},
|
|
||||||
expected: map[string]map[string]*runtime.TCPRouterInfo{},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "Valid configuration with a known entrypoint",
|
|
||||||
conf: dynamic.Configuration{
|
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
|
||||||
Routers: map[string]*dynamic.Router{
|
|
||||||
"foo": {
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foo`)",
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
EntryPoints: []string{"webs"},
|
|
||||||
Service: "bar-service@myprovider",
|
|
||||||
Rule: "Host(`foo.bar`)",
|
|
||||||
},
|
|
||||||
"foobar": {
|
|
||||||
EntryPoints: []string{"web", "webs"},
|
|
||||||
Service: "foobar-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foobar`)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TCP: &dynamic.TCPConfiguration{
|
|
||||||
Routers: map[string]*dynamic.TCPRouter{
|
|
||||||
"foo": {
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foo`)",
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
EntryPoints: []string{"webs"},
|
|
||||||
Service: "bar-service@myprovider",
|
|
||||||
Rule: "HostSNI(`foo.bar`)",
|
|
||||||
},
|
|
||||||
"foobar": {
|
|
||||||
EntryPoints: []string{"web", "webs"},
|
|
||||||
Service: "foobar-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foobar`)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
entryPoints: []string{"web"},
|
|
||||||
expected: map[string]map[string]*runtime.TCPRouterInfo{
|
|
||||||
"web": {
|
|
||||||
"foo": {
|
|
||||||
TCPRouter: &dynamic.TCPRouter{
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foo`)",
|
|
||||||
},
|
|
||||||
Status: "enabled",
|
|
||||||
},
|
|
||||||
"foobar": {
|
|
||||||
TCPRouter: &dynamic.TCPRouter{
|
|
||||||
EntryPoints: []string{"web", "webs"},
|
|
||||||
Service: "foobar-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foobar`)",
|
|
||||||
},
|
|
||||||
Status: "enabled",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "Valid configuration with multiple known entrypoints",
|
|
||||||
conf: dynamic.Configuration{
|
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
|
||||||
Routers: map[string]*dynamic.Router{
|
|
||||||
"foo": {
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foo`)",
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
EntryPoints: []string{"webs"},
|
|
||||||
Service: "bar-service@myprovider",
|
|
||||||
Rule: "Host(`foo.bar`)",
|
|
||||||
},
|
|
||||||
"foobar": {
|
|
||||||
EntryPoints: []string{"web", "webs"},
|
|
||||||
Service: "foobar-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foobar`)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TCP: &dynamic.TCPConfiguration{
|
|
||||||
Routers: map[string]*dynamic.TCPRouter{
|
|
||||||
"foo": {
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foo`)",
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
EntryPoints: []string{"webs"},
|
|
||||||
Service: "bar-service@myprovider",
|
|
||||||
Rule: "HostSNI(`foo.bar`)",
|
|
||||||
},
|
|
||||||
"foobar": {
|
|
||||||
EntryPoints: []string{"web", "webs"},
|
|
||||||
Service: "foobar-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foobar`)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
entryPoints: []string{"web", "webs"},
|
|
||||||
expected: map[string]map[string]*runtime.TCPRouterInfo{
|
|
||||||
"web": {
|
|
||||||
"foo": {
|
|
||||||
TCPRouter: &dynamic.TCPRouter{
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foo`)",
|
|
||||||
},
|
|
||||||
Status: "enabled",
|
|
||||||
},
|
|
||||||
"foobar": {
|
|
||||||
TCPRouter: &dynamic.TCPRouter{
|
|
||||||
EntryPoints: []string{"web", "webs"},
|
|
||||||
Service: "foobar-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foobar`)",
|
|
||||||
},
|
|
||||||
Status: "enabled",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"webs": {
|
|
||||||
"bar": {
|
|
||||||
TCPRouter: &dynamic.TCPRouter{
|
|
||||||
|
|
||||||
EntryPoints: []string{"webs"},
|
|
||||||
Service: "bar-service@myprovider",
|
|
||||||
Rule: "HostSNI(`foo.bar`)",
|
|
||||||
},
|
|
||||||
Status: "enabled",
|
|
||||||
},
|
|
||||||
"foobar": {
|
|
||||||
TCPRouter: &dynamic.TCPRouter{
|
|
||||||
EntryPoints: []string{"web", "webs"},
|
|
||||||
Service: "foobar-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foobar`)",
|
|
||||||
},
|
|
||||||
Status: "enabled",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range testCases {
|
|
||||||
test := test
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
runtimeConfig := runtime.NewConfig(test.conf)
|
|
||||||
actual := runtimeConfig.GetTCPRoutersByEntryPoints(context.Background(), test.entryPoints)
|
|
||||||
assert.Equal(t, test.expected, actual)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetRoutersByEntryPoints(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
desc string
|
|
||||||
conf dynamic.Configuration
|
|
||||||
entryPoints []string
|
|
||||||
expected map[string]map[string]*runtime.RouterInfo
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
desc: "Empty Configuration without entrypoint",
|
|
||||||
conf: dynamic.Configuration{},
|
|
||||||
entryPoints: []string{""},
|
|
||||||
expected: map[string]map[string]*runtime.RouterInfo{},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "Empty Configuration with unknown entrypoints",
|
|
||||||
conf: dynamic.Configuration{},
|
|
||||||
entryPoints: []string{"foo"},
|
|
||||||
expected: map[string]map[string]*runtime.RouterInfo{},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "Valid configuration with an unknown entrypoint",
|
|
||||||
conf: dynamic.Configuration{
|
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
|
||||||
Routers: map[string]*dynamic.Router{
|
|
||||||
"foo": {
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foo`)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TCP: &dynamic.TCPConfiguration{
|
|
||||||
Routers: map[string]*dynamic.TCPRouter{
|
|
||||||
"foo": {
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foo`)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
entryPoints: []string{"foo"},
|
|
||||||
expected: map[string]map[string]*runtime.RouterInfo{},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "Valid configuration with a known entrypoint",
|
|
||||||
conf: dynamic.Configuration{
|
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
|
||||||
Routers: map[string]*dynamic.Router{
|
|
||||||
"foo": {
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foo`)",
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
EntryPoints: []string{"webs"},
|
|
||||||
Service: "bar-service@myprovider",
|
|
||||||
Rule: "Host(`foo.bar`)",
|
|
||||||
},
|
|
||||||
"foobar": {
|
|
||||||
EntryPoints: []string{"web", "webs"},
|
|
||||||
Service: "foobar-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foobar`)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TCP: &dynamic.TCPConfiguration{
|
|
||||||
Routers: map[string]*dynamic.TCPRouter{
|
|
||||||
"foo": {
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foo`)",
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
EntryPoints: []string{"webs"},
|
|
||||||
Service: "bar-service@myprovider",
|
|
||||||
Rule: "HostSNI(`foo.bar`)",
|
|
||||||
},
|
|
||||||
"foobar": {
|
|
||||||
EntryPoints: []string{"web", "webs"},
|
|
||||||
Service: "foobar-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foobar`)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
entryPoints: []string{"web"},
|
|
||||||
expected: map[string]map[string]*runtime.RouterInfo{
|
|
||||||
"web": {
|
|
||||||
"foo": {
|
|
||||||
Router: &dynamic.Router{
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foo`)",
|
|
||||||
},
|
|
||||||
Status: "enabled",
|
|
||||||
},
|
|
||||||
"foobar": {
|
|
||||||
Router: &dynamic.Router{
|
|
||||||
EntryPoints: []string{"web", "webs"},
|
|
||||||
Service: "foobar-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foobar`)",
|
|
||||||
},
|
|
||||||
Status: "enabled",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "Valid configuration with multiple known entrypoints",
|
|
||||||
conf: dynamic.Configuration{
|
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
|
||||||
Routers: map[string]*dynamic.Router{
|
|
||||||
"foo": {
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foo`)",
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
EntryPoints: []string{"webs"},
|
|
||||||
Service: "bar-service@myprovider",
|
|
||||||
Rule: "Host(`foo.bar`)",
|
|
||||||
},
|
|
||||||
"foobar": {
|
|
||||||
EntryPoints: []string{"web", "webs"},
|
|
||||||
Service: "foobar-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foobar`)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TCP: &dynamic.TCPConfiguration{
|
|
||||||
Routers: map[string]*dynamic.TCPRouter{
|
|
||||||
"foo": {
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foo`)",
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
EntryPoints: []string{"webs"},
|
|
||||||
Service: "bar-service@myprovider",
|
|
||||||
Rule: "HostSNI(`foo.bar`)",
|
|
||||||
},
|
|
||||||
"foobar": {
|
|
||||||
EntryPoints: []string{"web", "webs"},
|
|
||||||
Service: "foobar-service@myprovider",
|
|
||||||
Rule: "HostSNI(`bar.foobar`)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
entryPoints: []string{"web", "webs"},
|
|
||||||
expected: map[string]map[string]*runtime.RouterInfo{
|
|
||||||
"web": {
|
|
||||||
"foo": {
|
|
||||||
Router: &dynamic.Router{
|
|
||||||
EntryPoints: []string{"web"},
|
|
||||||
Service: "foo-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foo`)",
|
|
||||||
},
|
|
||||||
Status: "enabled",
|
|
||||||
},
|
|
||||||
"foobar": {
|
|
||||||
Router: &dynamic.Router{
|
|
||||||
EntryPoints: []string{"web", "webs"},
|
|
||||||
Service: "foobar-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foobar`)",
|
|
||||||
},
|
|
||||||
Status: "enabled",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"webs": {
|
|
||||||
"bar": {
|
|
||||||
Router: &dynamic.Router{
|
|
||||||
|
|
||||||
EntryPoints: []string{"webs"},
|
|
||||||
Service: "bar-service@myprovider",
|
|
||||||
Rule: "Host(`foo.bar`)",
|
|
||||||
},
|
|
||||||
Status: "enabled",
|
|
||||||
},
|
|
||||||
"foobar": {
|
|
||||||
Router: &dynamic.Router{
|
|
||||||
EntryPoints: []string{"web", "webs"},
|
|
||||||
Service: "foobar-service@myprovider",
|
|
||||||
Rule: "Host(`bar.foobar`)",
|
|
||||||
},
|
|
||||||
Status: "enabled",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range testCases {
|
|
||||||
test := test
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
runtimeConfig := runtime.NewConfig(test.conf)
|
|
||||||
actual := runtimeConfig.GetRoutersByEntryPoints(context.Background(), test.entryPoints, false)
|
|
||||||
assert.Equal(t, test.expected, actual)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue