mirror of
https://github.com/traefik/traefik.git
synced 2025-05-05 15:33:01 +00:00
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:
parent
550d96ea67
commit
9e029a84c4
@ -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.
|
||||
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.
|
||||
|
@ -221,6 +221,7 @@
|
||||
- "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.secure=true"
|
||||
- "traefik.http.services.service02.loadbalancer.strategy=foobar"
|
||||
- "traefik.http.services.service02.loadbalancer.server.port=foobar"
|
||||
- "traefik.http.services.service02.loadbalancer.server.preservepath=true"
|
||||
- "traefik.http.services.service02.loadbalancer.server.scheme=foobar"
|
||||
|
@ -54,6 +54,7 @@
|
||||
[http.services.Service01.failover.healthCheck]
|
||||
[http.services.Service02]
|
||||
[http.services.Service02.loadBalancer]
|
||||
strategy = "foobar"
|
||||
passHostHeader = true
|
||||
serversTransport = "foobar"
|
||||
[http.services.Service02.loadBalancer.sticky]
|
||||
|
@ -80,6 +80,7 @@ http:
|
||||
- url: foobar
|
||||
weight: 42
|
||||
preservePath: true
|
||||
strategy: foobar
|
||||
healthCheck:
|
||||
scheme: foobar
|
||||
mode: foobar
|
||||
|
@ -290,10 +290,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
@ -1217,10 +1221,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
@ -2924,10 +2932,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
@ -3048,10 +3060,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
@ -3250,10 +3266,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
|
@ -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/sameSite` | `foobar` |
|
||||
| `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/maxBodySize` | `42` |
|
||||
| `traefik/http/services/Service03/mirroring/mirrorBody` | `true` |
|
||||
|
@ -290,10 +290,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
|
@ -454,10 +454,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
|
@ -314,10 +314,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
@ -438,10 +442,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
@ -640,10 +648,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
|
@ -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
|
||||
```
|
||||
|
||||
??? 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
|
||||
|
||||
You can declare pieces of middleware using tags starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options.
|
||||
|
@ -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"
|
||||
```
|
||||
|
||||
??? 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
|
||||
|
||||
You can declare pieces of middleware using labels starting with `traefik.http.middlewares.<name-of-your-choice>.`,
|
||||
|
@ -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
|
||||
```
|
||||
|
||||
??? 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
|
||||
|
||||
You can declare pieces of middleware using labels starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options.
|
||||
|
@ -358,19 +358,19 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne
|
||||
maxAge: 42
|
||||
path: /foo
|
||||
domain: foo.com
|
||||
strategy: RoundRobin
|
||||
strategy: wrr # [16]
|
||||
weight: 10
|
||||
nativeLB: true # [16]
|
||||
nodePortLB: true # [17]
|
||||
tls: # [18]
|
||||
secretName: supersecret # [19]
|
||||
options: # [20]
|
||||
name: opt # [21]
|
||||
namespace: default # [22]
|
||||
certResolver: foo # [23]
|
||||
domains: # [24]
|
||||
- main: example.net # [25]
|
||||
sans: # [26]
|
||||
nativeLB: true # [17]
|
||||
nodePortLB: true # [18]
|
||||
tls: # [19]
|
||||
secretName: supersecret # [20]
|
||||
options: # [21]
|
||||
name: opt # [22]
|
||||
namespace: default # [23]
|
||||
certResolver: foo # [24]
|
||||
domains: # [25]
|
||||
- main: example.net # [26]
|
||||
sans: # [27]
|
||||
- a.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. |
|
||||
| [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. |
|
||||
| [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. |
|
||||
| [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. |
|
||||
| [18] | `tls` | Defines [TLS](../routers/index.md#tls) certificate configuration |
|
||||
| [19] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) |
|
||||
| [20] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) |
|
||||
| [21] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name |
|
||||
| [22] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace |
|
||||
| [23] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver) |
|
||||
| [24] | `tls.domains` | List of [domains](../routers/index.md#domains) |
|
||||
| [25] | `domains[n].main` | Defines the main domain name |
|
||||
| [26] | `domains[n].sans` | List of SANs (alternative domains) |
|
||||
| [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].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] | `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` | Defines [TLS](../routers/index.md#tls) certificate configuration |
|
||||
| [20] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) |
|
||||
| [21] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) |
|
||||
| [22] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name |
|
||||
| [23] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace |
|
||||
| [24] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver) |
|
||||
| [25] | `tls.domains` | List of [domains](../routers/index.md#domains) |
|
||||
| [26] | `domains[n].main` | Defines the main domain name |
|
||||
| [27] | `domains[n].sans` | List of SANs (alternative domains) |
|
||||
|
||||
??? example "Declaring an IngressRoute"
|
||||
|
||||
@ -605,7 +606,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne
|
||||
|
||||
#### 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"
|
||||
|
||||
|
@ -300,6 +300,14 @@ A Story of key & values
|
||||
|---------------------------------------------------------------------------------|-------|
|
||||
| `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`"
|
||||
|
||||
| Key (Path) | Value |
|
||||
|
@ -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
|
||||
```
|
||||
|
||||
??? 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
|
||||
|
||||
You can declare pieces of middleware using tags starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options.
|
||||
|
@ -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"
|
||||
```
|
||||
|
||||
??? 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
|
||||
|
||||
You can declare pieces of middleware using labels starting with `traefik.http.middlewares.<name-of-your-choice>.`,
|
||||
|
@ -139,6 +139,47 @@ The `url` option point to a specific instance.
|
||||
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.
|
||||
|
||||
??? 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
|
||||
```
|
||||
|
||||
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 "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)"
|
||||
??? example "P2C Load Balancing -- Using the [File Provider](../../providers/file.md)"
|
||||
|
||||
```yaml tab="YAML"
|
||||
## Dynamic configuration
|
||||
@ -209,19 +222,24 @@ For now, only round robin load balancing is supported:
|
||||
services:
|
||||
my-service:
|
||||
loadBalancer:
|
||||
strategy: "p2c"
|
||||
servers:
|
||||
- url: "http://private-ip-server-1/"
|
||||
- url: "http://private-ip-server-2/"
|
||||
- url: "http://private-ip-server-3/"
|
||||
```
|
||||
|
||||
```toml tab="TOML"
|
||||
## Dynamic configuration
|
||||
[http.services]
|
||||
[http.services.my-service.loadBalancer]
|
||||
strategy = "p2c"
|
||||
[[http.services.my-service.loadBalancer.servers]]
|
||||
url = "http://private-ip-server-1/"
|
||||
[[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
|
||||
|
@ -290,10 +290,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
@ -1217,10 +1221,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
@ -2924,10 +2932,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
@ -3048,10 +3060,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
@ -3250,10 +3266,14 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
default: wrr
|
||||
description: |-
|
||||
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:
|
||||
- wrr
|
||||
- p2c
|
||||
- RoundRobin
|
||||
type: string
|
||||
weight:
|
||||
|
3
integration/testdata/rawdata-consul.json
vendored
3
integration/testdata/rawdata-consul.json
vendored
@ -200,6 +200,7 @@
|
||||
"url": "http://10.0.1.1:8889"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
@ -225,6 +226,7 @@
|
||||
"url": "http://10.0.1.2:8889"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
@ -242,6 +244,7 @@
|
||||
"url": "http://10.0.1.3:8889"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
|
@ -58,6 +58,7 @@
|
||||
"url": "http://10.42.0.5:80"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
|
4
integration/testdata/rawdata-crd.json
vendored
4
integration/testdata/rawdata-crd.json
vendored
@ -172,6 +172,7 @@
|
||||
"url": "http://10.42.0.5:80"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
@ -196,6 +197,7 @@
|
||||
"url": "http://10.42.0.5:80"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
@ -220,6 +222,7 @@
|
||||
"url": "http://10.42.0.5:80"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
@ -245,6 +248,7 @@
|
||||
"url": "http://10.42.0.5:80"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
|
3
integration/testdata/rawdata-etcd.json
vendored
3
integration/testdata/rawdata-etcd.json
vendored
@ -200,6 +200,7 @@
|
||||
"url": "http://10.0.1.1:8889"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
@ -225,6 +226,7 @@
|
||||
"url": "http://10.0.1.2:8889"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
@ -242,6 +244,7 @@
|
||||
"url": "http://10.0.1.3:8889"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
|
1
integration/testdata/rawdata-gateway.json
vendored
1
integration/testdata/rawdata-gateway.json
vendored
@ -126,6 +126,7 @@
|
||||
"url": "http://10.42.0.6:80"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
|
@ -106,6 +106,7 @@
|
||||
"url": "http://10.42.0.5:80"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
|
2
integration/testdata/rawdata-ingress.json
vendored
2
integration/testdata/rawdata-ingress.json
vendored
@ -157,6 +157,7 @@
|
||||
"url": "http://10.42.0.5:80"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
@ -182,6 +183,7 @@
|
||||
"url": "http://10.42.0.5:80"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
|
@ -106,6 +106,7 @@
|
||||
"url": "http://10.42.0.5:80"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
|
3
integration/testdata/rawdata-redis.json
vendored
3
integration/testdata/rawdata-redis.json
vendored
@ -200,6 +200,7 @@
|
||||
"url": "http://10.0.1.1:8889"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
@ -225,6 +226,7 @@
|
||||
"url": "http://10.0.1.2:8889"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
@ -242,6 +244,7 @@
|
||||
"url": "http://10.0.1.3:8889"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
|
3
integration/testdata/rawdata-zk.json
vendored
3
integration/testdata/rawdata-zk.json
vendored
@ -200,6 +200,7 @@
|
||||
"url": "http://10.0.1.1:8889"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
@ -225,6 +226,7 @@
|
||||
"url": "http://10.0.1.2:8889"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
@ -242,6 +244,7 @@
|
||||
"url": "http://10.0.1.3:8889"
|
||||
}
|
||||
],
|
||||
"strategy": "wrr",
|
||||
"passHostHeader": true,
|
||||
"responseForwarding": {
|
||||
"flushInterval": "100ms"
|
||||
|
@ -211,12 +211,22 @@ func (c *Cookie) SetDefaults() {
|
||||
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
|
||||
|
||||
// ServersLoadBalancer holds the ServersLoadBalancer configuration.
|
||||
type ServersLoadBalancer struct {
|
||||
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"`
|
||||
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"`
|
||||
Strategy BalancerStrategy `json:"strategy,omitempty" toml:"strategy,omitempty" yaml:"strategy,omitempty" export:"true"`
|
||||
// HealthCheck enables regular active checks of the responsiveness of the
|
||||
// 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
|
||||
@ -249,6 +259,7 @@ func (l *ServersLoadBalancer) SetDefaults() {
|
||||
defaultPassHostHeader := DefaultPassHostHeader
|
||||
l.PassHostHeader = &defaultPassHostHeader
|
||||
|
||||
l.Strategy = BalancerStrategyWRR
|
||||
l.ResponseForwarding = &ResponseForwarding{}
|
||||
l.ResponseForwarding.SetDefaults()
|
||||
}
|
||||
|
@ -172,6 +172,7 @@ func TestDecodeConfiguration(t *testing.T) {
|
||||
"traefik.http.services.Service0.loadbalancer.healthcheck.followredirects": "true",
|
||||
"traefik.http.services.Service0.loadbalancer.passhostheader": "true",
|
||||
"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.preservepath": "true",
|
||||
"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.passhostheader": "true",
|
||||
"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.preservepath": "true",
|
||||
"traefik.http.services.Service1.loadbalancer.server.scheme": "foobar",
|
||||
@ -680,6 +682,7 @@ func TestDecodeConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service0": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: "foobar",
|
||||
Sticky: &dynamic.Sticky{
|
||||
Cookie: &dynamic.Cookie{
|
||||
Name: "foobar",
|
||||
@ -722,6 +725,7 @@ func TestDecodeConfiguration(t *testing.T) {
|
||||
},
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: "foobar",
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "foobar",
|
||||
@ -1222,6 +1226,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service0": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: "foobar",
|
||||
Sticky: &dynamic.Sticky{
|
||||
Cookie: &dynamic.Cookie{
|
||||
Name: "foobar",
|
||||
@ -1261,6 +1266,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
||||
},
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: "foobar",
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "foobar",
|
||||
@ -1473,6 +1479,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
||||
"traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Timeout": "1000000000",
|
||||
"traefik.HTTP.Services.Service0.LoadBalancer.PassHostHeader": "true",
|
||||
"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.PreservePath": "true",
|
||||
"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.PassHostHeader": "true",
|
||||
"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.PreservePath": "true",
|
||||
"traefik.HTTP.Services.Service1.LoadBalancer.server.Port": "8080",
|
||||
|
@ -61,6 +61,7 @@ func TestDefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -119,6 +120,7 @@ func TestDefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -169,6 +171,7 @@ func TestDefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -219,6 +222,7 @@ func TestDefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -275,6 +279,7 @@ func TestDefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -369,6 +374,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"dev-Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -430,6 +436,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"dev-Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "https://127.0.0.1:443",
|
||||
@ -521,6 +528,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"dev-Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "https://127.0.0.1:443",
|
||||
@ -609,6 +617,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -622,6 +631,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
},
|
||||
"Test2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.2:80",
|
||||
@ -686,6 +696,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -753,6 +764,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.2:80",
|
||||
@ -817,6 +829,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -876,6 +889,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -933,6 +947,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -982,6 +997,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1044,6 +1060,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1096,6 +1113,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1109,6 +1127,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
},
|
||||
"Service2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1288,6 +1307,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1346,6 +1366,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1424,6 +1445,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1492,6 +1514,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1573,6 +1596,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1640,6 +1664,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1715,6 +1740,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1788,6 +1814,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1847,6 +1874,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1904,6 +1932,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "h2c://127.0.0.1:8080",
|
||||
@ -1960,6 +1989,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://1.2.3.4:5678",
|
||||
@ -2017,6 +2047,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://1.2.3.4:5678",
|
||||
@ -2143,6 +2174,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -2156,6 +2188,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
},
|
||||
"Service2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:8080",
|
||||
@ -2389,6 +2422,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -2456,6 +2490,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -2889,6 +2924,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -2980,6 +3016,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -3201,6 +3238,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "https://127.0.0.1:80",
|
||||
@ -3215,6 +3253,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
},
|
||||
"Test-97077516270503695": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "https://127.0.0.2:80",
|
||||
@ -3501,6 +3540,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"dev-Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -3677,6 +3717,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -3690,6 +3731,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
||||
},
|
||||
"Test2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:81",
|
||||
@ -3793,6 +3835,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:81",
|
||||
@ -3873,6 +3916,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -3886,6 +3930,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
||||
},
|
||||
"Test2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:81",
|
||||
@ -3985,6 +4030,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -3998,6 +4044,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
||||
},
|
||||
"Test2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:81",
|
||||
@ -4011,6 +4058,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
||||
},
|
||||
"Test3": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:82",
|
||||
@ -4024,6 +4072,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
||||
},
|
||||
"Test4": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:83",
|
||||
|
@ -69,6 +69,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -132,6 +133,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -197,6 +199,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -254,6 +257,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -311,6 +315,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -374,6 +379,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -606,6 +612,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -689,6 +696,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -702,6 +710,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
},
|
||||
"Test2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.2:80",
|
||||
@ -782,6 +791,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -849,6 +859,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -914,6 +925,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -971,6 +983,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1041,6 +1054,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1101,6 +1115,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1114,6 +1129,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
},
|
||||
"Service2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1178,6 +1194,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1421,6 +1438,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1487,6 +1505,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1584,6 +1603,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1671,6 +1691,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1777,6 +1798,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1861,6 +1883,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1961,6 +1984,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -2050,6 +2074,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -2129,6 +2154,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -2142,6 +2168,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
},
|
||||
"Test2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.2:80",
|
||||
@ -2206,6 +2233,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -2271,6 +2299,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "h2c://127.0.0.1:8080",
|
||||
@ -2330,6 +2359,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -2343,6 +2373,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
},
|
||||
"Service2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:8080",
|
||||
@ -2407,6 +2438,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://1.2.3.4:5678",
|
||||
@ -2472,6 +2504,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://1.2.3.4:5678",
|
||||
@ -2772,6 +2805,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -3032,6 +3066,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -3107,6 +3142,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -3578,6 +3614,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -3762,6 +3799,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://192.168.0.1:8081",
|
||||
@ -3825,6 +3863,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:79",
|
||||
|
@ -63,6 +63,7 @@ func TestDefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.0.0.1:1337",
|
||||
@ -121,6 +122,7 @@ func TestDefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -181,6 +183,7 @@ func TestDefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -233,6 +236,7 @@ func TestDefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -285,6 +289,7 @@ func TestDefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -343,6 +348,7 @@ func TestDefaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -552,6 +558,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -625,6 +632,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -638,6 +646,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
},
|
||||
"Test2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.2:80",
|
||||
@ -708,6 +717,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -770,6 +780,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -830,6 +841,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -882,6 +894,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -947,6 +960,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1002,6 +1016,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1015,6 +1030,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
},
|
||||
"Service2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1074,6 +1090,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1282,6 +1299,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1343,6 +1361,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1430,6 +1449,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1507,6 +1527,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1598,6 +1619,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1672,6 +1694,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1757,6 +1780,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1837,6 +1861,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1906,6 +1931,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -1919,6 +1945,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
},
|
||||
"Test2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.2:80",
|
||||
@ -1978,6 +2005,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -2038,6 +2066,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "h2c://127.0.0.1:8080",
|
||||
@ -2097,6 +2126,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://1.2.3.4:5678",
|
||||
@ -2157,6 +2187,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://1.2.3.4:5678",
|
||||
@ -2298,6 +2329,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "h2c://127.0.0.1:8040",
|
||||
@ -2366,6 +2398,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:32124",
|
||||
@ -2379,6 +2412,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
},
|
||||
"Service2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:32123",
|
||||
@ -2433,6 +2467,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -2446,6 +2481,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
},
|
||||
"Service2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:8080",
|
||||
@ -2736,6 +2772,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -2806,6 +2843,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -3237,6 +3275,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -3400,6 +3439,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
|
@ -21,9 +21,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
roundRobinStrategy = "RoundRobin"
|
||||
httpsProtocol = "https"
|
||||
httpProtocol = "http"
|
||||
httpsProtocol = "https"
|
||||
httpProtocol = "http"
|
||||
)
|
||||
|
||||
func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Client, tlsConfigs map[string]*tls.CertAndStores) *dynamic.HTTPConfiguration {
|
||||
@ -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.
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lb := &dynamic.ServersLoadBalancer{}
|
||||
lb.SetDefaults()
|
||||
lb.Servers = servers
|
||||
|
||||
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) {
|
||||
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)
|
||||
|
||||
if !isNamespaceAllowed(c.allowCrossNamespace, parentNamespace, namespace) {
|
||||
|
@ -1387,6 +1387,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-whoami-ipv6-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
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": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
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{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -1815,6 +1818,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test2-route-23c7f4c450289ee29016": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -1893,6 +1897,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test2-route-3c9bf014491ebdba74f7": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -1948,6 +1953,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test2-route-23c7f4c450289ee29016": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -2009,6 +2015,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test2-route-23c7f4c450289ee29016": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -2061,6 +2068,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -2077,6 +2085,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-test-route-77c62dfe9517144aeeaa": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -2139,6 +2148,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -2155,6 +2165,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami2-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.3:8080",
|
||||
@ -2212,6 +2223,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami5-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.3:8080",
|
||||
@ -2262,6 +2274,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami5-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.3:8080",
|
||||
@ -2337,6 +2350,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami4-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -2353,6 +2367,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami5-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.3:8080",
|
||||
@ -2383,6 +2398,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami6-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.5:80",
|
||||
@ -2399,6 +2415,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami7-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.7:8080",
|
||||
@ -2470,6 +2487,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami5-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.3:8080",
|
||||
@ -2553,6 +2571,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami4-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:8080",
|
||||
@ -2569,6 +2588,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami5-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.3:8080",
|
||||
@ -2615,6 +2635,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-77c62dfe9517144aeeaa": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "https://external.domain:443",
|
||||
@ -2679,6 +2700,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-external-svc-443": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "https://external.domain:443",
|
||||
@ -2698,6 +2720,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-external-svc-with-https-443": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "https://external.domain:443",
|
||||
@ -2741,6 +2764,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-external-svc-443": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "https://external.domain:443",
|
||||
@ -2819,6 +2843,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"baz-whoami6-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.5:8080",
|
||||
@ -2857,6 +2882,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"foo-whoami4-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:8080",
|
||||
@ -2883,6 +2909,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"foo-whoami5-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.3:8080",
|
||||
@ -2989,6 +3016,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami4-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:8080",
|
||||
@ -3005,6 +3033,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami5-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.3:8080",
|
||||
@ -3080,6 +3109,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami4-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:8080",
|
||||
@ -3096,6 +3126,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami5-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.3:8080",
|
||||
@ -3157,6 +3188,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -3173,6 +3205,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami2-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.3:8080",
|
||||
@ -3267,6 +3300,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-02719a68b11e915a4b23": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -3324,6 +3358,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -3397,6 +3432,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -3458,6 +3494,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -3474,6 +3511,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-test-route-default-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -3547,6 +3585,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -3621,6 +3660,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -3693,6 +3733,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -3769,6 +3810,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -3846,6 +3888,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -3894,6 +3937,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -3941,6 +3985,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "https://10.10.0.5:8443",
|
||||
@ -3988,6 +4033,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "https://10.10.0.7:8443",
|
||||
@ -4250,6 +4296,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-errorpage-errorpage-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -4296,6 +4343,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -4352,6 +4400,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -4413,6 +4462,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -4470,6 +4520,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -4486,6 +4537,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-test-route-default-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -4534,6 +4586,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6f97418635c7e18853da": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://external.domain:80",
|
||||
@ -4577,6 +4630,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6f97418635c7e18853da": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://external.domain:80",
|
||||
@ -4620,6 +4674,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6f97418635c7e18853da": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "https://external.domain:443",
|
||||
@ -4723,6 +4778,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-external-svc-with-https-443": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "https://external.domain:443",
|
||||
@ -4737,6 +4793,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoamitls-443": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "https://10.10.0.5:8443",
|
||||
@ -4822,6 +4879,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -4862,6 +4920,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -4918,6 +4977,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:8080",
|
||||
@ -4993,6 +5053,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-test-errorpage-errorpage-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -5024,6 +5085,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-without-endpointslice-endpoints-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -5136,6 +5198,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami2-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Sticky: &dynamic.Sticky{
|
||||
Cookie: &dynamic.Cookie{
|
||||
Name: "cookie",
|
||||
@ -5162,6 +5225,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Sticky: &dynamic.Sticky{
|
||||
Cookie: &dynamic.Cookie{
|
||||
Name: "cookie",
|
||||
@ -5188,6 +5252,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami3-8443": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.7:8443",
|
||||
@ -5273,6 +5338,7 @@ func TestLoadIngressRoutes_multipleEndpointAddresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -6199,6 +6265,7 @@ func TestCrossNamespace(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-crossnamespace-route-9313b71dbe6a649d5049": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6277,6 +6344,7 @@ func TestCrossNamespace(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-crossnamespace-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6293,6 +6361,7 @@ func TestCrossNamespace(t *testing.T) {
|
||||
},
|
||||
"default-test-crossnamespace-route-9313b71dbe6a649d5049": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6309,6 +6378,7 @@ func TestCrossNamespace(t *testing.T) {
|
||||
},
|
||||
"default-test-errorpage-errorpage-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6325,6 +6395,7 @@ func TestCrossNamespace(t *testing.T) {
|
||||
},
|
||||
"default-test-crossnamespace-route-a1963878aac7331b7950": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6404,6 +6475,7 @@ func TestCrossNamespace(t *testing.T) {
|
||||
},
|
||||
"default-cross-ns-route-1bc3efa892379bb93c6e": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6421,6 +6493,7 @@ func TestCrossNamespace(t *testing.T) {
|
||||
},
|
||||
"cross-ns-whoami-svc-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6479,6 +6552,7 @@ func TestCrossNamespace(t *testing.T) {
|
||||
},
|
||||
"default-whoami-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6529,6 +6603,7 @@ func TestCrossNamespace(t *testing.T) {
|
||||
},
|
||||
"cross-ns-whoami-svc-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6556,6 +6631,7 @@ func TestCrossNamespace(t *testing.T) {
|
||||
},
|
||||
"default-whoami-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6604,6 +6680,7 @@ func TestCrossNamespace(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6701,6 +6778,7 @@ func TestCrossNamespace(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6764,6 +6842,7 @@ func TestCrossNamespace(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6b204d94623b3df4370c": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -7382,6 +7461,7 @@ func TestExternalNameService(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6f97418635c7e18853da": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://external.domain:80",
|
||||
@ -7649,6 +7729,7 @@ func TestNativeLB(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6f97418635c7e18853da": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
@ -7830,6 +7911,7 @@ func TestNodePortLB(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6f97418635c7e18853da": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
@ -8273,6 +8355,7 @@ func TestGlobalNativeLB(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-global-native-lb-6f97418635c7e18853da": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
@ -8315,6 +8398,7 @@ func TestGlobalNativeLB(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-6f97418635c7e18853da": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
|
@ -113,9 +113,11 @@ type LoadBalancerSpec struct {
|
||||
// It defaults to https when Kubernetes Service port is 443, http otherwise.
|
||||
Scheme string `json:"scheme,omitempty"`
|
||||
// Strategy defines the load balancing strategy between the servers.
|
||||
// RoundRobin is the only supported value at the moment.
|
||||
// +kubebuilder:validation:Enum=RoundRobin
|
||||
Strategy string `json:"strategy,omitempty"`
|
||||
// Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
|
||||
// RoundRobin value is deprecated and supported for backward compatibility.
|
||||
// +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.
|
||||
// By default, passHostHeader is true.
|
||||
PassHostHeader *bool `json:"passHostHeader,omitempty"`
|
||||
|
@ -637,6 +637,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -733,6 +734,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -803,6 +805,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -864,6 +867,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -925,6 +929,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -1003,6 +1008,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -1019,6 +1025,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami2-http-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.3:8080",
|
||||
@ -1084,6 +1091,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -1100,6 +1108,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami2-http-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.3:8080",
|
||||
@ -1184,6 +1193,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -1277,6 +1287,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -1381,6 +1392,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -1442,6 +1454,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -1503,6 +1516,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -1564,6 +1578,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -1642,6 +1657,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -1658,6 +1674,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"bar-whoami-bar-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.11:80",
|
||||
@ -1719,6 +1736,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"bar-whoami-bar-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.11:80",
|
||||
@ -1789,6 +1807,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -1859,6 +1878,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -2021,6 +2041,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -2089,6 +2110,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -2159,6 +2181,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -2220,6 +2243,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -2282,6 +2306,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -2353,6 +2378,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -2420,6 +2446,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.10.1:80",
|
||||
@ -2478,6 +2505,7 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-native-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
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"},
|
||||
groupKindBackendFuncs: map[string]map[string]BuildBackendFunc{
|
||||
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": {
|
||||
@ -2638,6 +2666,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) {
|
||||
},
|
||||
"whoami": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{URL: "foobar"},
|
||||
},
|
||||
@ -2797,6 +2826,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -2872,6 +2902,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) {
|
||||
},
|
||||
"default-whoami-h2c-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "h2c://10.10.0.13:80",
|
||||
@ -2885,6 +2916,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) {
|
||||
},
|
||||
"default-whoami-ws-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.14:80",
|
||||
@ -2898,6 +2930,7 @@ func TestLoadHTTPRoutes_backendExtensionRef(t *testing.T) {
|
||||
},
|
||||
"default-whoami-wss-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "https://10.10.0.15:80",
|
||||
@ -3012,6 +3045,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -3084,6 +3118,7 @@ func TestLoadHTTPRoutes_filterExtensionRef(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -3296,6 +3331,7 @@ func TestLoadGRPCRoutes_filterExtensionRef(t *testing.T) {
|
||||
},
|
||||
"default-whoami-80-grpc": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "h2c://10.10.0.1:80",
|
||||
@ -3368,6 +3404,7 @@ func TestLoadGRPCRoutes_filterExtensionRef(t *testing.T) {
|
||||
},
|
||||
"default-whoami-80-grpc": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "h2c://10.10.0.1:80",
|
||||
@ -5951,6 +5988,7 @@ func TestLoadMixedRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6139,6 +6177,7 @@ func TestLoadMixedRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6359,6 +6398,7 @@ func TestLoadMixedRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
@ -6375,6 +6415,7 @@ func TestLoadMixedRoutes(t *testing.T) {
|
||||
},
|
||||
"bar-whoami-bar-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.11:80",
|
||||
@ -6535,6 +6576,7 @@ func TestLoadMixedRoutes(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"bar-whoami-bar-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.11:80",
|
||||
@ -6694,6 +6736,7 @@ func TestLoadMixedRoutes(t *testing.T) {
|
||||
},
|
||||
"default-whoami-http-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
|
@ -73,6 +73,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -128,6 +129,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -173,6 +175,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -209,6 +212,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -245,6 +249,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -281,6 +286,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -313,6 +319,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -345,6 +352,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-example-com-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -378,6 +386,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -414,6 +423,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -450,6 +460,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -466,6 +477,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
},
|
||||
"testing-service2-8082": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -499,6 +511,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -535,6 +548,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-backend": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -567,6 +581,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -599,6 +614,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-tchouk": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -631,6 +647,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-tchouk": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -667,6 +684,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-tchouk": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -683,6 +701,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
},
|
||||
"testing-service1-carotte": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -715,6 +734,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-tchouk": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -751,6 +771,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-tchouk": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -767,6 +788,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
},
|
||||
"toto-service1-tchouk": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -819,6 +841,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -849,6 +872,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-example-com-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -888,6 +912,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-443": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -920,6 +945,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-8443": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -953,6 +979,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-8443": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -987,6 +1014,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-backend": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1019,6 +1047,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1091,6 +1120,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1123,6 +1153,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1158,6 +1189,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1188,6 +1220,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1217,6 +1250,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1246,6 +1280,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1275,6 +1310,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1304,6 +1340,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1333,6 +1370,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1365,6 +1403,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1397,6 +1436,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1426,6 +1466,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1481,6 +1522,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-foobar": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1522,6 +1564,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-backend": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1551,6 +1594,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1630,6 +1674,7 @@ func TestLoadConfigurationFromIngressesWithExternalNameServices(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
@ -1659,6 +1704,7 @@ func TestLoadConfigurationFromIngressesWithExternalNameServices(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service-bar-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
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{
|
||||
"testing-service-foo-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
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{
|
||||
"testing-service1-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
@ -1790,6 +1838,7 @@ func TestLoadConfigurationFromIngressesWithNodePortLB(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
@ -2027,6 +2076,7 @@ func TestLoadConfigurationFromIngressesWithNativeLBByDefault(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
@ -2054,6 +2104,7 @@ func TestLoadConfigurationFromIngressesWithNativeLBByDefault(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-service1-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
|
@ -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/httpOnly": "true",
|
||||
"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/1/url": "foobar",
|
||||
"traefik/http/services/Service02/mirroring/service": "foobar",
|
||||
@ -646,6 +647,7 @@ func Test_buildConfiguration(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service01": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: "foobar",
|
||||
Sticky: &dynamic.Sticky{
|
||||
Cookie: &dynamic.Cookie{
|
||||
Name: "foobar",
|
||||
|
@ -56,6 +56,7 @@ func Test_defaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -114,6 +115,7 @@ func Test_defaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -163,6 +165,7 @@ func Test_defaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -218,6 +221,7 @@ func Test_defaultRule(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -296,6 +300,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"dev-Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -363,6 +368,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://192.168.1.101:9999",
|
||||
@ -376,6 +382,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
},
|
||||
"Test2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://192.168.1.102:9999",
|
||||
@ -440,6 +447,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -507,6 +515,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.2:9999",
|
||||
@ -571,6 +580,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -630,6 +640,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -687,6 +698,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -772,6 +784,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -834,6 +847,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -886,6 +900,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -899,6 +914,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
},
|
||||
"Service2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -1079,6 +1095,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -1137,6 +1154,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -1216,6 +1234,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -1285,6 +1304,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -1348,6 +1368,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -1416,6 +1437,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -1475,6 +1497,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -1532,6 +1555,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "h2c://127.0.0.1:8080",
|
||||
@ -1588,6 +1612,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://1.2.3.4:5678",
|
||||
@ -1645,6 +1670,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://1.2.3.4:5678",
|
||||
@ -1771,6 +1797,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -1784,6 +1811,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
},
|
||||
"Service2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:8080",
|
||||
@ -1983,6 +2011,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -2050,6 +2079,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -2459,6 +2489,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -2550,6 +2581,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -2770,6 +2802,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:80",
|
||||
@ -2783,6 +2816,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
},
|
||||
"Test-1234154071633021619": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.2:80",
|
||||
@ -3002,6 +3036,7 @@ func Test_buildConfig(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"dev-Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:9999",
|
||||
@ -3093,6 +3128,7 @@ func Test_buildConfigAllowEmptyServicesTrue(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: nil,
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
|
@ -53,6 +53,7 @@ func TestRouterManager_Get(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: server.URL,
|
||||
@ -76,6 +77,7 @@ func TestRouterManager_Get(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: server.URL,
|
||||
@ -114,6 +116,7 @@ func TestRouterManager_Get(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: server.URL,
|
||||
@ -138,6 +141,7 @@ func TestRouterManager_Get(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: server.URL,
|
||||
@ -179,6 +183,7 @@ func TestRouterManager_Get(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: server.URL,
|
||||
@ -219,6 +224,7 @@ func TestRouterManager_Get(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service@provider-1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: server.URL,
|
||||
@ -242,6 +248,7 @@ func TestRouterManager_Get(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service@provider-2": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: server.URL,
|
||||
@ -266,6 +273,7 @@ func TestRouterManager_Get(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service@provider-1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: server.URL,
|
||||
@ -351,6 +359,7 @@ func TestRuntimeConfiguration(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1:8085",
|
||||
@ -385,6 +394,7 @@ func TestRuntimeConfiguration(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
@ -412,6 +422,7 @@ func TestRuntimeConfiguration(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
@ -439,6 +450,7 @@ func TestRuntimeConfiguration(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
@ -482,6 +494,7 @@ func TestRuntimeConfiguration(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
@ -522,6 +535,7 @@ func TestRuntimeConfiguration(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
@ -552,6 +566,7 @@ func TestRuntimeConfiguration(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
@ -582,6 +597,7 @@ func TestRuntimeConfiguration(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
@ -608,6 +624,7 @@ func TestRuntimeConfiguration(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
@ -641,6 +658,7 @@ func TestRuntimeConfiguration(t *testing.T) {
|
||||
serviceConfig: map[string]*dynamic.Service{
|
||||
"foo-service": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
@ -730,7 +748,8 @@ func TestProviderOnMiddlewares(t *testing.T) {
|
||||
Services: map[string]*dynamic.Service{
|
||||
"test@file": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Servers: []dynamic.Server{},
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
227
pkg/server/service/loadbalancer/p2c/p2c.go
Normal file
227
pkg/server/service/loadbalancer/p2c/p2c.go
Normal 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)
|
||||
}
|
||||
}
|
288
pkg/server/service/loadbalancer/p2c/p2c_test.go
Normal file
288
pkg/server/service/loadbalancer/p2c/p2c_test.go
Normal 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
|
||||
}
|
179
pkg/server/service/loadbalancer/sticky.go
Normal file
179
pkg/server/service/loadbalancer/sticky.go
Normal 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]
|
||||
}
|
138
pkg/server/service/loadbalancer/sticky_test.go
Normal file
138
pkg/server/service/loadbalancer/sticky_test.go
Normal 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)
|
||||
}
|
@ -3,47 +3,20 @@ package wrr
|
||||
import (
|
||||
"container/heap"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"hash/fnv"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"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 string
|
||||
hashedName string
|
||||
weight 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
|
||||
}
|
||||
weight float64
|
||||
deadline float64
|
||||
}
|
||||
|
||||
// Balancer is a WeightedRoundRobin load balancer based on Earliest Deadline First (EDF).
|
||||
@ -52,15 +25,10 @@ func convertSameSite(sameSite string) http.SameSite {
|
||||
// Entries have deadlines set at currentDeadline + 1 / weight,
|
||||
// providing weighted round-robin behavior with floating point weights and an O(log n) pick time.
|
||||
type Balancer struct {
|
||||
stickyCookie *stickyCookie
|
||||
wantsHealthCheck bool
|
||||
|
||||
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
|
||||
curDeadline float64
|
||||
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,
|
||||
@ -71,31 +39,21 @@ type Balancer struct {
|
||||
updaters []func(bool)
|
||||
// fenced is the list of terminating yet still serving child services.
|
||||
fenced map[string]struct{}
|
||||
|
||||
sticky *loadbalancer.Sticky
|
||||
|
||||
curDeadline float64
|
||||
}
|
||||
|
||||
// New creates a new load balancer.
|
||||
func New(sticky *dynamic.Sticky, wantHealthCheck bool) *Balancer {
|
||||
func New(sticky *dynamic.Sticky, wantsHealthCheck bool) *Balancer {
|
||||
balancer := &Balancer{
|
||||
status: make(map[string]struct{}),
|
||||
fenced: make(map[string]struct{}),
|
||||
wantsHealthCheck: wantHealthCheck,
|
||||
wantsHealthCheck: wantsHealthCheck,
|
||||
}
|
||||
if sticky != nil && sticky.Cookie != nil {
|
||||
balancer.stickyCookie = &stickyCookie{
|
||||
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)
|
||||
balancer.sticky = loadbalancer.NewSticky(*sticky.Cookie)
|
||||
}
|
||||
|
||||
return balancer
|
||||
@ -216,43 +174,21 @@ func (b *Balancer) nextServer() (*namedHandler, error) {
|
||||
return handler, nil
|
||||
}
|
||||
|
||||
func (b *Balancer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
if b.stickyCookie != nil {
|
||||
cookie, err := req.Cookie(b.stickyCookie.name)
|
||||
|
||||
if err != nil && !errors.Is(err, http.ErrNoCookie) {
|
||||
log.Warn().Err(err).Msg("Error while reading cookie")
|
||||
}
|
||||
|
||||
if err == nil && cookie != nil {
|
||||
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
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
h.ServeHTTP(rw, req)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -260,32 +196,25 @@ func (b *Balancer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
server, err := b.nextServer()
|
||||
if err != nil {
|
||||
if errors.Is(err, errNoAvailableServer) {
|
||||
http.Error(w, errNoAvailableServer.Error(), http.StatusServiceUnavailable)
|
||||
http.Error(rw, errNoAvailableServer.Error(), http.StatusServiceUnavailable)
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if b.stickyCookie != nil {
|
||||
b.writeStickyCookie(w, server)
|
||||
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(w, req)
|
||||
server.ServeHTTP(rw, req)
|
||||
}
|
||||
|
||||
func (b *Balancer) writeStickyCookie(w http.ResponseWriter, handler *namedHandler) {
|
||||
cookie := &http.Cookie{
|
||||
Name: b.stickyCookie.name,
|
||||
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)
|
||||
// AddServer adds a handler with a server.
|
||||
func (b *Balancer) AddServer(name string, handler http.Handler, server dynamic.Server) {
|
||||
b.Add(name, handler, server.Weight, server.Fenced)
|
||||
}
|
||||
|
||||
// Add adds a handler.
|
||||
@ -309,41 +238,9 @@ func (b *Balancer) Add(name string, handler http.Handler, weight *int, fenced bo
|
||||
if fenced {
|
||||
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()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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
|
||||
if b.sticky != nil {
|
||||
b.sticky.AddHandler(name, handler)
|
||||
}
|
||||
return hashedInput[:16]
|
||||
}
|
||||
|
@ -10,6 +10,10 @@ import (
|
||||
"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 TestBalancer(t *testing.T) {
|
||||
@ -61,10 +65,6 @@ func TestBalancerOneServerZeroWeight(t *testing.T) {
|
||||
assert.Equal(t, 3, recorder.save["first"])
|
||||
}
|
||||
|
||||
type key string
|
||||
|
||||
const serviceName key = "serviceName"
|
||||
|
||||
func TestBalancerNoServiceUp(t *testing.T) {
|
||||
balancer := New(nil, false)
|
||||
|
||||
@ -264,8 +264,8 @@ func TestSticky(t *testing.T) {
|
||||
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
for range 3 {
|
||||
for _, cookie := range recorder.Result().Cookies() {
|
||||
assert.NotContains(t, "test=first", cookie.Value)
|
||||
assert.NotContains(t, "test=second", cookie.Value)
|
||||
assert.NotContains(t, "first", cookie.Value)
|
||||
assert.NotContains(t, "second", cookie.Value)
|
||||
req.AddCookie(cookie)
|
||||
}
|
||||
recorder.ResponseRecorder = httptest.NewRecorder()
|
||||
@ -283,7 +283,7 @@ func TestSticky(t *testing.T) {
|
||||
assert.Equal(t, "/foo", recorder.cookies["test"].Path)
|
||||
}
|
||||
|
||||
func TestSticky_FallBack(t *testing.T) {
|
||||
func TestSticky_Fallback(t *testing.T) {
|
||||
balancer := New(&dynamic.Sticky{
|
||||
Cookie: &dynamic.Cookie{Name: "test"},
|
||||
}, false)
|
||||
@ -312,6 +312,44 @@ func TestSticky_FallBack(t *testing.T) {
|
||||
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,
|
||||
// and that it does not "over-favor" the high-weighted ones with a biased start-up regime.
|
||||
func TestBalancerBias(t *testing.T) {
|
||||
@ -355,137 +393,3 @@ func (r *responseRecorder) WriteHeader(statusCode int) {
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import (
|
||||
"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/mirror"
|
||||
"github.com/traefik/traefik/v3/pkg/server/service/loadbalancer/p2c"
|
||||
"github.com/traefik/traefik/v3/pkg/server/service/loadbalancer/wrr"
|
||||
"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) {
|
||||
service := info.LoadBalancer
|
||||
|
||||
@ -330,7 +338,18 @@ func (m *Manager) getLoadBalancerServiceHandler(ctx context.Context, serviceName
|
||||
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)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
lb.Add(server.URL, proxy, server.Weight, server.Fenced)
|
||||
lb.AddServer(server.URL, proxy, server)
|
||||
|
||||
// servers are considered UP by default.
|
||||
info.UpdateServerStatus(target.String(), runtime.StatusUp)
|
||||
|
@ -38,6 +38,7 @@ func TestGetLoadBalancer(t *testing.T) {
|
||||
desc: "Fails when provided an invalid URL",
|
||||
serviceName: "test",
|
||||
service: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: ":",
|
||||
@ -50,7 +51,9 @@ func TestGetLoadBalancer(t *testing.T) {
|
||||
{
|
||||
desc: "Succeeds when there are no servers",
|
||||
serviceName: "test",
|
||||
service: &dynamic.ServersLoadBalancer{},
|
||||
service: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
},
|
||||
fwd: &forwarderMock{},
|
||||
expectError: false,
|
||||
},
|
||||
@ -58,7 +61,8 @@ func TestGetLoadBalancer(t *testing.T) {
|
||||
desc: "Succeeds when sticky.cookie is set",
|
||||
serviceName: "test",
|
||||
service: &dynamic.ServersLoadBalancer{
|
||||
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}},
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}},
|
||||
},
|
||||
fwd: &forwarderMock{},
|
||||
expectError: false,
|
||||
@ -140,6 +144,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
|
||||
desc: "Load balances between the two servers",
|
||||
serviceName: "test",
|
||||
service: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: boolPtr(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
@ -165,6 +170,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
|
||||
desc: "StatusBadGateway when the server is not reachable",
|
||||
serviceName: "test",
|
||||
service: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://foo",
|
||||
@ -181,7 +187,8 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
|
||||
desc: "ServiceUnavailable when no servers are available",
|
||||
serviceName: "test",
|
||||
service: &dynamic.ServersLoadBalancer{
|
||||
Servers: []dynamic.Server{},
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{},
|
||||
},
|
||||
expected: []ExpectedResult{
|
||||
{
|
||||
@ -193,7 +200,8 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
|
||||
desc: "Always call the same server when sticky.cookie is true",
|
||||
serviceName: "test",
|
||||
service: &dynamic.ServersLoadBalancer{
|
||||
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}},
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}},
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: server1.URL,
|
||||
@ -216,7 +224,8 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
|
||||
desc: "Sticky Cookie's options set correctly",
|
||||
serviceName: "test",
|
||||
service: &dynamic.ServersLoadBalancer{
|
||||
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{HTTPOnly: true, Secure: true}},
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{HTTPOnly: true, Secure: true}},
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: server1.URL,
|
||||
@ -236,6 +245,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
|
||||
desc: "PassHost passes the host instead of the IP",
|
||||
serviceName: "test",
|
||||
service: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}},
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
@ -255,6 +265,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
|
||||
desc: "PassHost doesn't pass the host instead of the IP",
|
||||
serviceName: "test",
|
||||
service: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
PassHostHeader: pointer(false),
|
||||
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}},
|
||||
Servers: []dynamic.Server{
|
||||
@ -274,6 +285,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
|
||||
desc: "No user-agent",
|
||||
serviceName: "test",
|
||||
service: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: hasNoUserAgent.URL,
|
||||
@ -291,6 +303,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
|
||||
serviceName: "test",
|
||||
userAgent: "foobar",
|
||||
service: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: hasUserAgent.URL,
|
||||
@ -379,6 +392,7 @@ func Test1xxResponses(t *testing.T) {
|
||||
info := &runtime.ServiceInfo{
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: backend.URL,
|
||||
@ -466,7 +480,9 @@ func TestManager_ServiceBuilders(t *testing.T) {
|
||||
manager := NewManager(map[string]*runtime.ServiceInfo{
|
||||
"test@test": {
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{},
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil, nil, &TransportManager{
|
||||
@ -505,7 +521,9 @@ func TestManager_Build(t *testing.T) {
|
||||
configs: map[string]*runtime.ServiceInfo{
|
||||
"serviceName": {
|
||||
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{
|
||||
"serviceName@provider-1": {
|
||||
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{
|
||||
"serviceName@provider-1": {
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{},
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Strategy: dynamic.BalancerStrategyWRR,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -70,6 +70,8 @@ func WithLoadBalancerServices(opts ...func(service *dynamic.ServersLoadBalancer)
|
||||
c.Services = make(map[string]*dynamic.Service)
|
||||
for _, opt := range opts {
|
||||
b := &dynamic.ServersLoadBalancer{}
|
||||
b.SetDefaults()
|
||||
|
||||
name := opt(b)
|
||||
c.Services[name] = &dynamic.Service{
|
||||
LoadBalancer: b,
|
||||
|
Loading…
x
Reference in New Issue
Block a user