Backward compatibility for sticky
This commit is contained in:
parent
3afd6024b5
commit
08503655d9
22 changed files with 140 additions and 260 deletions
|
@ -354,21 +354,19 @@ The default cookie name is an abbreviation of a sha1 (ex: `_1d52e`).
|
||||||
On subsequent requests, the client will be directed to the backend stored in the cookie if it is still healthy.
|
On subsequent requests, the client will be directed to the backend stored in the cookie if it is still healthy.
|
||||||
If not, a new backend will be assigned.
|
If not, a new backend will be assigned.
|
||||||
|
|
||||||
To activate sticky session:
|
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[backends]
|
[backends]
|
||||||
[backends.backend1]
|
[backends.backend1]
|
||||||
|
# Enable sticky session
|
||||||
[backends.backend1.loadbalancer.stickiness]
|
[backends.backend1.loadbalancer.stickiness]
|
||||||
```
|
|
||||||
|
|
||||||
To customize the cookie name:
|
# Customize the cookie name
|
||||||
|
#
|
||||||
```toml
|
# Optional
|
||||||
[backends]
|
# Default: a sha1 (6 chars)
|
||||||
[backends.backend1]
|
#
|
||||||
[backends.backend1.loadbalancer.stickiness]
|
# cookieName = "my_cookie"
|
||||||
cookieName = "my_cookie"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The deprecated way:
|
The deprecated way:
|
||||||
|
|
|
@ -397,17 +397,19 @@ func (p *CatalogProvider) getBasicAuth(tags []string) []string {
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CatalogProvider) hasStickinessLabel(tags []string) bool {
|
func (p *CatalogProvider) getSticky(tags []string) string {
|
||||||
stickinessTag := p.getTag(types.LabelBackendLoadbalancerStickiness, tags, "")
|
|
||||||
|
|
||||||
stickyTag := p.getTag(types.LabelBackendLoadbalancerSticky, tags, "")
|
stickyTag := p.getTag(types.LabelBackendLoadbalancerSticky, tags, "")
|
||||||
if len(stickyTag) > 0 {
|
if len(stickyTag) > 0 {
|
||||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", types.LabelBackendLoadbalancerSticky, types.LabelBackendLoadbalancerStickiness)
|
log.Warnf("Deprecated configuration found: %s. Please use %s.", types.LabelBackendLoadbalancerSticky, types.LabelBackendLoadbalancerStickiness)
|
||||||
|
} else {
|
||||||
|
stickyTag = "false"
|
||||||
}
|
}
|
||||||
|
return stickyTag
|
||||||
|
}
|
||||||
|
|
||||||
stickiness := len(stickinessTag) > 0 && strings.EqualFold(strings.TrimSpace(stickinessTag), "true")
|
func (p *CatalogProvider) hasStickinessLabel(tags []string) bool {
|
||||||
sticky := len(stickyTag) > 0 && strings.EqualFold(strings.TrimSpace(stickyTag), "true")
|
stickinessTag := p.getTag(types.LabelBackendLoadbalancerStickiness, tags, "")
|
||||||
return stickiness || sticky
|
return len(stickinessTag) > 0 && strings.EqualFold(strings.TrimSpace(stickinessTag), "true")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CatalogProvider) getStickinessCookieName(tags []string) string {
|
func (p *CatalogProvider) getStickinessCookieName(tags []string) string {
|
||||||
|
@ -465,6 +467,7 @@ func (p *CatalogProvider) buildConfig(catalog []catalogUpdate) *types.Configurat
|
||||||
"getBackendName": p.getBackendName,
|
"getBackendName": p.getBackendName,
|
||||||
"getBackendAddress": p.getBackendAddress,
|
"getBackendAddress": p.getBackendAddress,
|
||||||
"getBasicAuth": p.getBasicAuth,
|
"getBasicAuth": p.getBasicAuth,
|
||||||
|
"getSticky": p.getSticky,
|
||||||
"hasStickinessLabel": p.hasStickinessLabel,
|
"hasStickinessLabel": p.hasStickinessLabel,
|
||||||
"getStickinessCookieName": p.getStickinessCookieName,
|
"getStickinessCookieName": p.getStickinessCookieName,
|
||||||
"getAttribute": p.getAttribute,
|
"getAttribute": p.getAttribute,
|
||||||
|
|
|
@ -904,43 +904,19 @@ func TestConsulCatalogHasStickinessLabel(t *testing.T) {
|
||||||
tags: []string{},
|
tags: []string{},
|
||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "sticky=true",
|
|
||||||
tags: []string{
|
|
||||||
"traefik.backend.loadbalancer.sticky=true",
|
|
||||||
},
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
desc: "stickiness=true",
|
desc: "stickiness=true",
|
||||||
tags: []string{
|
tags: []string{
|
||||||
"traefik.backend.loadbalancer.stickiness=true",
|
types.LabelBackendLoadbalancerStickiness + "=true",
|
||||||
},
|
},
|
||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "sticky=true and stickiness=true",
|
desc: "stickiness=false",
|
||||||
tags: []string{
|
tags: []string{
|
||||||
"traefik.backend.loadbalancer.sticky=true",
|
types.LabelBackendLoadbalancerStickiness + "=false",
|
||||||
"traefik.backend.loadbalancer.stickiness=true",
|
|
||||||
},
|
},
|
||||||
expected: true,
|
expected: false,
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "sticky=false and stickiness=true",
|
|
||||||
tags: []string{
|
|
||||||
"traefik.backend.loadbalancer.sticky=true",
|
|
||||||
"traefik.backend.loadbalancer.stickiness=false",
|
|
||||||
},
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "sticky=true and stickiness=false",
|
|
||||||
tags: []string{
|
|
||||||
"traefik.backend.loadbalancer.sticky=true",
|
|
||||||
"traefik.backend.loadbalancer.stickiness=false",
|
|
||||||
},
|
|
||||||
expected: true,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -275,6 +275,7 @@ func (p *Provider) loadDockerConfig(containersInspected []dockerData) *types.Con
|
||||||
"hasMaxConnLabels": p.hasMaxConnLabels,
|
"hasMaxConnLabels": p.hasMaxConnLabels,
|
||||||
"getMaxConnAmount": p.getMaxConnAmount,
|
"getMaxConnAmount": p.getMaxConnAmount,
|
||||||
"getMaxConnExtractorFunc": p.getMaxConnExtractorFunc,
|
"getMaxConnExtractorFunc": p.getMaxConnExtractorFunc,
|
||||||
|
"getSticky": p.getSticky,
|
||||||
"getStickinessCookieName": p.getStickinessCookieName,
|
"getStickinessCookieName": p.getStickinessCookieName,
|
||||||
"hasStickinessLabel": p.hasStickinessLabel,
|
"hasStickinessLabel": p.hasStickinessLabel,
|
||||||
"getIsBackendLBSwarm": p.getIsBackendLBSwarm,
|
"getIsBackendLBSwarm": p.getIsBackendLBSwarm,
|
||||||
|
@ -465,10 +466,10 @@ func (p *Provider) getServiceProtocol(container dockerData, serviceName string)
|
||||||
func (p *Provider) hasLoadBalancerLabel(container dockerData) bool {
|
func (p *Provider) hasLoadBalancerLabel(container dockerData) bool {
|
||||||
_, errMethod := getLabel(container, types.LabelBackendLoadbalancerMethod)
|
_, errMethod := getLabel(container, types.LabelBackendLoadbalancerMethod)
|
||||||
_, errSticky := getLabel(container, types.LabelBackendLoadbalancerSticky)
|
_, errSticky := getLabel(container, types.LabelBackendLoadbalancerSticky)
|
||||||
if errMethod != nil && errSticky != nil {
|
_, errStickiness := getLabel(container, types.LabelBackendLoadbalancerStickiness)
|
||||||
return false
|
_, errCookieName := getLabel(container, types.LabelBackendLoadbalancerStickinessCookieName)
|
||||||
}
|
|
||||||
return true
|
return errMethod == nil || errSticky == nil || errStickiness == nil || errCookieName == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) hasMaxConnLabels(container dockerData) bool {
|
func (p *Provider) hasMaxConnLabels(container dockerData) bool {
|
||||||
|
@ -646,15 +647,17 @@ func (p *Provider) getWeight(container dockerData) string {
|
||||||
|
|
||||||
func (p *Provider) hasStickinessLabel(container dockerData) bool {
|
func (p *Provider) hasStickinessLabel(container dockerData) bool {
|
||||||
labelStickiness, errStickiness := getLabel(container, types.LabelBackendLoadbalancerStickiness)
|
labelStickiness, errStickiness := getLabel(container, types.LabelBackendLoadbalancerStickiness)
|
||||||
|
return errStickiness == nil && len(labelStickiness) > 0 && strings.EqualFold(strings.TrimSpace(labelStickiness), "true")
|
||||||
|
}
|
||||||
|
|
||||||
labelSticky, errSticky := getLabel(container, types.LabelBackendLoadbalancerSticky)
|
func (p *Provider) getSticky(container dockerData) string {
|
||||||
if len(labelSticky) > 0 {
|
if label, err := getLabel(container, types.LabelBackendLoadbalancerSticky); err == nil {
|
||||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", types.LabelBackendLoadbalancerSticky, types.LabelBackendLoadbalancerStickiness)
|
if len(label) > 0 {
|
||||||
|
log.Warnf("Deprecated configuration found: %s. Please use %s.", types.LabelBackendLoadbalancerSticky, types.LabelBackendLoadbalancerStickiness)
|
||||||
|
}
|
||||||
|
return label
|
||||||
}
|
}
|
||||||
|
return "false"
|
||||||
stickiness := errStickiness == nil && len(labelStickiness) > 0 && strings.EqualFold(strings.TrimSpace(labelStickiness), "true")
|
|
||||||
sticky := errSticky == nil && len(labelSticky) > 0 && strings.EqualFold(strings.TrimSpace(labelSticky), "true")
|
|
||||||
return stickiness || sticky
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) getStickinessCookieName(container dockerData) string {
|
func (p *Provider) getStickinessCookieName(container dockerData) string {
|
||||||
|
|
|
@ -1060,24 +1060,10 @@ func TestDockerHasStickinessLabel(t *testing.T) {
|
||||||
expected bool
|
expected bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
desc: "no sticky/stickiness-label",
|
desc: "no stickiness-label",
|
||||||
container: containerJSON(),
|
container: containerJSON(),
|
||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "sticky true",
|
|
||||||
container: containerJSON(labels(map[string]string{
|
|
||||||
types.LabelBackendLoadbalancerSticky: "true",
|
|
||||||
})),
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "sticky false",
|
|
||||||
container: containerJSON(labels(map[string]string{
|
|
||||||
types.LabelBackendLoadbalancerSticky: "false",
|
|
||||||
})),
|
|
||||||
expected: false,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
desc: "stickiness true",
|
desc: "stickiness true",
|
||||||
container: containerJSON(labels(map[string]string{
|
container: containerJSON(labels(map[string]string{
|
||||||
|
@ -1092,30 +1078,6 @@ func TestDockerHasStickinessLabel(t *testing.T) {
|
||||||
})),
|
})),
|
||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "sticky true + stickiness false",
|
|
||||||
container: containerJSON(labels(map[string]string{
|
|
||||||
types.LabelBackendLoadbalancerSticky: "true",
|
|
||||||
types.LabelBackendLoadbalancerStickiness: "false",
|
|
||||||
})),
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "sticky false + stickiness true",
|
|
||||||
container: containerJSON(labels(map[string]string{
|
|
||||||
types.LabelBackendLoadbalancerSticky: "false",
|
|
||||||
types.LabelBackendLoadbalancerStickiness: "true",
|
|
||||||
})),
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "sticky false + stickiness false",
|
|
||||||
container: containerJSON(labels(map[string]string{
|
|
||||||
types.LabelBackendLoadbalancerSticky: "false",
|
|
||||||
types.LabelBackendLoadbalancerStickiness: "false",
|
|
||||||
})),
|
|
||||||
expected: false,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
|
|
@ -184,6 +184,7 @@ func (p *Provider) loadECSConfig(ctx context.Context, client *awsClient) (*types
|
||||||
"getFrontendRule": p.getFrontendRule,
|
"getFrontendRule": p.getFrontendRule,
|
||||||
"getBasicAuth": p.getBasicAuth,
|
"getBasicAuth": p.getBasicAuth,
|
||||||
"getLoadBalancerMethod": p.getLoadBalancerMethod,
|
"getLoadBalancerMethod": p.getLoadBalancerMethod,
|
||||||
|
"getLoadBalancerSticky": p.getLoadBalancerSticky,
|
||||||
"hasStickinessLabel": p.hasStickinessLabel,
|
"hasStickinessLabel": p.hasStickinessLabel,
|
||||||
"getStickinessCookieName": p.getStickinessCookieName,
|
"getStickinessCookieName": p.getStickinessCookieName,
|
||||||
}
|
}
|
||||||
|
@ -485,16 +486,20 @@ func getFirstInstanceLabel(instances []ecsInstance, labelName string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Provider) getLoadBalancerSticky(instances []ecsInstance) string {
|
||||||
|
if len(instances) > 0 {
|
||||||
|
label := getFirstInstanceLabel(instances, types.LabelBackendLoadbalancerSticky)
|
||||||
|
if label != "" {
|
||||||
|
log.Warnf("Deprecated configuration found: %s. Please use %s.", types.LabelBackendLoadbalancerSticky, types.LabelBackendLoadbalancerStickiness)
|
||||||
|
return label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "false"
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Provider) hasStickinessLabel(instances []ecsInstance) bool {
|
func (p *Provider) hasStickinessLabel(instances []ecsInstance) bool {
|
||||||
stickinessLabel := getFirstInstanceLabel(instances, types.LabelBackendLoadbalancerStickiness)
|
stickinessLabel := getFirstInstanceLabel(instances, types.LabelBackendLoadbalancerStickiness)
|
||||||
|
return len(stickinessLabel) > 0 && strings.EqualFold(strings.TrimSpace(stickinessLabel), "true")
|
||||||
stickyLabel := getFirstInstanceLabel(instances, types.LabelBackendLoadbalancerSticky)
|
|
||||||
if len(stickyLabel) > 0 {
|
|
||||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", types.LabelBackendLoadbalancerSticky, types.LabelBackendLoadbalancerStickiness)
|
|
||||||
}
|
|
||||||
stickiness := len(stickinessLabel) > 0 && strings.EqualFold(strings.TrimSpace(stickinessLabel), "true")
|
|
||||||
sticky := len(stickyLabel) > 0 && strings.EqualFold(strings.TrimSpace(stickyLabel), "true")
|
|
||||||
return stickiness || sticky
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) getStickinessCookieName(instances []ecsInstance) string {
|
func (p *Provider) getStickinessCookieName(instances []ecsInstance) string {
|
||||||
|
|
|
@ -248,13 +248,15 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
||||||
templateObjects.Backends[r.Host+pa.Path].LoadBalancer.Method = "drr"
|
templateObjects.Backends[r.Host+pa.Path].LoadBalancer.Method = "drr"
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(service.Annotations[types.LabelBackendLoadbalancerSticky]) > 0 {
|
if sticky := service.Annotations[types.LabelBackendLoadbalancerSticky]; len(sticky) > 0 {
|
||||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", types.LabelBackendLoadbalancerSticky, types.LabelBackendLoadbalancerStickiness)
|
log.Warnf("Deprecated configuration found: %s. Please use %s.", types.LabelBackendLoadbalancerSticky, types.LabelBackendLoadbalancerStickiness)
|
||||||
|
templateObjects.Backends[r.Host+pa.Path].LoadBalancer.Sticky = strings.EqualFold(strings.TrimSpace(sticky), "true")
|
||||||
}
|
}
|
||||||
|
|
||||||
if service.Annotations[types.LabelBackendLoadbalancerSticky] == "true" || service.Annotations[types.LabelBackendLoadbalancerStickiness] == "true" {
|
if service.Annotations[types.LabelBackendLoadbalancerStickiness] == "true" {
|
||||||
templateObjects.Backends[r.Host+pa.Path].LoadBalancer.Stickiness = &types.Stickiness{
|
templateObjects.Backends[r.Host+pa.Path].LoadBalancer.Stickiness = &types.Stickiness{}
|
||||||
CookieName: r.Host + pa.Path,
|
if cookieName := service.Annotations[types.LabelBackendLoadbalancerStickinessCookieName]; len(cookieName) > 0 {
|
||||||
|
templateObjects.Backends[r.Host+pa.Path].LoadBalancer.Stickiness.CookieName = cookieName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1325,9 +1325,7 @@ func TestServiceAnnotations(t *testing.T) {
|
||||||
CircuitBreaker: nil,
|
CircuitBreaker: nil,
|
||||||
LoadBalancer: &types.LoadBalancer{
|
LoadBalancer: &types.LoadBalancer{
|
||||||
Method: "wrr",
|
Method: "wrr",
|
||||||
Stickiness: &types.Stickiness{
|
Sticky: true,
|
||||||
CookieName: "bar",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1356,7 +1354,7 @@ func TestServiceAnnotations(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, expected, actual)
|
assert.EqualValues(t, expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIngressAnnotations(t *testing.T) {
|
func TestIngressAnnotations(t *testing.T) {
|
||||||
|
|
|
@ -144,6 +144,7 @@ func (p *Provider) loadConfig() *types.Configuration {
|
||||||
"Get": p.get,
|
"Get": p.get,
|
||||||
"SplitGet": p.splitGet,
|
"SplitGet": p.splitGet,
|
||||||
"Last": p.last,
|
"Last": p.last,
|
||||||
|
"getSticky": p.getSticky,
|
||||||
"hasStickinessLabel": p.hasStickinessLabel,
|
"hasStickinessLabel": p.hasStickinessLabel,
|
||||||
"getStickinessCookieName": p.getStickinessCookieName,
|
"getStickinessCookieName": p.getStickinessCookieName,
|
||||||
}
|
}
|
||||||
|
@ -242,18 +243,19 @@ func (p *Provider) checkConstraints(keys ...string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) hasStickinessLabel(rootPath string) bool {
|
func (p *Provider) getSticky(rootPath string) string {
|
||||||
stickyValue := p.get("false", rootPath, "/loadbalancer", "/sticky")
|
stickyValue := p.get("", rootPath, "/loadbalancer", "/sticky")
|
||||||
|
if len(stickyValue) > 0 {
|
||||||
sticky := len(stickyValue) != 0 && strings.EqualFold(strings.TrimSpace(stickyValue), "true")
|
|
||||||
if sticky {
|
|
||||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", "loadbalancer/sticky", "loadbalancer/stickiness")
|
log.Warnf("Deprecated configuration found: %s. Please use %s.", "loadbalancer/sticky", "loadbalancer/stickiness")
|
||||||
|
} else {
|
||||||
|
stickyValue = "false"
|
||||||
}
|
}
|
||||||
|
return stickyValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Provider) hasStickinessLabel(rootPath string) bool {
|
||||||
stickinessValue := p.get("false", rootPath, "/loadbalancer", "/stickiness")
|
stickinessValue := p.get("false", rootPath, "/loadbalancer", "/stickiness")
|
||||||
stickiness := len(stickinessValue) > 0 && strings.EqualFold(strings.TrimSpace(stickinessValue), "true")
|
return len(stickinessValue) > 0 && strings.EqualFold(strings.TrimSpace(stickinessValue), "true")
|
||||||
|
|
||||||
return stickiness || sticky
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) getStickinessCookieName(rootPath string) string {
|
func (p *Provider) getStickinessCookieName(rootPath string) string {
|
||||||
|
|
|
@ -399,48 +399,6 @@ func TestKVHasStickinessLabel(t *testing.T) {
|
||||||
},
|
},
|
||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "stickiness=true and sticky=true",
|
|
||||||
KVPairs: []*store.KVPair{
|
|
||||||
{
|
|
||||||
Key: "loadbalancer/stickiness",
|
|
||||||
Value: []byte("true"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Key: "loadbalancer/sticky",
|
|
||||||
Value: []byte("true"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "stickiness=false and sticky=true",
|
|
||||||
KVPairs: []*store.KVPair{
|
|
||||||
{
|
|
||||||
Key: "loadbalancer/stickiness",
|
|
||||||
Value: []byte("false"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Key: "loadbalancer/sticky",
|
|
||||||
Value: []byte("true"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "stickiness=true and sticky=false",
|
|
||||||
KVPairs: []*store.KVPair{
|
|
||||||
{
|
|
||||||
Key: "loadbalancer/stickiness",
|
|
||||||
Value: []byte("true"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Key: "loadbalancer/sticky",
|
|
||||||
Value: []byte("false"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
|
|
@ -188,8 +188,9 @@ func (p *Provider) loadMarathonConfig() *types.Configuration {
|
||||||
"getMaxConnAmount": p.getMaxConnAmount,
|
"getMaxConnAmount": p.getMaxConnAmount,
|
||||||
"getLoadBalancerMethod": p.getLoadBalancerMethod,
|
"getLoadBalancerMethod": p.getLoadBalancerMethod,
|
||||||
"getCircuitBreakerExpression": p.getCircuitBreakerExpression,
|
"getCircuitBreakerExpression": p.getCircuitBreakerExpression,
|
||||||
"getStickinessCookieName": p.getStickinessCookieName,
|
"getSticky": p.getSticky,
|
||||||
"hasStickinessLabel": p.hasStickinessLabel,
|
"hasStickinessLabel": p.hasStickinessLabel,
|
||||||
|
"getStickinessCookieName": p.getStickinessCookieName,
|
||||||
"hasHealthCheckLabels": p.hasHealthCheckLabels,
|
"hasHealthCheckLabels": p.hasHealthCheckLabels,
|
||||||
"getHealthCheckPath": p.getHealthCheckPath,
|
"getHealthCheckPath": p.getHealthCheckPath,
|
||||||
"getHealthCheckInterval": p.getHealthCheckInterval,
|
"getHealthCheckInterval": p.getHealthCheckInterval,
|
||||||
|
@ -429,17 +430,17 @@ func (p *Provider) getProtocol(application marathon.Application, serviceName str
|
||||||
return "http"
|
return "http"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Provider) getSticky(application marathon.Application) string {
|
||||||
|
if sticky, ok := p.getAppLabel(application, types.LabelBackendLoadbalancerSticky); ok {
|
||||||
|
log.Warnf("Deprecated configuration found: %s. Please use %s.", types.LabelBackendLoadbalancerSticky, types.LabelBackendLoadbalancerStickiness)
|
||||||
|
return sticky
|
||||||
|
}
|
||||||
|
return "false"
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Provider) hasStickinessLabel(application marathon.Application) bool {
|
func (p *Provider) hasStickinessLabel(application marathon.Application) bool {
|
||||||
labelStickiness, okStickiness := p.getAppLabel(application, types.LabelBackendLoadbalancerStickiness)
|
labelStickiness, okStickiness := p.getAppLabel(application, types.LabelBackendLoadbalancerStickiness)
|
||||||
|
return okStickiness && len(labelStickiness) > 0 && strings.EqualFold(strings.TrimSpace(labelStickiness), "true")
|
||||||
labelSticky, okSticky := p.getAppLabel(application, types.LabelBackendLoadbalancerSticky)
|
|
||||||
if len(labelSticky) > 0 {
|
|
||||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", types.LabelBackendLoadbalancerSticky, types.LabelBackendLoadbalancerStickiness)
|
|
||||||
}
|
|
||||||
|
|
||||||
stickiness := okStickiness && len(labelStickiness) > 0 && strings.EqualFold(strings.TrimSpace(labelStickiness), "true")
|
|
||||||
sticky := okSticky && len(labelSticky) > 0 && strings.EqualFold(strings.TrimSpace(labelSticky), "true")
|
|
||||||
return stickiness || sticky
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) getStickinessCookieName(application marathon.Application) string {
|
func (p *Provider) getStickinessCookieName(application marathon.Application) string {
|
||||||
|
|
|
@ -854,6 +854,36 @@ func TestMarathonGetProtocol(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func TestMarathonGetSticky(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
application marathon.Application
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "label missing",
|
||||||
|
application: application(),
|
||||||
|
expected: "false",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "label existing",
|
||||||
|
application: application(label(types.LabelBackendLoadbalancerSticky, "true")),
|
||||||
|
expected: "true",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
provider := &Provider{}
|
||||||
|
actual := provider.getSticky(test.application)
|
||||||
|
if actual != test.expected {
|
||||||
|
t.Errorf("actual %q, expected %q", actual, test.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestMarathonHasStickinessLabel(t *testing.T) {
|
func TestMarathonHasStickinessLabel(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
|
@ -866,16 +896,6 @@ func TestMarathonHasStickinessLabel(t *testing.T) {
|
||||||
application: application(),
|
application: application(),
|
||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "sticky=true (deprecated)",
|
|
||||||
application: application(label(types.LabelBackendLoadbalancerSticky, "true")),
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "sticky=false (deprecated)",
|
|
||||||
application: application(label(types.LabelBackendLoadbalancerSticky, "false")),
|
|
||||||
expected: false,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
desc: "stickiness=true",
|
desc: "stickiness=true",
|
||||||
application: application(label(types.LabelBackendLoadbalancerStickiness, "true")),
|
application: application(label(types.LabelBackendLoadbalancerStickiness, "true")),
|
||||||
|
@ -886,20 +906,6 @@ func TestMarathonHasStickinessLabel(t *testing.T) {
|
||||||
application: application(label(types.LabelBackendLoadbalancerStickiness, "true")),
|
application: application(label(types.LabelBackendLoadbalancerStickiness, "true")),
|
||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "sticky=false stickiness=true ",
|
|
||||||
application: application(
|
|
||||||
label(types.LabelBackendLoadbalancerStickiness, "true"),
|
|
||||||
label(types.LabelBackendLoadbalancerSticky, "false")),
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "sticky=true stickiness=false ",
|
|
||||||
application: application(
|
|
||||||
label(types.LabelBackendLoadbalancerStickiness, "false"),
|
|
||||||
label(types.LabelBackendLoadbalancerSticky, "true")),
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
|
|
@ -92,10 +92,10 @@ func (p *Provider) getLoadBalancerMethod(service rancherData) string {
|
||||||
func (p *Provider) hasLoadBalancerLabel(service rancherData) bool {
|
func (p *Provider) hasLoadBalancerLabel(service rancherData) bool {
|
||||||
_, errMethod := getServiceLabel(service, types.LabelBackendLoadbalancerMethod)
|
_, errMethod := getServiceLabel(service, types.LabelBackendLoadbalancerMethod)
|
||||||
_, errSticky := getServiceLabel(service, types.LabelBackendLoadbalancerSticky)
|
_, errSticky := getServiceLabel(service, types.LabelBackendLoadbalancerSticky)
|
||||||
if errMethod != nil && errSticky != nil {
|
_, errStickiness := getServiceLabel(service, types.LabelBackendLoadbalancerStickiness)
|
||||||
return false
|
_, errCookieName := getServiceLabel(service, types.LabelBackendLoadbalancerStickinessCookieName)
|
||||||
}
|
|
||||||
return true
|
return errMethod == nil || errSticky == nil || errStickiness == nil || errCookieName == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) hasCircuitBreakerLabel(service rancherData) bool {
|
func (p *Provider) hasCircuitBreakerLabel(service rancherData) bool {
|
||||||
|
@ -112,17 +112,18 @@ func (p *Provider) getCircuitBreakerExpression(service rancherData) string {
|
||||||
return "NetworkErrorRatio() > 1"
|
return "NetworkErrorRatio() > 1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Provider) getSticky(service rancherData) string {
|
||||||
|
if _, err := getServiceLabel(service, types.LabelBackendLoadbalancerSticky); err == nil {
|
||||||
|
log.Warnf("Deprecated configuration found: %s. Please use %s.", types.LabelBackendLoadbalancerSticky, types.LabelBackendLoadbalancerStickiness)
|
||||||
|
return "true"
|
||||||
|
}
|
||||||
|
return "false"
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Provider) hasStickinessLabel(service rancherData) bool {
|
func (p *Provider) hasStickinessLabel(service rancherData) bool {
|
||||||
labelStickiness, errStickiness := getServiceLabel(service, types.LabelBackendLoadbalancerStickiness)
|
labelStickiness, errStickiness := getServiceLabel(service, types.LabelBackendLoadbalancerStickiness)
|
||||||
|
|
||||||
labelSticky, errSticky := getServiceLabel(service, types.LabelBackendLoadbalancerSticky)
|
return errStickiness == nil && len(labelStickiness) > 0 && strings.EqualFold(strings.TrimSpace(labelStickiness), "true")
|
||||||
if len(labelSticky) > 0 {
|
|
||||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", types.LabelBackendLoadbalancerSticky, types.LabelBackendLoadbalancerStickiness)
|
|
||||||
}
|
|
||||||
|
|
||||||
stickiness := errStickiness == nil && len(labelStickiness) > 0 && strings.EqualFold(strings.TrimSpace(labelStickiness), "true")
|
|
||||||
sticky := errSticky == nil && len(labelSticky) > 0 && strings.EqualFold(strings.TrimSpace(labelSticky), "true")
|
|
||||||
return stickiness || sticky
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) getStickinessCookieName(service rancherData, backendName string) string {
|
func (p *Provider) getStickinessCookieName(service rancherData, backendName string) string {
|
||||||
|
@ -235,6 +236,7 @@ func (p *Provider) loadRancherConfig(services []rancherData) *types.Configuratio
|
||||||
"hasMaxConnLabels": p.hasMaxConnLabels,
|
"hasMaxConnLabels": p.hasMaxConnLabels,
|
||||||
"getMaxConnAmount": p.getMaxConnAmount,
|
"getMaxConnAmount": p.getMaxConnAmount,
|
||||||
"getMaxConnExtractorFunc": p.getMaxConnExtractorFunc,
|
"getMaxConnExtractorFunc": p.getMaxConnExtractorFunc,
|
||||||
|
"getSticky": p.getSticky,
|
||||||
"hasStickinessLabel": p.hasStickinessLabel,
|
"hasStickinessLabel": p.hasStickinessLabel,
|
||||||
"getStickinessCookieName": p.getStickinessCookieName,
|
"getStickinessCookieName": p.getStickinessCookieName,
|
||||||
}
|
}
|
||||||
|
|
|
@ -616,16 +616,6 @@ func TestRancherHasStickinessLabel(t *testing.T) {
|
||||||
},
|
},
|
||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "sticky=true",
|
|
||||||
service: rancherData{
|
|
||||||
Name: "test-service",
|
|
||||||
Labels: map[string]string{
|
|
||||||
types.LabelBackendLoadbalancerSticky: "true",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
desc: "stickiness=true",
|
desc: "stickiness=true",
|
||||||
service: rancherData{
|
service: rancherData{
|
||||||
|
@ -637,49 +627,15 @@ func TestRancherHasStickinessLabel(t *testing.T) {
|
||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "sticky=true and stickiness=true",
|
desc: "stickiness=true",
|
||||||
service: rancherData{
|
service: rancherData{
|
||||||
Name: "test-service",
|
Name: "test-service",
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
types.LabelBackendLoadbalancerSticky: "true",
|
|
||||||
types.LabelBackendLoadbalancerStickiness: "true",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "sticky=false and stickiness=false",
|
|
||||||
service: rancherData{
|
|
||||||
Name: "test-service",
|
|
||||||
Labels: map[string]string{
|
|
||||||
types.LabelBackendLoadbalancerSticky: "false",
|
|
||||||
types.LabelBackendLoadbalancerStickiness: "false",
|
types.LabelBackendLoadbalancerStickiness: "false",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "sticky=true and stickiness=false",
|
|
||||||
service: rancherData{
|
|
||||||
Name: "test-service",
|
|
||||||
Labels: map[string]string{
|
|
||||||
types.LabelBackendLoadbalancerSticky: "true",
|
|
||||||
types.LabelBackendLoadbalancerStickiness: "false",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "sticky=false and stickiness=true",
|
|
||||||
service: rancherData{
|
|
||||||
Name: "test-service",
|
|
||||||
Labels: map[string]string{
|
|
||||||
types.LabelBackendLoadbalancerSticky: "false",
|
|
||||||
types.LabelBackendLoadbalancerStickiness: "true",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
|
|
@ -1172,7 +1172,8 @@ func (server *Server) configureFrontends(frontends map[string]*types.Frontend) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Server) configureBackends(backends map[string]*types.Backend) {
|
func (*Server) configureBackends(backends map[string]*types.Backend) {
|
||||||
for backendName, backend := range backends {
|
for backendName := range backends {
|
||||||
|
backend := backends[backendName]
|
||||||
if backend.LoadBalancer != nil && backend.LoadBalancer.Sticky {
|
if backend.LoadBalancer != nil && backend.LoadBalancer.Sticky {
|
||||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", "backend.LoadBalancer.Sticky", "backend.LoadBalancer.Stickiness")
|
log.Warnf("Deprecated configuration found: %s. Please use %s.", "backend.LoadBalancer.Sticky", "backend.LoadBalancer.Stickiness")
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
|
|
||||||
[backends."backend-{{$service}}".loadbalancer]
|
[backends."backend-{{$service}}".loadbalancer]
|
||||||
method = "{{getAttribute "backend.loadbalancer" .Attributes "wrr"}}"
|
method = "{{getAttribute "backend.loadbalancer" .Attributes "wrr"}}"
|
||||||
sticky = {{getAttribute "backend.loadbalancer.sticky" .Attributes "false"}}
|
sticky = {{getSticky .Attributes}}
|
||||||
{{if hasStickinessLabel .Attributes}}
|
{{if hasStickinessLabel .Attributes}}
|
||||||
[Backends."backend-{{$service}}".LoadBalancer.Stickiness]
|
[backends."backend-{{$service}}".loadbalancer.stickiness]
|
||||||
cookieName = "{{getStickinessCookieName .Attributes}}"
|
cookieName = "{{getStickinessCookieName .Attributes}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,9 @@
|
||||||
{{if hasLoadBalancerLabel $backend}}
|
{{if hasLoadBalancerLabel $backend}}
|
||||||
[backends.backend-{{$backendName}}.loadbalancer]
|
[backends.backend-{{$backendName}}.loadbalancer]
|
||||||
method = "{{getLoadBalancerMethod $backend}}"
|
method = "{{getLoadBalancerMethod $backend}}"
|
||||||
|
sticky = {{getSticky $backend}}
|
||||||
{{if hasStickinessLabel $backend}}
|
{{if hasStickinessLabel $backend}}
|
||||||
[Backends."{{$backendName}}".LoadBalancer.Stickiness]
|
[backends.backend-{{$backendName}}.loadBalancer.stickiness]
|
||||||
cookieName = "{{getStickinessCookieName $backend}}"
|
cookieName = "{{getStickinessCookieName $backend}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
[backends]{{range $serviceName, $instances := .Services}}
|
[backends]{{range $serviceName, $instances := .Services}}
|
||||||
[backends.backend-{{ $serviceName }}.loadbalancer]
|
[backends.backend-{{ $serviceName }}.loadbalancer]
|
||||||
method = "{{ getLoadBalancerMethod $instances}}"
|
method = "{{ getLoadBalancerMethod $instances}}"
|
||||||
|
sticky = {{ getLoadBalancerSticky $instances}}
|
||||||
{{if hasStickinessLabel $instances}}
|
{{if hasStickinessLabel $instances}}
|
||||||
[Backends.backend-{{ $serviceName }}.LoadBalancer.Stickiness]
|
[backends.backend-{{ $serviceName }}.loadbalancer.stickiness]
|
||||||
cookieName = "{{getStickinessCookieName $instances}}"
|
cookieName = "{{getStickinessCookieName $instances}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,11 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
[backends."{{$backendName}}".loadbalancer]
|
[backends."{{$backendName}}".loadbalancer]
|
||||||
method = "{{$backend.LoadBalancer.Method}}"
|
method = "{{$backend.LoadBalancer.Method}}"
|
||||||
|
{{if $backend.LoadBalancer.Sticky}}
|
||||||
|
sticky = true
|
||||||
|
{{end}}
|
||||||
{{if $backend.LoadBalancer.Stickiness}}
|
{{if $backend.LoadBalancer.Stickiness}}
|
||||||
[Backends."{{$backendName}}".LoadBalancer.Stickiness]
|
[backends."{{$backendName}}".loadbalancer.stickiness]
|
||||||
cookieName = "{{$backend.LoadBalancer.Stickiness.CookieName}}"
|
cookieName = "{{$backend.LoadBalancer.Stickiness.CookieName}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
{{range $serverName, $server := $backend.Servers}}
|
{{range $serverName, $server := $backend.Servers}}
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
{{with $loadBalancer}}
|
{{with $loadBalancer}}
|
||||||
[backends."{{$backendName}}".loadBalancer]
|
[backends."{{$backendName}}".loadBalancer]
|
||||||
method = "{{$loadBalancer}}"
|
method = "{{$loadBalancer}}"
|
||||||
sticky = {{ Get "false" . "/loadbalancer/" "sticky" }}
|
sticky = {{ getSticky . }}
|
||||||
{{if hasStickinessLabel $backend}}
|
{{if hasStickinessLabel $backend}}
|
||||||
[Backends."{{$backendName}}".LoadBalancer.Stickiness]
|
[backends."{{$backendName}}".loadBalancer.stickiness]
|
||||||
cookieName = {{getStickinessCookieName $backend}}
|
cookieName = {{getStickinessCookieName $backend}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -20,8 +20,9 @@
|
||||||
{{ if hasLoadBalancerLabels $app }}
|
{{ if hasLoadBalancerLabels $app }}
|
||||||
[backends."backend{{getBackend $app $serviceName }}".loadbalancer]
|
[backends."backend{{getBackend $app $serviceName }}".loadbalancer]
|
||||||
method = "{{getLoadBalancerMethod $app }}"
|
method = "{{getLoadBalancerMethod $app }}"
|
||||||
|
sticky = {{getSticky $app}}
|
||||||
{{if hasStickinessLabel $app}}
|
{{if hasStickinessLabel $app}}
|
||||||
[Backends."backend{{getBackend $app $serviceName }}".LoadBalancer.Stickiness]
|
[backends."backend{{getBackend $app $serviceName }}".loadbalancer.stickiness]
|
||||||
cookieName = "{{getStickinessCookieName $app}}"
|
cookieName = "{{getStickinessCookieName $app}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -8,8 +8,9 @@
|
||||||
{{if hasLoadBalancerLabel $backend}}
|
{{if hasLoadBalancerLabel $backend}}
|
||||||
[backends.backend-{{$backendName}}.loadbalancer]
|
[backends.backend-{{$backendName}}.loadbalancer]
|
||||||
method = "{{getLoadBalancerMethod $backend}}"
|
method = "{{getLoadBalancerMethod $backend}}"
|
||||||
|
sticky = {{getSticky $backend}}
|
||||||
{{if hasStickinessLabel $backend}}
|
{{if hasStickinessLabel $backend}}
|
||||||
[Backends."{{$backendName}}".LoadBalancer.Stickiness]
|
[backends.backend-{{$backendName}}.loadbalancer.stickiness]
|
||||||
cookieName = "{{getStickinessCookieName $backend}}"
|
cookieName = "{{getStickinessCookieName $backend}}"
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
Loading…
Reference in a new issue