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
|
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
|
### Specific Provider Options
|
||||||
|
|
||||||
#### `traefik.enable`
|
#### `traefik.enable`
|
||||||
|
|
|
@ -508,6 +508,54 @@ You can declare TCP Routers and/or Services using labels.
|
||||||
- "traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100"
|
- "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
|
### Specific Provider Options
|
||||||
|
|
||||||
#### `traefik.enable`
|
#### `traefik.enable`
|
||||||
|
|
|
@ -405,6 +405,55 @@ You can declare TCP Routers and/or Services using labels.
|
||||||
"traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay": "100"
|
"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
|
### Specific Provider Options
|
||||||
|
|
||||||
#### `traefik.enable`
|
#### `traefik.enable`
|
||||||
|
|
|
@ -408,6 +408,54 @@ You can declare TCP Routers and/or Services using labels.
|
||||||
- "traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100"
|
- "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
|
### Specific Provider Options
|
||||||
|
|
||||||
#### `traefik.enable`
|
#### `traefik.enable`
|
||||||
|
|
|
@ -11,9 +11,10 @@ func DecodeConfiguration(labels map[string]string) (*dynamic.Configuration, erro
|
||||||
conf := &dynamic.Configuration{
|
conf := &dynamic.Configuration{
|
||||||
HTTP: &dynamic.HTTPConfiguration{},
|
HTTP: &dynamic.HTTPConfiguration{},
|
||||||
TCP: &dynamic.TCPConfiguration{},
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,6 +177,13 @@ func TestDecodeConfiguration(t *testing.T) {
|
||||||
"traefik.tcp.services.Service0.loadbalancer.TerminationDelay": "42",
|
"traefik.tcp.services.Service0.loadbalancer.TerminationDelay": "42",
|
||||||
"traefik.tcp.services.Service1.loadbalancer.server.Port": "42",
|
"traefik.tcp.services.Service1.loadbalancer.server.Port": "42",
|
||||||
"traefik.tcp.services.Service1.loadbalancer.TerminationDelay": "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)
|
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{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{
|
Routers: map[string]*dynamic.Router{
|
||||||
"Router0": {
|
"Router0": {
|
||||||
|
@ -627,6 +672,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
||||||
Port: "42",
|
Port: "42",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
TerminationDelay: func(i int) *int { return &i }(42),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Service1": {
|
"Service1": {
|
||||||
|
@ -636,6 +682,45 @@ func TestEncodeConfiguration(t *testing.T) {
|
||||||
Port: "42",
|
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",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1158,7 +1243,16 @@ func TestEncodeConfiguration(t *testing.T) {
|
||||||
"traefik.TCP.Routers.Router1.TLS.Passthrough": "false",
|
"traefik.TCP.Routers.Router1.TLS.Passthrough": "false",
|
||||||
"traefik.TCP.Routers.Router1.TLS.Options": "foo",
|
"traefik.TCP.Routers.Router1.TLS.Options": "foo",
|
||||||
"traefik.TCP.Services.Service0.LoadBalancer.server.Port": "42",
|
"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.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 {
|
for key, val := range expected {
|
||||||
|
|
|
@ -46,6 +46,12 @@ func Merge(ctx context.Context, configurations map[string]*dynamic.Configuration
|
||||||
routersTCPToDelete := map[string]struct{}{}
|
routersTCPToDelete := map[string]struct{}{}
|
||||||
routersTCP := map[string][]string{}
|
routersTCP := map[string][]string{}
|
||||||
|
|
||||||
|
servicesUDPToDelete := map[string]struct{}{}
|
||||||
|
servicesUDP := map[string][]string{}
|
||||||
|
|
||||||
|
routersUDPToDelete := map[string]struct{}{}
|
||||||
|
routersUDP := map[string][]string{}
|
||||||
|
|
||||||
middlewaresToDelete := map[string]struct{}{}
|
middlewaresToDelete := map[string]struct{}{}
|
||||||
middlewares := map[string][]string{}
|
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 {
|
for middlewareName, middleware := range conf.HTTP.Middlewares {
|
||||||
middlewares[middlewareName] = append(middlewares[middlewareName], root)
|
middlewares[middlewareName] = append(middlewares[middlewareName], root)
|
||||||
if !AddMiddleware(configuration.HTTP, middlewareName, middleware) {
|
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)
|
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 {
|
for middlewareName := range middlewaresToDelete {
|
||||||
logger.WithField(log.MiddlewareName, middlewareName).
|
logger.WithField(log.MiddlewareName, middlewareName).
|
||||||
Errorf("Middleware defined multiple times with different configurations in %v", middlewares[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
|
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.
|
// AddRouterTCP Adds a router to a configurations.
|
||||||
func AddRouterTCP(configuration *dynamic.TCPConfiguration, routerName string, router *dynamic.TCPRouter) bool {
|
func AddRouterTCP(configuration *dynamic.TCPConfiguration, routerName string, router *dynamic.TCPRouter) bool {
|
||||||
if _, ok := configuration.Routers[routerName]; !ok {
|
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)
|
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.
|
// AddService Adds a service to a configurations.
|
||||||
func AddService(configuration *dynamic.HTTPConfiguration, serviceName string, service *dynamic.Service) bool {
|
func AddService(configuration *dynamic.HTTPConfiguration, serviceName string, service *dynamic.Service) bool {
|
||||||
if _, ok := configuration.Services[serviceName]; !ok {
|
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.
|
// BuildRouterConfiguration Builds a router configuration.
|
||||||
func BuildRouterConfiguration(ctx context.Context, configuration *dynamic.HTTPConfiguration, defaultRouterName string, defaultRuleTpl *template.Template, model interface{}) {
|
func BuildRouterConfiguration(ctx context.Context, configuration *dynamic.HTTPConfiguration, defaultRouterName string, defaultRuleTpl *template.Template, model interface{}) {
|
||||||
if len(configuration.Routers) == 0 {
|
if len(configuration.Routers) == 0 {
|
||||||
|
|
|
@ -33,22 +33,35 @@ func (p *Provider) buildConfiguration(ctx context.Context, items []itemData) *dy
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tcpOrUDP bool
|
||||||
if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 {
|
if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 {
|
||||||
|
tcpOrUDP = true
|
||||||
|
|
||||||
err := p.buildTCPServiceConfiguration(ctxSvc, item, confFromLabel.TCP)
|
err := p.buildTCPServiceConfiguration(ctxSvc, item, confFromLabel.TCP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
provider.BuildTCPRouterConfiguration(ctxSvc, confFromLabel.TCP)
|
provider.BuildTCPRouterConfiguration(ctxSvc, confFromLabel.TCP)
|
||||||
|
}
|
||||||
|
|
||||||
if len(confFromLabel.HTTP.Routers) == 0 &&
|
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.Middlewares) == 0 &&
|
||||||
len(confFromLabel.HTTP.Services) == 0 {
|
len(confFromLabel.HTTP.Services) == 0 {
|
||||||
configurations[svcName] = confFromLabel
|
configurations[svcName] = confFromLabel
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
err = p.buildServiceConfiguration(ctxSvc, item, confFromLabel.HTTP)
|
err = p.buildServiceConfiguration(ctxSvc, item, confFromLabel.HTTP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -121,6 +134,28 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, item itemDa
|
||||||
return nil
|
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 {
|
func (p *Provider) buildServiceConfiguration(ctx context.Context, item itemData, configuration *dynamic.HTTPConfiguration) error {
|
||||||
if len(configuration.Services) == 0 {
|
if len(configuration.Services) == 0 {
|
||||||
configuration.Services = make(map[string]*dynamic.Service)
|
configuration.Services = make(map[string]*dynamic.Service)
|
||||||
|
@ -171,6 +206,33 @@ func (p *Provider) addServerTCP(ctx context.Context, item itemData, loadBalancer
|
||||||
return nil
|
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 {
|
func (p *Provider) addServer(ctx context.Context, item itemData, loadBalancer *dynamic.ServersLoadBalancer) error {
|
||||||
if loadBalancer == nil {
|
if loadBalancer == nil {
|
||||||
return errors.New("load-balancer is not defined")
|
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",
|
desc: "tcp with label without rule",
|
||||||
items: []itemData{
|
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",
|
desc: "tcp with label and port and http service",
|
||||||
items: []itemData{
|
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",
|
desc: "tcp with label for tcp service",
|
||||||
items: []itemData{
|
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",
|
desc: "tcp with label for tcp service, with termination delay",
|
||||||
items: []itemData{
|
items: []itemData{
|
||||||
|
|
|
@ -34,20 +34,35 @@ func (p *Provider) buildConfiguration(ctx context.Context, containersInspected [
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tcpOrUDP bool
|
||||||
if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 {
|
if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 {
|
||||||
|
tcpOrUDP = true
|
||||||
|
|
||||||
err := p.buildTCPServiceConfiguration(ctxContainer, container, confFromLabel.TCP)
|
err := p.buildTCPServiceConfiguration(ctxContainer, container, confFromLabel.TCP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
provider.BuildTCPRouterConfiguration(ctxContainer, confFromLabel.TCP)
|
provider.BuildTCPRouterConfiguration(ctxContainer, confFromLabel.TCP)
|
||||||
if len(confFromLabel.HTTP.Routers) == 0 &&
|
}
|
||||||
|
|
||||||
|
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.Middlewares) == 0 &&
|
||||||
len(confFromLabel.HTTP.Services) == 0 {
|
len(confFromLabel.HTTP.Services) == 0 {
|
||||||
configurations[containerName] = confFromLabel
|
configurations[containerName] = confFromLabel
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
err = p.buildServiceConfiguration(ctxContainer, container, confFromLabel.HTTP)
|
err = p.buildServiceConfiguration(ctxContainer, container, confFromLabel.HTTP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -96,6 +111,28 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, container d
|
||||||
return nil
|
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 {
|
func (p *Provider) buildServiceConfiguration(ctx context.Context, container dockerData, configuration *dynamic.HTTPConfiguration) error {
|
||||||
serviceName := getServiceName(container)
|
serviceName := getServiceName(container)
|
||||||
|
|
||||||
|
@ -175,6 +212,36 @@ func (p *Provider) addServerTCP(ctx context.Context, container dockerData, loadB
|
||||||
return nil
|
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 {
|
func (p *Provider) addServer(ctx context.Context, container dockerData, loadBalancer *dynamic.ServersLoadBalancer) error {
|
||||||
if loadBalancer == nil {
|
if loadBalancer == nil {
|
||||||
return errors.New("load-balancer is not defined")
|
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",
|
desc: "one container no label",
|
||||||
containers: []dockerData{
|
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",
|
desc: "tcp with label without rule",
|
||||||
containers: []dockerData{
|
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{
|
containers: []dockerData{
|
||||||
{
|
{
|
||||||
ServiceName: "Test",
|
ServiceName: "Test",
|
||||||
Name: "Test",
|
Name: "Test",
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
|
"traefik.udp.routers.foo.entrypoints": "mydns",
|
||||||
"traefik.tcp.routers.foo.tls": "true",
|
"traefik.udp.services.foo.loadbalancer.server.port": "8080",
|
||||||
"traefik.tcp.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",
|
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
|
||||||
},
|
},
|
||||||
NetworkSettings: networkSettings{
|
NetworkSettings: networkSettings{
|
||||||
|
@ -2520,9 +2664,8 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
ServiceName: "Test",
|
ServiceName: "Test",
|
||||||
Name: "Test",
|
Name: "Test",
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
"traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)",
|
"traefik.udp.routers.foo.entrypoints": "mydns",
|
||||||
"traefik.tcp.routers.foo.tls": "true",
|
"traefik.udp.services.foo.loadbalancer.server.port": "8080",
|
||||||
"traefik.tcp.services.foo.loadbalancer.server.port": "8080",
|
|
||||||
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
|
"traefik.http.services.Service1.loadbalancer.passhostheader": "true",
|
||||||
},
|
},
|
||||||
NetworkSettings: networkSettings{
|
NetworkSettings: networkSettings{
|
||||||
|
@ -2539,18 +2682,17 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: &dynamic.Configuration{
|
expected: &dynamic.Configuration{
|
||||||
TCP: &dynamic.TCPConfiguration{
|
UDP: &dynamic.UDPConfiguration{
|
||||||
Routers: map[string]*dynamic.TCPRouter{
|
Routers: map[string]*dynamic.UDPRouter{
|
||||||
"foo": {
|
"foo": {
|
||||||
Service: "foo",
|
Service: "foo",
|
||||||
Rule: "HostSNI(`foo.bar`)",
|
EntryPoints: []string{"mydns"},
|
||||||
TLS: &dynamic.RouterTCPTLSConfig{},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Services: map[string]*dynamic.TCPService{
|
Services: map[string]*dynamic.UDPService{
|
||||||
"foo": {
|
"foo": {
|
||||||
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||||
Servers: []dynamic.TCPServer{
|
Servers: []dynamic.UDPServer{
|
||||||
{
|
{
|
||||||
Address: "127.0.0.1:8080",
|
Address: "127.0.0.1:8080",
|
||||||
},
|
},
|
||||||
|
@ -2558,14 +2700,13 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
Address: "127.0.0.2:8080",
|
Address: "127.0.0.2:8080",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TerminationDelay: Int(100),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
UDP: &dynamic.UDPConfiguration{
|
TCP: &dynamic.TCPConfiguration{
|
||||||
Routers: map[string]*dynamic.UDPRouter{},
|
Routers: map[string]*dynamic.TCPRouter{},
|
||||||
Services: map[string]*dynamic.UDPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{
|
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{
|
containers: []dockerData{
|
||||||
{
|
{
|
||||||
ServiceName: "Test",
|
ServiceName: "Test",
|
||||||
Name: "Test",
|
Name: "Test",
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
"traefik.tcp.services.foo.loadbalancer.server.port": "8080",
|
"traefik.udp.services.foo.loadbalancer.server.port": "8080",
|
||||||
},
|
},
|
||||||
NetworkSettings: networkSettings{
|
NetworkSettings: networkSettings{
|
||||||
Ports: nat.PortMap{
|
Ports: nat.PortMap{
|
||||||
|
@ -2616,24 +2757,23 @@ func Test_buildConfiguration(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: &dynamic.Configuration{
|
expected: &dynamic.Configuration{
|
||||||
TCP: &dynamic.TCPConfiguration{
|
UDP: &dynamic.UDPConfiguration{
|
||||||
Routers: map[string]*dynamic.TCPRouter{},
|
Routers: map[string]*dynamic.UDPRouter{},
|
||||||
Services: map[string]*dynamic.TCPService{
|
Services: map[string]*dynamic.UDPService{
|
||||||
"foo": {
|
"foo": {
|
||||||
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
LoadBalancer: &dynamic.UDPServersLoadBalancer{
|
||||||
Servers: []dynamic.TCPServer{
|
Servers: []dynamic.UDPServer{
|
||||||
{
|
{
|
||||||
Address: "127.0.0.1:8080",
|
Address: "127.0.0.1:8080",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TerminationDelay: Int(100),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
UDP: &dynamic.UDPConfiguration{
|
TCP: &dynamic.TCPConfiguration{
|
||||||
Routers: map[string]*dynamic.UDPRouter{},
|
Routers: map[string]*dynamic.TCPRouter{},
|
||||||
Services: map[string]*dynamic.UDPService{},
|
Services: map[string]*dynamic.TCPService{},
|
||||||
},
|
},
|
||||||
HTTP: &dynamic.HTTPConfiguration{
|
HTTP: &dynamic.HTTPConfiguration{
|
||||||
Routers: map[string]*dynamic.Router{},
|
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/0/weight": "42",
|
||||||
"traefik/tcp/services/TCPService02/weighted/services/1/name": "foobar",
|
"traefik/tcp/services/TCPService02/weighted/services/1/name": "foobar",
|
||||||
"traefik/tcp/services/TCPService02/weighted/services/1/weight": "43",
|
"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/minVersion": "foobar",
|
||||||
"traefik/tls/options/Options0/maxVersion": "foobar",
|
"traefik/tls/options/Options0/maxVersion": "foobar",
|
||||||
"traefik/tls/options/Options0/cipherSuites/0": "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{
|
TLS: &dynamic.TLSConfiguration{
|
||||||
Certificates: []*tls.CertAndStores{
|
Certificates: []*tls.CertAndStores{
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,20 +49,35 @@ func (p *Provider) buildConfiguration(ctx context.Context, applications *maratho
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tcpOrUDP bool
|
||||||
if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 {
|
if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 {
|
||||||
|
tcpOrUDP = true
|
||||||
|
|
||||||
err := p.buildTCPServiceConfiguration(ctxApp, app, extraConf, confFromLabel.TCP)
|
err := p.buildTCPServiceConfiguration(ctxApp, app, extraConf, confFromLabel.TCP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
provider.BuildTCPRouterConfiguration(ctxApp, confFromLabel.TCP)
|
provider.BuildTCPRouterConfiguration(ctxApp, confFromLabel.TCP)
|
||||||
if len(confFromLabel.HTTP.Routers) == 0 &&
|
}
|
||||||
|
|
||||||
|
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.Middlewares) == 0 &&
|
||||||
len(confFromLabel.HTTP.Services) == 0 {
|
len(confFromLabel.HTTP.Services) == 0 {
|
||||||
configurations[app.ID] = confFromLabel
|
configurations[app.ID] = confFromLabel
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
err = p.buildServiceConfiguration(ctxApp, app, extraConf, confFromLabel.HTTP)
|
err = p.buildServiceConfiguration(ctxApp, app, extraConf, confFromLabel.HTTP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -116,7 +131,9 @@ func (p *Provider) buildServiceConfiguration(ctx context.Context, app marathon.A
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, task := range app.Tasks {
|
for _, task := range app.Tasks {
|
||||||
if p.taskFilter(ctx, *task, app) {
|
if !p.taskFilter(ctx, *task, app) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
server, err := p.getServer(app, *task, extraConf, defaultServer)
|
server, err := p.getServer(app, *task, extraConf, defaultServer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.FromContext(appCtx).Errorf("Skip task: %v", err)
|
log.FromContext(appCtx).Errorf("Skip task: %v", err)
|
||||||
|
@ -124,7 +141,6 @@ func (p *Provider) buildServiceConfiguration(ctx context.Context, app marathon.A
|
||||||
}
|
}
|
||||||
servers = append(servers, server)
|
servers = append(servers, server)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if len(servers) == 0 {
|
if len(servers) == 0 {
|
||||||
return fmt.Errorf("no server for the service %s", serviceName)
|
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
|
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 {
|
func (p *Provider) keepApplication(ctx context.Context, extraConf configuration, labels map[string]string) bool {
|
||||||
logger := log.FromContext(ctx)
|
logger := log.FromContext(ctx)
|
||||||
|
|
||||||
|
@ -229,6 +286,24 @@ func (p *Provider) getTCPServer(app marathon.Application, task marathon.Task, ex
|
||||||
return server, nil
|
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) {
|
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)
|
host, err := p.getServerHost(task, app, extraConf)
|
||||||
if len(host) == 0 {
|
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",
|
desc: "one app with tcp labels without rule",
|
||||||
applications: withApplications(
|
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",
|
desc: "one app with tcp labels with port, with termination delay",
|
||||||
applications: withApplications(
|
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 {
|
for _, test := range testCases {
|
||||||
|
|
|
@ -32,20 +32,35 @@ func (p *Provider) buildConfiguration(ctx context.Context, services []rancherDat
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tcpOrUDP bool
|
||||||
if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 {
|
if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 {
|
||||||
|
tcpOrUDP = true
|
||||||
|
|
||||||
err := p.buildTCPServiceConfiguration(ctxService, service, confFromLabel.TCP)
|
err := p.buildTCPServiceConfiguration(ctxService, service, confFromLabel.TCP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
provider.BuildTCPRouterConfiguration(ctxService, confFromLabel.TCP)
|
provider.BuildTCPRouterConfiguration(ctxService, confFromLabel.TCP)
|
||||||
if len(confFromLabel.HTTP.Routers) == 0 &&
|
}
|
||||||
|
|
||||||
|
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.Middlewares) == 0 &&
|
||||||
len(confFromLabel.HTTP.Services) == 0 {
|
len(confFromLabel.HTTP.Services) == 0 {
|
||||||
configurations[service.Name] = confFromLabel
|
configurations[service.Name] = confFromLabel
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
err = p.buildServiceConfiguration(ctx, service, confFromLabel.HTTP)
|
err = p.buildServiceConfiguration(ctx, service, confFromLabel.HTTP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -91,6 +106,28 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, service ran
|
||||||
return nil
|
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 {
|
func (p *Provider) buildServiceConfiguration(ctx context.Context, service rancherData, configuration *dynamic.HTTPConfiguration) error {
|
||||||
serviceName := service.Name
|
serviceName := service.Name
|
||||||
|
|
||||||
|
@ -182,6 +219,43 @@ func (p *Provider) addServerTCP(ctx context.Context, service rancherData, loadBa
|
||||||
return nil
|
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 {
|
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)
|
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",
|
desc: "tcp with label without rule",
|
||||||
containers: []rancherData{
|
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",
|
desc: "tcp with label and port and http service",
|
||||||
containers: []rancherData{
|
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",
|
desc: "tcp with label for tcp service",
|
||||||
containers: []rancherData{
|
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",
|
desc: "tcp with label for tcp service, with termination delay",
|
||||||
containers: []rancherData{
|
containers: []rancherData{
|
||||||
|
|
Loading…
Reference in a new issue