Add p2c load-balancing strategy for servers load-balancer

Co-authored-by: Ian Ross <ifross@gmail.com>
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
This commit is contained in:
Romain 2025-03-10 12:12:04 +01:00 committed by GitHub
parent 550d96ea67
commit 9e029a84c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
50 changed files with 1621 additions and 382 deletions

View file

@ -187,3 +187,18 @@ and will be removed in the next major version.
In `v3.3.4`, the OpenTelemetry Request Duration metric (named `traefik_(entrypoint|router|service)_request_duration_seconds`) unit has been changed from milliseconds to seconds. In `v3.3.4`, the OpenTelemetry Request Duration metric (named `traefik_(entrypoint|router|service)_request_duration_seconds`) unit has been changed from milliseconds to seconds.
To be consistent with the naming and other metrics providers, the metric now reports the duration in seconds. To be consistent with the naming and other metrics providers, the metric now reports the duration in seconds.
## v3.3 to v3.4
### Kubernetes CRD Provider
In `v3.4`, the HTTP service definition has been updated.
The strategy field now supports two new values: `wrr` and `p2c` (please refer to the [HTTP Services Load Balancing documentation](../../routing/services/#load-balancing-strategy) for more details).
CRDs can be updated with this command:
```shell
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.4/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
```
Please note that the `RoundRobin` strategy value is now deprecated, but still supported and equivalent to `wrr`, and will be removed in the next major release.

View file

@ -221,6 +221,7 @@
- "traefik.http.services.service02.loadbalancer.sticky.cookie.path=foobar" - "traefik.http.services.service02.loadbalancer.sticky.cookie.path=foobar"
- "traefik.http.services.service02.loadbalancer.sticky.cookie.samesite=foobar" - "traefik.http.services.service02.loadbalancer.sticky.cookie.samesite=foobar"
- "traefik.http.services.service02.loadbalancer.sticky.cookie.secure=true" - "traefik.http.services.service02.loadbalancer.sticky.cookie.secure=true"
- "traefik.http.services.service02.loadbalancer.strategy=foobar"
- "traefik.http.services.service02.loadbalancer.server.port=foobar" - "traefik.http.services.service02.loadbalancer.server.port=foobar"
- "traefik.http.services.service02.loadbalancer.server.preservepath=true" - "traefik.http.services.service02.loadbalancer.server.preservepath=true"
- "traefik.http.services.service02.loadbalancer.server.scheme=foobar" - "traefik.http.services.service02.loadbalancer.server.scheme=foobar"

View file

@ -54,6 +54,7 @@
[http.services.Service01.failover.healthCheck] [http.services.Service01.failover.healthCheck]
[http.services.Service02] [http.services.Service02]
[http.services.Service02.loadBalancer] [http.services.Service02.loadBalancer]
strategy = "foobar"
passHostHeader = true passHostHeader = true
serversTransport = "foobar" serversTransport = "foobar"
[http.services.Service02.loadBalancer.sticky] [http.services.Service02.loadBalancer.sticky]

View file

@ -80,6 +80,7 @@ http:
- url: foobar - url: foobar
weight: 42 weight: 42
preservePath: true preservePath: true
strategy: foobar
healthCheck: healthCheck:
scheme: foobar scheme: foobar
mode: foobar mode: foobar

View file

@ -290,10 +290,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:
@ -1217,10 +1221,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:
@ -2924,10 +2932,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:
@ -3048,10 +3060,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:
@ -3250,10 +3266,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:

View file

@ -297,6 +297,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/path` | `foobar` | | `traefik/http/services/Service02/loadBalancer/sticky/cookie/path` | `foobar` |
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/sameSite` | `foobar` | | `traefik/http/services/Service02/loadBalancer/sticky/cookie/sameSite` | `foobar` |
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/secure` | `true` | | `traefik/http/services/Service02/loadBalancer/sticky/cookie/secure` | `true` |
| `traefik/http/services/Service02/loadBalancer/strategy` | `foobar` |
| `traefik/http/services/Service03/mirroring/healthCheck` | `` | | `traefik/http/services/Service03/mirroring/healthCheck` | `` |
| `traefik/http/services/Service03/mirroring/maxBodySize` | `42` | | `traefik/http/services/Service03/mirroring/maxBodySize` | `42` |
| `traefik/http/services/Service03/mirroring/mirrorBody` | `true` | | `traefik/http/services/Service03/mirroring/mirrorBody` | `true` |

View file

@ -290,10 +290,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:

View file

@ -454,10 +454,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:

View file

@ -314,10 +314,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:
@ -438,10 +442,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:
@ -640,10 +648,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:

View file

@ -346,6 +346,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10 traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10
``` ```
??? info "`traefik.http.services.<service_name>.loadbalancer.strategy`"
See [load balancing strategy](../services/index.md#load-balancing-strategy) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.strategy=p2c
```
### Middleware ### Middleware
You can declare pieces of middleware using tags starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options. You can declare pieces of middleware using tags starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options.

View file

@ -461,6 +461,14 @@ you'd add the label `traefik.http.services.<name-of-your-choice>.loadbalancer.pa
- "traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10" - "traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10"
``` ```
??? info "`traefik.http.services.<service_name>.loadbalancer.strategy`"
See [load balancing strategy](../services/index.md#load-balancing-strategy) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.strategy=p2c"
```
### Middleware ### Middleware
You can declare pieces of middleware using labels starting with `traefik.http.middlewares.<name-of-your-choice>.`, You can declare pieces of middleware using labels starting with `traefik.http.middlewares.<name-of-your-choice>.`,

View file

@ -350,6 +350,14 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa
traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10 traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10
``` ```
??? info "`traefik.http.services.<service_name>.loadbalancer.strategy`"
See [load balancing strategy](../services/index.md#load-balancing-strategy) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.strategy=p2c
```
### Middleware ### Middleware
You can declare pieces of middleware using labels starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options. You can declare pieces of middleware using labels starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options.

View file

@ -358,19 +358,19 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne
maxAge: 42 maxAge: 42
path: /foo path: /foo
domain: foo.com domain: foo.com
strategy: RoundRobin strategy: wrr # [16]
weight: 10 weight: 10
nativeLB: true # [16] nativeLB: true # [17]
nodePortLB: true # [17] nodePortLB: true # [18]
tls: # [18] tls: # [19]
secretName: supersecret # [19] secretName: supersecret # [20]
options: # [20] options: # [21]
name: opt # [21] name: opt # [22]
namespace: default # [22] namespace: default # [23]
certResolver: foo # [23] certResolver: foo # [24]
domains: # [24] domains: # [25]
- main: example.net # [25] - main: example.net # [26]
sans: # [26] sans: # [27]
- a.example.net - a.example.net
- b.example.net - b.example.net
``` ```
@ -392,17 +392,18 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne
| [13] | `services[n].port` | Defines the port of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/). This can be a reference to a named port. | | [13] | `services[n].port` | Defines the port of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/). This can be a reference to a named port. |
| [14] | `services[n].serversTransport` | Defines the reference to a [ServersTransport](#kind-serverstransport). The ServersTransport namespace is assumed to be the [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) namespace (see [ServersTransport reference](#serverstransport-reference)). | | [14] | `services[n].serversTransport` | Defines the reference to a [ServersTransport](#kind-serverstransport). The ServersTransport namespace is assumed to be the [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) namespace (see [ServersTransport reference](#serverstransport-reference)). |
| [15] | `services[n].healthCheck` | Defines the HealthCheck when service references a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type ExternalName. | | [15] | `services[n].healthCheck` | Defines the HealthCheck when service references a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type ExternalName. |
| [16] | `services[n].nativeLB` | Controls, when creating the load-balancer, whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. | | [16] | `services[n].strategy` | Defines the load-balancing strategy for the load-balancer. Supported values are `wrr` and `p2c`, please refer to the [Load Balancing documentation](../routing/services/#load-balancing-strategy) for more information. |
| [17] | `services[n].nodePortLB` | Controls, when creating the load-balancer, whether the LB's children are directly the nodes internal IPs using the nodePort when the service type is NodePort. | | [17] | `services[n].nativeLB` | Controls, when creating the load-balancer, whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. |
| [18] | `tls` | Defines [TLS](../routers/index.md#tls) certificate configuration | | [18] | `services[n].nodePortLB` | Controls, when creating the load-balancer, whether the LB's children are directly the nodes internal IPs using the nodePort when the service type is NodePort. |
| [19] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) | | [19] | `tls` | Defines [TLS](../routers/index.md#tls) certificate configuration |
| [20] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) | | [20] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) |
| [21] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name | | [21] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) |
| [22] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace | | [22] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name |
| [23] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver) | | [23] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace |
| [24] | `tls.domains` | List of [domains](../routers/index.md#domains) | | [24] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver) |
| [25] | `domains[n].main` | Defines the main domain name | | [25] | `tls.domains` | List of [domains](../routers/index.md#domains) |
| [26] | `domains[n].sans` | List of SANs (alternative domains) | | [26] | `domains[n].main` | Defines the main domain name |
| [27] | `domains[n].sans` | List of SANs (alternative domains) |
??? example "Declaring an IngressRoute" ??? example "Declaring an IngressRoute"
@ -605,7 +606,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne
#### Load Balancing #### Load Balancing
More information in the dedicated server [load balancing](../services/index.md#load-balancing) section. More information in the dedicated server [load balancing](../services/index.md#load-balancing-strategy) section.
!!! info "Declaring and using Kubernetes Service Load Balancing" !!! info "Declaring and using Kubernetes Service Load Balancing"

View file

@ -300,6 +300,14 @@ A Story of key & values
|---------------------------------------------------------------------------------|-------| |---------------------------------------------------------------------------------|-------|
| `traefik/http/services/myservice/loadbalancer/responseforwarding/flushinterval` | `10` | | `traefik/http/services/myservice/loadbalancer/responseforwarding/flushinterval` | `10` |
??? info "`traefik/http/services/<service_name>/loadbalancer/strategy`"
See [load balancing strategy](../services/index.md#load-balancing-strategy) for more information.
| Key (Path) | Value |
|---------------------------------------------------------|-------|
| `traefik/http/services/myservice/loadbalancer/strategy` | `p2c` |
??? info "`traefik/http/services/<service_name>/mirroring/service`" ??? info "`traefik/http/services/<service_name>/mirroring/service`"
| Key (Path) | Value | | Key (Path) | Value |

View file

@ -338,6 +338,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10 traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10
``` ```
??? info "`traefik.http.services.<service_name>.loadbalancer.strategy`"
See [load balancing strategy](../services/index.md#load-balancing-strategy) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.strategy=p2c
```
### Middleware ### Middleware
You can declare pieces of middleware using tags starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options. You can declare pieces of middleware using tags starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options.

View file

@ -467,6 +467,14 @@ you'd add the label `traefik.http.services.<name-of-your-choice>.loadbalancer.pa
- "traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10" - "traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10"
``` ```
??? info "`traefik.http.services.<service_name>.loadbalancer.strategy`"
See [load balancing strategy](../services/index.md#load-balancing-strategy) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.strategy=p2c"
```
### Middleware ### Middleware
You can declare pieces of middleware using labels starting with `traefik.http.middlewares.<name-of-your-choice>.`, You can declare pieces of middleware using labels starting with `traefik.http.middlewares.<name-of-your-choice>.`,

View file

@ -139,6 +139,47 @@ The `url` option point to a specific instance.
url = "http://private-ip-server-1/" url = "http://private-ip-server-1/"
``` ```
The `preservePath` option allows to preserve the URL path.
!!! info "Health Check"
When a [health check](#health-check) is configured for the server, the path is not preserved.
??? example "A Service with One Server and PreservePath -- Using the [File Provider](../../providers/file.md)"
```yaml tab="YAML"
## Dynamic configuration
http:
services:
my-service:
loadBalancer:
servers:
- url: "http://private-ip-server-1/base"
preservePath: true
```
```toml tab="TOML"
## Dynamic configuration
[http.services]
[http.services.my-service.loadBalancer]
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-1/base"
preservePath = true
```
#### Load Balancing Strategy
The `strategy` option allows to choose the load balancing algorithm.
Two load balancing algorithms are supported:
- Weighed round-robin (wrr)
- Power of two choices (p2c)
##### WRR
Weighed round-robin is the default strategy (and does not need to be specified).
The `weight` option allows for weighted load balancing on the servers. The `weight` option allows for weighted load balancing on the servers.
??? example "A Service with Two Servers with Weight -- Using the [File Provider](../../providers/file.md)" ??? example "A Service with Two Servers with Weight -- Using the [File Provider](../../providers/file.md)"
@ -169,39 +210,11 @@ The `weight` option allows for weighted load balancing on the servers.
weight = 1 weight = 1
``` ```
The `preservePath` option allows to preserve the URL path. ##### P2C
!!! info "Health Check" Power of two choices algorithm is a load balancing strategy that selects two servers at random and chooses the one with the least number of active requests.
When a [health check](#health-check) is configured for the server, the path is not preserved. ??? example "P2C Load Balancing -- Using the [File Provider](../../providers/file.md)"
??? example "A Service with One Server and PreservePath -- Using the [File Provider](../../providers/file.md)"
```yaml tab="YAML"
## Dynamic configuration
http:
services:
my-service:
loadBalancer:
servers:
- url: "http://private-ip-server-1/base"
preservePath: true
```
```toml tab="TOML"
## Dynamic configuration
[http.services]
[http.services.my-service.loadBalancer]
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-1/base"
preservePath = true
```
#### Load-balancing
For now, only round robin load balancing is supported:
??? example "Load Balancing -- Using the [File Provider](../../providers/file.md)"
```yaml tab="YAML" ```yaml tab="YAML"
## Dynamic configuration ## Dynamic configuration
@ -209,19 +222,24 @@ For now, only round robin load balancing is supported:
services: services:
my-service: my-service:
loadBalancer: loadBalancer:
strategy: "p2c"
servers: servers:
- url: "http://private-ip-server-1/" - url: "http://private-ip-server-1/"
- url: "http://private-ip-server-2/" - url: "http://private-ip-server-2/"
- url: "http://private-ip-server-3/"
``` ```
```toml tab="TOML" ```toml tab="TOML"
## Dynamic configuration ## Dynamic configuration
[http.services] [http.services]
[http.services.my-service.loadBalancer] [http.services.my-service.loadBalancer]
strategy = "p2c"
[[http.services.my-service.loadBalancer.servers]] [[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-1/" url = "http://private-ip-server-1/"
[[http.services.my-service.loadBalancer.servers]] [[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-2/" url = "http://private-ip-server-2/"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-3/"
``` ```
#### Sticky sessions #### Sticky sessions

View file

@ -290,10 +290,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:
@ -1217,10 +1221,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:
@ -2924,10 +2932,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:
@ -3048,10 +3060,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:
@ -3250,10 +3266,14 @@ spec:
type: object type: object
type: object type: object
strategy: strategy:
default: wrr
description: |- description: |-
Strategy defines the load balancing strategy between the servers. Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment. Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum: enum:
- wrr
- p2c
- RoundRobin - RoundRobin
type: string type: string
weight: weight:

View file

@ -200,6 +200,7 @@
"url": "http://10.0.1.1:8889" "url": "http://10.0.1.1:8889"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"
@ -225,6 +226,7 @@
"url": "http://10.0.1.2:8889" "url": "http://10.0.1.2:8889"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"
@ -242,6 +244,7 @@
"url": "http://10.0.1.3:8889" "url": "http://10.0.1.3:8889"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"

View file

@ -58,6 +58,7 @@
"url": "http://10.42.0.5:80" "url": "http://10.42.0.5:80"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"

View file

@ -172,6 +172,7 @@
"url": "http://10.42.0.5:80" "url": "http://10.42.0.5:80"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"
@ -196,6 +197,7 @@
"url": "http://10.42.0.5:80" "url": "http://10.42.0.5:80"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"
@ -220,6 +222,7 @@
"url": "http://10.42.0.5:80" "url": "http://10.42.0.5:80"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"
@ -245,6 +248,7 @@
"url": "http://10.42.0.5:80" "url": "http://10.42.0.5:80"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"

View file

@ -200,6 +200,7 @@
"url": "http://10.0.1.1:8889" "url": "http://10.0.1.1:8889"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"
@ -225,6 +226,7 @@
"url": "http://10.0.1.2:8889" "url": "http://10.0.1.2:8889"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"
@ -242,6 +244,7 @@
"url": "http://10.0.1.3:8889" "url": "http://10.0.1.3:8889"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"

View file

@ -126,6 +126,7 @@
"url": "http://10.42.0.6:80" "url": "http://10.42.0.6:80"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"

View file

@ -106,6 +106,7 @@
"url": "http://10.42.0.5:80" "url": "http://10.42.0.5:80"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"

View file

@ -157,6 +157,7 @@
"url": "http://10.42.0.5:80" "url": "http://10.42.0.5:80"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"
@ -182,6 +183,7 @@
"url": "http://10.42.0.5:80" "url": "http://10.42.0.5:80"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"

View file

@ -106,6 +106,7 @@
"url": "http://10.42.0.5:80" "url": "http://10.42.0.5:80"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"

View file

@ -200,6 +200,7 @@
"url": "http://10.0.1.1:8889" "url": "http://10.0.1.1:8889"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"
@ -225,6 +226,7 @@
"url": "http://10.0.1.2:8889" "url": "http://10.0.1.2:8889"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"
@ -242,6 +244,7 @@
"url": "http://10.0.1.3:8889" "url": "http://10.0.1.3:8889"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"

View file

@ -200,6 +200,7 @@
"url": "http://10.0.1.1:8889" "url": "http://10.0.1.1:8889"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"
@ -225,6 +226,7 @@
"url": "http://10.0.1.2:8889" "url": "http://10.0.1.2:8889"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"
@ -242,6 +244,7 @@
"url": "http://10.0.1.3:8889" "url": "http://10.0.1.3:8889"
} }
], ],
"strategy": "wrr",
"passHostHeader": true, "passHostHeader": true,
"responseForwarding": { "responseForwarding": {
"flushInterval": "100ms" "flushInterval": "100ms"

View file

@ -211,12 +211,22 @@ func (c *Cookie) SetDefaults() {
c.Path = &defaultPath c.Path = &defaultPath
} }
type BalancerStrategy string
const (
// BalancerStrategyWRR is the weighted round-robin strategy.
BalancerStrategyWRR BalancerStrategy = "wrr"
// BalancerStrategyP2C is the power of two choices strategy.
BalancerStrategyP2C BalancerStrategy = "p2c"
)
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true
// ServersLoadBalancer holds the ServersLoadBalancer configuration. // ServersLoadBalancer holds the ServersLoadBalancer configuration.
type ServersLoadBalancer struct { type ServersLoadBalancer struct {
Sticky *Sticky `json:"sticky,omitempty" toml:"sticky,omitempty" yaml:"sticky,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"` Sticky *Sticky `json:"sticky,omitempty" toml:"sticky,omitempty" yaml:"sticky,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"`
Servers []Server `json:"servers,omitempty" toml:"servers,omitempty" yaml:"servers,omitempty" label-slice-as-struct:"server" export:"true"` Servers []Server `json:"servers,omitempty" toml:"servers,omitempty" yaml:"servers,omitempty" label-slice-as-struct:"server" export:"true"`
Strategy BalancerStrategy `json:"strategy,omitempty" toml:"strategy,omitempty" yaml:"strategy,omitempty" export:"true"`
// HealthCheck enables regular active checks of the responsiveness of the // HealthCheck enables regular active checks of the responsiveness of the
// children servers of this load-balancer. To propagate status changes (e.g. all // children servers of this load-balancer. To propagate status changes (e.g. all
// servers of this service are down) upwards, HealthCheck must also be enabled on // servers of this service are down) upwards, HealthCheck must also be enabled on
@ -249,6 +259,7 @@ func (l *ServersLoadBalancer) SetDefaults() {
defaultPassHostHeader := DefaultPassHostHeader defaultPassHostHeader := DefaultPassHostHeader
l.PassHostHeader = &defaultPassHostHeader l.PassHostHeader = &defaultPassHostHeader
l.Strategy = BalancerStrategyWRR
l.ResponseForwarding = &ResponseForwarding{} l.ResponseForwarding = &ResponseForwarding{}
l.ResponseForwarding.SetDefaults() l.ResponseForwarding.SetDefaults()
} }

View file

@ -172,6 +172,7 @@ func TestDecodeConfiguration(t *testing.T) {
"traefik.http.services.Service0.loadbalancer.healthcheck.followredirects": "true", "traefik.http.services.Service0.loadbalancer.healthcheck.followredirects": "true",
"traefik.http.services.Service0.loadbalancer.passhostheader": "true", "traefik.http.services.Service0.loadbalancer.passhostheader": "true",
"traefik.http.services.Service0.loadbalancer.responseforwarding.flushinterval": "1s", "traefik.http.services.Service0.loadbalancer.responseforwarding.flushinterval": "1s",
"traefik.http.services.Service0.loadbalancer.strategy": "foobar",
"traefik.http.services.Service0.loadbalancer.server.url": "foobar", "traefik.http.services.Service0.loadbalancer.server.url": "foobar",
"traefik.http.services.Service0.loadbalancer.server.preservepath": "true", "traefik.http.services.Service0.loadbalancer.server.preservepath": "true",
"traefik.http.services.Service0.loadbalancer.server.scheme": "foobar", "traefik.http.services.Service0.loadbalancer.server.scheme": "foobar",
@ -195,6 +196,7 @@ func TestDecodeConfiguration(t *testing.T) {
"traefik.http.services.Service1.loadbalancer.healthcheck.followredirects": "true", "traefik.http.services.Service1.loadbalancer.healthcheck.followredirects": "true",
"traefik.http.services.Service1.loadbalancer.passhostheader": "true", "traefik.http.services.Service1.loadbalancer.passhostheader": "true",
"traefik.http.services.Service1.loadbalancer.responseforwarding.flushinterval": "1s", "traefik.http.services.Service1.loadbalancer.responseforwarding.flushinterval": "1s",
"traefik.http.services.Service1.loadbalancer.strategy": "foobar",
"traefik.http.services.Service1.loadbalancer.server.url": "foobar", "traefik.http.services.Service1.loadbalancer.server.url": "foobar",
"traefik.http.services.Service1.loadbalancer.server.preservepath": "true", "traefik.http.services.Service1.loadbalancer.server.preservepath": "true",
"traefik.http.services.Service1.loadbalancer.server.scheme": "foobar", "traefik.http.services.Service1.loadbalancer.server.scheme": "foobar",
@ -680,6 +682,7 @@ func TestDecodeConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service0": { "Service0": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: "foobar",
Sticky: &dynamic.Sticky{ Sticky: &dynamic.Sticky{
Cookie: &dynamic.Cookie{ Cookie: &dynamic.Cookie{
Name: "foobar", Name: "foobar",
@ -722,6 +725,7 @@ func TestDecodeConfiguration(t *testing.T) {
}, },
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: "foobar",
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "foobar", URL: "foobar",
@ -1222,6 +1226,7 @@ func TestEncodeConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service0": { "Service0": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: "foobar",
Sticky: &dynamic.Sticky{ Sticky: &dynamic.Sticky{
Cookie: &dynamic.Cookie{ Cookie: &dynamic.Cookie{
Name: "foobar", Name: "foobar",
@ -1261,6 +1266,7 @@ func TestEncodeConfiguration(t *testing.T) {
}, },
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: "foobar",
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "foobar", URL: "foobar",
@ -1473,6 +1479,7 @@ func TestEncodeConfiguration(t *testing.T) {
"traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Timeout": "1000000000", "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Timeout": "1000000000",
"traefik.HTTP.Services.Service0.LoadBalancer.PassHostHeader": "true", "traefik.HTTP.Services.Service0.LoadBalancer.PassHostHeader": "true",
"traefik.HTTP.Services.Service0.LoadBalancer.ResponseForwarding.FlushInterval": "1000000000", "traefik.HTTP.Services.Service0.LoadBalancer.ResponseForwarding.FlushInterval": "1000000000",
"traefik.HTTP.Services.Service0.LoadBalancer.Strategy": "foobar",
"traefik.HTTP.Services.Service0.LoadBalancer.server.URL": "foobar", "traefik.HTTP.Services.Service0.LoadBalancer.server.URL": "foobar",
"traefik.HTTP.Services.Service0.LoadBalancer.server.PreservePath": "true", "traefik.HTTP.Services.Service0.LoadBalancer.server.PreservePath": "true",
"traefik.HTTP.Services.Service0.LoadBalancer.server.Port": "8080", "traefik.HTTP.Services.Service0.LoadBalancer.server.Port": "8080",
@ -1496,6 +1503,7 @@ func TestEncodeConfiguration(t *testing.T) {
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Timeout": "1000000000", "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Timeout": "1000000000",
"traefik.HTTP.Services.Service1.LoadBalancer.PassHostHeader": "true", "traefik.HTTP.Services.Service1.LoadBalancer.PassHostHeader": "true",
"traefik.HTTP.Services.Service1.LoadBalancer.ResponseForwarding.FlushInterval": "1000000000", "traefik.HTTP.Services.Service1.LoadBalancer.ResponseForwarding.FlushInterval": "1000000000",
"traefik.HTTP.Services.Service1.LoadBalancer.Strategy": "foobar",
"traefik.HTTP.Services.Service1.LoadBalancer.server.URL": "foobar", "traefik.HTTP.Services.Service1.LoadBalancer.server.URL": "foobar",
"traefik.HTTP.Services.Service1.LoadBalancer.server.PreservePath": "true", "traefik.HTTP.Services.Service1.LoadBalancer.server.PreservePath": "true",
"traefik.HTTP.Services.Service1.LoadBalancer.server.Port": "8080", "traefik.HTTP.Services.Service1.LoadBalancer.server.Port": "8080",

View file

@ -61,6 +61,7 @@ func TestDefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -119,6 +120,7 @@ func TestDefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -169,6 +171,7 @@ func TestDefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -219,6 +222,7 @@ func TestDefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -275,6 +279,7 @@ func TestDefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -369,6 +374,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"dev-Test": { "dev-Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -430,6 +436,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"dev-Test": { "dev-Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "https://127.0.0.1:443", URL: "https://127.0.0.1:443",
@ -521,6 +528,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"dev-Test": { "dev-Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "https://127.0.0.1:443", URL: "https://127.0.0.1:443",
@ -609,6 +617,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -622,6 +631,7 @@ func Test_buildConfiguration(t *testing.T) {
}, },
"Test2": { "Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.2:80", URL: "http://127.0.0.2:80",
@ -686,6 +696,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -753,6 +764,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.2:80", URL: "http://127.0.0.2:80",
@ -817,6 +829,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -876,6 +889,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -933,6 +947,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -982,6 +997,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1044,6 +1060,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1096,6 +1113,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1109,6 +1127,7 @@ func Test_buildConfiguration(t *testing.T) {
}, },
"Service2": { "Service2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1288,6 +1307,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1346,6 +1366,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1424,6 +1445,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1492,6 +1514,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1573,6 +1596,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1640,6 +1664,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1715,6 +1740,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1788,6 +1814,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1847,6 +1874,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1904,6 +1932,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "h2c://127.0.0.1:8080", URL: "h2c://127.0.0.1:8080",
@ -1960,6 +1989,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://1.2.3.4:5678", URL: "http://1.2.3.4:5678",
@ -2017,6 +2047,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://1.2.3.4:5678", URL: "http://1.2.3.4:5678",
@ -2143,6 +2174,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -2156,6 +2188,7 @@ func Test_buildConfiguration(t *testing.T) {
}, },
"Service2": { "Service2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:8080", URL: "http://127.0.0.1:8080",
@ -2389,6 +2422,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -2456,6 +2490,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -2889,6 +2924,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -2980,6 +3016,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -3201,6 +3238,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "https://127.0.0.1:80", URL: "https://127.0.0.1:80",
@ -3215,6 +3253,7 @@ func Test_buildConfiguration(t *testing.T) {
}, },
"Test-97077516270503695": { "Test-97077516270503695": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "https://127.0.0.2:80", URL: "https://127.0.0.2:80",
@ -3501,6 +3540,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"dev-Test": { "dev-Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -3677,6 +3717,7 @@ func TestFilterHealthStatuses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test1": { "Test1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -3690,6 +3731,7 @@ func TestFilterHealthStatuses(t *testing.T) {
}, },
"Test2": { "Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:81", URL: "http://127.0.0.1:81",
@ -3793,6 +3835,7 @@ func TestFilterHealthStatuses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test2": { "Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:81", URL: "http://127.0.0.1:81",
@ -3873,6 +3916,7 @@ func TestFilterHealthStatuses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test1": { "Test1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -3886,6 +3930,7 @@ func TestFilterHealthStatuses(t *testing.T) {
}, },
"Test2": { "Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:81", URL: "http://127.0.0.1:81",
@ -3985,6 +4030,7 @@ func TestFilterHealthStatuses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test1": { "Test1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -3998,6 +4044,7 @@ func TestFilterHealthStatuses(t *testing.T) {
}, },
"Test2": { "Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:81", URL: "http://127.0.0.1:81",
@ -4011,6 +4058,7 @@ func TestFilterHealthStatuses(t *testing.T) {
}, },
"Test3": { "Test3": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:82", URL: "http://127.0.0.1:82",
@ -4024,6 +4072,7 @@ func TestFilterHealthStatuses(t *testing.T) {
}, },
"Test4": { "Test4": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:83", URL: "http://127.0.0.1:83",

View file

@ -69,6 +69,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -132,6 +133,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -197,6 +199,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -254,6 +257,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -311,6 +315,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -374,6 +379,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -606,6 +612,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -689,6 +696,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -702,6 +710,7 @@ func TestDynConfBuilder_build(t *testing.T) {
}, },
"Test2": { "Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.2:80", URL: "http://127.0.0.2:80",
@ -782,6 +791,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -849,6 +859,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -914,6 +925,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -971,6 +983,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1041,6 +1054,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1101,6 +1115,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1114,6 +1129,7 @@ func TestDynConfBuilder_build(t *testing.T) {
}, },
"Service2": { "Service2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1178,6 +1194,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1421,6 +1438,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1487,6 +1505,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1584,6 +1603,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1671,6 +1691,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1777,6 +1798,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1861,6 +1883,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1961,6 +1984,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -2050,6 +2074,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -2129,6 +2154,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -2142,6 +2168,7 @@ func TestDynConfBuilder_build(t *testing.T) {
}, },
"Test2": { "Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.2:80", URL: "http://127.0.0.2:80",
@ -2206,6 +2233,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -2271,6 +2299,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "h2c://127.0.0.1:8080", URL: "h2c://127.0.0.1:8080",
@ -2330,6 +2359,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -2343,6 +2373,7 @@ func TestDynConfBuilder_build(t *testing.T) {
}, },
"Service2": { "Service2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:8080", URL: "http://127.0.0.1:8080",
@ -2407,6 +2438,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://1.2.3.4:5678", URL: "http://1.2.3.4:5678",
@ -2472,6 +2504,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://1.2.3.4:5678", URL: "http://1.2.3.4:5678",
@ -2772,6 +2805,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -3032,6 +3066,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -3107,6 +3142,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -3578,6 +3614,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -3762,6 +3799,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://192.168.0.1:8081", URL: "http://192.168.0.1:8081",
@ -3825,6 +3863,7 @@ func TestDynConfBuilder_build(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:79", URL: "http://127.0.0.1:79",

View file

@ -63,6 +63,7 @@ func TestDefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.0.0.1:1337", URL: "http://10.0.0.1:1337",
@ -121,6 +122,7 @@ func TestDefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -181,6 +183,7 @@ func TestDefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -233,6 +236,7 @@ func TestDefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -285,6 +289,7 @@ func TestDefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -343,6 +348,7 @@ func TestDefaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -552,6 +558,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -625,6 +632,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -638,6 +646,7 @@ func Test_buildConfiguration(t *testing.T) {
}, },
"Test2": { "Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.2:80", URL: "http://127.0.0.2:80",
@ -708,6 +717,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -770,6 +780,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -830,6 +841,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -882,6 +894,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -947,6 +960,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1002,6 +1016,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1015,6 +1030,7 @@ func Test_buildConfiguration(t *testing.T) {
}, },
"Service2": { "Service2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1074,6 +1090,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1282,6 +1299,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1343,6 +1361,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1430,6 +1449,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1507,6 +1527,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1598,6 +1619,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1672,6 +1694,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1757,6 +1780,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1837,6 +1861,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1906,6 +1931,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -1919,6 +1945,7 @@ func Test_buildConfiguration(t *testing.T) {
}, },
"Test2": { "Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.2:80", URL: "http://127.0.0.2:80",
@ -1978,6 +2005,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -2038,6 +2066,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "h2c://127.0.0.1:8080", URL: "h2c://127.0.0.1:8080",
@ -2097,6 +2126,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://1.2.3.4:5678", URL: "http://1.2.3.4:5678",
@ -2157,6 +2187,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://1.2.3.4:5678", URL: "http://1.2.3.4:5678",
@ -2298,6 +2329,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "h2c://127.0.0.1:8040", URL: "h2c://127.0.0.1:8040",
@ -2366,6 +2398,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:32124", URL: "http://127.0.0.1:32124",
@ -2379,6 +2412,7 @@ func Test_buildConfiguration(t *testing.T) {
}, },
"Service2": { "Service2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:32123", URL: "http://127.0.0.1:32123",
@ -2433,6 +2467,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -2446,6 +2481,7 @@ func Test_buildConfiguration(t *testing.T) {
}, },
"Service2": { "Service2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:8080", URL: "http://127.0.0.1:8080",
@ -2736,6 +2772,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -2806,6 +2843,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -3237,6 +3275,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -3400,6 +3439,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",

View file

@ -21,7 +21,6 @@ import (
) )
const ( const (
roundRobinStrategy = "RoundRobin"
httpsProtocol = "https" httpsProtocol = "https"
httpProtocol = "http" httpProtocol = "http"
) )
@ -322,13 +321,33 @@ func (c configBuilder) buildMirroring(ctx context.Context, tService *traefikv1al
// buildServersLB creates the configuration for the load-balancer of servers defined by svc. // buildServersLB creates the configuration for the load-balancer of servers defined by svc.
func (c configBuilder) buildServersLB(namespace string, svc traefikv1alpha1.LoadBalancerSpec) (*dynamic.Service, error) { func (c configBuilder) buildServersLB(namespace string, svc traefikv1alpha1.LoadBalancerSpec) (*dynamic.Service, error) {
lb := &dynamic.ServersLoadBalancer{}
lb.SetDefaults()
// This is required by the tests as the fake client does not apply default values.
// TODO: remove this when the fake client apply default values.
if svc.Strategy != "" {
switch svc.Strategy {
case dynamic.BalancerStrategyWRR, dynamic.BalancerStrategyP2C:
lb.Strategy = svc.Strategy
// Here we are just logging a warning as the default value is already applied.
case "RoundRobin":
log.Warn().
Str("namespace", namespace).
Str("service", svc.Name).
Msgf("RoundRobin strategy value is deprecated, please use %s value instead", dynamic.BalancerStrategyWRR)
default:
return nil, fmt.Errorf("load-balancer strategy %s is not supported", svc.Strategy)
}
}
servers, err := c.loadServers(namespace, svc) servers, err := c.loadServers(namespace, svc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
lb := &dynamic.ServersLoadBalancer{}
lb.SetDefaults()
lb.Servers = servers lb.Servers = servers
if svc.HealthCheck != nil { if svc.HealthCheck != nil {
@ -421,14 +440,6 @@ func (c configBuilder) makeServersTransportKey(parentNamespace string, serversTr
} }
func (c configBuilder) loadServers(parentNamespace string, svc traefikv1alpha1.LoadBalancerSpec) ([]dynamic.Server, error) { func (c configBuilder) loadServers(parentNamespace string, svc traefikv1alpha1.LoadBalancerSpec) ([]dynamic.Server, error) {
strategy := svc.Strategy
if strategy == "" {
strategy = roundRobinStrategy
}
if strategy != roundRobinStrategy {
return nil, fmt.Errorf("load balancing strategy %s is not supported", strategy)
}
namespace := namespaceOrFallback(svc, parentNamespace) namespace := namespaceOrFallback(svc, parentNamespace)
if !isNamespaceAllowed(c.allowCrossNamespace, parentNamespace, namespace) { if !isNamespaceAllowed(c.allowCrossNamespace, parentNamespace, namespace) {

View file

@ -1387,6 +1387,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-whoami-ipv6-8080": { "default-whoami-ipv6-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://[2001:db8:85a3:8d3:1319:8a2e:370:7348]:8080", URL: "http://[2001:db8:85a3:8d3:1319:8a2e:370:7348]:8080",
@ -1400,6 +1401,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
}, },
"default-external-svc-with-ipv6-8080": { "default-external-svc-with-ipv6-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://[2001:db8:85a3:8d3:1319:8a2e:370:7347]:8080", URL: "http://[2001:db8:85a3:8d3:1319:8a2e:370:7347]:8080",
@ -1743,6 +1745,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -1815,6 +1818,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test2-route-23c7f4c450289ee29016": { "default-test2-route-23c7f4c450289ee29016": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -1893,6 +1897,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test2-route-3c9bf014491ebdba74f7": { "default-test2-route-3c9bf014491ebdba74f7": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -1948,6 +1953,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test2-route-23c7f4c450289ee29016": { "default-test2-route-23c7f4c450289ee29016": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -2009,6 +2015,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test2-route-23c7f4c450289ee29016": { "default-test2-route-23c7f4c450289ee29016": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -2061,6 +2068,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -2077,6 +2085,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-test-route-77c62dfe9517144aeeaa": { "default-test-route-77c62dfe9517144aeeaa": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -2139,6 +2148,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami-80": { "default-whoami-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -2155,6 +2165,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami2-8080": { "default-whoami2-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.3:8080", URL: "http://10.10.0.3:8080",
@ -2212,6 +2223,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami5-8080": { "default-whoami5-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.3:8080", URL: "http://10.10.0.3:8080",
@ -2262,6 +2274,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami5-8080": { "default-whoami5-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.3:8080", URL: "http://10.10.0.3:8080",
@ -2337,6 +2350,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami4-80": { "default-whoami4-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -2353,6 +2367,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami5-8080": { "default-whoami5-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.3:8080", URL: "http://10.10.0.3:8080",
@ -2383,6 +2398,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami6-80": { "default-whoami6-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.5:80", URL: "http://10.10.0.5:80",
@ -2399,6 +2415,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami7-8080": { "default-whoami7-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.7:8080", URL: "http://10.10.0.7:8080",
@ -2470,6 +2487,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami5-8080": { "default-whoami5-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.3:8080", URL: "http://10.10.0.3:8080",
@ -2553,6 +2571,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami4-8080": { "default-whoami4-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:8080", URL: "http://10.10.0.1:8080",
@ -2569,6 +2588,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami5-8080": { "default-whoami5-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.3:8080", URL: "http://10.10.0.3:8080",
@ -2615,6 +2635,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-77c62dfe9517144aeeaa": { "default-test-route-77c62dfe9517144aeeaa": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "https://external.domain:443", URL: "https://external.domain:443",
@ -2679,6 +2700,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-external-svc-443": { "default-external-svc-443": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "https://external.domain:443", URL: "https://external.domain:443",
@ -2698,6 +2720,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-external-svc-with-https-443": { "default-external-svc-with-https-443": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "https://external.domain:443", URL: "https://external.domain:443",
@ -2741,6 +2764,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-external-svc-443": { "default-external-svc-443": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "https://external.domain:443", URL: "https://external.domain:443",
@ -2819,6 +2843,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"baz-whoami6-8080": { "baz-whoami6-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.5:8080", URL: "http://10.10.0.5:8080",
@ -2857,6 +2882,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"foo-whoami4-8080": { "foo-whoami4-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:8080", URL: "http://10.10.0.1:8080",
@ -2883,6 +2909,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"foo-whoami5-8080": { "foo-whoami5-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.3:8080", URL: "http://10.10.0.3:8080",
@ -2989,6 +3016,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami4-8080": { "default-whoami4-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:8080", URL: "http://10.10.0.1:8080",
@ -3005,6 +3033,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami5-8080": { "default-whoami5-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.3:8080", URL: "http://10.10.0.3:8080",
@ -3080,6 +3109,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami4-8080": { "default-whoami4-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:8080", URL: "http://10.10.0.1:8080",
@ -3096,6 +3126,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami5-8080": { "default-whoami5-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.3:8080", URL: "http://10.10.0.3:8080",
@ -3157,6 +3188,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami-80": { "default-whoami-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -3173,6 +3205,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami2-8080": { "default-whoami2-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.3:8080", URL: "http://10.10.0.3:8080",
@ -3267,6 +3300,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-02719a68b11e915a4b23": { "default-test-route-02719a68b11e915a4b23": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -3324,6 +3358,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -3397,6 +3432,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -3458,6 +3494,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -3474,6 +3511,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-test-route-default-6b204d94623b3df4370c": { "default-test-route-default-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -3547,6 +3585,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -3621,6 +3660,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -3693,6 +3733,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -3769,6 +3810,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -3846,6 +3888,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -3894,6 +3937,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -3941,6 +3985,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "https://10.10.0.5:8443", URL: "https://10.10.0.5:8443",
@ -3988,6 +4033,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "https://10.10.0.7:8443", URL: "https://10.10.0.7:8443",
@ -4250,6 +4296,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-errorpage-errorpage-service": { "default-errorpage-errorpage-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -4296,6 +4343,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -4352,6 +4400,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -4413,6 +4462,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -4470,6 +4520,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -4486,6 +4537,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-test-route-default-6b204d94623b3df4370c": { "default-test-route-default-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -4534,6 +4586,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6f97418635c7e18853da": { "default-test-route-6f97418635c7e18853da": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://external.domain:80", URL: "http://external.domain:80",
@ -4577,6 +4630,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6f97418635c7e18853da": { "default-test-route-6f97418635c7e18853da": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://external.domain:80", URL: "http://external.domain:80",
@ -4620,6 +4674,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6f97418635c7e18853da": { "default-test-route-6f97418635c7e18853da": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "https://external.domain:443", URL: "https://external.domain:443",
@ -4723,6 +4778,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-external-svc-with-https-443": { "default-external-svc-with-https-443": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "https://external.domain:443", URL: "https://external.domain:443",
@ -4737,6 +4793,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoamitls-443": { "default-whoamitls-443": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "https://10.10.0.5:8443", URL: "https://10.10.0.5:8443",
@ -4822,6 +4879,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -4862,6 +4920,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -4918,6 +4977,7 @@ func TestLoadIngressRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:8080", URL: "http://10.10.0.1:8080",
@ -4993,6 +5053,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-test-errorpage-errorpage-service": { "default-test-errorpage-errorpage-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -5024,6 +5085,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami-without-endpointslice-endpoints-80": { "default-whoami-without-endpointslice-endpoints-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -5136,6 +5198,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami2-8080": { "default-whoami2-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Sticky: &dynamic.Sticky{ Sticky: &dynamic.Sticky{
Cookie: &dynamic.Cookie{ Cookie: &dynamic.Cookie{
Name: "cookie", Name: "cookie",
@ -5162,6 +5225,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami-80": { "default-whoami-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Sticky: &dynamic.Sticky{ Sticky: &dynamic.Sticky{
Cookie: &dynamic.Cookie{ Cookie: &dynamic.Cookie{
Name: "cookie", Name: "cookie",
@ -5188,6 +5252,7 @@ func TestLoadIngressRoutes(t *testing.T) {
}, },
"default-whoami3-8443": { "default-whoami3-8443": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.7:8443", URL: "http://10.10.0.7:8443",
@ -5273,6 +5338,7 @@ func TestLoadIngressRoutes_multipleEndpointAddresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -6199,6 +6265,7 @@ func TestCrossNamespace(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-crossnamespace-route-9313b71dbe6a649d5049": { "default-test-crossnamespace-route-9313b71dbe6a649d5049": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6277,6 +6344,7 @@ func TestCrossNamespace(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-crossnamespace-route-6b204d94623b3df4370c": { "default-test-crossnamespace-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6293,6 +6361,7 @@ func TestCrossNamespace(t *testing.T) {
}, },
"default-test-crossnamespace-route-9313b71dbe6a649d5049": { "default-test-crossnamespace-route-9313b71dbe6a649d5049": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6309,6 +6378,7 @@ func TestCrossNamespace(t *testing.T) {
}, },
"default-test-errorpage-errorpage-service": { "default-test-errorpage-errorpage-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6325,6 +6395,7 @@ func TestCrossNamespace(t *testing.T) {
}, },
"default-test-crossnamespace-route-a1963878aac7331b7950": { "default-test-crossnamespace-route-a1963878aac7331b7950": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6404,6 +6475,7 @@ func TestCrossNamespace(t *testing.T) {
}, },
"default-cross-ns-route-1bc3efa892379bb93c6e": { "default-cross-ns-route-1bc3efa892379bb93c6e": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6421,6 +6493,7 @@ func TestCrossNamespace(t *testing.T) {
}, },
"cross-ns-whoami-svc-80": { "cross-ns-whoami-svc-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6479,6 +6552,7 @@ func TestCrossNamespace(t *testing.T) {
}, },
"default-whoami-80": { "default-whoami-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6529,6 +6603,7 @@ func TestCrossNamespace(t *testing.T) {
}, },
"cross-ns-whoami-svc-80": { "cross-ns-whoami-svc-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6556,6 +6631,7 @@ func TestCrossNamespace(t *testing.T) {
}, },
"default-whoami-80": { "default-whoami-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6604,6 +6680,7 @@ func TestCrossNamespace(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6701,6 +6778,7 @@ func TestCrossNamespace(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6764,6 +6842,7 @@ func TestCrossNamespace(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6b204d94623b3df4370c": { "default-test-route-6b204d94623b3df4370c": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -7382,6 +7461,7 @@ func TestExternalNameService(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6f97418635c7e18853da": { "default-test-route-6f97418635c7e18853da": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://external.domain:80", URL: "http://external.domain:80",
@ -7649,6 +7729,7 @@ func TestNativeLB(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6f97418635c7e18853da": { "default-test-route-6f97418635c7e18853da": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval}, ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
@ -7830,6 +7911,7 @@ func TestNodePortLB(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6f97418635c7e18853da": { "default-test-route-6f97418635c7e18853da": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval}, ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
@ -8273,6 +8355,7 @@ func TestGlobalNativeLB(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-global-native-lb-6f97418635c7e18853da": { "default-global-native-lb-6f97418635c7e18853da": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval}, ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
@ -8315,6 +8398,7 @@ func TestGlobalNativeLB(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-test-route-6f97418635c7e18853da": { "default-test-route-6f97418635c7e18853da": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval}, ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {

View file

@ -113,9 +113,11 @@ type LoadBalancerSpec struct {
// It defaults to https when Kubernetes Service port is 443, http otherwise. // It defaults to https when Kubernetes Service port is 443, http otherwise.
Scheme string `json:"scheme,omitempty"` Scheme string `json:"scheme,omitempty"`
// Strategy defines the load balancing strategy between the servers. // Strategy defines the load balancing strategy between the servers.
// RoundRobin is the only supported value at the moment. // Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
// +kubebuilder:validation:Enum=RoundRobin // RoundRobin value is deprecated and supported for backward compatibility.
Strategy string `json:"strategy,omitempty"` // +kubebuilder:validation:Enum=wrr;p2c;RoundRobin
// +kubebuilder:default:=wrr
Strategy dynamic.BalancerStrategy `json:"strategy,omitempty"`
// PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. // PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service.
// By default, passHostHeader is true. // By default, passHostHeader is true.
PassHostHeader *bool `json:"passHostHeader,omitempty"` PassHostHeader *bool `json:"passHostHeader,omitempty"`

View file

@ -637,6 +637,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -733,6 +734,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -803,6 +805,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -864,6 +867,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -925,6 +929,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -1003,6 +1008,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -1019,6 +1025,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami2-http-8080": { "default-whoami2-http-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.3:8080", URL: "http://10.10.0.3:8080",
@ -1084,6 +1091,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -1100,6 +1108,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami2-http-8080": { "default-whoami2-http-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.3:8080", URL: "http://10.10.0.3:8080",
@ -1184,6 +1193,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -1277,6 +1287,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -1381,6 +1392,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -1442,6 +1454,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -1503,6 +1516,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -1564,6 +1578,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -1642,6 +1657,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -1658,6 +1674,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"bar-whoami-bar-http-80": { "bar-whoami-bar-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.11:80", URL: "http://10.10.0.11:80",
@ -1719,6 +1736,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"bar-whoami-bar-http-80": { "bar-whoami-bar-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.11:80", URL: "http://10.10.0.11:80",
@ -1789,6 +1807,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -1859,6 +1878,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -2021,6 +2041,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -2089,6 +2110,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -2159,6 +2181,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -2220,6 +2243,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -2282,6 +2306,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -2353,6 +2378,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -2420,6 +2446,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.10.1:80", URL: "http://10.10.10.1:80",
@ -2478,6 +2505,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
}, },
"default-whoami-native-http-80": { "default-whoami-native-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.10.1:80", URL: "http://10.10.10.1:80",
@ -2597,7 +2625,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) {
paths: []string{"services.yml", "httproute/simple_with_TraefikService.yml"}, paths: []string{"services.yml", "httproute/simple_with_TraefikService.yml"},
groupKindBackendFuncs: map[string]map[string]BuildBackendFunc{ groupKindBackendFuncs: map[string]map[string]BuildBackendFunc{
traefikv1alpha1.GroupName: {"TraefikService": func(name, namespace string) (string, *dynamic.Service, error) { traefikv1alpha1.GroupName: {"TraefikService": func(name, namespace string) (string, *dynamic.Service, error) {
return name, &dynamic.Service{LoadBalancer: &dynamic.ServersLoadBalancer{Servers: []dynamic.Server{{URL: "foobar"}}}}, nil return name, &dynamic.Service{LoadBalancer: &dynamic.ServersLoadBalancer{Strategy: dynamic.BalancerStrategyWRR, Servers: []dynamic.Server{{URL: "foobar"}}}}, nil
}}, }},
}, },
entryPoints: map[string]Entrypoint{"web": { entryPoints: map[string]Entrypoint{"web": {
@ -2638,6 +2666,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) {
}, },
"whoami": { "whoami": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{URL: "foobar"}, {URL: "foobar"},
}, },
@ -2797,6 +2826,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -2872,6 +2902,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) {
}, },
"default-whoami-h2c-http-80": { "default-whoami-h2c-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "h2c://10.10.0.13:80", URL: "h2c://10.10.0.13:80",
@ -2885,6 +2916,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) {
}, },
"default-whoami-ws-http-80": { "default-whoami-ws-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.14:80", URL: "http://10.10.0.14:80",
@ -2898,6 +2930,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) {
}, },
"default-whoami-wss-http-80": { "default-whoami-wss-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "https://10.10.0.15:80", URL: "https://10.10.0.15:80",
@ -3012,6 +3045,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -3084,6 +3118,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -3296,6 +3331,7 @@ func TestLoadGRPCRoutes_filterExtensionRef(t *testing.T) {
}, },
"default-whoami-80-grpc": { "default-whoami-80-grpc": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "h2c://10.10.0.1:80", URL: "h2c://10.10.0.1:80",
@ -3368,6 +3404,7 @@ func TestLoadGRPCRoutes_filterExtensionRef(t *testing.T) {
}, },
"default-whoami-80-grpc": { "default-whoami-80-grpc": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "h2c://10.10.0.1:80", URL: "h2c://10.10.0.1:80",
@ -5951,6 +5988,7 @@ func TestLoadMixedRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6139,6 +6177,7 @@ func TestLoadMixedRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6359,6 +6398,7 @@ func TestLoadMixedRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",
@ -6375,6 +6415,7 @@ func TestLoadMixedRoutes(t *testing.T) {
}, },
"bar-whoami-bar-http-80": { "bar-whoami-bar-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.11:80", URL: "http://10.10.0.11:80",
@ -6535,6 +6576,7 @@ func TestLoadMixedRoutes(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"bar-whoami-bar-http-80": { "bar-whoami-bar-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.11:80", URL: "http://10.10.0.11:80",
@ -6694,6 +6736,7 @@ func TestLoadMixedRoutes(t *testing.T) {
}, },
"default-whoami-http-80": { "default-whoami-http-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://10.10.0.1:80", URL: "http://10.10.0.1:80",

View file

@ -73,6 +73,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -128,6 +129,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -173,6 +175,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -209,6 +212,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -245,6 +249,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -281,6 +286,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -313,6 +319,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -345,6 +352,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-example-com-80": { "testing-example-com-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -378,6 +386,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -414,6 +423,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -450,6 +460,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -466,6 +477,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
}, },
"testing-service2-8082": { "testing-service2-8082": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -499,6 +511,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -535,6 +548,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-backend": { "default-backend": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -567,6 +581,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -599,6 +614,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-tchouk": { "testing-service1-tchouk": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -631,6 +647,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-tchouk": { "testing-service1-tchouk": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -667,6 +684,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-tchouk": { "testing-service1-tchouk": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -683,6 +701,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
}, },
"testing-service1-carotte": { "testing-service1-carotte": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -715,6 +734,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-tchouk": { "testing-service1-tchouk": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -751,6 +771,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-tchouk": { "testing-service1-tchouk": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -767,6 +788,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
}, },
"toto-service1-tchouk": { "toto-service1-tchouk": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -819,6 +841,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-8080": { "testing-service1-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -849,6 +872,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-example-com-80": { "testing-example-com-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -888,6 +912,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-443": { "testing-service1-443": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -920,6 +945,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-8443": { "testing-service1-8443": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -953,6 +979,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-8443": { "testing-service1-8443": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -987,6 +1014,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-backend": { "default-backend": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1019,6 +1047,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1091,6 +1120,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1123,6 +1153,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1158,6 +1189,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1188,6 +1220,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1217,6 +1250,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1246,6 +1280,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1275,6 +1310,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1304,6 +1340,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1333,6 +1370,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1365,6 +1403,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1397,6 +1436,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1426,6 +1466,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1481,6 +1522,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-foobar": { "testing-service1-foobar": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1522,6 +1564,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-backend": { "default-backend": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1551,6 +1594,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-80": { "testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1630,6 +1674,7 @@ func TestLoadConfigurationFromIngressesWithExternalNameServices(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-8080": { "testing-service1-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond), FlushInterval: ptypes.Duration(100 * time.Millisecond),
@ -1659,6 +1704,7 @@ func TestLoadConfigurationFromIngressesWithExternalNameServices(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service-bar-8080": { "testing-service-bar-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://[2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b]:8080", URL: "http://[2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b]:8080",
@ -1689,6 +1735,7 @@ func TestLoadConfigurationFromIngressesWithExternalNameServices(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service-foo-8080": { "testing-service-foo-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://[2001:0db8:3c4d:0015:0000:0000:1a2f:2a3b]:8080", URL: "http://[2001:0db8:3c4d:0015:0000:0000:1a2f:2a3b]:8080",
@ -1741,6 +1788,7 @@ func TestLoadConfigurationFromIngressesWithNativeLB(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-8080": { "testing-service1-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval}, ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
Servers: []dynamic.Server{ Servers: []dynamic.Server{
@ -1790,6 +1838,7 @@ func TestLoadConfigurationFromIngressesWithNodePortLB(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-8080": { "testing-service1-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval}, ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
Servers: []dynamic.Server{ Servers: []dynamic.Server{
@ -2027,6 +2076,7 @@ func TestLoadConfigurationFromIngressesWithNativeLBByDefault(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"testing-service1-8080": { "testing-service1-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval}, ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
Servers: []dynamic.Server{ Servers: []dynamic.Server{
@ -2054,6 +2104,7 @@ func TestLoadConfigurationFromIngressesWithNativeLBByDefault(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"default-service1-8080": { "default-service1-8080": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval}, ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
Servers: []dynamic.Server{ Servers: []dynamic.Server{

View file

@ -58,6 +58,7 @@ func Test_buildConfiguration(t *testing.T) {
"traefik/http/services/Service01/loadBalancer/sticky/cookie/secure": "true", "traefik/http/services/Service01/loadBalancer/sticky/cookie/secure": "true",
"traefik/http/services/Service01/loadBalancer/sticky/cookie/httpOnly": "true", "traefik/http/services/Service01/loadBalancer/sticky/cookie/httpOnly": "true",
"traefik/http/services/Service01/loadBalancer/sticky/cookie/path": "foobar", "traefik/http/services/Service01/loadBalancer/sticky/cookie/path": "foobar",
"traefik/http/services/Service01/loadBalancer/strategy": "foobar",
"traefik/http/services/Service01/loadBalancer/servers/0/url": "foobar", "traefik/http/services/Service01/loadBalancer/servers/0/url": "foobar",
"traefik/http/services/Service01/loadBalancer/servers/1/url": "foobar", "traefik/http/services/Service01/loadBalancer/servers/1/url": "foobar",
"traefik/http/services/Service02/mirroring/service": "foobar", "traefik/http/services/Service02/mirroring/service": "foobar",
@ -646,6 +647,7 @@ func Test_buildConfiguration(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service01": { "Service01": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: "foobar",
Sticky: &dynamic.Sticky{ Sticky: &dynamic.Sticky{
Cookie: &dynamic.Cookie{ Cookie: &dynamic.Cookie{
Name: "foobar", Name: "foobar",

View file

@ -56,6 +56,7 @@ func Test_defaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -114,6 +115,7 @@ func Test_defaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -163,6 +165,7 @@ func Test_defaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -218,6 +221,7 @@ func Test_defaultRule(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -296,6 +300,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"dev-Test": { "dev-Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -363,6 +368,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test1": { "Test1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://192.168.1.101:9999", URL: "http://192.168.1.101:9999",
@ -376,6 +382,7 @@ func Test_buildConfig(t *testing.T) {
}, },
"Test2": { "Test2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://192.168.1.102:9999", URL: "http://192.168.1.102:9999",
@ -440,6 +447,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -507,6 +515,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.2:9999", URL: "http://127.0.0.2:9999",
@ -571,6 +580,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -630,6 +640,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -687,6 +698,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -772,6 +784,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -834,6 +847,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -886,6 +900,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -899,6 +914,7 @@ func Test_buildConfig(t *testing.T) {
}, },
"Service2": { "Service2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -1079,6 +1095,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -1137,6 +1154,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -1216,6 +1234,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -1285,6 +1304,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -1348,6 +1368,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -1416,6 +1437,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -1475,6 +1497,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -1532,6 +1555,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "h2c://127.0.0.1:8080", URL: "h2c://127.0.0.1:8080",
@ -1588,6 +1612,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://1.2.3.4:5678", URL: "http://1.2.3.4:5678",
@ -1645,6 +1670,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://1.2.3.4:5678", URL: "http://1.2.3.4:5678",
@ -1771,6 +1797,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -1784,6 +1811,7 @@ func Test_buildConfig(t *testing.T) {
}, },
"Service2": { "Service2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:8080", URL: "http://127.0.0.1:8080",
@ -1983,6 +2011,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -2050,6 +2079,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -2459,6 +2489,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -2550,6 +2581,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Service1": { "Service1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -2770,6 +2802,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:80", URL: "http://127.0.0.1:80",
@ -2783,6 +2816,7 @@ func Test_buildConfig(t *testing.T) {
}, },
"Test-1234154071633021619": { "Test-1234154071633021619": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.2:80", URL: "http://127.0.0.2:80",
@ -3002,6 +3036,7 @@ func Test_buildConfig(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"dev-Test": { "dev-Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:9999", URL: "http://127.0.0.1:9999",
@ -3093,6 +3128,7 @@ func Test_buildConfigAllowEmptyServicesTrue(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"Test": { "Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: nil, Servers: nil,
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{ ResponseForwarding: &dynamic.ResponseForwarding{

View file

@ -53,6 +53,7 @@ func TestRouterManager_Get(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: server.URL, URL: server.URL,
@ -76,6 +77,7 @@ func TestRouterManager_Get(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: server.URL, URL: server.URL,
@ -114,6 +116,7 @@ func TestRouterManager_Get(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: server.URL, URL: server.URL,
@ -138,6 +141,7 @@ func TestRouterManager_Get(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: server.URL, URL: server.URL,
@ -179,6 +183,7 @@ func TestRouterManager_Get(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: server.URL, URL: server.URL,
@ -219,6 +224,7 @@ func TestRouterManager_Get(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service@provider-1": { "foo-service@provider-1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: server.URL, URL: server.URL,
@ -242,6 +248,7 @@ func TestRouterManager_Get(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service@provider-2": { "foo-service@provider-2": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: server.URL, URL: server.URL,
@ -266,6 +273,7 @@ func TestRouterManager_Get(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service@provider-1": { "foo-service@provider-1": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: server.URL, URL: server.URL,
@ -351,6 +359,7 @@ func TestRuntimeConfiguration(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1:8085", URL: "http://127.0.0.1:8085",
@ -385,6 +394,7 @@ func TestRuntimeConfiguration(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1", URL: "http://127.0.0.1",
@ -412,6 +422,7 @@ func TestRuntimeConfiguration(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1", URL: "http://127.0.0.1",
@ -439,6 +450,7 @@ func TestRuntimeConfiguration(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1", URL: "http://127.0.0.1",
@ -482,6 +494,7 @@ func TestRuntimeConfiguration(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1", URL: "http://127.0.0.1",
@ -522,6 +535,7 @@ func TestRuntimeConfiguration(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1", URL: "http://127.0.0.1",
@ -552,6 +566,7 @@ func TestRuntimeConfiguration(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1", URL: "http://127.0.0.1",
@ -582,6 +597,7 @@ func TestRuntimeConfiguration(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1", URL: "http://127.0.0.1",
@ -608,6 +624,7 @@ func TestRuntimeConfiguration(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1", URL: "http://127.0.0.1",
@ -641,6 +658,7 @@ func TestRuntimeConfiguration(t *testing.T) {
serviceConfig: map[string]*dynamic.Service{ serviceConfig: map[string]*dynamic.Service{
"foo-service": { "foo-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://127.0.0.1", URL: "http://127.0.0.1",
@ -730,6 +748,7 @@ func TestProviderOnMiddlewares(t *testing.T) {
Services: map[string]*dynamic.Service{ Services: map[string]*dynamic.Service{
"test@file": { "test@file": {
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{}, Servers: []dynamic.Server{},
}, },
}, },

View file

@ -0,0 +1,227 @@
package p2c
import (
"context"
"errors"
"math/rand"
"net/http"
"sync"
"sync/atomic"
"time"
"github.com/rs/zerolog/log"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/server/service/loadbalancer"
)
type namedHandler struct {
http.Handler
// name is the handler name.
name string
// inflight is the number of inflight requests.
// It is used to implement the "power-of-two-random-choices" algorithm.
inflight atomic.Int64
}
func (h *namedHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
h.inflight.Add(1)
defer h.inflight.Add(-1)
h.Handler.ServeHTTP(rw, req)
}
type rnd interface {
Intn(n int) int
}
// Balancer implements the power-of-two-random-choices algorithm for load balancing.
// The idea is to randomly select two of the available backends and choose the one with the fewest in-flight requests.
// This algorithm balances the load more effectively than a round-robin approach, while maintaining a constant time for the selection:
// The strategy also has more advantageous "herd" behavior than the "fewest connections" algorithm, especially when the load balancer
// doesn't have perfect knowledge of the global number of connections to the backend, for example, when running in a distributed fashion.
type Balancer struct {
wantsHealthCheck bool
handlersMu sync.RWMutex
handlers []*namedHandler
// status is a record of which child services of the Balancer are healthy, keyed
// by name of child service. A service is initially added to the map when it is
// created via Add, and it is later removed or added to the map as needed,
// through the SetStatus method.
status map[string]struct{}
// updaters is the list of hooks that are run (to update the Balancer
// parent(s)), whenever the Balancer status changes.
updaters []func(bool)
// fenced is the list of terminating yet still serving child services.
fenced map[string]struct{}
sticky *loadbalancer.Sticky
rand rnd
}
// New creates a new power-of-two-random-choices load balancer.
func New(stickyConfig *dynamic.Sticky, wantsHealthCheck bool) *Balancer {
balancer := &Balancer{
status: make(map[string]struct{}),
fenced: make(map[string]struct{}),
wantsHealthCheck: wantsHealthCheck,
rand: rand.New(rand.NewSource(time.Now().UnixNano())),
}
if stickyConfig != nil && stickyConfig.Cookie != nil {
balancer.sticky = loadbalancer.NewSticky(*stickyConfig.Cookie)
}
return balancer
}
// SetStatus sets on the balancer that its given child is now of the given
// status. balancerName is only needed for logging purposes.
func (b *Balancer) SetStatus(ctx context.Context, childName string, up bool) {
b.handlersMu.Lock()
defer b.handlersMu.Unlock()
upBefore := len(b.status) > 0
status := "DOWN"
if up {
status = "UP"
}
log.Ctx(ctx).Debug().Msgf("Setting status of %s to %v", childName, status)
if up {
b.status[childName] = struct{}{}
} else {
delete(b.status, childName)
}
upAfter := len(b.status) > 0
status = "DOWN"
if upAfter {
status = "UP"
}
// No Status Change
if upBefore == upAfter {
// We're still with the same status, no need to propagate
log.Ctx(ctx).Debug().Msgf("Still %s, no need to propagate", status)
return
}
// Status Change
log.Ctx(ctx).Debug().Msgf("Propagating new %s status", status)
for _, fn := range b.updaters {
fn(upAfter)
}
}
// RegisterStatusUpdater adds fn to the list of hooks that are run when the
// status of the Balancer changes.
// Not thread safe.
func (b *Balancer) RegisterStatusUpdater(fn func(up bool)) error {
if !b.wantsHealthCheck {
return errors.New("healthCheck not enabled in config for this weighted service")
}
b.updaters = append(b.updaters, fn)
return nil
}
var errNoAvailableServer = errors.New("no available server")
func (b *Balancer) nextServer() (*namedHandler, error) {
// We kept the same representation (map) as in the WRR strategy to improve maintainability.
// However, with the P2C strategy, we only need a slice of healthy servers.
b.handlersMu.RLock()
var healthy []*namedHandler
for _, h := range b.handlers {
if _, ok := b.status[h.name]; ok {
if _, fenced := b.fenced[h.name]; !fenced {
healthy = append(healthy, h)
}
}
}
b.handlersMu.RUnlock()
if len(healthy) == 0 {
return nil, errNoAvailableServer
}
// If there is only one healthy server, return it.
if len(healthy) == 1 {
return healthy[0], nil
}
// In order to not get the same backend twice, we make the second call to s.rand.IntN one fewer
// than the length of the slice. We then have to shift over the second index if it is equal or
// greater than the first index, wrapping round if needed.
n1, n2 := b.rand.Intn(len(healthy)), b.rand.Intn(len(healthy))
if n2 == n1 {
n2 = (n2 + 1) % len(healthy)
}
h1, h2 := healthy[n1], healthy[n2]
// Ensure h1 has fewer inflight requests than h2.
if h2.inflight.Load() < h1.inflight.Load() {
log.Debug().Msgf("Service selected by P2C: %s", h2.name)
return h2, nil
}
log.Debug().Msgf("Service selected by P2C: %s", h1.name)
return h1, nil
}
func (b *Balancer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if b.sticky != nil {
h, rewrite, err := b.sticky.StickyHandler(req)
if err != nil {
log.Error().Err(err).Msg("Error while getting sticky handler")
} else if h != nil {
if _, ok := b.status[h.Name]; ok {
if rewrite {
if err := b.sticky.WriteStickyCookie(rw, h.Name); err != nil {
log.Error().Err(err).Msg("Writing sticky cookie")
}
}
h.ServeHTTP(rw, req)
return
}
}
}
server, err := b.nextServer()
if err != nil {
if errors.Is(err, errNoAvailableServer) {
http.Error(rw, errNoAvailableServer.Error(), http.StatusServiceUnavailable)
} else {
http.Error(rw, err.Error(), http.StatusInternalServerError)
}
return
}
if b.sticky != nil {
if err := b.sticky.WriteStickyCookie(rw, server.name); err != nil {
log.Error().Err(err).Msg("Error while writing sticky cookie")
}
}
server.ServeHTTP(rw, req)
}
// AddServer adds a handler with a server.
func (b *Balancer) AddServer(name string, handler http.Handler, server dynamic.Server) {
h := &namedHandler{Handler: handler, name: name}
b.handlersMu.Lock()
b.handlers = append(b.handlers, h)
b.status[name] = struct{}{}
if server.Fenced {
b.fenced[name] = struct{}{}
}
b.handlersMu.Unlock()
if b.sticky != nil {
b.sticky.AddHandler(name, h)
}
}

View file

@ -0,0 +1,288 @@
package p2c
import (
"context"
"net/http"
"net/http/httptest"
"strconv"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
)
func TestP2C(t *testing.T) {
testCases := []struct {
desc string
handlers []*namedHandler
rand *mockRand
expectedHandler string
}{
{
desc: "one healthy handler",
handlers: testHandlers(0),
rand: nil,
expectedHandler: "0",
},
{
desc: "two handlers zero in flight",
handlers: testHandlers(0, 0),
rand: &mockRand{vals: []int{1, 0}},
expectedHandler: "1",
},
{
desc: "chooses lower of two",
handlers: testHandlers(0, 1),
rand: &mockRand{vals: []int{1, 0}},
expectedHandler: "0",
},
{
desc: "chooses lower of three",
handlers: testHandlers(10, 90, 40),
rand: &mockRand{vals: []int{1, 1}},
expectedHandler: "2",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
balancer := New(nil, false)
balancer.rand = test.rand
for _, h := range test.handlers {
balancer.handlers = append(balancer.handlers, h)
balancer.status[h.name] = struct{}{}
}
got, err := balancer.nextServer()
require.NoError(t, err)
assert.Equal(t, test.expectedHandler, got.name)
})
}
}
func TestSticky(t *testing.T) {
balancer := New(&dynamic.Sticky{
Cookie: &dynamic.Cookie{
Name: "test",
Secure: true,
HTTPOnly: true,
SameSite: "none",
MaxAge: 42,
Path: func(v string) *string { return &v }("/foo"),
},
}, false)
balancer.rand = &mockRand{vals: []int{1, 0}}
balancer.AddServer("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "first")
rw.WriteHeader(http.StatusOK)
}), dynamic.Server{})
balancer.AddServer("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "second")
rw.WriteHeader(http.StatusOK)
}), dynamic.Server{})
recorder := &responseRecorder{
ResponseRecorder: httptest.NewRecorder(),
save: map[string]int{},
cookies: make(map[string]*http.Cookie),
}
req := httptest.NewRequest(http.MethodGet, "/", nil)
for range 3 {
for _, cookie := range recorder.Result().Cookies() {
assert.NotContains(t, "first", cookie.Value)
assert.NotContains(t, "second", cookie.Value)
req.AddCookie(cookie)
}
recorder.ResponseRecorder = httptest.NewRecorder()
balancer.ServeHTTP(recorder, req)
}
assert.Equal(t, 0, recorder.save["first"])
assert.Equal(t, 3, recorder.save["second"])
assert.True(t, recorder.cookies["test"].HttpOnly)
assert.True(t, recorder.cookies["test"].Secure)
assert.Equal(t, http.SameSiteNoneMode, recorder.cookies["test"].SameSite)
assert.Equal(t, 42, recorder.cookies["test"].MaxAge)
assert.Equal(t, "/foo", recorder.cookies["test"].Path)
}
func TestSticky_Fallback(t *testing.T) {
balancer := New(&dynamic.Sticky{
Cookie: &dynamic.Cookie{Name: "test"},
}, false)
balancer.rand = &mockRand{vals: []int{1, 0}}
balancer.AddServer("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "first")
rw.WriteHeader(http.StatusOK)
}), dynamic.Server{})
balancer.AddServer("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "second")
rw.WriteHeader(http.StatusOK)
}), dynamic.Server{})
recorder := &responseRecorder{ResponseRecorder: httptest.NewRecorder(), save: map[string]int{}, cookies: make(map[string]*http.Cookie)}
req := httptest.NewRequest(http.MethodGet, "/", nil)
req.AddCookie(&http.Cookie{Name: "test", Value: "second"})
for range 3 {
recorder.ResponseRecorder = httptest.NewRecorder()
balancer.ServeHTTP(recorder, req)
}
assert.Equal(t, 0, recorder.save["first"])
assert.Equal(t, 3, recorder.save["second"])
}
// TestSticky_Fenced checks that fenced node receive traffic if their sticky cookie matches.
func TestSticky_Fenced(t *testing.T) {
balancer := New(&dynamic.Sticky{Cookie: &dynamic.Cookie{Name: "test"}}, false)
balancer.rand = &mockRand{vals: []int{1, 0, 1, 0}}
balancer.AddServer("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "first")
rw.WriteHeader(http.StatusOK)
}), dynamic.Server{})
balancer.AddServer("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "second")
rw.WriteHeader(http.StatusOK)
}), dynamic.Server{})
balancer.AddServer("fenced", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "fenced")
rw.WriteHeader(http.StatusOK)
}), dynamic.Server{Fenced: true})
recorder := &responseRecorder{ResponseRecorder: httptest.NewRecorder(), save: map[string]int{}, cookies: make(map[string]*http.Cookie)}
stickyReq := httptest.NewRequest(http.MethodGet, "/", nil)
stickyReq.AddCookie(&http.Cookie{Name: "test", Value: "fenced"})
req := httptest.NewRequest(http.MethodGet, "/", nil)
for range 2 {
recorder.ResponseRecorder = httptest.NewRecorder()
balancer.ServeHTTP(recorder, stickyReq)
balancer.ServeHTTP(recorder, req)
}
assert.Equal(t, 2, recorder.save["fenced"])
assert.Equal(t, 0, recorder.save["first"])
assert.Equal(t, 2, recorder.save["second"])
}
func TestBalancerPropagate(t *testing.T) {
balancer := New(nil, true)
balancer.AddServer("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "first")
rw.WriteHeader(http.StatusOK)
}), dynamic.Server{})
balancer.AddServer("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "second")
rw.WriteHeader(http.StatusOK)
}), dynamic.Server{})
var calls int
err := balancer.RegisterStatusUpdater(func(up bool) {
calls++
})
require.NoError(t, err)
recorder := httptest.NewRecorder()
balancer.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/", nil))
assert.Equal(t, http.StatusOK, recorder.Code)
// two gets downed, but balancer still up since first is still up.
balancer.SetStatus(context.Background(), "second", false)
assert.Equal(t, 0, calls)
recorder = httptest.NewRecorder()
balancer.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/", nil))
assert.Equal(t, http.StatusOK, recorder.Code)
assert.Equal(t, "first", recorder.Header().Get("server"))
// first gets downed, balancer is down.
balancer.SetStatus(context.Background(), "first", false)
assert.Equal(t, 1, calls)
recorder = httptest.NewRecorder()
balancer.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/", nil))
assert.Equal(t, http.StatusServiceUnavailable, recorder.Code)
// two gets up, balancer up.
balancer.SetStatus(context.Background(), "second", true)
assert.Equal(t, 2, calls)
recorder = httptest.NewRecorder()
balancer.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/", nil))
assert.Equal(t, http.StatusOK, recorder.Code)
assert.Equal(t, "second", recorder.Header().Get("server"))
}
func TestBalancerAllServersFenced(t *testing.T) {
balancer := New(nil, false)
balancer.AddServer("test", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {}), dynamic.Server{Fenced: true})
balancer.AddServer("test2", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {}), dynamic.Server{Fenced: true})
recorder := httptest.NewRecorder()
balancer.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/", nil))
assert.Equal(t, http.StatusServiceUnavailable, recorder.Result().StatusCode)
}
type responseRecorder struct {
*httptest.ResponseRecorder
save map[string]int
sequence []string
status []int
cookies map[string]*http.Cookie
}
func (r *responseRecorder) WriteHeader(statusCode int) {
r.save[r.Header().Get("server")]++
r.sequence = append(r.sequence, r.Header().Get("server"))
r.status = append(r.status, statusCode)
for _, cookie := range r.Result().Cookies() {
r.cookies[cookie.Name] = cookie
}
r.ResponseRecorder.WriteHeader(statusCode)
}
type mockRand struct {
vals []int
calls int
}
func (m *mockRand) Intn(int) int {
defer func() {
m.calls++
}()
return m.vals[m.calls]
}
func testHandlers(inflights ...int) []*namedHandler {
var out []*namedHandler
for i, inflight := range inflights {
h := &namedHandler{
name: strconv.Itoa(i),
}
h.inflight.Store(int64(inflight))
out = append(out, h)
}
return out
}

View file

@ -0,0 +1,179 @@
package loadbalancer
import (
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"hash/fnv"
"net/http"
"strconv"
"sync"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
)
// NamedHandler is a http.Handler with a name.
type NamedHandler struct {
http.Handler
Name string
}
// stickyCookie represents a sticky cookie.
type stickyCookie struct {
name string
secure bool
httpOnly bool
sameSite http.SameSite
maxAge int
path string
domain string
}
// Sticky ensures that client consistently interacts with the same HTTP handler by adding a sticky cookie to the response.
// This cookie allows subsequent requests from the same client to be routed to the same handler,
// enabling session persistence across multiple requests.
type Sticky struct {
// cookie is the sticky cookie configuration.
cookie *stickyCookie
// References all the handlers by name and also by the hashed value of the name.
handlersMu sync.RWMutex
hashMap map[string]string
stickyMap map[string]*NamedHandler
compatibilityStickyMap map[string]*NamedHandler
}
// NewSticky creates a new Sticky instance.
func NewSticky(cookieConfig dynamic.Cookie) *Sticky {
cookie := &stickyCookie{
name: cookieConfig.Name,
secure: cookieConfig.Secure,
httpOnly: cookieConfig.HTTPOnly,
sameSite: convertSameSite(cookieConfig.SameSite),
maxAge: cookieConfig.MaxAge,
path: "/",
domain: cookieConfig.Domain,
}
if cookieConfig.Path != nil {
cookie.path = *cookieConfig.Path
}
return &Sticky{
cookie: cookie,
hashMap: make(map[string]string),
stickyMap: make(map[string]*NamedHandler),
compatibilityStickyMap: make(map[string]*NamedHandler),
}
}
// AddHandler adds a http.Handler to the sticky pool.
func (s *Sticky) AddHandler(name string, h http.Handler) {
s.handlersMu.Lock()
defer s.handlersMu.Unlock()
sha256HashedName := sha256Hash(name)
s.hashMap[name] = sha256HashedName
handler := &NamedHandler{
Handler: h,
Name: name,
}
s.stickyMap[sha256HashedName] = handler
s.compatibilityStickyMap[name] = handler
hashedName := fnvHash(name)
s.compatibilityStickyMap[hashedName] = handler
// server.URL was fnv hashed in service.Manager
// so we can have "double" fnv hash in already existing cookies
hashedName = fnvHash(hashedName)
s.compatibilityStickyMap[hashedName] = handler
}
// StickyHandler returns the NamedHandler corresponding to the sticky cookie if one.
// It also returns a boolean which indicates if the sticky cookie has to be overwritten because it uses a deprecated hash algorithm.
func (s *Sticky) StickyHandler(req *http.Request) (*NamedHandler, bool, error) {
cookie, err := req.Cookie(s.cookie.name)
if err != nil && errors.Is(err, http.ErrNoCookie) {
return nil, false, nil
}
if err != nil {
return nil, false, fmt.Errorf("reading cookie: %w", err)
}
s.handlersMu.RLock()
handler, ok := s.stickyMap[cookie.Value]
s.handlersMu.RUnlock()
if ok && handler != nil {
return handler, false, nil
}
s.handlersMu.RLock()
handler, ok = s.compatibilityStickyMap[cookie.Value]
s.handlersMu.RUnlock()
return handler, ok, nil
}
// WriteStickyCookie writes a sticky cookie to the response to stick the client to the given handler name.
func (s *Sticky) WriteStickyCookie(rw http.ResponseWriter, name string) error {
s.handlersMu.RLock()
hash, ok := s.hashMap[name]
s.handlersMu.RUnlock()
if !ok {
return fmt.Errorf("no hash found for handler named %s", name)
}
cookie := &http.Cookie{
Name: s.cookie.name,
Value: hash,
Path: s.cookie.path,
Domain: s.cookie.domain,
HttpOnly: s.cookie.httpOnly,
Secure: s.cookie.secure,
SameSite: s.cookie.sameSite,
MaxAge: s.cookie.maxAge,
}
http.SetCookie(rw, cookie)
return nil
}
func convertSameSite(sameSite string) http.SameSite {
switch sameSite {
case "none":
return http.SameSiteNoneMode
case "lax":
return http.SameSiteLaxMode
case "strict":
return http.SameSiteStrictMode
default:
return http.SameSiteDefaultMode
}
}
// fnvHash returns the FNV-64 hash of the input string.
func fnvHash(input string) string {
hasher := fnv.New64()
// We purposely ignore the error because the implementation always returns nil.
_, _ = hasher.Write([]byte(input))
return strconv.FormatUint(hasher.Sum64(), 16)
}
// sha256 returns the SHA-256 hash, truncated to 16 characters, of the input string.
func sha256Hash(input string) string {
hash := sha256.New()
// We purposely ignore the error because the implementation always returns nil.
_, _ = hash.Write([]byte(input))
hashedInput := hex.EncodeToString(hash.Sum(nil))
if len(hashedInput) < 16 {
return hashedInput
}
return hashedInput[:16]
}

View file

@ -0,0 +1,138 @@
package loadbalancer
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
)
func pointer[T any](v T) *T { return &v }
func TestSticky_StickyHandler(t *testing.T) {
testCases := []struct {
desc string
handlers []string
cookies []*http.Cookie
wantHandler string
wantRewrite bool
}{
{
desc: "No previous cookie",
handlers: []string{"first"},
wantHandler: "",
wantRewrite: false,
},
{
desc: "Wrong previous cookie",
handlers: []string{"first"},
cookies: []*http.Cookie{
{Name: "test", Value: sha256Hash("foo")},
},
wantHandler: "",
wantRewrite: false,
},
{
desc: "Sha256 previous cookie",
handlers: []string{"first", "second"},
cookies: []*http.Cookie{
{Name: "test", Value: sha256Hash("first")},
},
wantHandler: "first",
wantRewrite: false,
},
{
desc: "Raw previous cookie",
handlers: []string{"first", "second"},
cookies: []*http.Cookie{
{Name: "test", Value: "first"},
},
wantHandler: "first",
wantRewrite: true,
},
{
desc: "Fnv previous cookie",
handlers: []string{"first", "second"},
cookies: []*http.Cookie{
{Name: "test", Value: fnvHash("first")},
},
wantHandler: "first",
wantRewrite: true,
},
{
desc: "Double fnv previous cookie",
handlers: []string{"first", "second"},
cookies: []*http.Cookie{
{Name: "test", Value: fnvHash("first")},
},
wantHandler: "first",
wantRewrite: true,
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
sticky := NewSticky(dynamic.Cookie{Name: "test"})
for _, handler := range test.handlers {
sticky.AddHandler(handler, http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {}))
}
req := httptest.NewRequest(http.MethodGet, "/", nil)
for _, cookie := range test.cookies {
req.AddCookie(cookie)
}
h, rewrite, err := sticky.StickyHandler(req)
require.NoError(t, err)
if test.wantHandler != "" {
assert.NotNil(t, h)
assert.Equal(t, test.wantHandler, h.Name)
} else {
assert.Nil(t, h)
}
assert.Equal(t, test.wantRewrite, rewrite)
})
}
}
func TestSticky_WriteStickyCookie(t *testing.T) {
sticky := NewSticky(dynamic.Cookie{
Name: "test",
Secure: true,
HTTPOnly: true,
SameSite: "none",
MaxAge: 42,
Path: pointer("/foo"),
Domain: "foo.com",
})
// Should return an error if the handler does not exist.
res := httptest.NewRecorder()
require.Error(t, sticky.WriteStickyCookie(res, "first"))
// Should write the sticky cookie and use the sha256 hash.
sticky.AddHandler("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {}))
res = httptest.NewRecorder()
require.NoError(t, sticky.WriteStickyCookie(res, "first"))
assert.Len(t, res.Result().Cookies(), 1)
cookie := res.Result().Cookies()[0]
assert.Equal(t, sha256Hash("first"), cookie.Value)
assert.Equal(t, "test", cookie.Name)
assert.True(t, cookie.Secure)
assert.True(t, cookie.HttpOnly)
assert.Equal(t, http.SameSiteNoneMode, cookie.SameSite)
assert.Equal(t, 42, cookie.MaxAge)
assert.Equal(t, "/foo", cookie.Path)
assert.Equal(t, "foo.com", cookie.Domain)
}

View file

@ -3,64 +3,32 @@ package wrr
import ( import (
"container/heap" "container/heap"
"context" "context"
"crypto/sha256"
"encoding/hex"
"errors" "errors"
"hash/fnv"
"net/http" "net/http"
"strconv"
"sync" "sync"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/server/service/loadbalancer"
) )
type namedHandler struct { type namedHandler struct {
http.Handler http.Handler
name string name string
hashedName string
weight float64 weight float64
deadline float64 deadline float64
} }
type stickyCookie struct {
name string
secure bool
httpOnly bool
sameSite string
maxAge int
path string
domain string
}
func convertSameSite(sameSite string) http.SameSite {
switch sameSite {
case "none":
return http.SameSiteNoneMode
case "lax":
return http.SameSiteLaxMode
case "strict":
return http.SameSiteStrictMode
default:
return http.SameSiteDefaultMode
}
}
// Balancer is a WeightedRoundRobin load balancer based on Earliest Deadline First (EDF). // Balancer is a WeightedRoundRobin load balancer based on Earliest Deadline First (EDF).
// (https://en.wikipedia.org/wiki/Earliest_deadline_first_scheduling) // (https://en.wikipedia.org/wiki/Earliest_deadline_first_scheduling)
// Each pick from the schedule has the earliest deadline entry selected. // Each pick from the schedule has the earliest deadline entry selected.
// Entries have deadlines set at currentDeadline + 1 / weight, // Entries have deadlines set at currentDeadline + 1 / weight,
// providing weighted round-robin behavior with floating point weights and an O(log n) pick time. // providing weighted round-robin behavior with floating point weights and an O(log n) pick time.
type Balancer struct { type Balancer struct {
stickyCookie *stickyCookie
wantsHealthCheck bool wantsHealthCheck bool
handlersMu sync.RWMutex handlersMu sync.RWMutex
// References all the handlers by name and also by the hashed value of the name.
stickyMap map[string]*namedHandler
compatibilityStickyMap map[string]*namedHandler
handlers []*namedHandler handlers []*namedHandler
curDeadline float64
// status is a record of which child services of the Balancer are healthy, keyed // status is a record of which child services of the Balancer are healthy, keyed
// by name of child service. A service is initially added to the map when it is // by name of child service. A service is initially added to the map when it is
// created via Add, and it is later removed or added to the map as needed, // created via Add, and it is later removed or added to the map as needed,
@ -71,31 +39,21 @@ type Balancer struct {
updaters []func(bool) updaters []func(bool)
// fenced is the list of terminating yet still serving child services. // fenced is the list of terminating yet still serving child services.
fenced map[string]struct{} fenced map[string]struct{}
sticky *loadbalancer.Sticky
curDeadline float64
} }
// New creates a new load balancer. // New creates a new load balancer.
func New(sticky *dynamic.Sticky, wantHealthCheck bool) *Balancer { func New(sticky *dynamic.Sticky, wantsHealthCheck bool) *Balancer {
balancer := &Balancer{ balancer := &Balancer{
status: make(map[string]struct{}), status: make(map[string]struct{}),
fenced: make(map[string]struct{}), fenced: make(map[string]struct{}),
wantsHealthCheck: wantHealthCheck, wantsHealthCheck: wantsHealthCheck,
} }
if sticky != nil && sticky.Cookie != nil { if sticky != nil && sticky.Cookie != nil {
balancer.stickyCookie = &stickyCookie{ balancer.sticky = loadbalancer.NewSticky(*sticky.Cookie)
name: sticky.Cookie.Name,
secure: sticky.Cookie.Secure,
httpOnly: sticky.Cookie.HTTPOnly,
sameSite: sticky.Cookie.SameSite,
maxAge: sticky.Cookie.MaxAge,
path: "/",
domain: sticky.Cookie.Domain,
}
if sticky.Cookie.Path != nil {
balancer.stickyCookie.path = *sticky.Cookie.Path
}
balancer.stickyMap = make(map[string]*namedHandler)
balancer.compatibilityStickyMap = make(map[string]*namedHandler)
} }
return balancer return balancer
@ -216,76 +174,47 @@ func (b *Balancer) nextServer() (*namedHandler, error) {
return handler, nil return handler, nil
} }
func (b *Balancer) ServeHTTP(w http.ResponseWriter, req *http.Request) { func (b *Balancer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if b.stickyCookie != nil { if b.sticky != nil {
cookie, err := req.Cookie(b.stickyCookie.name) h, rewrite, err := b.sticky.StickyHandler(req)
if err != nil {
if err != nil && !errors.Is(err, http.ErrNoCookie) { log.Error().Err(err).Msg("Error while getting sticky handler")
log.Warn().Err(err).Msg("Error while reading cookie") } else if h != nil {
if _, ok := b.status[h.Name]; ok {
if rewrite {
if err := b.sticky.WriteStickyCookie(rw, h.Name); err != nil {
log.Error().Err(err).Msg("Writing sticky cookie")
}
} }
if err == nil && cookie != nil { h.ServeHTTP(rw, req)
b.handlersMu.RLock()
handler, ok := b.stickyMap[cookie.Value]
b.handlersMu.RUnlock()
if ok && handler != nil {
b.handlersMu.RLock()
_, isHealthy := b.status[handler.name]
b.handlersMu.RUnlock()
if isHealthy {
handler.ServeHTTP(w, req)
return return
} }
} }
b.handlersMu.RLock()
handler, ok = b.compatibilityStickyMap[cookie.Value]
b.handlersMu.RUnlock()
if ok && handler != nil {
b.handlersMu.RLock()
_, isHealthy := b.status[handler.name]
b.handlersMu.RUnlock()
if isHealthy {
b.writeStickyCookie(w, handler)
handler.ServeHTTP(w, req)
return
}
}
}
} }
server, err := b.nextServer() server, err := b.nextServer()
if err != nil { if err != nil {
if errors.Is(err, errNoAvailableServer) { if errors.Is(err, errNoAvailableServer) {
http.Error(w, errNoAvailableServer.Error(), http.StatusServiceUnavailable) http.Error(rw, errNoAvailableServer.Error(), http.StatusServiceUnavailable)
} else { } else {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(rw, err.Error(), http.StatusInternalServerError)
} }
return return
} }
if b.stickyCookie != nil { if b.sticky != nil {
b.writeStickyCookie(w, server) if err := b.sticky.WriteStickyCookie(rw, server.name); err != nil {
log.Error().Err(err).Msg("Error while writing sticky cookie")
}
} }
server.ServeHTTP(w, req) server.ServeHTTP(rw, req)
} }
func (b *Balancer) writeStickyCookie(w http.ResponseWriter, handler *namedHandler) { // AddServer adds a handler with a server.
cookie := &http.Cookie{ func (b *Balancer) AddServer(name string, handler http.Handler, server dynamic.Server) {
Name: b.stickyCookie.name, b.Add(name, handler, server.Weight, server.Fenced)
Value: handler.hashedName,
Path: b.stickyCookie.path,
HttpOnly: b.stickyCookie.httpOnly,
Secure: b.stickyCookie.secure,
SameSite: convertSameSite(b.stickyCookie.sameSite),
MaxAge: b.stickyCookie.maxAge,
Domain: b.stickyCookie.domain,
}
http.SetCookie(w, cookie)
} }
// Add adds a handler. // Add adds a handler.
@ -309,41 +238,9 @@ func (b *Balancer) Add(name string, handler http.Handler, weight *int, fenced bo
if fenced { if fenced {
b.fenced[name] = struct{}{} b.fenced[name] = struct{}{}
} }
if b.stickyCookie != nil {
sha256HashedName := sha256Hash(name)
h.hashedName = sha256HashedName
b.stickyMap[sha256HashedName] = h
b.compatibilityStickyMap[name] = h
hashedName := fnvHash(name)
b.compatibilityStickyMap[hashedName] = h
// server.URL was fnv hashed in service.Manager
// so we can have "double" fnv hash in already existing cookies
hashedName = fnvHash(hashedName)
b.compatibilityStickyMap[hashedName] = h
}
b.handlersMu.Unlock() b.handlersMu.Unlock()
}
func fnvHash(input string) string { if b.sticky != nil {
hasher := fnv.New64() b.sticky.AddHandler(name, handler)
// We purposely ignore the error because the implementation always returns nil.
_, _ = hasher.Write([]byte(input))
return strconv.FormatUint(hasher.Sum64(), 16)
}
func sha256Hash(input string) string {
hash := sha256.New()
// We purposely ignore the error because the implementation always returns nil.
_, _ = hash.Write([]byte(input))
hashedInput := hex.EncodeToString(hash.Sum(nil))
if len(hashedInput) < 16 {
return hashedInput
} }
return hashedInput[:16]
} }

View file

@ -10,6 +10,10 @@ import (
"github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/config/dynamic"
) )
type key string
const serviceName key = "serviceName"
func pointer[T any](v T) *T { return &v } func pointer[T any](v T) *T { return &v }
func TestBalancer(t *testing.T) { func TestBalancer(t *testing.T) {
@ -61,10 +65,6 @@ func TestBalancerOneServerZeroWeight(t *testing.T) {
assert.Equal(t, 3, recorder.save["first"]) assert.Equal(t, 3, recorder.save["first"])
} }
type key string
const serviceName key = "serviceName"
func TestBalancerNoServiceUp(t *testing.T) { func TestBalancerNoServiceUp(t *testing.T) {
balancer := New(nil, false) balancer := New(nil, false)
@ -264,8 +264,8 @@ func TestSticky(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/", nil) req := httptest.NewRequest(http.MethodGet, "/", nil)
for range 3 { for range 3 {
for _, cookie := range recorder.Result().Cookies() { for _, cookie := range recorder.Result().Cookies() {
assert.NotContains(t, "test=first", cookie.Value) assert.NotContains(t, "first", cookie.Value)
assert.NotContains(t, "test=second", cookie.Value) assert.NotContains(t, "second", cookie.Value)
req.AddCookie(cookie) req.AddCookie(cookie)
} }
recorder.ResponseRecorder = httptest.NewRecorder() recorder.ResponseRecorder = httptest.NewRecorder()
@ -283,7 +283,7 @@ func TestSticky(t *testing.T) {
assert.Equal(t, "/foo", recorder.cookies["test"].Path) assert.Equal(t, "/foo", recorder.cookies["test"].Path)
} }
func TestSticky_FallBack(t *testing.T) { func TestSticky_Fallback(t *testing.T) {
balancer := New(&dynamic.Sticky{ balancer := New(&dynamic.Sticky{
Cookie: &dynamic.Cookie{Name: "test"}, Cookie: &dynamic.Cookie{Name: "test"},
}, false) }, false)
@ -312,6 +312,44 @@ func TestSticky_FallBack(t *testing.T) {
assert.Equal(t, 3, recorder.save["second"]) assert.Equal(t, 3, recorder.save["second"])
} }
// TestSticky_Fenced checks that fenced node receive traffic if their sticky cookie matches.
func TestSticky_Fenced(t *testing.T) {
balancer := New(&dynamic.Sticky{Cookie: &dynamic.Cookie{Name: "test"}}, false)
balancer.Add("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "first")
rw.WriteHeader(http.StatusOK)
}), pointer(1), false)
balancer.Add("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "second")
rw.WriteHeader(http.StatusOK)
}), pointer(1), false)
balancer.Add("fenced", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "fenced")
rw.WriteHeader(http.StatusOK)
}), pointer(1), true)
recorder := &responseRecorder{ResponseRecorder: httptest.NewRecorder(), save: map[string]int{}, cookies: make(map[string]*http.Cookie)}
stickyReq := httptest.NewRequest(http.MethodGet, "/", nil)
stickyReq.AddCookie(&http.Cookie{Name: "test", Value: "fenced"})
req := httptest.NewRequest(http.MethodGet, "/", nil)
for range 4 {
recorder.ResponseRecorder = httptest.NewRecorder()
balancer.ServeHTTP(recorder, stickyReq)
balancer.ServeHTTP(recorder, req)
}
assert.Equal(t, 4, recorder.save["fenced"])
assert.Equal(t, 2, recorder.save["first"])
assert.Equal(t, 2, recorder.save["second"])
}
// TestBalancerBias makes sure that the WRR algorithm spreads elements evenly right from the start, // TestBalancerBias makes sure that the WRR algorithm spreads elements evenly right from the start,
// and that it does not "over-favor" the high-weighted ones with a biased start-up regime. // and that it does not "over-favor" the high-weighted ones with a biased start-up regime.
func TestBalancerBias(t *testing.T) { func TestBalancerBias(t *testing.T) {
@ -355,137 +393,3 @@ func (r *responseRecorder) WriteHeader(statusCode int) {
} }
r.ResponseRecorder.WriteHeader(statusCode) r.ResponseRecorder.WriteHeader(statusCode)
} }
// TestSticky_Fenced checks that fenced node receive traffic if their sticky cookie matches.
func TestSticky_Fenced(t *testing.T) {
balancer := New(&dynamic.Sticky{Cookie: &dynamic.Cookie{Name: "test"}}, false)
balancer.Add("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "first")
rw.WriteHeader(http.StatusOK)
}), pointer(1), false)
balancer.Add("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "second")
rw.WriteHeader(http.StatusOK)
}), pointer(1), false)
balancer.Add("fenced", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("server", "fenced")
rw.WriteHeader(http.StatusOK)
}), pointer(1), true)
recorder := &responseRecorder{ResponseRecorder: httptest.NewRecorder(), save: map[string]int{}, cookies: make(map[string]*http.Cookie)}
stickyReq := httptest.NewRequest(http.MethodGet, "/", nil)
stickyReq.AddCookie(&http.Cookie{Name: "test", Value: "fenced"})
req := httptest.NewRequest(http.MethodGet, "/", nil)
for range 4 {
recorder.ResponseRecorder = httptest.NewRecorder()
balancer.ServeHTTP(recorder, stickyReq)
balancer.ServeHTTP(recorder, req)
}
assert.Equal(t, 4, recorder.save["fenced"])
assert.Equal(t, 2, recorder.save["first"])
assert.Equal(t, 2, recorder.save["second"])
}
func TestStickyWithCompatibility(t *testing.T) {
testCases := []struct {
desc string
servers []string
cookies []*http.Cookie
expectedCookies []*http.Cookie
expectedServer string
}{
{
desc: "No previous cookie",
servers: []string{"first"},
expectedServer: "first",
expectedCookies: []*http.Cookie{
{Name: "test", Value: sha256Hash("first")},
},
},
{
desc: "Sha256 previous cookie",
servers: []string{"first", "second"},
cookies: []*http.Cookie{
{Name: "test", Value: sha256Hash("first")},
},
expectedServer: "first",
expectedCookies: []*http.Cookie{},
},
{
desc: "Raw previous cookie",
servers: []string{"first", "second"},
cookies: []*http.Cookie{
{Name: "test", Value: "first"},
},
expectedServer: "first",
expectedCookies: []*http.Cookie{
{Name: "test", Value: sha256Hash("first")},
},
},
{
desc: "Fnv previous cookie",
servers: []string{"first", "second"},
cookies: []*http.Cookie{
{Name: "test", Value: fnvHash("first")},
},
expectedServer: "first",
expectedCookies: []*http.Cookie{
{Name: "test", Value: sha256Hash("first")},
},
},
{
desc: "Double fnv previous cookie",
servers: []string{"first", "second"},
cookies: []*http.Cookie{
{Name: "test", Value: fnvHash(fnvHash("first"))},
},
expectedServer: "first",
expectedCookies: []*http.Cookie{
{Name: "test", Value: sha256Hash("first")},
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
balancer := New(&dynamic.Sticky{Cookie: &dynamic.Cookie{Name: "test"}}, false)
for _, server := range test.servers {
balancer.Add(server, http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(http.StatusOK)
_, _ = rw.Write([]byte(server))
}), pointer(1), false)
}
// Do it twice, to be sure it's not just the luck.
for range 2 {
req := httptest.NewRequest(http.MethodGet, "/", nil)
for _, cookie := range test.cookies {
req.AddCookie(cookie)
}
recorder := &responseRecorder{ResponseRecorder: httptest.NewRecorder(), save: map[string]int{}, cookies: make(map[string]*http.Cookie)}
balancer.ServeHTTP(recorder, req)
assert.Equal(t, test.expectedServer, recorder.Body.String())
assert.Len(t, recorder.cookies, len(test.expectedCookies))
for _, cookie := range test.expectedCookies {
assert.Equal(t, cookie.Value, recorder.cookies[cookie.Name].Value)
}
}
})
}
}

View file

@ -29,6 +29,7 @@ import (
"github.com/traefik/traefik/v3/pkg/server/provider" "github.com/traefik/traefik/v3/pkg/server/provider"
"github.com/traefik/traefik/v3/pkg/server/service/loadbalancer/failover" "github.com/traefik/traefik/v3/pkg/server/service/loadbalancer/failover"
"github.com/traefik/traefik/v3/pkg/server/service/loadbalancer/mirror" "github.com/traefik/traefik/v3/pkg/server/service/loadbalancer/mirror"
"github.com/traefik/traefik/v3/pkg/server/service/loadbalancer/p2c"
"github.com/traefik/traefik/v3/pkg/server/service/loadbalancer/wrr" "github.com/traefik/traefik/v3/pkg/server/service/loadbalancer/wrr"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
) )
@ -304,6 +305,13 @@ func (m *Manager) getServiceHandler(ctx context.Context, service dynamic.WRRServ
} }
} }
type serverBalancer interface {
http.Handler
healthcheck.StatusSetter
AddServer(name string, handler http.Handler, server dynamic.Server)
}
func (m *Manager) getLoadBalancerServiceHandler(ctx context.Context, serviceName string, info *runtime.ServiceInfo) (http.Handler, error) { func (m *Manager) getLoadBalancerServiceHandler(ctx context.Context, serviceName string, info *runtime.ServiceInfo) (http.Handler, error) {
service := info.LoadBalancer service := info.LoadBalancer
@ -330,7 +338,18 @@ func (m *Manager) getLoadBalancerServiceHandler(ctx context.Context, serviceName
passHostHeader = *service.PassHostHeader passHostHeader = *service.PassHostHeader
} }
lb := wrr.New(service.Sticky, service.HealthCheck != nil) var lb serverBalancer
switch service.Strategy {
// Here we are handling the empty value to comply with providers that are not applying defaults (e.g. REST provider)
// TODO: remove this when all providers apply default values.
case dynamic.BalancerStrategyWRR, "":
lb = wrr.New(service.Sticky, service.HealthCheck != nil)
case dynamic.BalancerStrategyP2C:
lb = p2c.New(service.Sticky, service.HealthCheck != nil)
default:
return nil, fmt.Errorf("unsupported load-balancer strategy %q", service.Strategy)
}
healthCheckTargets := make(map[string]*url.URL) healthCheckTargets := make(map[string]*url.URL)
for i, server := range shuffle(service.Servers, m.rand) { for i, server := range shuffle(service.Servers, m.rand) {
@ -385,7 +404,7 @@ func (m *Manager) getLoadBalancerServiceHandler(ctx context.Context, serviceName
proxy, _ = capture.Wrap(proxy) proxy, _ = capture.Wrap(proxy)
} }
lb.Add(server.URL, proxy, server.Weight, server.Fenced) lb.AddServer(server.URL, proxy, server)
// servers are considered UP by default. // servers are considered UP by default.
info.UpdateServerStatus(target.String(), runtime.StatusUp) info.UpdateServerStatus(target.String(), runtime.StatusUp)

View file

@ -38,6 +38,7 @@ func TestGetLoadBalancer(t *testing.T) {
desc: "Fails when provided an invalid URL", desc: "Fails when provided an invalid URL",
serviceName: "test", serviceName: "test",
service: &dynamic.ServersLoadBalancer{ service: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: ":", URL: ":",
@ -50,7 +51,9 @@ func TestGetLoadBalancer(t *testing.T) {
{ {
desc: "Succeeds when there are no servers", desc: "Succeeds when there are no servers",
serviceName: "test", serviceName: "test",
service: &dynamic.ServersLoadBalancer{}, service: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
},
fwd: &forwarderMock{}, fwd: &forwarderMock{},
expectError: false, expectError: false,
}, },
@ -58,6 +61,7 @@ func TestGetLoadBalancer(t *testing.T) {
desc: "Succeeds when sticky.cookie is set", desc: "Succeeds when sticky.cookie is set",
serviceName: "test", serviceName: "test",
service: &dynamic.ServersLoadBalancer{ service: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}}, Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}},
}, },
fwd: &forwarderMock{}, fwd: &forwarderMock{},
@ -140,6 +144,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
desc: "Load balances between the two servers", desc: "Load balances between the two servers",
serviceName: "test", serviceName: "test",
service: &dynamic.ServersLoadBalancer{ service: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: boolPtr(true), PassHostHeader: boolPtr(true),
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
@ -165,6 +170,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
desc: "StatusBadGateway when the server is not reachable", desc: "StatusBadGateway when the server is not reachable",
serviceName: "test", serviceName: "test",
service: &dynamic.ServersLoadBalancer{ service: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: "http://foo", URL: "http://foo",
@ -181,6 +187,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
desc: "ServiceUnavailable when no servers are available", desc: "ServiceUnavailable when no servers are available",
serviceName: "test", serviceName: "test",
service: &dynamic.ServersLoadBalancer{ service: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{}, Servers: []dynamic.Server{},
}, },
expected: []ExpectedResult{ expected: []ExpectedResult{
@ -193,6 +200,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
desc: "Always call the same server when sticky.cookie is true", desc: "Always call the same server when sticky.cookie is true",
serviceName: "test", serviceName: "test",
service: &dynamic.ServersLoadBalancer{ service: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}}, Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}},
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
@ -216,6 +224,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
desc: "Sticky Cookie's options set correctly", desc: "Sticky Cookie's options set correctly",
serviceName: "test", serviceName: "test",
service: &dynamic.ServersLoadBalancer{ service: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{HTTPOnly: true, Secure: true}}, Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{HTTPOnly: true, Secure: true}},
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
@ -236,6 +245,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
desc: "PassHost passes the host instead of the IP", desc: "PassHost passes the host instead of the IP",
serviceName: "test", serviceName: "test",
service: &dynamic.ServersLoadBalancer{ service: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}}, Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}},
PassHostHeader: pointer(true), PassHostHeader: pointer(true),
Servers: []dynamic.Server{ Servers: []dynamic.Server{
@ -255,6 +265,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
desc: "PassHost doesn't pass the host instead of the IP", desc: "PassHost doesn't pass the host instead of the IP",
serviceName: "test", serviceName: "test",
service: &dynamic.ServersLoadBalancer{ service: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
PassHostHeader: pointer(false), PassHostHeader: pointer(false),
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}}, Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}},
Servers: []dynamic.Server{ Servers: []dynamic.Server{
@ -274,6 +285,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
desc: "No user-agent", desc: "No user-agent",
serviceName: "test", serviceName: "test",
service: &dynamic.ServersLoadBalancer{ service: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: hasNoUserAgent.URL, URL: hasNoUserAgent.URL,
@ -291,6 +303,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
serviceName: "test", serviceName: "test",
userAgent: "foobar", userAgent: "foobar",
service: &dynamic.ServersLoadBalancer{ service: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: hasUserAgent.URL, URL: hasUserAgent.URL,
@ -379,6 +392,7 @@ func Test1xxResponses(t *testing.T) {
info := &runtime.ServiceInfo{ info := &runtime.ServiceInfo{
Service: &dynamic.Service{ Service: &dynamic.Service{
LoadBalancer: &dynamic.ServersLoadBalancer{ LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{ Servers: []dynamic.Server{
{ {
URL: backend.URL, URL: backend.URL,
@ -466,7 +480,9 @@ func TestManager_ServiceBuilders(t *testing.T) {
manager := NewManager(map[string]*runtime.ServiceInfo{ manager := NewManager(map[string]*runtime.ServiceInfo{
"test@test": { "test@test": {
Service: &dynamic.Service{ Service: &dynamic.Service{
LoadBalancer: &dynamic.ServersLoadBalancer{}, LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
},
}, },
}, },
}, nil, nil, &TransportManager{ }, nil, nil, &TransportManager{
@ -505,7 +521,9 @@ func TestManager_Build(t *testing.T) {
configs: map[string]*runtime.ServiceInfo{ configs: map[string]*runtime.ServiceInfo{
"serviceName": { "serviceName": {
Service: &dynamic.Service{ Service: &dynamic.Service{
LoadBalancer: &dynamic.ServersLoadBalancer{}, LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
},
}, },
}, },
}, },
@ -516,7 +534,9 @@ func TestManager_Build(t *testing.T) {
configs: map[string]*runtime.ServiceInfo{ configs: map[string]*runtime.ServiceInfo{
"serviceName@provider-1": { "serviceName@provider-1": {
Service: &dynamic.Service{ Service: &dynamic.Service{
LoadBalancer: &dynamic.ServersLoadBalancer{}, LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
},
}, },
}, },
}, },
@ -527,7 +547,9 @@ func TestManager_Build(t *testing.T) {
configs: map[string]*runtime.ServiceInfo{ configs: map[string]*runtime.ServiceInfo{
"serviceName@provider-1": { "serviceName@provider-1": {
Service: &dynamic.Service{ Service: &dynamic.Service{
LoadBalancer: &dynamic.ServersLoadBalancer{}, LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
},
}, },
}, },
}, },

View file

@ -70,6 +70,8 @@ func WithLoadBalancerServices(opts ...func(service *dynamic.ServersLoadBalancer)
c.Services = make(map[string]*dynamic.Service) c.Services = make(map[string]*dynamic.Service)
for _, opt := range opts { for _, opt := range opts {
b := &dynamic.ServersLoadBalancer{} b := &dynamic.ServersLoadBalancer{}
b.SetDefaults()
name := opt(b) name := opt(b)
c.Services[name] = &dynamic.Service{ c.Services[name] = &dynamic.Service{
LoadBalancer: b, LoadBalancer: b,