2019-01-18 17:18:04 +03:00
package provider
import (
2019-01-21 21:06:02 +03:00
"bytes"
2019-01-18 17:18:04 +03:00
"context"
"reflect"
"sort"
2019-01-21 21:06:02 +03:00
"strings"
"text/template"
"unicode"
2019-01-18 17:18:04 +03:00
2021-01-20 17:10:04 +03:00
"github.com/Masterminds/sprig/v3"
2022-11-21 20:36:05 +03:00
"github.com/rs/zerolog/log"
2023-02-03 17:24:05 +03:00
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/logs"
2024-03-12 12:38:29 +03:00
"github.com/traefik/traefik/v3/pkg/tls"
2024-07-29 16:39:06 +03:00
"golang.org/x/exp/maps"
2019-01-18 17:18:04 +03:00
)
2024-02-26 12:02:06 +03:00
// Merge merges multiple configurations.
2019-07-10 10:26:04 +03:00
func Merge ( ctx context . Context , configurations map [ string ] * dynamic . Configuration ) * dynamic . Configuration {
2022-11-21 20:36:05 +03:00
logger := log . Ctx ( ctx )
2019-01-18 17:18:04 +03:00
2019-07-10 10:26:04 +03:00
configuration := & dynamic . Configuration {
HTTP : & dynamic . HTTPConfiguration {
2021-07-15 15:02:11 +03:00
Routers : make ( map [ string ] * dynamic . Router ) ,
Middlewares : make ( map [ string ] * dynamic . Middleware ) ,
Services : make ( map [ string ] * dynamic . Service ) ,
ServersTransports : make ( map [ string ] * dynamic . ServersTransport ) ,
2019-03-14 11:30:04 +03:00
} ,
2019-07-10 10:26:04 +03:00
TCP : & dynamic . TCPConfiguration {
2022-12-09 11:58:05 +03:00
Routers : make ( map [ string ] * dynamic . TCPRouter ) ,
Services : make ( map [ string ] * dynamic . TCPService ) ,
Middlewares : make ( map [ string ] * dynamic . TCPMiddleware ) ,
ServersTransports : make ( map [ string ] * dynamic . TCPServersTransport ) ,
2019-03-14 11:30:04 +03:00
} ,
2020-02-11 03:26:04 +03:00
UDP : & dynamic . UDPConfiguration {
Routers : make ( map [ string ] * dynamic . UDPRouter ) ,
Services : make ( map [ string ] * dynamic . UDPService ) ,
} ,
2024-02-26 12:02:06 +03:00
TLS : & dynamic . TLSConfiguration {
Stores : make ( map [ string ] tls . Store ) ,
} ,
2019-01-18 17:18:04 +03:00
}
servicesToDelete := map [ string ] struct { } { }
services := map [ string ] [ ] string { }
routersToDelete := map [ string ] struct { } { }
routers := map [ string ] [ ] string { }
2019-03-21 17:22:06 +03:00
servicesTCPToDelete := map [ string ] struct { } { }
servicesTCP := map [ string ] [ ] string { }
routersTCPToDelete := map [ string ] struct { } { }
routersTCP := map [ string ] [ ] string { }
2020-02-21 00:24:05 +03:00
servicesUDPToDelete := map [ string ] struct { } { }
servicesUDP := map [ string ] [ ] string { }
routersUDPToDelete := map [ string ] struct { } { }
routersUDP := map [ string ] [ ] string { }
2019-01-18 17:18:04 +03:00
middlewaresToDelete := map [ string ] struct { } { }
middlewares := map [ string ] [ ] string { }
2021-06-11 16:30:05 +03:00
middlewaresTCPToDelete := map [ string ] struct { } { }
middlewaresTCP := map [ string ] [ ] string { }
2021-07-15 15:02:11 +03:00
transportsToDelete := map [ string ] struct { } { }
transports := map [ string ] [ ] string { }
2022-12-09 11:58:05 +03:00
transportsTCPToDelete := map [ string ] struct { } { }
transportsTCP := map [ string ] [ ] string { }
2024-02-26 12:02:06 +03:00
storesToDelete := map [ string ] struct { } { }
stores := map [ string ] [ ] string { }
2019-01-18 17:18:04 +03:00
var sortedKeys [ ] string
for key := range configurations {
sortedKeys = append ( sortedKeys , key )
}
sort . Strings ( sortedKeys )
for _ , root := range sortedKeys {
conf := configurations [ root ]
2019-03-14 11:30:04 +03:00
for serviceName , service := range conf . HTTP . Services {
2019-01-18 17:18:04 +03:00
services [ serviceName ] = append ( services [ serviceName ] , root )
2019-03-14 11:30:04 +03:00
if ! AddService ( configuration . HTTP , serviceName , service ) {
2019-01-18 17:18:04 +03:00
servicesToDelete [ serviceName ] = struct { } { }
}
}
2019-03-14 11:30:04 +03:00
for routerName , router := range conf . HTTP . Routers {
2019-01-18 17:18:04 +03:00
routers [ routerName ] = append ( routers [ routerName ] , root )
2019-03-14 11:30:04 +03:00
if ! AddRouter ( configuration . HTTP , routerName , router ) {
2019-01-18 17:18:04 +03:00
routersToDelete [ routerName ] = struct { } { }
}
}
2021-07-15 15:02:11 +03:00
for transportName , transport := range conf . HTTP . ServersTransports {
transports [ transportName ] = append ( transports [ transportName ] , root )
if ! AddTransport ( configuration . HTTP , transportName , transport ) {
transportsToDelete [ transportName ] = struct { } { }
}
}
2019-03-21 17:22:06 +03:00
for serviceName , service := range conf . TCP . Services {
servicesTCP [ serviceName ] = append ( servicesTCP [ serviceName ] , root )
if ! AddServiceTCP ( configuration . TCP , serviceName , service ) {
servicesTCPToDelete [ serviceName ] = struct { } { }
}
}
for routerName , router := range conf . TCP . Routers {
routersTCP [ routerName ] = append ( routersTCP [ routerName ] , root )
if ! AddRouterTCP ( configuration . TCP , routerName , router ) {
routersTCPToDelete [ routerName ] = struct { } { }
}
}
2022-12-09 11:58:05 +03:00
for transportName , transport := range conf . TCP . ServersTransports {
transportsTCP [ transportName ] = append ( transportsTCP [ transportName ] , root )
if ! AddTransportTCP ( configuration . TCP , transportName , transport ) {
transportsTCPToDelete [ transportName ] = struct { } { }
}
}
2020-02-21 00:24:05 +03:00
for serviceName , service := range conf . UDP . Services {
servicesUDP [ serviceName ] = append ( servicesUDP [ serviceName ] , root )
if ! AddServiceUDP ( configuration . UDP , serviceName , service ) {
servicesUDPToDelete [ serviceName ] = struct { } { }
}
}
for routerName , router := range conf . UDP . Routers {
routersUDP [ routerName ] = append ( routersUDP [ routerName ] , root )
if ! AddRouterUDP ( configuration . UDP , routerName , router ) {
routersUDPToDelete [ routerName ] = struct { } { }
}
}
2019-03-14 11:30:04 +03:00
for middlewareName , middleware := range conf . HTTP . Middlewares {
2019-01-18 17:18:04 +03:00
middlewares [ middlewareName ] = append ( middlewares [ middlewareName ] , root )
2019-03-14 11:30:04 +03:00
if ! AddMiddleware ( configuration . HTTP , middlewareName , middleware ) {
2019-01-18 17:18:04 +03:00
middlewaresToDelete [ middlewareName ] = struct { } { }
}
}
2021-06-11 16:30:05 +03:00
for middlewareName , middleware := range conf . TCP . Middlewares {
middlewaresTCP [ middlewareName ] = append ( middlewaresTCP [ middlewareName ] , root )
if ! AddMiddlewareTCP ( configuration . TCP , middlewareName , middleware ) {
middlewaresTCPToDelete [ middlewareName ] = struct { } { }
}
}
2024-02-26 12:02:06 +03:00
for storeName , store := range conf . TLS . Stores {
stores [ storeName ] = append ( stores [ storeName ] , root )
if ! AddStore ( configuration . TLS , storeName , store ) {
storesToDelete [ storeName ] = struct { } { }
}
}
2019-01-18 17:18:04 +03:00
}
for serviceName := range servicesToDelete {
2022-11-21 20:36:05 +03:00
logger . Error ( ) . Str ( logs . ServiceName , serviceName ) .
2022-12-09 11:58:05 +03:00
Interface ( "configuration" , services [ serviceName ] ) .
Msg ( "Service defined multiple times with different configurations" )
2019-03-14 11:30:04 +03:00
delete ( configuration . HTTP . Services , serviceName )
2019-01-18 17:18:04 +03:00
}
for routerName := range routersToDelete {
2022-11-21 20:36:05 +03:00
logger . Error ( ) . Str ( logs . RouterName , routerName ) .
2022-12-09 11:58:05 +03:00
Interface ( "configuration" , routers [ routerName ] ) .
Msg ( "Router defined multiple times with different configurations" )
2019-03-14 11:30:04 +03:00
delete ( configuration . HTTP . Routers , routerName )
2019-01-18 17:18:04 +03:00
}
2021-07-15 15:02:11 +03:00
for transportName := range transportsToDelete {
2022-11-21 20:36:05 +03:00
logger . Error ( ) . Str ( logs . ServersTransportName , transportName ) .
2022-12-09 11:58:05 +03:00
Interface ( "configuration" , transports [ transportName ] ) .
Msg ( "ServersTransport defined multiple times with different configurations" )
2021-07-15 15:02:11 +03:00
delete ( configuration . HTTP . ServersTransports , transportName )
}
2019-03-21 17:22:06 +03:00
for serviceName := range servicesTCPToDelete {
2022-11-21 20:36:05 +03:00
logger . Error ( ) . Str ( logs . ServiceName , serviceName ) .
2022-12-09 11:58:05 +03:00
Interface ( "configuration" , servicesTCP [ serviceName ] ) .
Msg ( "Service TCP defined multiple times with different configurations" )
2019-03-21 17:22:06 +03:00
delete ( configuration . TCP . Services , serviceName )
}
for routerName := range routersTCPToDelete {
2022-11-21 20:36:05 +03:00
logger . Error ( ) . Str ( logs . RouterName , routerName ) .
2022-12-09 11:58:05 +03:00
Interface ( "configuration" , routersTCP [ routerName ] ) .
Msg ( "Router TCP defined multiple times with different configurations" )
2019-03-21 17:22:06 +03:00
delete ( configuration . TCP . Routers , routerName )
}
2022-12-09 11:58:05 +03:00
for transportName := range transportsTCPToDelete {
logger . Error ( ) . Str ( logs . ServersTransportName , transportName ) .
Interface ( "configuration" , transportsTCP [ transportName ] ) .
Msg ( "ServersTransport TCP defined multiple times with different configurations" )
delete ( configuration . TCP . ServersTransports , transportName )
}
2020-02-21 00:24:05 +03:00
for serviceName := range servicesUDPToDelete {
2022-11-21 20:36:05 +03:00
logger . Error ( ) . Str ( logs . ServiceName , serviceName ) .
2022-12-09 11:58:05 +03:00
Interface ( "configuration" , servicesUDP [ serviceName ] ) .
Msg ( "UDP service defined multiple times with different configurations" )
2020-02-21 00:24:05 +03:00
delete ( configuration . UDP . Services , serviceName )
}
for routerName := range routersUDPToDelete {
2022-11-21 20:36:05 +03:00
logger . Error ( ) . Str ( logs . RouterName , routerName ) .
2022-12-09 11:58:05 +03:00
Interface ( "configuration" , routersUDP [ routerName ] ) .
Msg ( "UDP router defined multiple times with different configurations" )
2020-02-21 00:24:05 +03:00
delete ( configuration . UDP . Routers , routerName )
}
2019-01-18 17:18:04 +03:00
for middlewareName := range middlewaresToDelete {
2022-11-21 20:36:05 +03:00
logger . Error ( ) . Str ( logs . MiddlewareName , middlewareName ) .
2022-12-09 11:58:05 +03:00
Interface ( "configuration" , middlewares [ middlewareName ] ) .
Msg ( "Middleware defined multiple times with different configurations" )
2019-03-14 11:30:04 +03:00
delete ( configuration . HTTP . Middlewares , middlewareName )
2019-01-18 17:18:04 +03:00
}
2021-06-11 16:30:05 +03:00
for middlewareName := range middlewaresTCPToDelete {
2022-11-21 20:36:05 +03:00
logger . Error ( ) . Str ( logs . MiddlewareName , middlewareName ) .
2022-12-09 11:58:05 +03:00
Interface ( "configuration" , middlewaresTCP [ middlewareName ] ) .
Msg ( "TCP Middleware defined multiple times with different configurations" )
2021-06-11 16:30:05 +03:00
delete ( configuration . TCP . Middlewares , middlewareName )
}
2024-02-26 12:02:06 +03:00
for storeName := range storesToDelete {
2024-03-12 12:38:29 +03:00
logger . Error ( ) . Str ( "storeName" , storeName ) .
Msgf ( "TLS store defined multiple times with different configurations in %v" , stores [ storeName ] )
2024-02-26 12:02:06 +03:00
delete ( configuration . TLS . Stores , storeName )
}
2019-01-18 17:18:04 +03:00
return configuration
}
2022-12-09 11:58:05 +03:00
// AddServiceTCP adds a service to a configuration.
2019-07-10 10:26:04 +03:00
func AddServiceTCP ( configuration * dynamic . TCPConfiguration , serviceName string , service * dynamic . TCPService ) bool {
2019-03-21 17:22:06 +03:00
if _ , ok := configuration . Services [ serviceName ] ; ! ok {
configuration . Services [ serviceName ] = service
return true
}
if ! configuration . Services [ serviceName ] . LoadBalancer . Mergeable ( service . LoadBalancer ) {
return false
}
2020-12-15 18:40:05 +03:00
uniq := map [ string ] struct { } { }
for _ , server := range configuration . Services [ serviceName ] . LoadBalancer . Servers {
uniq [ server . Address ] = struct { } { }
}
for _ , server := range service . LoadBalancer . Servers {
if _ , ok := uniq [ server . Address ] ; ! ok {
configuration . Services [ serviceName ] . LoadBalancer . Servers = append ( configuration . Services [ serviceName ] . LoadBalancer . Servers , server )
}
}
2019-03-21 17:22:06 +03:00
return true
}
2022-12-09 11:58:05 +03:00
// AddRouterTCP adds a router to a configuration.
2020-12-15 18:40:05 +03:00
func AddRouterTCP ( configuration * dynamic . TCPConfiguration , routerName string , router * dynamic . TCPRouter ) bool {
if _ , ok := configuration . Routers [ routerName ] ; ! ok {
configuration . Routers [ routerName ] = router
return true
}
return reflect . DeepEqual ( configuration . Routers [ routerName ] , router )
}
2022-12-09 11:58:05 +03:00
// AddMiddlewareTCP adds a middleware to a configuration.
2021-06-11 16:30:05 +03:00
func AddMiddlewareTCP ( configuration * dynamic . TCPConfiguration , middlewareName string , middleware * dynamic . TCPMiddleware ) bool {
if _ , ok := configuration . Middlewares [ middlewareName ] ; ! ok {
configuration . Middlewares [ middlewareName ] = middleware
return true
}
return reflect . DeepEqual ( configuration . Middlewares [ middlewareName ] , middleware )
}
2022-12-09 11:58:05 +03:00
// AddTransportTCP adds a servers transport to a configuration.
func AddTransportTCP ( configuration * dynamic . TCPConfiguration , transportName string , transport * dynamic . TCPServersTransport ) bool {
if _ , ok := configuration . ServersTransports [ transportName ] ; ! ok {
configuration . ServersTransports [ transportName ] = transport
return true
}
return reflect . DeepEqual ( configuration . ServersTransports [ transportName ] , transport )
}
2020-02-21 00:24:05 +03:00
// AddServiceUDP adds a service to a configuration.
func AddServiceUDP ( configuration * dynamic . UDPConfiguration , serviceName string , service * dynamic . UDPService ) bool {
if _ , ok := configuration . Services [ serviceName ] ; ! ok {
configuration . Services [ serviceName ] = service
return true
}
if ! configuration . Services [ serviceName ] . LoadBalancer . Mergeable ( service . LoadBalancer ) {
return false
}
2020-12-15 18:40:05 +03:00
uniq := map [ string ] struct { } { }
for _ , server := range configuration . Services [ serviceName ] . LoadBalancer . Servers {
uniq [ server . Address ] = struct { } { }
}
2020-02-21 00:24:05 +03:00
2020-12-15 18:40:05 +03:00
for _ , server := range service . LoadBalancer . Servers {
if _ , ok := uniq [ server . Address ] ; ! ok {
configuration . Services [ serviceName ] . LoadBalancer . Servers = append ( configuration . Services [ serviceName ] . LoadBalancer . Servers , server )
}
2019-03-21 17:22:06 +03:00
}
2020-12-15 18:40:05 +03:00
return true
2019-03-21 17:22:06 +03:00
}
2020-02-21 00:24:05 +03:00
// AddRouterUDP adds a router to a configuration.
func AddRouterUDP ( configuration * dynamic . UDPConfiguration , routerName string , router * dynamic . UDPRouter ) bool {
if _ , ok := configuration . Routers [ routerName ] ; ! ok {
configuration . Routers [ routerName ] = router
return true
}
return reflect . DeepEqual ( configuration . Routers [ routerName ] , router )
}
2022-12-09 11:58:05 +03:00
// AddService adds a service to a configuration.
2019-07-10 10:26:04 +03:00
func AddService ( configuration * dynamic . HTTPConfiguration , serviceName string , service * dynamic . Service ) bool {
2019-01-18 17:18:04 +03:00
if _ , ok := configuration . Services [ serviceName ] ; ! ok {
configuration . Services [ serviceName ] = service
return true
}
if ! configuration . Services [ serviceName ] . LoadBalancer . Mergeable ( service . LoadBalancer ) {
return false
}
2020-12-15 18:40:05 +03:00
uniq := map [ string ] struct { } { }
for _ , server := range configuration . Services [ serviceName ] . LoadBalancer . Servers {
uniq [ server . URL ] = struct { } { }
}
for _ , server := range service . LoadBalancer . Servers {
if _ , ok := uniq [ server . URL ] ; ! ok {
configuration . Services [ serviceName ] . LoadBalancer . Servers = append ( configuration . Services [ serviceName ] . LoadBalancer . Servers , server )
}
}
2019-01-18 17:18:04 +03:00
return true
}
2022-12-09 11:58:05 +03:00
// AddRouter adds a router to a configuration.
2019-07-10 10:26:04 +03:00
func AddRouter ( configuration * dynamic . HTTPConfiguration , routerName string , router * dynamic . Router ) bool {
2019-01-18 17:18:04 +03:00
if _ , ok := configuration . Routers [ routerName ] ; ! ok {
configuration . Routers [ routerName ] = router
return true
}
return reflect . DeepEqual ( configuration . Routers [ routerName ] , router )
}
2022-12-09 11:58:05 +03:00
// AddTransport adds a servers transport to a configuration.
2021-07-15 15:02:11 +03:00
func AddTransport ( configuration * dynamic . HTTPConfiguration , transportName string , transport * dynamic . ServersTransport ) bool {
if _ , ok := configuration . ServersTransports [ transportName ] ; ! ok {
configuration . ServersTransports [ transportName ] = transport
return true
}
return reflect . DeepEqual ( configuration . ServersTransports [ transportName ] , transport )
}
2022-12-09 11:58:05 +03:00
// AddMiddleware adds a middleware to a configuration.
2019-07-10 10:26:04 +03:00
func AddMiddleware ( configuration * dynamic . HTTPConfiguration , middlewareName string , middleware * dynamic . Middleware ) bool {
2019-01-18 17:18:04 +03:00
if _ , ok := configuration . Middlewares [ middlewareName ] ; ! ok {
configuration . Middlewares [ middlewareName ] = middleware
return true
}
return reflect . DeepEqual ( configuration . Middlewares [ middlewareName ] , middleware )
}
2019-01-21 21:06:02 +03:00
2024-02-26 12:02:06 +03:00
// AddStore adds a middleware to a configurations.
func AddStore ( configuration * dynamic . TLSConfiguration , storeName string , store tls . Store ) bool {
if _ , ok := configuration . Stores [ storeName ] ; ! ok {
configuration . Stores [ storeName ] = store
return true
}
return reflect . DeepEqual ( configuration . Stores [ storeName ] , store )
}
// MakeDefaultRuleTemplate creates the default rule template.
2019-01-21 21:06:02 +03:00
func MakeDefaultRuleTemplate ( defaultRule string , funcMap template . FuncMap ) ( * template . Template , error ) {
defaultFuncMap := sprig . TxtFuncMap ( )
defaultFuncMap [ "normalize" ] = Normalize
for k , fn := range funcMap {
defaultFuncMap [ k ] = fn
}
return template . New ( "defaultRule" ) . Funcs ( defaultFuncMap ) . Parse ( defaultRule )
}
2024-02-26 12:02:06 +03:00
// BuildTCPRouterConfiguration builds a router configuration.
2019-07-10 10:26:04 +03:00
func BuildTCPRouterConfiguration ( ctx context . Context , configuration * dynamic . TCPConfiguration ) {
2019-03-21 17:22:06 +03:00
for routerName , router := range configuration . Routers {
2022-11-21 20:36:05 +03:00
loggerRouter := log . Ctx ( ctx ) . With ( ) . Str ( logs . RouterName , routerName ) . Logger ( )
2019-03-21 17:22:06 +03:00
if len ( router . Rule ) == 0 {
delete ( configuration . Routers , routerName )
2022-11-21 20:36:05 +03:00
loggerRouter . Error ( ) . Msg ( "Empty rule" )
2019-03-21 17:22:06 +03:00
continue
}
2023-11-21 17:08:06 +03:00
if router . Service == "" {
2019-03-21 17:22:06 +03:00
if len ( configuration . Services ) > 1 {
delete ( configuration . Routers , routerName )
2022-11-21 20:36:05 +03:00
loggerRouter . Error ( ) .
2024-07-30 16:14:29 +03:00
Msgf ( "Router %s cannot be linked automatically with multiple Services: %q" , routerName , maps . Keys ( configuration . Services ) )
2019-03-21 17:22:06 +03:00
continue
}
for serviceName := range configuration . Services {
router . Service = serviceName
}
}
}
}
2024-02-26 12:02:06 +03:00
// BuildUDPRouterConfiguration builds a router configuration.
2020-02-21 00:24:05 +03:00
func BuildUDPRouterConfiguration ( ctx context . Context , configuration * dynamic . UDPConfiguration ) {
for routerName , router := range configuration . Routers {
2022-11-21 20:36:05 +03:00
loggerRouter := log . Ctx ( ctx ) . With ( ) . Str ( logs . RouterName , routerName ) . Logger ( )
2023-11-21 17:08:06 +03:00
if router . Service != "" {
2020-02-21 00:24:05 +03:00
continue
}
if len ( configuration . Services ) > 1 {
delete ( configuration . Routers , routerName )
2024-07-30 16:14:29 +03:00
loggerRouter . Error ( ) .
Msgf ( "Router %s cannot be linked automatically with multiple Services: %q" , routerName , maps . Keys ( configuration . Services ) )
2020-02-21 00:24:05 +03:00
continue
}
for serviceName := range configuration . Services {
router . Service = serviceName
break
}
}
}
2024-02-26 12:02:06 +03:00
// BuildRouterConfiguration builds a router configuration.
2019-07-10 10:26:04 +03:00
func BuildRouterConfiguration ( ctx context . Context , configuration * dynamic . HTTPConfiguration , defaultRouterName string , defaultRuleTpl * template . Template , model interface { } ) {
2019-01-21 21:06:02 +03:00
if len ( configuration . Routers ) == 0 {
if len ( configuration . Services ) > 1 {
2022-11-21 20:36:05 +03:00
log . Ctx ( ctx ) . Info ( ) . Msg ( "Could not create a router for the container: too many services" )
2019-01-21 21:06:02 +03:00
} else {
2019-07-10 10:26:04 +03:00
configuration . Routers = make ( map [ string ] * dynamic . Router )
configuration . Routers [ defaultRouterName ] = & dynamic . Router { }
2019-01-21 21:06:02 +03:00
}
}
for routerName , router := range configuration . Routers {
2022-11-21 20:36:05 +03:00
loggerRouter := log . Ctx ( ctx ) . With ( ) . Str ( logs . RouterName , routerName ) . Logger ( )
2019-01-21 21:06:02 +03:00
if len ( router . Rule ) == 0 {
writer := & bytes . Buffer { }
if err := defaultRuleTpl . Execute ( writer , model ) ; err != nil {
2022-11-21 20:36:05 +03:00
loggerRouter . Error ( ) . Err ( err ) . Msg ( "Error while parsing default rule" )
2019-01-21 21:06:02 +03:00
delete ( configuration . Routers , routerName )
continue
}
router . Rule = writer . String ( )
if len ( router . Rule ) == 0 {
2022-11-21 20:36:05 +03:00
loggerRouter . Error ( ) . Msg ( "Undefined rule" )
2019-01-21 21:06:02 +03:00
delete ( configuration . Routers , routerName )
continue
}
2023-11-21 17:08:06 +03:00
// Flag default rule routers to add the denyRouterRecursion middleware.
router . DefaultRule = true
2019-01-21 21:06:02 +03:00
}
2023-11-21 17:08:06 +03:00
if router . Service == "" {
2019-01-21 21:06:02 +03:00
if len ( configuration . Services ) > 1 {
delete ( configuration . Routers , routerName )
2022-11-21 20:36:05 +03:00
loggerRouter . Error ( ) .
2024-07-30 16:14:29 +03:00
Msgf ( "Router %s cannot be linked automatically with multiple Services: %q" , routerName , maps . Keys ( configuration . Services ) )
2019-01-21 21:06:02 +03:00
continue
}
for serviceName := range configuration . Services {
router . Service = serviceName
}
}
}
}
2024-02-26 12:02:06 +03:00
// Normalize replaces all special chars with `-`.
2019-01-21 21:06:02 +03:00
func Normalize ( name string ) string {
fargs := func ( c rune ) bool {
return ! unicode . IsLetter ( c ) && ! unicode . IsNumber ( c )
}
// get function
return strings . Join ( strings . FieldsFunc ( name , fargs ) , "-" )
}