125 lines
4 KiB
Go
125 lines
4 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
"github.com/traefik/traefik/v3/pkg/config/runtime"
|
|
"github.com/traefik/traefik/v3/pkg/config/static"
|
|
"github.com/traefik/traefik/v3/pkg/server/middleware"
|
|
tcpmiddleware "github.com/traefik/traefik/v3/pkg/server/middleware/tcp"
|
|
"github.com/traefik/traefik/v3/pkg/server/router"
|
|
tcprouter "github.com/traefik/traefik/v3/pkg/server/router/tcp"
|
|
udprouter "github.com/traefik/traefik/v3/pkg/server/router/udp"
|
|
"github.com/traefik/traefik/v3/pkg/server/service"
|
|
tcpsvc "github.com/traefik/traefik/v3/pkg/server/service/tcp"
|
|
udpsvc "github.com/traefik/traefik/v3/pkg/server/service/udp"
|
|
"github.com/traefik/traefik/v3/pkg/tcp"
|
|
"github.com/traefik/traefik/v3/pkg/tls"
|
|
"github.com/traefik/traefik/v3/pkg/udp"
|
|
)
|
|
|
|
// RouterFactory the factory of TCP/UDP routers.
|
|
type RouterFactory struct {
|
|
entryPointsTCP []string
|
|
entryPointsUDP []string
|
|
allowACMEByPass map[string]bool
|
|
|
|
managerFactory *service.ManagerFactory
|
|
|
|
pluginBuilder middleware.PluginsBuilder
|
|
|
|
observabilityMgr *middleware.ObservabilityMgr
|
|
tlsManager *tls.Manager
|
|
|
|
dialerManager *tcp.DialerManager
|
|
|
|
cancelPrevState func()
|
|
}
|
|
|
|
// NewRouterFactory creates a new RouterFactory.
|
|
func NewRouterFactory(staticConfiguration static.Configuration, managerFactory *service.ManagerFactory, tlsManager *tls.Manager,
|
|
observabilityMgr *middleware.ObservabilityMgr, pluginBuilder middleware.PluginsBuilder, dialerManager *tcp.DialerManager,
|
|
) *RouterFactory {
|
|
handlesTLSChallenge := false
|
|
for _, resolver := range staticConfiguration.CertificatesResolvers {
|
|
if resolver.ACME.TLSChallenge != nil {
|
|
handlesTLSChallenge = true
|
|
break
|
|
}
|
|
}
|
|
|
|
allowACMEByPass := map[string]bool{}
|
|
var entryPointsTCP, entryPointsUDP []string
|
|
for name, ep := range staticConfiguration.EntryPoints {
|
|
allowACMEByPass[name] = ep.AllowACMEByPass || !handlesTLSChallenge
|
|
|
|
protocol, err := ep.GetProtocol()
|
|
if err != nil {
|
|
// Should never happen because Traefik should not start if protocol is invalid.
|
|
log.Error().Err(err).Msg("Invalid protocol")
|
|
}
|
|
|
|
if protocol == "udp" {
|
|
entryPointsUDP = append(entryPointsUDP, name)
|
|
} else {
|
|
entryPointsTCP = append(entryPointsTCP, name)
|
|
}
|
|
}
|
|
|
|
return &RouterFactory{
|
|
entryPointsTCP: entryPointsTCP,
|
|
entryPointsUDP: entryPointsUDP,
|
|
managerFactory: managerFactory,
|
|
observabilityMgr: observabilityMgr,
|
|
tlsManager: tlsManager,
|
|
pluginBuilder: pluginBuilder,
|
|
dialerManager: dialerManager,
|
|
allowACMEByPass: allowACMEByPass,
|
|
}
|
|
}
|
|
|
|
// CreateRouters creates new TCPRouters and UDPRouters.
|
|
func (f *RouterFactory) CreateRouters(rtConf *runtime.Configuration) (map[string]*tcprouter.Router, map[string]udp.Handler) {
|
|
if f.cancelPrevState != nil {
|
|
f.cancelPrevState()
|
|
}
|
|
|
|
var ctx context.Context
|
|
ctx, f.cancelPrevState = context.WithCancel(context.Background())
|
|
|
|
// HTTP
|
|
serviceManager := f.managerFactory.Build(rtConf)
|
|
|
|
middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager, f.pluginBuilder)
|
|
|
|
routerManager := router.NewManager(rtConf, serviceManager, middlewaresBuilder, f.observabilityMgr, f.tlsManager)
|
|
|
|
handlersNonTLS := routerManager.BuildHandlers(ctx, f.entryPointsTCP, false)
|
|
handlersTLS := routerManager.BuildHandlers(ctx, f.entryPointsTCP, true)
|
|
|
|
serviceManager.LaunchHealthCheck(ctx)
|
|
|
|
// TCP
|
|
svcTCPManager := tcpsvc.NewManager(rtConf, f.dialerManager)
|
|
|
|
middlewaresTCPBuilder := tcpmiddleware.NewBuilder(rtConf.TCPMiddlewares)
|
|
|
|
rtTCPManager := tcprouter.NewManager(rtConf, svcTCPManager, middlewaresTCPBuilder, handlersNonTLS, handlersTLS, f.tlsManager)
|
|
routersTCP := rtTCPManager.BuildHandlers(ctx, f.entryPointsTCP)
|
|
|
|
for ep, r := range routersTCP {
|
|
if allowACMEByPass, ok := f.allowACMEByPass[ep]; ok && allowACMEByPass {
|
|
r.EnableACMETLSPassthrough()
|
|
}
|
|
}
|
|
|
|
// UDP
|
|
svcUDPManager := udpsvc.NewManager(rtConf)
|
|
rtUDPManager := udprouter.NewManager(rtConf, svcUDPManager)
|
|
routersUDP := rtUDPManager.BuildHandlers(ctx, f.entryPointsUDP)
|
|
|
|
rtConf.PopulateUsedBy()
|
|
|
|
return routersTCP, routersUDP
|
|
}
|