From 740b4cfd2502df4fa56a2727c5faeb821d3599a3 Mon Sep 17 00:00:00 2001 From: Jorge Date: Thu, 6 Mar 2025 09:38:04 +0100 Subject: [PATCH] Support domain configuration for sticky cookies --- .../dynamic-configuration/docker-labels.yml | 1 + .../reference/dynamic-configuration/file.toml | 2 ++ .../reference/dynamic-configuration/file.yaml | 2 ++ .../kubernetes-crd-definition-v1.yml | 30 +++++++++++++++++++ .../reference/dynamic-configuration/kv-ref.md | 2 ++ .../traefik.io_ingressroutes.yaml | 5 ++++ .../traefik.io_middlewares.yaml | 5 ++++ .../traefik.io_traefikservices.yaml | 20 +++++++++++++ .../routing/providers/consul-catalog.md | 8 +++++ docs/content/routing/providers/docker.md | 8 +++++ docs/content/routing/providers/ecs.md | 8 +++++ .../routing/providers/kubernetes-crd.md | 1 + .../routing/providers/kubernetes-ingress.md | 8 +++++ docs/content/routing/providers/kv.md | 14 +++++++++ docs/content/routing/providers/nomad.md | 8 +++++ docs/content/routing/providers/swarm.md | 8 +++++ docs/content/routing/services/index.md | 8 +++++ integration/fixtures/k8s/01-traefik-crd.yml | 30 +++++++++++++++++++ pkg/config/dynamic/http_config.go | 3 ++ pkg/config/label/label_test.go | 4 +++ .../kubernetes/crd/kubernetes_http.go | 2 ++ .../kubernetes/ingress/annotations_test.go | 2 ++ pkg/server/service/loadbalancer/wrr/wrr.go | 3 ++ .../service/loadbalancer/wrr/wrr_test.go | 2 ++ 24 files changed, 184 insertions(+) diff --git a/docs/content/reference/dynamic-configuration/docker-labels.yml b/docs/content/reference/dynamic-configuration/docker-labels.yml index a6005b91d..baf1c4186 100644 --- a/docs/content/reference/dynamic-configuration/docker-labels.yml +++ b/docs/content/reference/dynamic-configuration/docker-labels.yml @@ -200,6 +200,7 @@ - "traefik.http.services.service02.loadbalancer.serverstransport=foobar" - "traefik.http.services.service02.loadbalancer.sticky=true" - "traefik.http.services.service02.loadbalancer.sticky.cookie=true" +- "traefik.http.services.service02.loadbalancer.sticky.cookie.domain=foobar" - "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" diff --git a/docs/content/reference/dynamic-configuration/file.toml b/docs/content/reference/dynamic-configuration/file.toml index 4b3a500f5..a5d45447b 100644 --- a/docs/content/reference/dynamic-configuration/file.toml +++ b/docs/content/reference/dynamic-configuration/file.toml @@ -64,6 +64,7 @@ sameSite = "foobar" maxAge = 42 path = "foobar" + domain = "foobar" [[http.services.Service02.loadBalancer.servers]] url = "foobar" @@ -122,6 +123,7 @@ sameSite = "foobar" maxAge = 42 path = "foobar" + domain = "foobar" [http.services.Service04.weighted.healthCheck] [http.middlewares] [http.middlewares.Middleware01] diff --git a/docs/content/reference/dynamic-configuration/file.yaml b/docs/content/reference/dynamic-configuration/file.yaml index 3894c86d8..c7daacc11 100644 --- a/docs/content/reference/dynamic-configuration/file.yaml +++ b/docs/content/reference/dynamic-configuration/file.yaml @@ -72,6 +72,7 @@ http: sameSite: foobar maxAge: 42 path: foobar + domain: foobar servers: - url: foobar weight: 42 @@ -123,6 +124,7 @@ http: sameSite: foobar maxAge: 42 path: foobar + domain: foobar healthCheck: {} middlewares: Middleware01: diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml index 12d430b5f..940131f91 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml @@ -247,6 +247,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as @@ -1147,6 +1152,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. @@ -2737,6 +2747,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. @@ -2850,6 +2865,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. @@ -3039,6 +3059,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. @@ -3092,6 +3117,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. diff --git a/docs/content/reference/dynamic-configuration/kv-ref.md b/docs/content/reference/dynamic-configuration/kv-ref.md index cb35b2b9c..e04f5b84e 100644 --- a/docs/content/reference/dynamic-configuration/kv-ref.md +++ b/docs/content/reference/dynamic-configuration/kv-ref.md @@ -275,6 +275,7 @@ THIS FILE MUST NOT BE EDITED BY HAND | `traefik/http/services/Service02/loadBalancer/servers/1/url` | `foobar` | | `traefik/http/services/Service02/loadBalancer/servers/1/weight` | `42` | | `traefik/http/services/Service02/loadBalancer/serversTransport` | `foobar` | +| `traefik/http/services/Service02/loadBalancer/sticky/cookie/domain` | `foobar` | | `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` | @@ -294,6 +295,7 @@ THIS FILE MUST NOT BE EDITED BY HAND | `traefik/http/services/Service04/weighted/services/0/weight` | `42` | | `traefik/http/services/Service04/weighted/services/1/name` | `foobar` | | `traefik/http/services/Service04/weighted/services/1/weight` | `42` | +| `traefik/http/services/Service04/weighted/sticky/cookie/domain` | `foobar` | | `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` | diff --git a/docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml b/docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml index d122fb4f0..f682dba72 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml @@ -247,6 +247,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as diff --git a/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml b/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml index 6b00592e8..a2dec5131 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml @@ -405,6 +405,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. diff --git a/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml b/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml index ccf0dd79b..5885bdf22 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml @@ -273,6 +273,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. @@ -386,6 +391,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. @@ -575,6 +585,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. @@ -628,6 +643,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. diff --git a/docs/content/routing/providers/consul-catalog.md b/docs/content/routing/providers/consul-catalog.md index 17b20c935..f539a6868 100644 --- a/docs/content/routing/providers/consul-catalog.md +++ b/docs/content/routing/providers/consul-catalog.md @@ -322,6 +322,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none ``` +??? info "`traefik.http.services..loadbalancer.sticky.cookie.domain`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + traefik.http.services.myservice.loadbalancer.sticky.cookie.domain=foo.com + ``` + ??? info "`traefik.http.services..loadbalancer.sticky.cookie.maxage`" See [sticky sessions](../services/index.md#sticky-sessions) for more information. diff --git a/docs/content/routing/providers/docker.md b/docs/content/routing/providers/docker.md index 2ed74a796..928fafef1 100644 --- a/docs/content/routing/providers/docker.md +++ b/docs/content/routing/providers/docker.md @@ -437,6 +437,14 @@ you'd add the label `traefik.http.services..loadbalancer.pa - "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none" ``` +??? info "`traefik.http.services..loadbalancer.sticky.cookie.domain`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + - "traefik.http.services.myservice.loadbalancer.sticky.cookie.domain=foo.com" + ``` + ??? info "`traefik.http.services..loadbalancer.sticky.cookie.maxage`" See [sticky sessions](../services/index.md#sticky-sessions) for more information. diff --git a/docs/content/routing/providers/ecs.md b/docs/content/routing/providers/ecs.md index b87f4f75e..6fed9e9ae 100644 --- a/docs/content/routing/providers/ecs.md +++ b/docs/content/routing/providers/ecs.md @@ -324,6 +324,14 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none ``` +??? info "`traefik.http.services..loadbalancer.sticky.cookie.domain`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + traefik.http.services.myservice.loadbalancer.sticky.cookie.domain=foo.com + ``` + ??? info "`traefik.http.services..loadbalancer.sticky.cookie.maxage`" See [sticky sessions](../services/index.md#sticky-sessions) for more information. diff --git a/docs/content/routing/providers/kubernetes-crd.md b/docs/content/routing/providers/kubernetes-crd.md index d9bf0caef..9188837df 100644 --- a/docs/content/routing/providers/kubernetes-crd.md +++ b/docs/content/routing/providers/kubernetes-crd.md @@ -357,6 +357,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne sameSite: none maxAge: 42 path: /foo + domain: foo.com strategy: RoundRobin weight: 10 nativeLB: true # [16] diff --git a/docs/content/routing/providers/kubernetes-ingress.md b/docs/content/routing/providers/kubernetes-ingress.md index 7701fa701..c6cc107e9 100644 --- a/docs/content/routing/providers/kubernetes-ingress.md +++ b/docs/content/routing/providers/kubernetes-ingress.md @@ -391,6 +391,14 @@ which in turn will create the resulting routers, services, handlers, etc. traefik.ingress.kubernetes.io/service.sticky.cookie.samesite: "none" ``` +??? info "`traefik.ingress.kubernetes.io/service.sticky.cookie.domain`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + traefik.ingress.kubernetes.io/service.sticky.cookie.domain: "foo.com" + ``` + ??? info "`traefik.ingress.kubernetes.io/service.sticky.cookie.httponly`" See [sticky sessions](../services/index.md#sticky-sessions) for more information. diff --git a/docs/content/routing/providers/kv.md b/docs/content/routing/providers/kv.md index 86f70bc14..1234d1357 100644 --- a/docs/content/routing/providers/kv.md +++ b/docs/content/routing/providers/kv.md @@ -276,6 +276,14 @@ A Story of key & values |-----------------------------------------------------------------------|--------| | `traefik/http/services/myservice/loadbalancer/sticky/cookie/samesite` | `none` | +??? info "`traefik/http/services//loadbalancer/sticky/cookie/domain`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + | Key (Path) | Value | + |-----------------------------------------------------------------------|-----------| + | `traefik/http/services/myservice/loadbalancer/sticky/cookie/domain` | `foo.com` | + ??? info "`traefik/http/services//loadbalancer/sticky/cookie/maxage`" See [sticky sessions](../services/index.md#sticky-sessions) for more information. @@ -340,6 +348,12 @@ A Story of key & values |------------------------------------------------------------------------|--------| | `traefik/http/services//weighted/sticky/cookie/samesite` | `none` | +??? info "`traefik/http/services//weighted/sticky/cookie/domain`" + + | Key (Path) | Value | + |------------------------------------------------------------------------|-----------| + | `traefik/http/services//weighted/sticky/cookie/domain` | `foo.com` | + ??? info "`traefik/http/services//weighted/sticky/cookie/httpOnly`" | Key (Path) | Value | diff --git a/docs/content/routing/providers/nomad.md b/docs/content/routing/providers/nomad.md index 8a9dcd4b7..175f1d61c 100644 --- a/docs/content/routing/providers/nomad.md +++ b/docs/content/routing/providers/nomad.md @@ -306,6 +306,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none ``` +??? info "`traefik.http.services..loadbalancer.sticky.cookie.domain`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + traefik.http.services.myservice.loadbalancer.sticky.cookie.domain=foo.com + ``` + ??? info "`traefik.http.services..loadbalancer.sticky.cookie.maxage`" See [sticky sessions](../services/index.md#sticky-sessions) for more information. diff --git a/docs/content/routing/providers/swarm.md b/docs/content/routing/providers/swarm.md index 7224af183..754931a71 100644 --- a/docs/content/routing/providers/swarm.md +++ b/docs/content/routing/providers/swarm.md @@ -451,6 +451,14 @@ you'd add the label `traefik.http.services..loadbalancer.pa - "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none" ``` +??? info "`traefik.http.services..loadbalancer.sticky.cookie.domain`" + + See [sticky sessions](../services/index.md#sticky-sessions) for more information. + + ```yaml + - "traefik.http.services.myservice.loadbalancer.sticky.cookie.domain=foo.com" + ``` + ??? info "`traefik.http.services..loadbalancer.responseforwarding.flushinterval`" See [response forwarding](../services/index.md#response-forwarding) for more information. diff --git a/docs/content/routing/services/index.md b/docs/content/routing/services/index.md index b58ac814a..9cc266acc 100644 --- a/docs/content/routing/services/index.md +++ b/docs/content/routing/services/index.md @@ -255,6 +255,12 @@ On subsequent requests, to keep the session alive with the same server, the clie `SameSite` can be `none`, `lax`, `strict` or empty. +!!! info "Domain" + + The Domain attribute of a cookie specifies the domain for which the cookie is valid. + + By setting the Domain attribute, the cookie can be shared across subdomains (for example, a cookie set for example.com would be accessible to www.example.com, api.example.com, etc.). This is particularly useful in cases where sticky sessions span multiple subdomains, ensuring that the session is maintained even when the client interacts with different parts of the infrastructure. + ??? example "Adding Stickiness -- Using the [File Provider](../../providers/file.md)" ```yaml tab="YAML" @@ -286,6 +292,7 @@ On subsequent requests, to keep the session alive with the same server, the clie cookie: name: my_sticky_cookie_name secure: true + domain: mysite.site httpOnly: true ``` @@ -297,6 +304,7 @@ On subsequent requests, to keep the session alive with the same server, the clie name = "my_sticky_cookie_name" secure = true httpOnly = true + domain = "mysite.site" sameSite = "none" ``` diff --git a/integration/fixtures/k8s/01-traefik-crd.yml b/integration/fixtures/k8s/01-traefik-crd.yml index 12d430b5f..940131f91 100644 --- a/integration/fixtures/k8s/01-traefik-crd.yml +++ b/integration/fixtures/k8s/01-traefik-crd.yml @@ -247,6 +247,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as @@ -1147,6 +1152,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. @@ -2737,6 +2747,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. @@ -2850,6 +2865,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. @@ -3039,6 +3059,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. @@ -3092,6 +3117,11 @@ spec: cookie: description: Cookie defines the sticky cookie configuration. properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string httpOnly: description: HTTPOnly defines whether the cookie can be accessed by client-side APIs, such as JavaScript. diff --git a/pkg/config/dynamic/http_config.go b/pkg/config/dynamic/http_config.go index 78fafefe9..b49fa82e9 100644 --- a/pkg/config/dynamic/http_config.go +++ b/pkg/config/dynamic/http_config.go @@ -199,6 +199,9 @@ type Cookie struct { // 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"` + // Domain defines the host to which the cookie will be sent. + // More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + Domain string `json:"domain,omitempty" toml:"domain,omitempty" yaml:"domain,omitempty"` } // SetDefaults set the default values for a Cookie. diff --git a/pkg/config/label/label_test.go b/pkg/config/label/label_test.go index b0e60a5ab..8c3e883b7 100644 --- a/pkg/config/label/label_test.go +++ b/pkg/config/label/label_test.go @@ -179,6 +179,7 @@ func TestDecodeConfiguration(t *testing.T) { "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.sticky.cookie.domain": "foo.com", "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", @@ -684,6 +685,7 @@ func TestDecodeConfiguration(t *testing.T) { Name: "foobar", Secure: true, HTTPOnly: false, + Domain: "foo.com", Path: func(v string) *string { return &v }("/foobar"), }, }, @@ -1224,6 +1226,7 @@ func TestEncodeConfiguration(t *testing.T) { Cookie: &dynamic.Cookie{ Name: "foobar", HTTPOnly: true, + Domain: "foo.com", Path: func(v string) *string { return &v }("/foobar"), }, }, @@ -1479,6 +1482,7 @@ func TestEncodeConfiguration(t *testing.T) { "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.Sticky.Cookie.Domain": "foo.com", "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", diff --git a/pkg/provider/kubernetes/crd/kubernetes_http.go b/pkg/provider/kubernetes/crd/kubernetes_http.go index 4c8668931..2f7afe328 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_http.go +++ b/pkg/provider/kubernetes/crd/kubernetes_http.go @@ -260,6 +260,7 @@ func (c configBuilder) buildServicesLB(ctx context.Context, namespace string, tS HTTPOnly: tService.Weighted.Sticky.Cookie.HTTPOnly, SameSite: tService.Weighted.Sticky.Cookie.SameSite, MaxAge: tService.Weighted.Sticky.Cookie.MaxAge, + Domain: tService.Weighted.Sticky.Cookie.Domain, }, } sticky.Cookie.SetDefaults() @@ -382,6 +383,7 @@ func (c configBuilder) buildServersLB(namespace string, svc traefikv1alpha1.Load HTTPOnly: svc.Sticky.Cookie.HTTPOnly, SameSite: svc.Sticky.Cookie.SameSite, MaxAge: svc.Sticky.Cookie.MaxAge, + Domain: svc.Sticky.Cookie.Domain, }, } lb.Sticky.Cookie.SetDefaults() diff --git a/pkg/provider/kubernetes/ingress/annotations_test.go b/pkg/provider/kubernetes/ingress/annotations_test.go index 84fc2c4fb..bda404889 100644 --- a/pkg/provider/kubernetes/ingress/annotations_test.go +++ b/pkg/provider/kubernetes/ingress/annotations_test.go @@ -121,6 +121,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.domain": "foo.com", "traefik.ingress.kubernetes.io/service.sticky.cookie.path": "foobar", }, expected: &ServiceConfig{ @@ -131,6 +132,7 @@ func Test_parseServiceConfig(t *testing.T) { Secure: true, HTTPOnly: true, SameSite: "none", + Domain: "foo.com", Path: pointer("foobar"), }, }, diff --git a/pkg/server/service/loadbalancer/wrr/wrr.go b/pkg/server/service/loadbalancer/wrr/wrr.go index 41e260d43..b26b06320 100644 --- a/pkg/server/service/loadbalancer/wrr/wrr.go +++ b/pkg/server/service/loadbalancer/wrr/wrr.go @@ -30,6 +30,7 @@ type stickyCookie struct { sameSite string maxAge int path string + domain string } func convertSameSite(sameSite string) http.SameSite { @@ -87,6 +88,7 @@ func New(sticky *dynamic.Sticky, wantHealthCheck bool) *Balancer { sameSite: sticky.Cookie.SameSite, maxAge: sticky.Cookie.MaxAge, path: "/", + domain: sticky.Cookie.Domain, } if sticky.Cookie.Path != nil { balancer.stickyCookie.path = *sticky.Cookie.Path @@ -281,6 +283,7 @@ func (b *Balancer) writeStickyCookie(w http.ResponseWriter, handler *namedHandle Secure: b.stickyCookie.secure, SameSite: convertSameSite(b.stickyCookie.sameSite), MaxAge: b.stickyCookie.maxAge, + Domain: b.stickyCookie.domain, } http.SetCookie(w, cookie) } diff --git a/pkg/server/service/loadbalancer/wrr/wrr_test.go b/pkg/server/service/loadbalancer/wrr/wrr_test.go index 1773c7ce0..266a58f3d 100644 --- a/pkg/server/service/loadbalancer/wrr/wrr_test.go +++ b/pkg/server/service/loadbalancer/wrr/wrr_test.go @@ -239,6 +239,7 @@ func TestSticky(t *testing.T) { Secure: true, HTTPOnly: true, SameSite: "none", + Domain: "foo.com", MaxAge: 42, Path: func(v string) *string { return &v }("/foo"), }, @@ -276,6 +277,7 @@ func TestSticky(t *testing.T) { assert.Equal(t, 3, recorder.save["second"]) assert.True(t, recorder.cookies["test"].HttpOnly) assert.True(t, recorder.cookies["test"].Secure) + assert.Equal(t, "foo.com", recorder.cookies["test"].Domain) 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)