Add UDP in providers with labels
This commit is contained in:
parent
a20a5f1a44
commit
bb4de11c51
16 changed files with 1440 additions and 68 deletions
|
@ -365,6 +365,50 @@ You can declare TCP Routers and/or Services using tags.
|
|||
traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100
|
||||
```
|
||||
|
||||
### UDP
|
||||
|
||||
You can declare UDP Routers and/or Services using tags.
|
||||
|
||||
??? example "Declaring UDP Routers and Services"
|
||||
|
||||
```yaml
|
||||
traefik.udp.routers.my-router.entrypoints=udp
|
||||
traefik.udp.services.my-service.loadbalancer.server.port=4123
|
||||
```
|
||||
|
||||
!!! warning "UDP and HTTP"
|
||||
|
||||
If you declare a UDP Router/Service, it will prevent Traefik from automatically creating an HTTP Router/Service (like it does by default if no UDP Router/Service is defined).
|
||||
You can declare both a UDP Router/Service and an HTTP Router/Service for the same consul service (but you have to do so manually).
|
||||
|
||||
#### UDP Routers
|
||||
|
||||
??? info "`traefik.udp.routers.<router_name>.entrypoints`"
|
||||
|
||||
See [entry points](../routers/index.md#entrypoints_2) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.udp.routers.myudprouter.entrypoints=ep1,ep2
|
||||
```
|
||||
|
||||
??? info "`traefik.udp.routers.<router_name>.service`"
|
||||
|
||||
See [service](../routers/index.md#services_1) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.udp.routers.myudprouter.service=myservice
|
||||
```
|
||||
|
||||
#### UDP Services
|
||||
|
||||
??? info "`traefik.udp.services.<service_name>.loadbalancer.server.port`"
|
||||
|
||||
Registers a port of the application.
|
||||
|
||||
```yaml
|
||||
traefik.udp.services.myudpservice.loadbalancer.server.port=423
|
||||
```
|
||||
|
||||
### Specific Provider Options
|
||||
|
||||
#### `traefik.enable`
|
||||
|
|
|
@ -508,6 +508,54 @@ You can declare TCP Routers and/or Services using labels.
|
|||
- "traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100"
|
||||
```
|
||||
|
||||
### UDP
|
||||
|
||||
You can declare UDP Routers and/or Services using labels.
|
||||
|
||||
??? example "Declaring UDP Routers and Services"
|
||||
|
||||
```yaml
|
||||
services:
|
||||
my-container:
|
||||
# ...
|
||||
labels:
|
||||
- "traefik.udp.routers.my-router.entrypoint=udp"
|
||||
- "traefik.udp.services.my-service.loadbalancer.server.port=4123"
|
||||
```
|
||||
|
||||
!!! warning "UDP and HTTP"
|
||||
|
||||
If you declare a UDP Router/Service, it will prevent Traefik from automatically creating an HTTP Router/Service (like it does by default if no UDP Router/Service is defined).
|
||||
You can declare both a UDP Router/Service and an HTTP Router/Service for the same container (but you have to do so manually).
|
||||
|
||||
#### UDP Routers
|
||||
|
||||
??? info "`traefik.udp.routers.<router_name>.entrypoints`"
|
||||
|
||||
See [entry points](../routers/index.md#entrypoints_2) for more information.
|
||||
|
||||
```yaml
|
||||
- "traefik.udp.routers.myudprouter.entrypoints=ep1,ep2"
|
||||
```
|
||||
|
||||
??? info "`traefik.udp.routers.<router_name>.service`"
|
||||
|
||||
See [service](../routers/index.md#services_1) for more information.
|
||||
|
||||
```yaml
|
||||
- "traefik.udp.routers.myudprouter.service=myservice"
|
||||
```
|
||||
|
||||
#### UDP Services
|
||||
|
||||
??? info "`traefik.udp.services.<service_name>.loadbalancer.server.port`"
|
||||
|
||||
Registers a port of the application.
|
||||
|
||||
```yaml
|
||||
- "traefik.udp.services.myudpservice.loadbalancer.server.port=423"
|
||||
```
|
||||
|
||||
### Specific Provider Options
|
||||
|
||||
#### `traefik.enable`
|
||||
|
|
|
@ -405,6 +405,55 @@ You can declare TCP Routers and/or Services using labels.
|
|||
"traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay": "100"
|
||||
```
|
||||
|
||||
### UDP
|
||||
|
||||
You can declare UDP Routers and/or Services using labels.
|
||||
|
||||
??? example "Declaring UDP Routers and Services"
|
||||
|
||||
```json
|
||||
{
|
||||
...
|
||||
"labels": {
|
||||
"traefik.udp.routers.my-router.entrypoints": "udp",
|
||||
"traefik.udp.services.my-service.loadbalancer.server.port": "4123"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
!!! warning "UDP and HTTP"
|
||||
|
||||
If you declare a UDP Router/Service, it will prevent Traefik from automatically creating an HTTP Router/Service (like it does by default if no UDP Router/Service is defined).
|
||||
You can declare both a UDP Router/Service and an HTTP Router/Service for the same container (but you have to do so manually).
|
||||
|
||||
#### UDP Routers
|
||||
|
||||
??? info "`traefik.udp.routers.<router_name>.entrypoints`"
|
||||
|
||||
See [entry points](../routers/index.md#entrypoints_2) for more information.
|
||||
|
||||
```json
|
||||
"traefik.udp.routers.myudprouter.entrypoints": "ep1,ep2"
|
||||
```
|
||||
|
||||
??? info "`traefik.udp.routers.<router_name>.service`"
|
||||
|
||||
See [service](../routers/index.md#services_1) for more information.
|
||||
|
||||
```json
|
||||
"traefik.udp.routers.myudprouter.service": "myservice"
|
||||
```
|
||||
|
||||
#### UDP Services
|
||||
|
||||
??? info "`traefik.udp.services.<service_name>.loadbalancer.server.port`"
|
||||
|
||||
Registers a port of the application.
|
||||
|
||||
```json
|
||||
"traefik.udp.services.myudpservice.loadbalancer.server.port": "423"
|
||||
```
|
||||
|
||||
### Specific Provider Options
|
||||
|
||||
#### `traefik.enable`
|
||||
|
|
|
@ -408,6 +408,54 @@ You can declare TCP Routers and/or Services using labels.
|
|||
- "traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100"
|
||||
```
|
||||
|
||||
### UDP
|
||||
|
||||
You can declare UDP Routers and/or Services using labels.
|
||||
|
||||
??? example "Declaring UDP Routers and Services"
|
||||
|
||||
```yaml
|
||||
services:
|
||||
my-container:
|
||||
# ...
|
||||
labels:
|
||||
- "traefik.udp.routers.my-router.entrypoints=udp"
|
||||
- "traefik.udp.services.my-service.loadbalancer.server.port=4123"
|
||||
```
|
||||
|
||||
!!! warning "UDP and HTTP"
|
||||
|
||||
If you declare a UDP Router/Service, it will prevent Traefik from automatically creating an HTTP Router/Service (like it does by default if no UDP Router/Service is defined).
|
||||
You can declare both a UDP Router/Service and an HTTP Router/Service for the same container (but you have to do so manually).
|
||||
|
||||
#### UDP Routers
|
||||
|
||||
??? info "`traefik.udp.routers.<router_name>.entrypoints`"
|
||||
|
||||
See [entry points](../routers/index.md#entrypoints_2) for more information.
|
||||
|
||||
```yaml
|
||||
- "traefik.udp.routers.myudprouter.entrypoints=ep1,ep2"
|
||||
```
|
||||
|
||||
??? info "`traefik.udp.routers.<router_name>.service`"
|
||||
|
||||
See [service](../routers/index.md#services_1) for more information.
|
||||
|
||||
```yaml
|
||||
- "traefik.udp.routers.myudprouter.service=myservice"
|
||||
```
|
||||
|
||||
#### UDP Services
|
||||
|
||||
??? info "`traefik.udp.services.<service_name>.loadbalancer.server.port`"
|
||||
|
||||
Registers a port of the application.
|
||||
|
||||
```yaml
|
||||
- "traefik.udp.services.myudpservice.loadbalancer.server.port=423"
|
||||
```
|
||||
|
||||
### Specific Provider Options
|
||||
|
||||
#### `traefik.enable`
|
||||
|
|
|
@ -11,9 +11,10 @@ func DecodeConfiguration(labels map[string]string) (*dynamic.Configuration, erro
|
|||
conf := &dynamic.Configuration{
|
||||
HTTP: &dynamic.HTTPConfiguration{},
|
||||
TCP: &dynamic.TCPConfiguration{},
|
||||
UDP: &dynamic.UDPConfiguration{},
|
||||
}
|
||||
|
||||
err := parser.Decode(labels, conf, parser.DefaultRootName, "traefik.http", "traefik.tcp")
|
||||
err := parser.Decode(labels, conf, parser.DefaultRootName, "traefik.http", "traefik.tcp", "traefik.udp")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -177,6 +177,13 @@ func TestDecodeConfiguration(t *testing.T) {
|
|||
"traefik.tcp.services.Service0.loadbalancer.TerminationDelay": "42",
|
||||
"traefik.tcp.services.Service1.loadbalancer.server.Port": "42",
|
||||
"traefik.tcp.services.Service1.loadbalancer.TerminationDelay": "42",
|
||||
|
||||
"traefik.udp.routers.Router0.entrypoints": "foobar, fiibar",
|
||||
"traefik.udp.routers.Router0.service": "foobar",
|
||||
"traefik.udp.routers.Router1.entrypoints": "foobar, fiibar",
|
||||
"traefik.udp.routers.Router1.service": "foobar",
|
||||
"traefik.udp.services.Service0.loadbalancer.server.Port": "42",
|
||||
"traefik.udp.services.Service1.loadbalancer.server.Port": "42",
|
||||
}
|
||||
|
||||
configuration, err := DecodeConfiguration(labels)
|
||||
|
@ -233,6 +240,44 @@ func TestDecodeConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"Router0": {
|
||||
EntryPoints: []string{
|
||||
"foobar",
|
||||
"fiibar",
|
||||
},
|
||||
Service: "foobar",
|
||||
},
|
||||
"Router1": {
|
||||
EntryPoints: []string{
|
||||
"foobar",
|
||||
"fiibar",
|
||||
},
|
||||
Service: "foobar",
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"Service0": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Port: "42",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Port: "42",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"Router0": {
|
||||
|
@ -627,6 +672,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
Port: "42",
|
||||
},
|
||||
},
|
||||
TerminationDelay: func(i int) *int { return &i }(42),
|
||||
},
|
||||
},
|
||||
"Service1": {
|
||||
|
@ -636,6 +682,45 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
Port: "42",
|
||||
},
|
||||
},
|
||||
TerminationDelay: func(i int) *int { return &i }(42),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"Router0": {
|
||||
EntryPoints: []string{
|
||||
"foobar",
|
||||
"fiibar",
|
||||
},
|
||||
Service: "foobar",
|
||||
},
|
||||
"Router1": {
|
||||
EntryPoints: []string{
|
||||
"foobar",
|
||||
"fiibar",
|
||||
},
|
||||
Service: "foobar",
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"Service0": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Port: "42",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Port: "42",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1147,18 +1232,27 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
"traefik.HTTP.Services.Service1.LoadBalancer.server.Scheme": "foobar",
|
||||
"traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Headers.name0": "foobar",
|
||||
|
||||
"traefik.TCP.Routers.Router0.Rule": "foobar",
|
||||
"traefik.TCP.Routers.Router0.EntryPoints": "foobar, fiibar",
|
||||
"traefik.TCP.Routers.Router0.Service": "foobar",
|
||||
"traefik.TCP.Routers.Router0.TLS.Passthrough": "false",
|
||||
"traefik.TCP.Routers.Router0.TLS.Options": "foo",
|
||||
"traefik.TCP.Routers.Router1.Rule": "foobar",
|
||||
"traefik.TCP.Routers.Router1.EntryPoints": "foobar, fiibar",
|
||||
"traefik.TCP.Routers.Router1.Service": "foobar",
|
||||
"traefik.TCP.Routers.Router1.TLS.Passthrough": "false",
|
||||
"traefik.TCP.Routers.Router1.TLS.Options": "foo",
|
||||
"traefik.TCP.Services.Service0.LoadBalancer.server.Port": "42",
|
||||
"traefik.TCP.Services.Service1.LoadBalancer.server.Port": "42",
|
||||
"traefik.TCP.Routers.Router0.Rule": "foobar",
|
||||
"traefik.TCP.Routers.Router0.EntryPoints": "foobar, fiibar",
|
||||
"traefik.TCP.Routers.Router0.Service": "foobar",
|
||||
"traefik.TCP.Routers.Router0.TLS.Passthrough": "false",
|
||||
"traefik.TCP.Routers.Router0.TLS.Options": "foo",
|
||||
"traefik.TCP.Routers.Router1.Rule": "foobar",
|
||||
"traefik.TCP.Routers.Router1.EntryPoints": "foobar, fiibar",
|
||||
"traefik.TCP.Routers.Router1.Service": "foobar",
|
||||
"traefik.TCP.Routers.Router1.TLS.Passthrough": "false",
|
||||
"traefik.TCP.Routers.Router1.TLS.Options": "foo",
|
||||
"traefik.TCP.Services.Service0.LoadBalancer.server.Port": "42",
|
||||
"traefik.TCP.Services.Service0.LoadBalancer.TerminationDelay": "42",
|
||||
"traefik.TCP.Services.Service1.LoadBalancer.server.Port": "42",
|
||||
"traefik.TCP.Services.Service1.LoadBalancer.TerminationDelay": "42",
|
||||
|
||||
"traefik.UDP.Routers.Router0.EntryPoints": "foobar, fiibar",
|
||||
"traefik.UDP.Routers.Router0.Service": "foobar",
|
||||
"traefik.UDP.Routers.Router1.EntryPoints": "foobar, fiibar",
|
||||
"traefik.UDP.Routers.Router1.Service": "foobar",
|
||||
"traefik.UDP.Services.Service0.LoadBalancer.server.Port": "42",
|
||||
"traefik.UDP.Services.Service1.LoadBalancer.server.Port": "42",
|
||||
}
|
||||
|
||||
for key, val := range expected {
|
||||
|
|
|
@ -46,6 +46,12 @@ func Merge(ctx context.Context, configurations map[string]*dynamic.Configuration
|
|||
routersTCPToDelete := map[string]struct{}{}
|
||||
routersTCP := map[string][]string{}
|
||||
|
||||
servicesUDPToDelete := map[string]struct{}{}
|
||||
servicesUDP := map[string][]string{}
|
||||
|
||||
routersUDPToDelete := map[string]struct{}{}
|
||||
routersUDP := map[string][]string{}
|
||||
|
||||
middlewaresToDelete := map[string]struct{}{}
|
||||
middlewares := map[string][]string{}
|
||||
|
||||
|
@ -85,6 +91,20 @@ func Merge(ctx context.Context, configurations map[string]*dynamic.Configuration
|
|||
}
|
||||
}
|
||||
|
||||
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{}{}
|
||||
}
|
||||
}
|
||||
|
||||
for middlewareName, middleware := range conf.HTTP.Middlewares {
|
||||
middlewares[middlewareName] = append(middlewares[middlewareName], root)
|
||||
if !AddMiddleware(configuration.HTTP, middlewareName, middleware) {
|
||||
|
@ -117,6 +137,18 @@ func Merge(ctx context.Context, configurations map[string]*dynamic.Configuration
|
|||
delete(configuration.TCP.Routers, routerName)
|
||||
}
|
||||
|
||||
for serviceName := range servicesUDPToDelete {
|
||||
logger.WithField(log.ServiceName, serviceName).
|
||||
Errorf("UDP service defined multiple times with different configurations in %v", servicesUDP[serviceName])
|
||||
delete(configuration.UDP.Services, serviceName)
|
||||
}
|
||||
|
||||
for routerName := range routersUDPToDelete {
|
||||
logger.WithField(log.RouterName, routerName).
|
||||
Errorf("UDP router defined multiple times with different configurations in %v", routersUDP[routerName])
|
||||
delete(configuration.UDP.Routers, routerName)
|
||||
}
|
||||
|
||||
for middlewareName := range middlewaresToDelete {
|
||||
logger.WithField(log.MiddlewareName, middlewareName).
|
||||
Errorf("Middleware defined multiple times with different configurations in %v", middlewares[middlewareName])
|
||||
|
@ -141,6 +173,21 @@ func AddServiceTCP(configuration *dynamic.TCPConfiguration, serviceName string,
|
|||
return true
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
configuration.Services[serviceName].LoadBalancer.Servers = append(configuration.Services[serviceName].LoadBalancer.Servers, service.LoadBalancer.Servers...)
|
||||
return true
|
||||
}
|
||||
|
||||
// AddRouterTCP Adds a router to a configurations.
|
||||
func AddRouterTCP(configuration *dynamic.TCPConfiguration, routerName string, router *dynamic.TCPRouter) bool {
|
||||
if _, ok := configuration.Routers[routerName]; !ok {
|
||||
|
@ -151,6 +198,16 @@ func AddRouterTCP(configuration *dynamic.TCPConfiguration, routerName string, ro
|
|||
return reflect.DeepEqual(configuration.Routers[routerName], router)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// AddService Adds a service to a configurations.
|
||||
func AddService(configuration *dynamic.HTTPConfiguration, serviceName string, service *dynamic.Service) bool {
|
||||
if _, ok := configuration.Services[serviceName]; !ok {
|
||||
|
@ -223,6 +280,28 @@ func BuildTCPRouterConfiguration(ctx context.Context, configuration *dynamic.TCP
|
|||
}
|
||||
}
|
||||
|
||||
// BuildUDPRouterConfiguration Builds a router configuration.
|
||||
func BuildUDPRouterConfiguration(ctx context.Context, configuration *dynamic.UDPConfiguration) {
|
||||
for routerName, router := range configuration.Routers {
|
||||
loggerRouter := log.FromContext(ctx).WithField(log.RouterName, routerName)
|
||||
if len(router.Service) > 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(configuration.Services) > 1 {
|
||||
delete(configuration.Routers, routerName)
|
||||
loggerRouter.
|
||||
Error("Could not define the service name for the router: too many services")
|
||||
continue
|
||||
}
|
||||
|
||||
for serviceName := range configuration.Services {
|
||||
router.Service = serviceName
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BuildRouterConfiguration Builds a router configuration.
|
||||
func BuildRouterConfiguration(ctx context.Context, configuration *dynamic.HTTPConfiguration, defaultRouterName string, defaultRuleTpl *template.Template, model interface{}) {
|
||||
if len(configuration.Routers) == 0 {
|
||||
|
|
|
@ -33,21 +33,34 @@ func (p *Provider) buildConfiguration(ctx context.Context, items []itemData) *dy
|
|||
continue
|
||||
}
|
||||
|
||||
var tcpOrUDP bool
|
||||
if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 {
|
||||
tcpOrUDP = true
|
||||
|
||||
err := p.buildTCPServiceConfiguration(ctxSvc, item, confFromLabel.TCP)
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
provider.BuildTCPRouterConfiguration(ctxSvc, confFromLabel.TCP)
|
||||
}
|
||||
|
||||
if len(confFromLabel.HTTP.Routers) == 0 &&
|
||||
len(confFromLabel.HTTP.Middlewares) == 0 &&
|
||||
len(confFromLabel.HTTP.Services) == 0 {
|
||||
configurations[svcName] = confFromLabel
|
||||
if len(confFromLabel.UDP.Routers) > 0 || len(confFromLabel.UDP.Services) > 0 {
|
||||
tcpOrUDP = true
|
||||
|
||||
err := p.buildUDPServiceConfiguration(ctxSvc, item, confFromLabel.UDP)
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
continue
|
||||
}
|
||||
provider.BuildUDPRouterConfiguration(ctxSvc, confFromLabel.UDP)
|
||||
}
|
||||
|
||||
if tcpOrUDP && len(confFromLabel.HTTP.Routers) == 0 &&
|
||||
len(confFromLabel.HTTP.Middlewares) == 0 &&
|
||||
len(confFromLabel.HTTP.Services) == 0 {
|
||||
configurations[svcName] = confFromLabel
|
||||
continue
|
||||
}
|
||||
|
||||
err = p.buildServiceConfiguration(ctxSvc, item, confFromLabel.HTTP)
|
||||
|
@ -121,6 +134,28 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, item itemDa
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) buildUDPServiceConfiguration(ctx context.Context, item itemData, configuration *dynamic.UDPConfiguration) error {
|
||||
if len(configuration.Services) == 0 {
|
||||
configuration.Services = make(map[string]*dynamic.UDPService)
|
||||
|
||||
lb := &dynamic.UDPServersLoadBalancer{}
|
||||
|
||||
configuration.Services[item.Name] = &dynamic.UDPService{
|
||||
LoadBalancer: lb,
|
||||
}
|
||||
}
|
||||
|
||||
for name, service := range configuration.Services {
|
||||
ctxSvc := log.With(ctx, log.Str(log.ServiceName, name))
|
||||
err := p.addServerUDP(ctxSvc, item, service.LoadBalancer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) buildServiceConfiguration(ctx context.Context, item itemData, configuration *dynamic.HTTPConfiguration) error {
|
||||
if len(configuration.Services) == 0 {
|
||||
configuration.Services = make(map[string]*dynamic.Service)
|
||||
|
@ -171,6 +206,33 @@ func (p *Provider) addServerTCP(ctx context.Context, item itemData, loadBalancer
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) addServerUDP(ctx context.Context, item itemData, loadBalancer *dynamic.UDPServersLoadBalancer) error {
|
||||
if loadBalancer == nil {
|
||||
return errors.New("load-balancer is not defined")
|
||||
}
|
||||
|
||||
if len(loadBalancer.Servers) == 0 {
|
||||
loadBalancer.Servers = []dynamic.UDPServer{{}}
|
||||
}
|
||||
|
||||
var port string
|
||||
if item.Port != "" {
|
||||
port = item.Port
|
||||
loadBalancer.Servers[0].Port = ""
|
||||
}
|
||||
|
||||
if port == "" {
|
||||
return errors.New("port is missing")
|
||||
}
|
||||
|
||||
if item.Address == "" {
|
||||
return errors.New("address is missing")
|
||||
}
|
||||
|
||||
loadBalancer.Servers[0].Address = net.JoinHostPort(item.Address, port)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) addServer(ctx context.Context, item itemData, loadBalancer *dynamic.ServersLoadBalancer) error {
|
||||
if loadBalancer == nil {
|
||||
return errors.New("load-balancer is not defined")
|
||||
|
|
|
@ -1839,6 +1839,51 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "udp with label",
|
||||
items: []itemData{
|
||||
{
|
||||
ID: "Test",
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.udp.routers.foo.entrypoints": "mydns",
|
||||
},
|
||||
Address: "127.0.0.1",
|
||||
Port: "80",
|
||||
Status: api.HealthPassing,
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"foo": {
|
||||
Service: "Test",
|
||||
EntryPoints: []string{"mydns"},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "tcp with label without rule",
|
||||
items: []itemData{
|
||||
|
@ -1931,6 +1976,52 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "udp with label and port",
|
||||
items: []itemData{
|
||||
{
|
||||
ID: "Test",
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.udp.routers.foo.entrypoints": "mydns",
|
||||
"traefik.udp.services.foo.loadbalancer.server.port": "80",
|
||||
},
|
||||
Address: "127.0.0.1",
|
||||
Port: "80",
|
||||
Status: api.HealthPassing,
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"foo": {
|
||||
Service: "foo",
|
||||
EntryPoints: []string{"mydns"},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"foo": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "tcp with label and port and http service",
|
||||
items: []itemData{
|
||||
|
@ -2016,6 +2107,87 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "udp with label and port and http service",
|
||||
items: []itemData{
|
||||
{
|
||||
ID: "1",
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.udp.routers.foo.entrypoints": "mydns",
|
||||
"traefik.udp.services.foo.loadbalancer.server.port": "80",
|
||||
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
|
||||
},
|
||||
Address: "127.0.0.1",
|
||||
Port: "80",
|
||||
Status: api.HealthPassing,
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.udp.routers.foo.entrypoints": "mydns",
|
||||
"traefik.udp.services.foo.loadbalancer.server.port": "80",
|
||||
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
|
||||
},
|
||||
Address: "127.0.0.2",
|
||||
Port: "80",
|
||||
Status: api.HealthPassing,
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"foo": {
|
||||
Service: "foo",
|
||||
EntryPoints: []string{"mydns"},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"foo": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "127.0.0.1:80",
|
||||
},
|
||||
{
|
||||
Address: "127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"Test": {
|
||||
Service: "Service1",
|
||||
Rule: "Host(`Test.traefik.wtf`)",
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
{
|
||||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "tcp with label for tcp service",
|
||||
items: []itemData{
|
||||
|
@ -2057,6 +2229,46 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "udp with label for tcp service",
|
||||
items: []itemData{
|
||||
{
|
||||
ID: "Test",
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.udp.services.foo.loadbalancer.server.port": "80",
|
||||
},
|
||||
Address: "127.0.0.1",
|
||||
Port: "80",
|
||||
Status: api.HealthPassing,
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"foo": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "tcp with label for tcp service, with termination delay",
|
||||
items: []itemData{
|
||||
|
|
|
@ -34,19 +34,34 @@ func (p *Provider) buildConfiguration(ctx context.Context, containersInspected [
|
|||
continue
|
||||
}
|
||||
|
||||
var tcpOrUDP bool
|
||||
if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 {
|
||||
tcpOrUDP = true
|
||||
|
||||
err := p.buildTCPServiceConfiguration(ctxContainer, container, confFromLabel.TCP)
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
continue
|
||||
}
|
||||
provider.BuildTCPRouterConfiguration(ctxContainer, confFromLabel.TCP)
|
||||
if len(confFromLabel.HTTP.Routers) == 0 &&
|
||||
len(confFromLabel.HTTP.Middlewares) == 0 &&
|
||||
len(confFromLabel.HTTP.Services) == 0 {
|
||||
configurations[containerName] = confFromLabel
|
||||
}
|
||||
|
||||
if len(confFromLabel.UDP.Routers) > 0 || len(confFromLabel.UDP.Services) > 0 {
|
||||
tcpOrUDP = true
|
||||
|
||||
err := p.buildUDPServiceConfiguration(ctxContainer, container, confFromLabel.UDP)
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
continue
|
||||
}
|
||||
provider.BuildUDPRouterConfiguration(ctxContainer, confFromLabel.UDP)
|
||||
}
|
||||
|
||||
if tcpOrUDP && len(confFromLabel.HTTP.Routers) == 0 &&
|
||||
len(confFromLabel.HTTP.Middlewares) == 0 &&
|
||||
len(confFromLabel.HTTP.Services) == 0 {
|
||||
configurations[containerName] = confFromLabel
|
||||
continue
|
||||
}
|
||||
|
||||
err = p.buildServiceConfiguration(ctxContainer, container, confFromLabel.HTTP)
|
||||
|
@ -96,6 +111,28 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, container d
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) buildUDPServiceConfiguration(ctx context.Context, container dockerData, configuration *dynamic.UDPConfiguration) error {
|
||||
serviceName := getServiceName(container)
|
||||
|
||||
if len(configuration.Services) == 0 {
|
||||
configuration.Services = make(map[string]*dynamic.UDPService)
|
||||
lb := &dynamic.UDPServersLoadBalancer{}
|
||||
configuration.Services[serviceName] = &dynamic.UDPService{
|
||||
LoadBalancer: lb,
|
||||
}
|
||||
}
|
||||
|
||||
for name, service := range configuration.Services {
|
||||
ctxSvc := log.With(ctx, log.Str(log.ServiceName, name))
|
||||
err := p.addServerUDP(ctxSvc, container, service.LoadBalancer)
|
||||
if err != nil {
|
||||
return fmt.Errorf("service %q error: %w", name, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) buildServiceConfiguration(ctx context.Context, container dockerData, configuration *dynamic.HTTPConfiguration) error {
|
||||
serviceName := getServiceName(container)
|
||||
|
||||
|
@ -175,6 +212,36 @@ func (p *Provider) addServerTCP(ctx context.Context, container dockerData, loadB
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) addServerUDP(ctx context.Context, container dockerData, loadBalancer *dynamic.UDPServersLoadBalancer) error {
|
||||
if loadBalancer == nil {
|
||||
return errors.New("load-balancer is not defined")
|
||||
}
|
||||
|
||||
var serverPort string
|
||||
if len(loadBalancer.Servers) > 0 {
|
||||
serverPort = loadBalancer.Servers[0].Port
|
||||
loadBalancer.Servers[0].Port = ""
|
||||
}
|
||||
|
||||
ip, port, err := p.getIPPort(ctx, container, serverPort)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(loadBalancer.Servers) == 0 {
|
||||
server := dynamic.UDPServer{}
|
||||
|
||||
loadBalancer.Servers = []dynamic.UDPServer{server}
|
||||
}
|
||||
|
||||
if port == "" {
|
||||
return errors.New("port is missing")
|
||||
}
|
||||
|
||||
loadBalancer.Servers[0].Address = net.JoinHostPort(ip, port)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) addServer(ctx context.Context, container dockerData, loadBalancer *dynamic.ServersLoadBalancer) error {
|
||||
if loadBalancer == nil {
|
||||
return errors.New("load-balancer is not defined")
|
||||
|
|
|
@ -445,6 +445,44 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "invalid UDP service definition",
|
||||
containers: []dockerData{
|
||||
{
|
||||
ServiceName: "Test",
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.udp.services.test": "",
|
||||
},
|
||||
NetworkSettings: networkSettings{
|
||||
Ports: nat.PortMap{
|
||||
nat.Port("80/udp"): []nat.PortBinding{},
|
||||
},
|
||||
Networks: map[string]*networkData{
|
||||
"bridge": {
|
||||
Name: "bridge",
|
||||
Addr: "127.0.0.1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
Services: map[string]*dynamic.UDPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "one container no label",
|
||||
containers: []dockerData{
|
||||
|
@ -2383,6 +2421,59 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "udp with label",
|
||||
containers: []dockerData{
|
||||
{
|
||||
ServiceName: "Test",
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.udp.routers.foo.entrypoints": "mydns",
|
||||
},
|
||||
NetworkSettings: networkSettings{
|
||||
Ports: nat.PortMap{
|
||||
nat.Port("80/tcp"): []nat.PortBinding{},
|
||||
},
|
||||
Networks: map[string]*networkData{
|
||||
"bridge": {
|
||||
Name: "bridge",
|
||||
Addr: "127.0.0.1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"foo": {
|
||||
Service: "Test",
|
||||
EntryPoints: []string{"mydns"},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "tcp with label without rule",
|
||||
containers: []dockerData{
|
||||
|
@ -2492,15 +2583,68 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
desc: "tcp with label and port and http service",
|
||||
desc: "udp with label and port",
|
||||
containers: []dockerData{
|
||||
{
|
||||
ServiceName: "Test",
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
|
||||
"traefik.tcp.routers.foo.tls": "true",
|
||||
"traefik.tcp.services.foo.loadbalancer.server.port": "8080",
|
||||
"traefik.udp.routers.foo.entrypoints": "mydns",
|
||||
"traefik.udp.services.foo.loadbalancer.server.port": "8080",
|
||||
},
|
||||
NetworkSettings: networkSettings{
|
||||
Ports: nat.PortMap{
|
||||
nat.Port("80/tcp"): []nat.PortBinding{},
|
||||
},
|
||||
Networks: map[string]*networkData{
|
||||
"bridge": {
|
||||
Name: "bridge",
|
||||
Addr: "127.0.0.1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"foo": {
|
||||
Service: "foo",
|
||||
EntryPoints: []string{"mydns"},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"foo": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "udp with label and port and http service",
|
||||
containers: []dockerData{
|
||||
{
|
||||
ServiceName: "Test",
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.udp.routers.foo.entrypoints": "mydns",
|
||||
"traefik.udp.services.foo.loadbalancer.server.port": "8080",
|
||||
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
|
||||
},
|
||||
NetworkSettings: networkSettings{
|
||||
|
@ -2520,9 +2664,8 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
ServiceName: "Test",
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
|
||||
"traefik.tcp.routers.foo.tls": "true",
|
||||
"traefik.tcp.services.foo.loadbalancer.server.port": "8080",
|
||||
"traefik.udp.routers.foo.entrypoints": "mydns",
|
||||
"traefik.udp.services.foo.loadbalancer.server.port": "8080",
|
||||
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
|
||||
},
|
||||
NetworkSettings: networkSettings{
|
||||
|
@ -2539,18 +2682,17 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"foo": {
|
||||
Service: "foo",
|
||||
Rule: "HostSNI(`foo.bar`)",
|
||||
TLS: &dynamic.RouterTCPTLSConfig{},
|
||||
Service: "foo",
|
||||
EntryPoints: []string{"mydns"},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.TCPService{
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"foo": {
|
||||
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
||||
Servers: []dynamic.TCPServer{
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "127.0.0.1:8080",
|
||||
},
|
||||
|
@ -2558,14 +2700,13 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
Address: "127.0.0.2:8080",
|
||||
},
|
||||
},
|
||||
TerminationDelay: Int(100),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
Services: map[string]*dynamic.UDPService{},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{
|
||||
|
@ -2594,13 +2735,13 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
desc: "tcp with label for tcp service",
|
||||
desc: "udp with label for tcp service",
|
||||
containers: []dockerData{
|
||||
{
|
||||
ServiceName: "Test",
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.tcp.services.foo.loadbalancer.server.port": "8080",
|
||||
"traefik.udp.services.foo.loadbalancer.server.port": "8080",
|
||||
},
|
||||
NetworkSettings: networkSettings{
|
||||
Ports: nat.PortMap{
|
||||
|
@ -2616,24 +2757,23 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"foo": {
|
||||
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
||||
Servers: []dynamic.TCPServer{
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
TerminationDelay: Int(100),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
Services: map[string]*dynamic.UDPService{},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
|
|
|
@ -224,6 +224,16 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
"traefik/tcp/services/TCPService02/weighted/services/0/weight": "42",
|
||||
"traefik/tcp/services/TCPService02/weighted/services/1/name": "foobar",
|
||||
"traefik/tcp/services/TCPService02/weighted/services/1/weight": "43",
|
||||
"traefik/udp/routers/UDPRouter0/entrypoints/0": "foobar",
|
||||
"traefik/udp/routers/UDPRouter0/entrypoints/1": "foobar",
|
||||
"traefik/udp/routers/UDPRouter0/service": "foobar",
|
||||
"traefik/udp/routers/UDPRouter1/entrypoints/0": "foobar",
|
||||
"traefik/udp/routers/UDPRouter1/entrypoints/1": "foobar",
|
||||
"traefik/udp/routers/UDPRouter1/service": "foobar",
|
||||
"traefik/udp/services/UDPService01/loadBalancer/servers/0/address": "foobar",
|
||||
"traefik/udp/services/UDPService01/loadBalancer/servers/1/address": "foobar",
|
||||
"traefik/udp/services/UDPService02/loadBalancer/servers/0/address": "foobar",
|
||||
"traefik/udp/services/UDPService02/loadBalancer/servers/1/address": "foobar",
|
||||
"traefik/tls/options/Options0/minVersion": "foobar",
|
||||
"traefik/tls/options/Options0/maxVersion": "foobar",
|
||||
"traefik/tls/options/Options0/cipherSuites/0": "foobar",
|
||||
|
@ -740,6 +750,36 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"UDPRouter0": {
|
||||
EntryPoints: []string{"foobar", "foobar"},
|
||||
Service: "foobar",
|
||||
},
|
||||
"UDPRouter1": {
|
||||
EntryPoints: []string{"foobar", "foobar"},
|
||||
Service: "foobar",
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"UDPService01": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{Address: "foobar"},
|
||||
{Address: "foobar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
"UDPService02": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{Address: "foobar"},
|
||||
{Address: "foobar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{
|
||||
Certificates: []*tls.CertAndStores{
|
||||
{
|
||||
|
|
|
@ -49,21 +49,36 @@ func (p *Provider) buildConfiguration(ctx context.Context, applications *maratho
|
|||
continue
|
||||
}
|
||||
|
||||
var tcpOrUDP bool
|
||||
if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 {
|
||||
tcpOrUDP = true
|
||||
|
||||
err := p.buildTCPServiceConfiguration(ctxApp, app, extraConf, confFromLabel.TCP)
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
continue
|
||||
}
|
||||
provider.BuildTCPRouterConfiguration(ctxApp, confFromLabel.TCP)
|
||||
if len(confFromLabel.HTTP.Routers) == 0 &&
|
||||
len(confFromLabel.HTTP.Middlewares) == 0 &&
|
||||
len(confFromLabel.HTTP.Services) == 0 {
|
||||
configurations[app.ID] = confFromLabel
|
||||
continue
|
||||
}
|
||||
|
||||
if len(confFromLabel.UDP.Routers) > 0 || len(confFromLabel.UDP.Services) > 0 {
|
||||
tcpOrUDP = true
|
||||
|
||||
err := p.buildUDPServiceConfiguration(ctxApp, app, extraConf, confFromLabel.UDP)
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
} else {
|
||||
provider.BuildUDPRouterConfiguration(ctxApp, confFromLabel.UDP)
|
||||
}
|
||||
}
|
||||
|
||||
if tcpOrUDP && len(confFromLabel.HTTP.Routers) == 0 &&
|
||||
len(confFromLabel.HTTP.Middlewares) == 0 &&
|
||||
len(confFromLabel.HTTP.Services) == 0 {
|
||||
configurations[app.ID] = confFromLabel
|
||||
continue
|
||||
}
|
||||
|
||||
err = p.buildServiceConfiguration(ctxApp, app, extraConf, confFromLabel.HTTP)
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
|
@ -116,14 +131,15 @@ func (p *Provider) buildServiceConfiguration(ctx context.Context, app marathon.A
|
|||
}
|
||||
|
||||
for _, task := range app.Tasks {
|
||||
if p.taskFilter(ctx, *task, app) {
|
||||
server, err := p.getServer(app, *task, extraConf, defaultServer)
|
||||
if err != nil {
|
||||
log.FromContext(appCtx).Errorf("Skip task: %v", err)
|
||||
continue
|
||||
}
|
||||
servers = append(servers, server)
|
||||
if !p.taskFilter(ctx, *task, app) {
|
||||
continue
|
||||
}
|
||||
server, err := p.getServer(app, *task, extraConf, defaultServer)
|
||||
if err != nil {
|
||||
log.FromContext(appCtx).Errorf("Skip task: %v", err)
|
||||
continue
|
||||
}
|
||||
servers = append(servers, server)
|
||||
}
|
||||
if len(servers) == 0 {
|
||||
return fmt.Errorf("no server for the service %s", serviceName)
|
||||
|
@ -175,6 +191,47 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, app maratho
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) buildUDPServiceConfiguration(ctx context.Context, app marathon.Application, extraConf configuration, conf *dynamic.UDPConfiguration) error {
|
||||
appName := getServiceName(app)
|
||||
appCtx := log.With(ctx, log.Str("ApplicationID", appName))
|
||||
|
||||
if len(conf.Services) == 0 {
|
||||
conf.Services = make(map[string]*dynamic.UDPService)
|
||||
lb := &dynamic.UDPServersLoadBalancer{}
|
||||
|
||||
conf.Services[appName] = &dynamic.UDPService{
|
||||
LoadBalancer: lb,
|
||||
}
|
||||
}
|
||||
|
||||
for serviceName, service := range conf.Services {
|
||||
var servers []dynamic.UDPServer
|
||||
|
||||
defaultServer := dynamic.UDPServer{}
|
||||
|
||||
if len(service.LoadBalancer.Servers) > 0 {
|
||||
defaultServer = service.LoadBalancer.Servers[0]
|
||||
}
|
||||
|
||||
for _, task := range app.Tasks {
|
||||
if p.taskFilter(ctx, *task, app) {
|
||||
server, err := p.getUDPServer(app, *task, extraConf, defaultServer)
|
||||
if err != nil {
|
||||
log.FromContext(appCtx).Errorf("Skip task: %v", err)
|
||||
continue
|
||||
}
|
||||
servers = append(servers, server)
|
||||
}
|
||||
}
|
||||
if len(servers) == 0 {
|
||||
return fmt.Errorf("no server for the service %s", serviceName)
|
||||
}
|
||||
service.LoadBalancer.Servers = servers
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) keepApplication(ctx context.Context, extraConf configuration, labels map[string]string) bool {
|
||||
logger := log.FromContext(ctx)
|
||||
|
||||
|
@ -229,6 +286,24 @@ func (p *Provider) getTCPServer(app marathon.Application, task marathon.Task, ex
|
|||
return server, nil
|
||||
}
|
||||
|
||||
func (p *Provider) getUDPServer(app marathon.Application, task marathon.Task, extraConf configuration, defaultServer dynamic.UDPServer) (dynamic.UDPServer, error) {
|
||||
host, err := p.getServerHost(task, app, extraConf)
|
||||
if len(host) == 0 {
|
||||
return dynamic.UDPServer{}, err
|
||||
}
|
||||
|
||||
port, err := getPort(task, app, defaultServer.Port)
|
||||
if err != nil {
|
||||
return dynamic.UDPServer{}, err
|
||||
}
|
||||
|
||||
server := dynamic.UDPServer{
|
||||
Address: net.JoinHostPort(host, port),
|
||||
}
|
||||
|
||||
return server, nil
|
||||
}
|
||||
|
||||
func (p *Provider) getServer(app marathon.Application, task marathon.Task, extraConf configuration, defaultServer dynamic.Server) (dynamic.Server, error) {
|
||||
host, err := p.getServerHost(task, app, extraConf)
|
||||
if len(host) == 0 {
|
||||
|
|
|
@ -1383,6 +1383,46 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "one app with udp labels",
|
||||
applications: withApplications(
|
||||
application(
|
||||
appID("/app"),
|
||||
appPorts(80, 81),
|
||||
withTasks(localhostTask(taskPorts(80, 81))),
|
||||
withLabel("traefik.udp.routers.foo.entrypoints", "mydns"),
|
||||
)),
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"foo": {
|
||||
Service: "app",
|
||||
EntryPoints: []string{"mydns"},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"app": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "localhost:80",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "one app with tcp labels without rule",
|
||||
applications: withApplications(
|
||||
|
@ -1463,6 +1503,47 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "one app with udp labels with port",
|
||||
applications: withApplications(
|
||||
application(
|
||||
appID("/app"),
|
||||
appPorts(80, 81),
|
||||
withTasks(localhostTask(taskPorts(80, 81))),
|
||||
withLabel("traefik.udp.routers.foo.entrypoints", "mydns"),
|
||||
withLabel("traefik.udp.services.foo.loadbalancer.server.port", "8080"),
|
||||
)),
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"foo": {
|
||||
Service: "foo",
|
||||
EntryPoints: []string{"mydns"},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"foo": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "localhost:8080",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "one app with tcp labels with port, with termination delay",
|
||||
applications: withApplications(
|
||||
|
@ -1569,6 +1650,64 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "one app with udp labels with port and http service",
|
||||
applications: withApplications(
|
||||
application(
|
||||
appID("/app"),
|
||||
appPorts(80, 81),
|
||||
withTasks(localhostTask(taskPorts(80, 81))),
|
||||
withLabel("traefik.udp.routers.foo.entrypoints", "mydns"),
|
||||
withLabel("traefik.udp.services.foo.loadbalancer.server.port", "8080"),
|
||||
withLabel("traefik.http.services.bar.loadbalancer.passhostheader", "true"),
|
||||
)),
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"foo": {
|
||||
Service: "foo",
|
||||
EntryPoints: []string{"mydns"},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"foo": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "localhost:8080",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"app": {
|
||||
Service: "bar",
|
||||
Rule: "Host(`app.marathon.localhost`)",
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"bar": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://localhost:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
|
|
|
@ -32,19 +32,34 @@ func (p *Provider) buildConfiguration(ctx context.Context, services []rancherDat
|
|||
continue
|
||||
}
|
||||
|
||||
var tcpOrUDP bool
|
||||
if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 {
|
||||
tcpOrUDP = true
|
||||
|
||||
err := p.buildTCPServiceConfiguration(ctxService, service, confFromLabel.TCP)
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
continue
|
||||
}
|
||||
provider.BuildTCPRouterConfiguration(ctxService, confFromLabel.TCP)
|
||||
if len(confFromLabel.HTTP.Routers) == 0 &&
|
||||
len(confFromLabel.HTTP.Middlewares) == 0 &&
|
||||
len(confFromLabel.HTTP.Services) == 0 {
|
||||
configurations[service.Name] = confFromLabel
|
||||
}
|
||||
|
||||
if len(confFromLabel.UDP.Routers) > 0 || len(confFromLabel.UDP.Services) > 0 {
|
||||
tcpOrUDP = true
|
||||
|
||||
err := p.buildUDPServiceConfiguration(ctxService, service, confFromLabel.UDP)
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
continue
|
||||
}
|
||||
provider.BuildUDPRouterConfiguration(ctxService, confFromLabel.UDP)
|
||||
}
|
||||
|
||||
if tcpOrUDP && len(confFromLabel.HTTP.Routers) == 0 &&
|
||||
len(confFromLabel.HTTP.Middlewares) == 0 &&
|
||||
len(confFromLabel.HTTP.Services) == 0 {
|
||||
configurations[service.Name] = confFromLabel
|
||||
continue
|
||||
}
|
||||
|
||||
err = p.buildServiceConfiguration(ctx, service, confFromLabel.HTTP)
|
||||
|
@ -91,6 +106,28 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, service ran
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) buildUDPServiceConfiguration(ctx context.Context, service rancherData, configuration *dynamic.UDPConfiguration) error {
|
||||
serviceName := service.Name
|
||||
|
||||
if len(configuration.Services) == 0 {
|
||||
configuration.Services = make(map[string]*dynamic.UDPService)
|
||||
lb := &dynamic.UDPServersLoadBalancer{}
|
||||
|
||||
configuration.Services[serviceName] = &dynamic.UDPService{
|
||||
LoadBalancer: lb,
|
||||
}
|
||||
}
|
||||
|
||||
for _, confService := range configuration.Services {
|
||||
err := p.addServerUDP(ctx, service, confService.LoadBalancer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) buildServiceConfiguration(ctx context.Context, service rancherData, configuration *dynamic.HTTPConfiguration) error {
|
||||
serviceName := service.Name
|
||||
|
||||
|
@ -182,6 +219,43 @@ func (p *Provider) addServerTCP(ctx context.Context, service rancherData, loadBa
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) addServerUDP(ctx context.Context, service rancherData, loadBalancer *dynamic.UDPServersLoadBalancer) error {
|
||||
log.FromContext(ctx).Debugf("Trying to add servers for service %s \n", service.Name)
|
||||
|
||||
serverPort := ""
|
||||
|
||||
if loadBalancer != nil && len(loadBalancer.Servers) > 0 {
|
||||
serverPort = loadBalancer.Servers[0].Port
|
||||
}
|
||||
|
||||
port := getServicePort(service)
|
||||
|
||||
if len(loadBalancer.Servers) == 0 {
|
||||
server := dynamic.UDPServer{}
|
||||
|
||||
loadBalancer.Servers = []dynamic.UDPServer{server}
|
||||
}
|
||||
|
||||
if serverPort != "" {
|
||||
port = serverPort
|
||||
loadBalancer.Servers[0].Port = ""
|
||||
}
|
||||
|
||||
if port == "" {
|
||||
return errors.New("port is missing")
|
||||
}
|
||||
|
||||
var servers []dynamic.UDPServer
|
||||
for _, containerIP := range service.Containers {
|
||||
servers = append(servers, dynamic.UDPServer{
|
||||
Address: net.JoinHostPort(containerIP, port),
|
||||
})
|
||||
}
|
||||
|
||||
loadBalancer.Servers = servers
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) addServers(ctx context.Context, service rancherData, loadBalancer *dynamic.ServersLoadBalancer) error {
|
||||
log.FromContext(ctx).Debugf("Trying to add servers for service %s \n", service.Name)
|
||||
|
||||
|
|
|
@ -575,6 +575,51 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "udp with label",
|
||||
containers: []rancherData{
|
||||
{
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.udp.routers.foo.entrypoints": "mydns",
|
||||
},
|
||||
Port: "80/tcp",
|
||||
Containers: []string{"127.0.0.1"},
|
||||
Health: "",
|
||||
State: "",
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"foo": {
|
||||
Service: "Test",
|
||||
EntryPoints: []string{"mydns"},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "tcp with label without rule",
|
||||
containers: []rancherData{
|
||||
|
@ -663,6 +708,52 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "udp with label and port",
|
||||
containers: []rancherData{
|
||||
{
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.udp.routers.foo.entrypoints": "mydns",
|
||||
"traefik.udp.services.foo.loadbalancer.server.port": "8080",
|
||||
},
|
||||
Port: "80/tcp",
|
||||
Containers: []string{"127.0.0.1"},
|
||||
Health: "",
|
||||
State: "",
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"foo": {
|
||||
Service: "foo",
|
||||
EntryPoints: []string{"mydns"},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"foo": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "tcp with label and port and http service",
|
||||
containers: []rancherData{
|
||||
|
@ -735,6 +826,75 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "udp with label and port and http service",
|
||||
containers: []rancherData{
|
||||
{
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.udp.routers.foo.entrypoints": "mydns",
|
||||
"traefik.udp.services.foo.loadbalancer.server.port": "8080",
|
||||
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
|
||||
},
|
||||
Port: "80/tcp",
|
||||
Containers: []string{"127.0.0.1", "127.0.0.2"},
|
||||
Health: "",
|
||||
State: "",
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{
|
||||
"foo": {
|
||||
Service: "foo",
|
||||
EntryPoints: []string{"mydns"},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"foo": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "127.0.0.1:8080",
|
||||
},
|
||||
{
|
||||
Address: "127.0.0.2:8080",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"Test": {
|
||||
Service: "Service1",
|
||||
Rule: "Host(`Test.traefik.wtf`)",
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
{
|
||||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "tcp with label for tcp service",
|
||||
containers: []rancherData{
|
||||
|
@ -776,6 +936,46 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "udp with label for tcp service",
|
||||
containers: []rancherData{
|
||||
{
|
||||
Name: "Test",
|
||||
Labels: map[string]string{
|
||||
"traefik.udp.services.foo.loadbalancer.server.port": "8080",
|
||||
},
|
||||
Port: "80/tcp",
|
||||
Containers: []string{"127.0.0.1"},
|
||||
Health: "",
|
||||
State: "",
|
||||
},
|
||||
},
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
Services: map[string]*dynamic.UDPService{
|
||||
"foo": {
|
||||
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||
Servers: []dynamic.UDPServer{
|
||||
{
|
||||
Address: "127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "tcp with label for tcp service, with termination delay",
|
||||
containers: []rancherData{
|
||||
|
|
Loading…
Reference in a new issue