2020-02-11 01:26:04 +01:00
package udp
import (
"context"
"errors"
2020-02-17 18:02:04 +01:00
"sort"
2020-02-11 01:26:04 +01:00
2020-09-16 15:46:04 +02:00
"github.com/traefik/traefik/v2/pkg/config/runtime"
"github.com/traefik/traefik/v2/pkg/log"
"github.com/traefik/traefik/v2/pkg/server/provider"
udpservice "github.com/traefik/traefik/v2/pkg/server/service/udp"
"github.com/traefik/traefik/v2/pkg/udp"
2020-02-11 01:26:04 +01:00
)
2020-05-11 12:06:07 +02:00
// NewManager Creates a new Manager.
2020-02-11 01:26:04 +01:00
func NewManager ( conf * runtime . Configuration ,
serviceManager * udpservice . Manager ,
) * Manager {
return & Manager {
serviceManager : serviceManager ,
conf : conf ,
}
}
2020-05-11 12:06:07 +02:00
// Manager is a route/router manager.
2020-02-11 01:26:04 +01:00
type Manager struct {
serviceManager * udpservice . Manager
conf * runtime . Configuration
}
func ( m * Manager ) getUDPRouters ( ctx context . Context , entryPoints [ ] string ) map [ string ] map [ string ] * runtime . UDPRouterInfo {
if m . conf != nil {
return m . conf . GetUDPRoutersByEntryPoints ( ctx , entryPoints )
}
return make ( map [ string ] map [ string ] * runtime . UDPRouterInfo )
}
2020-05-11 12:06:07 +02:00
// BuildHandlers builds the handlers for the given entrypoints.
2020-02-11 01:26:04 +01:00
func ( m * Manager ) BuildHandlers ( rootCtx context . Context , entryPoints [ ] string ) map [ string ] udp . Handler {
entryPointsRouters := m . getUDPRouters ( rootCtx , entryPoints )
entryPointHandlers := make ( map [ string ] udp . Handler )
for _ , entryPointName := range entryPoints {
routers := entryPointsRouters [ entryPointName ]
ctx := log . With ( rootCtx , log . Str ( log . EntryPointName , entryPointName ) )
2020-02-17 18:02:04 +01:00
if len ( routers ) > 1 {
log . FromContext ( ctx ) . Warn ( "Config has more than one udp router for a given entrypoint." )
}
2022-08-31 08:24:08 +02:00
handlers := m . buildEntryPointHandlers ( ctx , routers )
2020-02-17 18:02:04 +01:00
if len ( handlers ) > 0 {
// As UDP support only one router per entrypoint, we only take the first one.
entryPointHandlers [ entryPointName ] = handlers [ 0 ]
}
2020-02-11 01:26:04 +01:00
}
return entryPointHandlers
}
2022-08-31 08:24:08 +02:00
func ( m * Manager ) buildEntryPointHandlers ( ctx context . Context , configs map [ string ] * runtime . UDPRouterInfo ) [ ] udp . Handler {
2020-02-17 18:02:04 +01:00
var rtNames [ ] string
for routerName := range configs {
rtNames = append ( rtNames , routerName )
2020-02-11 01:26:04 +01:00
}
2020-02-17 18:02:04 +01:00
sort . Slice ( rtNames , func ( i , j int ) bool {
return rtNames [ i ] > rtNames [ j ]
} )
var handlers [ ] udp . Handler
for _ , routerName := range rtNames {
routerConfig := configs [ routerName ]
2020-02-11 01:26:04 +01:00
ctxRouter := log . With ( provider . AddInContext ( ctx , routerName ) , log . Str ( log . RouterName , routerName ) )
logger := log . FromContext ( ctxRouter )
if routerConfig . Service == "" {
err := errors . New ( "the service is missing on the udp router" )
routerConfig . AddError ( err , true )
logger . Error ( err )
continue
}
handler , err := m . serviceManager . BuildUDP ( ctxRouter , routerConfig . Service )
if err != nil {
routerConfig . AddError ( err , true )
logger . Error ( err )
continue
}
2020-02-17 18:02:04 +01:00
handlers = append ( handlers , handler )
2020-02-11 01:26:04 +01:00
}
2022-08-31 08:24:08 +02:00
return handlers
2020-02-11 01:26:04 +01:00
}