Compare commits
4 commits
f0ff5999a2
...
a3c1875eaa
Author | SHA1 | Date | |
---|---|---|---|
a3c1875eaa | |||
|
ec00c4aa42 | ||
|
552bd8f180 | ||
|
97caf758ef |
36 changed files with 579 additions and 38 deletions
|
@ -238,6 +238,9 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
|
|||
}
|
||||
|
||||
pluginBuilder, err := createPluginBuilder(staticConfiguration)
|
||||
if err != nil && staticConfiguration.Experimental != nil && staticConfiguration.Experimental.AbortOnPluginFailure {
|
||||
return nil, fmt.Errorf("plugin: failed to create plugin builder: %w", err)
|
||||
}
|
||||
if err != nil {
|
||||
pluginLogger.Err(err).Msg("Plugins are disabled because an error has occurred.")
|
||||
} else if hasPlugins {
|
||||
|
|
|
@ -191,6 +191,7 @@
|
|||
- "traefik.http.services.service02.loadbalancer.sticky.cookie.httponly=true"
|
||||
- "traefik.http.services.service02.loadbalancer.sticky.cookie.maxage=42"
|
||||
- "traefik.http.services.service02.loadbalancer.sticky.cookie.name=foobar"
|
||||
- "traefik.http.services.service02.loadbalancer.sticky.cookie.path=foobar"
|
||||
- "traefik.http.services.service02.loadbalancer.sticky.cookie.samesite=foobar"
|
||||
- "traefik.http.services.service02.loadbalancer.sticky.cookie.secure=true"
|
||||
- "traefik.http.services.service02.loadbalancer.server.port=foobar"
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
httpOnly = true
|
||||
sameSite = "foobar"
|
||||
maxAge = 42
|
||||
path = "foobar"
|
||||
|
||||
[[http.services.Service02.loadBalancer.servers]]
|
||||
url = "foobar"
|
||||
|
@ -112,6 +113,7 @@
|
|||
httpOnly = true
|
||||
sameSite = "foobar"
|
||||
maxAge = 42
|
||||
path = "foobar"
|
||||
[http.services.Service04.weighted.healthCheck]
|
||||
[http.middlewares]
|
||||
[http.middlewares.Middleware01]
|
||||
|
|
|
@ -63,6 +63,7 @@ http:
|
|||
httpOnly: true
|
||||
sameSite: foobar
|
||||
maxAge: 42
|
||||
path: foobar
|
||||
servers:
|
||||
- url: foobar
|
||||
weight: 42
|
||||
|
@ -113,6 +114,7 @@ http:
|
|||
httpOnly: true
|
||||
sameSite: foobar
|
||||
maxAge: 42
|
||||
path: foobar
|
||||
healthCheck: {}
|
||||
middlewares:
|
||||
Middleware01:
|
||||
|
|
|
@ -57,6 +57,7 @@ spec:
|
|||
description: |-
|
||||
Kind defines the kind of the route.
|
||||
Rule is the only supported kind.
|
||||
If not defined, defaults to Rule.
|
||||
enum:
|
||||
- Rule
|
||||
type: string
|
||||
|
@ -241,13 +242,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
@ -280,7 +287,6 @@ spec:
|
|||
More info: https://doc.traefik.io/traefik/v3.2/routing/routers/#rulesyntax
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- match
|
||||
type: object
|
||||
type: array
|
||||
|
@ -1133,13 +1139,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
@ -2686,13 +2698,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
@ -2793,13 +2811,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
@ -2976,13 +3000,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
@ -3023,13 +3053,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
|
|
@ -266,6 +266,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
|
|||
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/httpOnly` | `true` |
|
||||
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/maxAge` | `42` |
|
||||
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/name` | `foobar` |
|
||||
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/path` | `foobar` |
|
||||
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/sameSite` | `foobar` |
|
||||
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/secure` | `true` |
|
||||
| `traefik/http/services/Service03/mirroring/healthCheck` | `` |
|
||||
|
@ -284,6 +285,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
|
|||
| `traefik/http/services/Service04/weighted/sticky/cookie/httpOnly` | `true` |
|
||||
| `traefik/http/services/Service04/weighted/sticky/cookie/maxAge` | `42` |
|
||||
| `traefik/http/services/Service04/weighted/sticky/cookie/name` | `foobar` |
|
||||
| `traefik/http/services/Service04/weighted/sticky/cookie/path` | `foobar` |
|
||||
| `traefik/http/services/Service04/weighted/sticky/cookie/sameSite` | `foobar` |
|
||||
| `traefik/http/services/Service04/weighted/sticky/cookie/secure` | `true` |
|
||||
| `traefik/tcp/middlewares/TCPMiddleware01/ipAllowList/sourceRange/0` | `foobar` |
|
||||
|
|
|
@ -57,6 +57,7 @@ spec:
|
|||
description: |-
|
||||
Kind defines the kind of the route.
|
||||
Rule is the only supported kind.
|
||||
If not defined, defaults to Rule.
|
||||
enum:
|
||||
- Rule
|
||||
type: string
|
||||
|
@ -241,13 +242,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
@ -280,7 +287,6 @@ spec:
|
|||
More info: https://doc.traefik.io/traefik/v3.2/routing/routers/#rulesyntax
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- match
|
||||
type: object
|
||||
type: array
|
||||
|
|
|
@ -409,13 +409,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
|
|
@ -279,13 +279,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
@ -386,13 +392,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
@ -569,13 +581,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
@ -616,13 +634,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
|
|
@ -228,6 +228,9 @@ WriteTimeout is the maximum duration before timing out writes of the response. I
|
|||
`--entrypoints.<name>.udp.timeout`:
|
||||
Timeout defines how long to wait on an idle session before releasing the related resources. (Default: ```3```)
|
||||
|
||||
`--experimental.abortonpluginfailure`:
|
||||
Defines whether all plugins must be loaded successfully for Traefik to start. (Default: ```false```)
|
||||
|
||||
`--experimental.fastproxy`:
|
||||
Enable the FastProxy implementation. (Default: ```false```)
|
||||
|
||||
|
|
|
@ -228,6 +228,9 @@ WriteTimeout is the maximum duration before timing out writes of the response. I
|
|||
`TRAEFIK_ENTRYPOINTS_<NAME>_UDP_TIMEOUT`:
|
||||
Timeout defines how long to wait on an idle session before releasing the related resources. (Default: ```3```)
|
||||
|
||||
`TRAEFIK_EXPERIMENTAL_ABORTONPLUGINFAILURE`:
|
||||
Defines whether all plugins must be loaded successfully for Traefik to start. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_EXPERIMENTAL_FASTPROXY`:
|
||||
Enable the FastProxy implementation. (Default: ```false```)
|
||||
|
||||
|
|
|
@ -488,6 +488,7 @@
|
|||
[certificatesResolvers.CertificateResolver1.tailscale]
|
||||
|
||||
[experimental]
|
||||
abortOnPluginFailure = true
|
||||
kubernetesGateway = true
|
||||
[experimental.plugins]
|
||||
[experimental.plugins.Descriptor0]
|
||||
|
|
|
@ -576,6 +576,7 @@ experimental:
|
|||
mounts:
|
||||
- foobar
|
||||
- foobar
|
||||
abortOnPluginFailure: true
|
||||
fastProxy:
|
||||
debug: true
|
||||
kubernetesGateway: true
|
||||
|
|
|
@ -265,6 +265,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
|
|||
traefik.http.services.myservice.loadbalancer.sticky.cookie.name=foobar
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.sticky.cookie.path=/foobar
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
|
|
@ -380,6 +380,14 @@ you'd add the label `traefik.http.services.<name-of-your-choice>.loadbalancer.pa
|
|||
- "traefik.http.services.myservice.loadbalancer.sticky.cookie.name=foobar"
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
||||
```yaml
|
||||
- "traefik.http.services.myservice.loadbalancer.sticky.cookie.path=/foobar"
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
|
|
@ -267,6 +267,14 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa
|
|||
traefik.http.services.myservice.loadbalancer.sticky.cookie.name=foobar
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.sticky.cookie.path=/foobar
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
|
|
@ -352,6 +352,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne
|
|||
secure: true
|
||||
sameSite: none
|
||||
maxAge: 42
|
||||
path: /foo
|
||||
strategy: RoundRobin
|
||||
weight: 10
|
||||
nativeLB: true # [12]
|
||||
|
|
|
@ -383,6 +383,14 @@ which in turn will create the resulting routers, services, handlers, etc.
|
|||
traefik.ingress.kubernetes.io/service.sticky.cookie.maxage: 42
|
||||
```
|
||||
|
||||
??? info "`traefik.ingress.kubernetes.io/service.sticky.cookie.path`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.ingress.kubernetes.io/service.sticky.cookie.path: /foobar
|
||||
```
|
||||
|
||||
## Path Types on Kubernetes 1.18+
|
||||
|
||||
If the Kubernetes cluster version is 1.18+,
|
||||
|
|
|
@ -228,6 +228,14 @@ A Story of key & values
|
|||
|-------------------------------------------------------------------|----------|
|
||||
| `traefik/http/services/myservice/loadbalancer/sticky/cookie/name` | `foobar` |
|
||||
|
||||
??? info "`traefik/http/services/<service_name>/loadbalancer/sticky/cookie/path`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
||||
| Key (Path) | Value |
|
||||
|-------------------------------------------------------------------|-----------|
|
||||
| `traefik/http/services/myservice/loadbalancer/sticky/cookie/path` | `/foobar` |
|
||||
|
||||
??? info "`traefik/http/services/<service_name>/loadbalancer/sticky/cookie/secure`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
@ -320,6 +328,12 @@ A Story of key & values
|
|||
|----------------------------------------------------------------------|-------|
|
||||
| `traefik/http/services/<service_name>/weighted/sticky/cookie/maxage` | `42` |
|
||||
|
||||
??? info "`traefik/http/services/<service_name>/weighted/sticky/cookie/path`"
|
||||
|
||||
| Key (Path) | Value |
|
||||
|----------------------------------------------------------------------|-----------|
|
||||
| `traefik/http/services/<service_name>/weighted/sticky/cookie/path` | `/foobar` |
|
||||
|
||||
### Middleware
|
||||
|
||||
More information about available middlewares in the dedicated [middlewares section](../../middlewares/overview.md).
|
||||
|
|
|
@ -281,6 +281,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
|
|||
traefik.http.services.myservice.loadbalancer.sticky.cookie.maxage=42
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.sticky.cookie.path=/foobar
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`"
|
||||
|
||||
See [response forwarding](../services/index.md#response-forwarding) for more information.
|
||||
|
|
|
@ -394,6 +394,14 @@ you'd add the label `traefik.http.services.<name-of-your-choice>.loadbalancer.pa
|
|||
- "traefik.http.services.myservice.loadbalancer.sticky.cookie.name=foobar"
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
||||
```yaml
|
||||
- "traefik.http.services.myservice.loadbalancer.sticky.cookie.path=/foobar"
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
|
|
@ -57,6 +57,7 @@ spec:
|
|||
description: |-
|
||||
Kind defines the kind of the route.
|
||||
Rule is the only supported kind.
|
||||
If not defined, defaults to Rule.
|
||||
enum:
|
||||
- Rule
|
||||
type: string
|
||||
|
@ -241,13 +242,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
@ -280,7 +287,6 @@ spec:
|
|||
More info: https://doc.traefik.io/traefik/v3.2/routing/routers/#rulesyntax
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- match
|
||||
type: object
|
||||
type: array
|
||||
|
@ -1133,13 +1139,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
@ -2686,13 +2698,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
@ -2793,13 +2811,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
@ -2976,13 +3000,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
@ -3023,13 +3053,19 @@ spec:
|
|||
type: boolean
|
||||
maxAge:
|
||||
description: |-
|
||||
MaxAge indicates the number of seconds until the cookie expires.
|
||||
MaxAge defines the number of seconds until the cookie expires.
|
||||
When set to a negative number, the cookie expires immediately.
|
||||
When set to zero, the cookie never expires.
|
||||
type: integer
|
||||
name:
|
||||
description: Name defines the Cookie name.
|
||||
type: string
|
||||
path:
|
||||
description: |-
|
||||
Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
When not provided the cookie will be sent on every request to the domain.
|
||||
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
type: string
|
||||
sameSite:
|
||||
description: |-
|
||||
SameSite defines the same site policy.
|
||||
|
|
|
@ -175,10 +175,20 @@ type Cookie struct {
|
|||
// SameSite defines the same site policy.
|
||||
// More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
|
||||
SameSite string `json:"sameSite,omitempty" toml:"sameSite,omitempty" yaml:"sameSite,omitempty" export:"true"`
|
||||
// MaxAge indicates the number of seconds until the cookie expires.
|
||||
// MaxAge defines the number of seconds until the cookie expires.
|
||||
// When set to a negative number, the cookie expires immediately.
|
||||
// When set to zero, the cookie never expires.
|
||||
MaxAge int `json:"maxAge,omitempty" toml:"maxAge,omitempty" yaml:"maxAge,omitempty" export:"true"`
|
||||
// Path defines the path that must exist in the requested URL for the browser to send the Cookie header.
|
||||
// When not provided the cookie will be sent on every request to the domain.
|
||||
// More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
|
||||
Path *string `json:"path,omitempty" toml:"path,omitempty" yaml:"path,omitempty" export:"true"`
|
||||
}
|
||||
|
||||
// SetDefaults set the default values for a Cookie.
|
||||
func (c *Cookie) SetDefaults() {
|
||||
defaultPath := "/"
|
||||
c.Path = &defaultPath
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
|
|
|
@ -266,6 +266,11 @@ func (in *ContentType) DeepCopy() *ContentType {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Cookie) DeepCopyInto(out *Cookie) {
|
||||
*out = *in
|
||||
if in.Path != nil {
|
||||
in, out := &in.Path, &out.Path
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1517,7 +1522,7 @@ func (in *Sticky) DeepCopyInto(out *Sticky) {
|
|||
if in.Cookie != nil {
|
||||
in, out := &in.Cookie, &out.Cookie
|
||||
*out = new(Cookie)
|
||||
**out = **in
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -174,6 +174,7 @@ func TestDecodeConfiguration(t *testing.T) {
|
|||
"traefik.http.services.Service0.loadbalancer.server.port": "8080",
|
||||
"traefik.http.services.Service0.loadbalancer.sticky.cookie.name": "foobar",
|
||||
"traefik.http.services.Service0.loadbalancer.sticky.cookie.secure": "true",
|
||||
"traefik.http.services.Service0.loadbalancer.sticky.cookie.path": "/foobar",
|
||||
"traefik.http.services.Service0.loadbalancer.serversTransport": "foobar",
|
||||
"traefik.http.services.Service1.loadbalancer.healthcheck.headers.name0": "foobar",
|
||||
"traefik.http.services.Service1.loadbalancer.healthcheck.headers.name1": "foobar",
|
||||
|
@ -674,6 +675,7 @@ func TestDecodeConfiguration(t *testing.T) {
|
|||
Name: "foobar",
|
||||
Secure: true,
|
||||
HTTPOnly: false,
|
||||
Path: func(v string) *string { return &v }("/foobar"),
|
||||
},
|
||||
},
|
||||
Servers: []dynamic.Server{
|
||||
|
@ -1196,6 +1198,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
Cookie: &dynamic.Cookie{
|
||||
Name: "foobar",
|
||||
HTTPOnly: true,
|
||||
Path: func(v string) *string { return &v }("/foobar"),
|
||||
},
|
||||
},
|
||||
Servers: []dynamic.Server{
|
||||
|
@ -1433,6 +1436,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
"traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.HTTPOnly": "true",
|
||||
"traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.Secure": "false",
|
||||
"traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.MaxAge": "0",
|
||||
"traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.Path": "/foobar",
|
||||
"traefik.HTTP.Services.Service0.LoadBalancer.ServersTransport": "foobar",
|
||||
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name0": "foobar",
|
||||
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name1": "foobar",
|
||||
|
|
|
@ -6,6 +6,7 @@ import "github.com/traefik/traefik/v3/pkg/plugins"
|
|||
type Experimental struct {
|
||||
Plugins map[string]plugins.Descriptor `description:"Plugins configuration." json:"plugins,omitempty" toml:"plugins,omitempty" yaml:"plugins,omitempty" export:"true"`
|
||||
LocalPlugins map[string]plugins.LocalDescriptor `description:"Local plugins configuration." json:"localPlugins,omitempty" toml:"localPlugins,omitempty" yaml:"localPlugins,omitempty" export:"true"`
|
||||
AbortOnPluginFailure bool `description:"Defines whether all plugins must be loaded successfully for Traefik to start." json:"abortOnPluginFailure,omitempty" toml:"abortOnPluginFailure,omitempty" yaml:"abortOnPluginFailure,omitempty" export:"true"`
|
||||
|
||||
FastProxy *FastProxyConfig `description:"Enable the FastProxy implementation." json:"fastProxy,omitempty" toml:"fastProxy,omitempty" yaml:"fastProxy,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
|
||||
|
||||
|
|
81
pkg/provider/kubernetes/crd/fixtures/with_sticky.yml
Normal file
81
pkg/provider/kubernetes/crd/fixtures/with_sticky.yml
Normal file
|
@ -0,0 +1,81 @@
|
|||
---
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: TraefikService
|
||||
metadata:
|
||||
name: sticky-default
|
||||
namespace: default
|
||||
spec:
|
||||
weighted:
|
||||
sticky:
|
||||
cookie:
|
||||
httpOnly: true
|
||||
name: cookie
|
||||
secure: true
|
||||
sameSite: none
|
||||
maxAge: 42
|
||||
services:
|
||||
- name: whoami3
|
||||
port: 8443
|
||||
|
||||
---
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: TraefikService
|
||||
metadata:
|
||||
name: sticky
|
||||
namespace: default
|
||||
spec:
|
||||
weighted:
|
||||
sticky:
|
||||
cookie:
|
||||
httpOnly: true
|
||||
name: cookie
|
||||
secure: true
|
||||
sameSite: none
|
||||
maxAge: 42
|
||||
path: /foo
|
||||
services:
|
||||
- name: whoami3
|
||||
port: 8443
|
||||
|
||||
---
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: test2.route
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
entryPoints:
|
||||
- web
|
||||
|
||||
routes:
|
||||
- match: Host(`traefik-service`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: sticky
|
||||
kind: TraefikService
|
||||
- name: sticky-default
|
||||
kind: TraefikService
|
||||
|
||||
- match: Host(`k8s-service`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: whoami
|
||||
port: 80
|
||||
sticky:
|
||||
cookie:
|
||||
httpOnly: true
|
||||
name: cookie
|
||||
secure: true
|
||||
sameSite: none
|
||||
maxAge: 42
|
||||
path: /foo
|
||||
- name: whoami2
|
||||
port: 8080
|
||||
sticky:
|
||||
cookie:
|
||||
httpOnly: true
|
||||
name: cookie
|
||||
secure: true
|
||||
sameSite: none
|
||||
maxAge: 42
|
|
@ -60,7 +60,7 @@ func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Cli
|
|||
}
|
||||
|
||||
for _, route := range ingressRoute.Spec.Routes {
|
||||
if route.Kind != "Rule" {
|
||||
if len(route.Kind) > 0 && route.Kind != "Rule" {
|
||||
logger.Error().Msgf("Unsupported match kind: %s. Only \"Rule\" is supported for now.", route.Kind)
|
||||
continue
|
||||
}
|
||||
|
@ -248,10 +248,28 @@ func (c configBuilder) buildServicesLB(ctx context.Context, namespace string, tS
|
|||
})
|
||||
}
|
||||
|
||||
var sticky *dynamic.Sticky
|
||||
if tService.Weighted.Sticky != nil && tService.Weighted.Sticky.Cookie != nil {
|
||||
sticky = &dynamic.Sticky{
|
||||
Cookie: &dynamic.Cookie{
|
||||
Name: tService.Weighted.Sticky.Cookie.Name,
|
||||
Secure: tService.Weighted.Sticky.Cookie.Secure,
|
||||
HTTPOnly: tService.Weighted.Sticky.Cookie.HTTPOnly,
|
||||
SameSite: tService.Weighted.Sticky.Cookie.SameSite,
|
||||
MaxAge: tService.Weighted.Sticky.Cookie.MaxAge,
|
||||
},
|
||||
}
|
||||
sticky.Cookie.SetDefaults()
|
||||
|
||||
if tService.Weighted.Sticky.Cookie.Path != nil {
|
||||
sticky.Cookie.Path = tService.Weighted.Sticky.Cookie.Path
|
||||
}
|
||||
}
|
||||
|
||||
conf[id] = &dynamic.Service{
|
||||
Weighted: &dynamic.WeightedRoundRobin{
|
||||
Services: wrrServices,
|
||||
Sticky: tService.Weighted.Sticky,
|
||||
Sticky: sticky,
|
||||
},
|
||||
}
|
||||
return nil
|
||||
|
@ -353,7 +371,22 @@ func (c configBuilder) buildServersLB(namespace string, svc traefikv1alpha1.Load
|
|||
}
|
||||
}
|
||||
|
||||
lb.Sticky = svc.Sticky
|
||||
if svc.Sticky != nil && svc.Sticky.Cookie != nil {
|
||||
lb.Sticky = &dynamic.Sticky{
|
||||
Cookie: &dynamic.Cookie{
|
||||
Name: svc.Sticky.Cookie.Name,
|
||||
Secure: svc.Sticky.Cookie.Secure,
|
||||
HTTPOnly: svc.Sticky.Cookie.HTTPOnly,
|
||||
SameSite: svc.Sticky.Cookie.SameSite,
|
||||
MaxAge: svc.Sticky.Cookie.MaxAge,
|
||||
},
|
||||
}
|
||||
lb.Sticky.Cookie.SetDefaults()
|
||||
|
||||
if svc.Sticky.Cookie.Path != nil {
|
||||
lb.Sticky.Cookie.Path = svc.Sticky.Cookie.Path
|
||||
}
|
||||
}
|
||||
|
||||
lb.ServersTransport, err = c.makeServersTransportKey(namespace, svc.ServersTransport)
|
||||
if err != nil {
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
kubefake "k8s.io/client-go/kubernetes/fake"
|
||||
kscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
var _ provider.Provider = (*Provider)(nil)
|
||||
|
@ -3114,8 +3115,8 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
desc: "Route with kind not of a rule type (empty kind) is ignored",
|
||||
paths: []string{"services.yml", "with_wrong_rule_kind.yml"},
|
||||
desc: "Route with empty kind is allowed",
|
||||
paths: []string{"services.yml", "with_empty_rule_kind.yml"},
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
|
@ -3129,9 +3130,33 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"default-test-route-02719a68b11e915a4b23": {
|
||||
EntryPoints: []string{"web"},
|
||||
Service: "default-test-route-02719a68b11e915a4b23",
|
||||
Rule: "/prefix",
|
||||
Priority: 12,
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test-route-02719a68b11e915a4b23": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
},
|
||||
{
|
||||
URL: "http://10.10.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
},
|
||||
},
|
||||
|
@ -4879,6 +4904,178 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Simple Ingress Route with sticky",
|
||||
allowCrossNamespace: true,
|
||||
paths: []string{"services.yml", "with_sticky.yml"},
|
||||
expected: &dynamic.Configuration{
|
||||
UDP: &dynamic.UDPConfiguration{
|
||||
Routers: map[string]*dynamic.UDPRouter{},
|
||||
Services: map[string]*dynamic.UDPService{},
|
||||
},
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{},
|
||||
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
||||
Services: map[string]*dynamic.TCPService{},
|
||||
ServersTransports: map[string]*dynamic.TCPServersTransport{},
|
||||
},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"default-test2-route-840425136fbd5d85a4ad": {
|
||||
EntryPoints: []string{"web"},
|
||||
Service: "default-test2-route-840425136fbd5d85a4ad",
|
||||
Rule: "Host(`k8s-service`)",
|
||||
},
|
||||
"default-test2-route-4f06607bbc69f34a4db5": {
|
||||
EntryPoints: []string{"web"},
|
||||
Service: "default-test2-route-4f06607bbc69f34a4db5",
|
||||
Rule: "Host(`traefik-service`)",
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-test2-route-840425136fbd5d85a4ad": {
|
||||
Weighted: &dynamic.WeightedRoundRobin{
|
||||
Services: []dynamic.WRRService{
|
||||
{
|
||||
Name: "default-whoami-80",
|
||||
Weight: Int(1),
|
||||
},
|
||||
{
|
||||
Name: "default-whoami2-8080",
|
||||
Weight: Int(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"default-test2-route-4f06607bbc69f34a4db5": {
|
||||
Weighted: &dynamic.WeightedRoundRobin{
|
||||
Services: []dynamic.WRRService{
|
||||
{
|
||||
Name: "default-sticky",
|
||||
Weight: Int(1),
|
||||
},
|
||||
{
|
||||
Name: "default-sticky-default",
|
||||
Weight: Int(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"default-sticky": {
|
||||
Weighted: &dynamic.WeightedRoundRobin{
|
||||
Sticky: &dynamic.Sticky{
|
||||
Cookie: &dynamic.Cookie{
|
||||
Name: "cookie",
|
||||
Secure: true,
|
||||
HTTPOnly: true,
|
||||
SameSite: "none",
|
||||
MaxAge: 42,
|
||||
Path: pointer.String("/foo"),
|
||||
},
|
||||
},
|
||||
Services: []dynamic.WRRService{
|
||||
{
|
||||
Name: "default-whoami3-8443",
|
||||
Weight: Int(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"default-sticky-default": {
|
||||
Weighted: &dynamic.WeightedRoundRobin{
|
||||
Sticky: &dynamic.Sticky{
|
||||
Cookie: &dynamic.Cookie{
|
||||
Name: "cookie",
|
||||
Secure: true,
|
||||
HTTPOnly: true,
|
||||
SameSite: "none",
|
||||
MaxAge: 42,
|
||||
Path: pointer.String("/"),
|
||||
},
|
||||
},
|
||||
Services: []dynamic.WRRService{
|
||||
{
|
||||
Name: "default-whoami3-8443",
|
||||
Weight: Int(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"default-whoami2-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Sticky: &dynamic.Sticky{
|
||||
Cookie: &dynamic.Cookie{
|
||||
Name: "cookie",
|
||||
Secure: true,
|
||||
HTTPOnly: true,
|
||||
SameSite: "none",
|
||||
MaxAge: 42,
|
||||
Path: pointer.String("/"),
|
||||
},
|
||||
},
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.3:8080",
|
||||
},
|
||||
{
|
||||
URL: "http://10.10.0.4:8080",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
},
|
||||
},
|
||||
"default-whoami-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Sticky: &dynamic.Sticky{
|
||||
Cookie: &dynamic.Cookie{
|
||||
Name: "cookie",
|
||||
Secure: true,
|
||||
HTTPOnly: true,
|
||||
SameSite: "none",
|
||||
MaxAge: 42,
|
||||
Path: pointer.String("/foo"),
|
||||
},
|
||||
},
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
},
|
||||
{
|
||||
URL: "http://10.10.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
},
|
||||
},
|
||||
"default-whoami3-8443": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.7:8443",
|
||||
},
|
||||
{
|
||||
URL: "http://10.10.0.8:8443",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
|
|
|
@ -28,8 +28,9 @@ type Route struct {
|
|||
Match string `json:"match"`
|
||||
// Kind defines the kind of the route.
|
||||
// Rule is the only supported kind.
|
||||
// If not defined, defaults to Rule.
|
||||
// +kubebuilder:validation:Enum=Rule
|
||||
Kind string `json:"kind"`
|
||||
Kind string `json:"kind,omitempty"`
|
||||
// Priority defines the router's priority.
|
||||
// More info: https://doc.traefik.io/traefik/v3.2/routing/routers/#priority
|
||||
Priority int `json:"priority,omitempty"`
|
||||
|
|
|
@ -113,6 +113,7 @@ func Test_parseServiceConfig(t *testing.T) {
|
|||
"traefik.ingress.kubernetes.io/service.sticky.cookie.name": "foobar",
|
||||
"traefik.ingress.kubernetes.io/service.sticky.cookie.secure": "true",
|
||||
"traefik.ingress.kubernetes.io/service.sticky.cookie.samesite": "none",
|
||||
"traefik.ingress.kubernetes.io/service.sticky.cookie.path": "foobar",
|
||||
},
|
||||
expected: &ServiceConfig{
|
||||
Service: &ServiceIng{
|
||||
|
@ -122,6 +123,7 @@ func Test_parseServiceConfig(t *testing.T) {
|
|||
Secure: true,
|
||||
HTTPOnly: true,
|
||||
SameSite: "none",
|
||||
Path: String("foobar"),
|
||||
},
|
||||
},
|
||||
ServersScheme: "protocol",
|
||||
|
@ -138,7 +140,11 @@ func Test_parseServiceConfig(t *testing.T) {
|
|||
},
|
||||
expected: &ServiceConfig{
|
||||
Service: &ServiceIng{
|
||||
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}},
|
||||
Sticky: &dynamic.Sticky{
|
||||
Cookie: &dynamic.Cookie{
|
||||
Path: String("/"),
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
},
|
||||
},
|
||||
|
|
|
@ -24,6 +24,8 @@ var _ provider.Provider = (*Provider)(nil)
|
|||
|
||||
func Bool(v bool) *bool { return &v }
|
||||
|
||||
func String(v string) *string { return &v }
|
||||
|
||||
func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
@ -126,6 +128,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Name: "foobar",
|
||||
Secure: true,
|
||||
HTTPOnly: true,
|
||||
Path: String("/"),
|
||||
},
|
||||
},
|
||||
Servers: []dynamic.Server{
|
||||
|
|
|
@ -58,6 +58,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
"traefik/http/services/Service01/loadBalancer/sticky/cookie/name": "foobar",
|
||||
"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/servers/0/url": "foobar",
|
||||
"traefik/http/services/Service01/loadBalancer/servers/1/url": "foobar",
|
||||
"traefik/http/services/Service02/mirroring/service": "foobar",
|
||||
|
@ -70,6 +71,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
"traefik/http/services/Service03/weighted/sticky/cookie/name": "foobar",
|
||||
"traefik/http/services/Service03/weighted/sticky/cookie/secure": "true",
|
||||
"traefik/http/services/Service03/weighted/sticky/cookie/httpOnly": "true",
|
||||
"traefik/http/services/Service03/weighted/sticky/cookie/path": "foobar",
|
||||
"traefik/http/services/Service03/weighted/services/0/name": "foobar",
|
||||
"traefik/http/services/Service03/weighted/services/0/weight": "42",
|
||||
"traefik/http/services/Service03/weighted/services/1/name": "foobar",
|
||||
|
@ -642,6 +644,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
Name: "foobar",
|
||||
Secure: true,
|
||||
HTTPOnly: true,
|
||||
Path: func(v string) *string { return &v }("foobar"),
|
||||
},
|
||||
},
|
||||
Servers: []dynamic.Server{
|
||||
|
@ -708,6 +711,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
Name: "foobar",
|
||||
Secure: true,
|
||||
HTTPOnly: true,
|
||||
Path: func(v string) *string { return &v }("foobar"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -26,6 +26,7 @@ type stickyCookie struct {
|
|||
httpOnly bool
|
||||
sameSite string
|
||||
maxAge int
|
||||
path string
|
||||
}
|
||||
|
||||
func convertSameSite(sameSite string) http.SameSite {
|
||||
|
@ -79,6 +80,10 @@ func New(sticky *dynamic.Sticky, wantHealthCheck bool) *Balancer {
|
|||
httpOnly: sticky.Cookie.HTTPOnly,
|
||||
sameSite: sticky.Cookie.SameSite,
|
||||
maxAge: sticky.Cookie.MaxAge,
|
||||
path: "/",
|
||||
}
|
||||
if sticky.Cookie.Path != nil {
|
||||
balancer.stickyCookie.path = *sticky.Cookie.Path
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,7 +241,7 @@ func (b *Balancer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
cookie := &http.Cookie{
|
||||
Name: b.stickyCookie.name,
|
||||
Value: hash(server.name),
|
||||
Path: "/",
|
||||
Path: b.stickyCookie.path,
|
||||
HttpOnly: b.stickyCookie.httpOnly,
|
||||
Secure: b.stickyCookie.secure,
|
||||
SameSite: convertSameSite(b.stickyCookie.sameSite),
|
||||
|
|
|
@ -226,6 +226,7 @@ func TestSticky(t *testing.T) {
|
|||
HTTPOnly: true,
|
||||
SameSite: "none",
|
||||
MaxAge: 42,
|
||||
Path: func(v string) *string { return &v }("/foo"),
|
||||
},
|
||||
}, false)
|
||||
|
||||
|
@ -263,6 +264,7 @@ func TestSticky(t *testing.T) {
|
|||
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) {
|
||||
|
|
Loading…
Reference in a new issue