From ee6d28b25ea6eed35bab0dd85e73ca0618185ccd Mon Sep 17 00:00:00 2001 From: Julien Salleyron Date: Mon, 17 Feb 2020 18:02:04 +0100 Subject: [PATCH] Build all UDP services on an entrypoint --- integration/fixtures/service_errors.toml | 38 ++------------------ integration/fixtures/tcp/service_errors.toml | 37 +++++++++++++++++++ integration/fixtures/udp/service_errors.toml | 35 ++++++++++++++++++ integration/simple_test.go | 6 ++-- pkg/server/router/udp/router.go | 38 ++++++++++++++------ 5 files changed, 106 insertions(+), 48 deletions(-) create mode 100644 integration/fixtures/tcp/service_errors.toml create mode 100644 integration/fixtures/udp/service_errors.toml diff --git a/integration/fixtures/service_errors.toml b/integration/fixtures/service_errors.toml index b135ea374..be90ddf52 100644 --- a/integration/fixtures/service_errors.toml +++ b/integration/fixtures/service_errors.toml @@ -20,11 +20,11 @@ ## dynamic configuration ## [http.routers] - [http.routers.router4] + [http.routers.router1] service = "service1" rule = "Host(`snitest.net`)" - [http.routers.router5] + [http.routers.router2] service = "service2" rule = "Host(`snitest.com`)" @@ -34,36 +34,4 @@ [http.services.service2] [http.services.service2.loadBalancer] [[http.services.service2.loadBalancer.servers]] - url = "http://127.0.0.1:9010" - -[tcp.routers] - [tcp.routers.router4] - service = "service1" - rule = "HostSNI(`snitest.net`)" - - [tcp.routers.router5] - service = "service2" - rule = "HostSNI(`snitest.com`)" - -[tcp.services] - [tcp.services.service1] - - [tcp.services.service2] - [tcp.services.service2.loadBalancer] - [[tcp.services.service2.loadBalancer.servers]] - address = "127.0.0.1:9010" - -[udp.routers] - [udp.routers.router4] - service = "service1" - - [udp.routers.router5] - service = "service2" - -[udp.services] - [udp.services.service1] - - [udp.services.service2] - [udp.services.service2.loadBalancer] - [[udp.services.service2.loadBalancer.servers]] - address = "127.0.0.1:9010" + url = "http://127.0.0.1:9010" \ No newline at end of file diff --git a/integration/fixtures/tcp/service_errors.toml b/integration/fixtures/tcp/service_errors.toml new file mode 100644 index 000000000..b6949da71 --- /dev/null +++ b/integration/fixtures/tcp/service_errors.toml @@ -0,0 +1,37 @@ +[global] + checkNewVersion = false + sendAnonymousUsage = false + +[log] + level = "DEBUG" + +[entryPoints] + [entryPoints.websecure] + address = ":4443" + [entryPoints.udp] + address = ":4443/udp" + +[api] + insecure = true + +[providers.file] + filename = "{{ .SelfFilename }}" + +## dynamic configuration ## + +[tcp.routers] + [tcp.routers.router1] + service = "service1" + rule = "HostSNI(`snitest.net`)" + + [tcp.routers.router2] + service = "service2" + rule = "HostSNI(`snitest.com`)" + +[tcp.services] + [tcp.services.service1] + + [tcp.services.service2] + [tcp.services.service2.loadBalancer] + [[tcp.services.service2.loadBalancer.servers]] + address = "127.0.0.1:9010" diff --git a/integration/fixtures/udp/service_errors.toml b/integration/fixtures/udp/service_errors.toml new file mode 100644 index 000000000..3031f9f73 --- /dev/null +++ b/integration/fixtures/udp/service_errors.toml @@ -0,0 +1,35 @@ +[global] + checkNewVersion = false + sendAnonymousUsage = false + +[log] + level = "DEBUG" + +[entryPoints] + [entryPoints.websecure] + address = ":4443" + [entryPoints.udp] + address = ":4443/udp" + +[api] + insecure = true + +[providers.file] + filename = "{{ .SelfFilename }}" + +## dynamic configuration ## + +[udp.routers] + [udp.routers.router1] + service = "service1" + + [udp.routers.router2] + service = "service2" + +[udp.services] + [udp.services.service1] + + [udp.services.service2] + [udp.services.service2.loadBalancer] + [[udp.services.service2.loadBalancer.servers]] + address = "127.0.0.1:9010" diff --git a/integration/simple_test.go b/integration/simple_test.go index 72dfe4143..b72dd1088 100644 --- a/integration/simple_test.go +++ b/integration/simple_test.go @@ -570,7 +570,7 @@ func (s *SimpleSuite) TestTCPRouterConfigErrors(c *check.C) { } func (s *SimpleSuite) TestTCPServiceConfigErrors(c *check.C) { - file := s.adaptFile(c, "fixtures/service_errors.toml", struct{}{}) + file := s.adaptFile(c, "fixtures/tcp/service_errors.toml", struct{}{}) defer os.Remove(file) cmd, output := s.traefikCmd(withConfigFile(file)) @@ -606,7 +606,7 @@ func (s *SimpleSuite) TestUDPRouterConfigErrors(c *check.C) { } func (s *SimpleSuite) TestUDPServiceConfigErrors(c *check.C) { - file := s.adaptFile(c, "fixtures/service_errors.toml", struct{}{}) + file := s.adaptFile(c, "fixtures/udp/service_errors.toml", struct{}{}) defer os.Remove(file) cmd, output := s.traefikCmd(withConfigFile(file)) @@ -616,7 +616,7 @@ func (s *SimpleSuite) TestUDPServiceConfigErrors(c *check.C) { c.Assert(err, checker.IsNil) defer cmd.Process.Kill() - err = try.GetRequest("http://127.0.0.1:8080/api/udp/services", 3000*time.Millisecond, try.BodyContains(`["the udp service \"service1@file\" does not have any type defined"]`)) + err = try.GetRequest("http://127.0.0.1:8080/api/udp/services", 1000*time.Millisecond, try.BodyContains(`["the udp service \"service1@file\" does not have any type defined"]`)) c.Assert(err, checker.IsNil) err = try.GetRequest("http://127.0.0.1:8080/api/udp/services/service1@file", 1000*time.Millisecond, try.BodyContains(`"status":"disabled"`)) diff --git a/pkg/server/router/udp/router.go b/pkg/server/router/udp/router.go index 873279956..cffeb513b 100644 --- a/pkg/server/router/udp/router.go +++ b/pkg/server/router/udp/router.go @@ -3,6 +3,7 @@ package udp import ( "context" "errors" + "sort" "github.com/containous/traefik/v2/pkg/config/runtime" "github.com/containous/traefik/v2/pkg/log" @@ -47,23 +48,39 @@ func (m *Manager) BuildHandlers(rootCtx context.Context, entryPoints []string) m ctx := log.With(rootCtx, log.Str(log.EntryPointName, entryPointName)) - handler, err := m.buildEntryPointHandler(ctx, routers) + if len(routers) > 1 { + log.FromContext(ctx).Warn("Config has more than one udp router for a given entrypoint.") + } + + handlers, err := m.buildEntryPointHandlers(ctx, routers) if err != nil { log.FromContext(ctx).Error(err) continue } - entryPointHandlers[entryPointName] = handler + + if len(handlers) > 0 { + // As UDP support only one router per entrypoint, we only take the first one. + entryPointHandlers[entryPointName] = handlers[0] + } } return entryPointHandlers } -func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string]*runtime.UDPRouterInfo) (udp.Handler, error) { - logger := log.FromContext(ctx) - - if len(configs) > 1 { - logger.Warn("Warning: config has more than one udp router for a given entrypoint") +func (m *Manager) buildEntryPointHandlers(ctx context.Context, configs map[string]*runtime.UDPRouterInfo) ([]udp.Handler, error) { + var rtNames []string + for routerName := range configs { + rtNames = append(rtNames, routerName) } - for routerName, routerConfig := range configs { + + sort.Slice(rtNames, func(i, j int) bool { + return rtNames[i] > rtNames[j] + }) + + var handlers []udp.Handler + + for _, routerName := range rtNames { + routerConfig := configs[routerName] + ctxRouter := log.With(provider.AddInContext(ctx, routerName), log.Str(log.RouterName, routerName)) logger := log.FromContext(ctxRouter) @@ -80,8 +97,9 @@ func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string logger.Error(err) continue } - return handler, nil + + handlers = append(handlers, handler) } - return nil, nil + return handlers, nil }