mirror of https://github.com/status-im/consul.git
Add session flag to cookie config
This commit is contained in:
parent
31fb1b75b5
commit
768dbaa68d
|
@ -1286,6 +1286,11 @@ func setupTestVariationConfigEntriesAndSnapshot(
|
||||||
FieldValue: "chocolate-chip",
|
FieldValue: "chocolate-chip",
|
||||||
Terminal: true,
|
Terminal: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Field: "cookie",
|
||||||
|
FieldValue: "chocolate-chip",
|
||||||
|
CookieConfig: &structs.CookieConfig{Session: true},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Field: "header",
|
Field: "header",
|
||||||
FieldValue: "x-user-id",
|
FieldValue: "x-user-id",
|
||||||
|
|
|
@ -882,9 +882,14 @@ func (e *ServiceResolverConfigEntry) Validate() error {
|
||||||
if hp.FieldValue != "" && hp.Field == "" {
|
if hp.FieldValue != "" && hp.Field == "" {
|
||||||
return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: FieldValue requires a Field to apply to", i)
|
return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: FieldValue requires a Field to apply to", i)
|
||||||
}
|
}
|
||||||
if hp.CookieConfig != nil && hp.Field != HashPolicyCookie {
|
if hp.CookieConfig != nil {
|
||||||
|
if hp.Field != HashPolicyCookie {
|
||||||
return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: cookie_config provided for %q", i, hp.Field)
|
return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: cookie_config provided for %q", i, hp.Field)
|
||||||
}
|
}
|
||||||
|
if hp.CookieConfig.Session && hp.CookieConfig.TTL != 0*time.Second {
|
||||||
|
return fmt.Errorf("Bad LoadBalancer HashPolicy[%d]: a session cookie cannot have an associated TTL", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1087,7 +1092,10 @@ type HashPolicy struct {
|
||||||
// CookieConfig contains configuration for the "cookie" hash policy type.
|
// CookieConfig contains configuration for the "cookie" hash policy type.
|
||||||
// This is specified to have Envoy generate a cookie for a client on its first request.
|
// This is specified to have Envoy generate a cookie for a client on its first request.
|
||||||
type CookieConfig struct {
|
type CookieConfig struct {
|
||||||
// TTL for generated cookies
|
// Generates a session cookie with no expiration.
|
||||||
|
Session bool `json:",omitempty"`
|
||||||
|
|
||||||
|
// TTL for generated cookies. Cannot be specified for session cookies.
|
||||||
TTL time.Duration `json:",omitempty"`
|
TTL time.Duration `json:",omitempty"`
|
||||||
|
|
||||||
// The path to set for the cookie
|
// The path to set for the cookie
|
||||||
|
|
|
@ -656,7 +656,7 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) {
|
||||||
validateErr: `HashPolicies specified for non-hash-based Policy`,
|
validateErr: `HashPolicies specified for non-hash-based Policy`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "empty policy with hash policy",
|
name: "cookie config with header policy",
|
||||||
entry: &ServiceResolverConfigEntry{
|
entry: &ServiceResolverConfigEntry{
|
||||||
Kind: ServiceResolver,
|
Kind: ServiceResolver,
|
||||||
Name: "test",
|
Name: "test",
|
||||||
|
@ -677,7 +677,28 @@ func TestServiceResolverConfigEntry_LoadBalancer(t *testing.T) {
|
||||||
validateErr: `cookie_config provided for "header"`,
|
validateErr: `cookie_config provided for "header"`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "empty policy with hash policy",
|
name: "cannot generate session cookie with ttl",
|
||||||
|
entry: &ServiceResolverConfigEntry{
|
||||||
|
Kind: ServiceResolver,
|
||||||
|
Name: "test",
|
||||||
|
LoadBalancer: &LoadBalancer{
|
||||||
|
Policy: LBPolicyMaglev,
|
||||||
|
HashPolicies: []HashPolicy{
|
||||||
|
{
|
||||||
|
Field: HashPolicyCookie,
|
||||||
|
FieldValue: "good-cookie",
|
||||||
|
CookieConfig: &CookieConfig{
|
||||||
|
Session: true,
|
||||||
|
TTL: 10 * time.Second,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
validateErr: `a session cookie cannot have an associated TTL`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid cookie policy",
|
||||||
entry: &ServiceResolverConfigEntry{
|
entry: &ServiceResolverConfigEntry{
|
||||||
Kind: ServiceResolver,
|
Kind: ServiceResolver,
|
||||||
Name: "test",
|
Name: "test",
|
||||||
|
|
|
@ -531,6 +531,156 @@ func TestDecodeConfigEntry(t *testing.T) {
|
||||||
Name: "main",
|
Name: "main",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "service-resolver: envoy hash lb kitchen sink",
|
||||||
|
snake: `
|
||||||
|
kind = "service-resolver"
|
||||||
|
name = "main"
|
||||||
|
load_balancer = {
|
||||||
|
policy = "ring_hash"
|
||||||
|
ring_hash_config = {
|
||||||
|
minimum_ring_size = 1
|
||||||
|
maximum_ring_size = 2
|
||||||
|
}
|
||||||
|
hash_policies = [
|
||||||
|
{
|
||||||
|
field = "cookie"
|
||||||
|
field_value = "good-cookie"
|
||||||
|
cookie_config = {
|
||||||
|
ttl = "1s"
|
||||||
|
path = "/oven"
|
||||||
|
}
|
||||||
|
terminal = true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field = "cookie"
|
||||||
|
field_value = "less-good-cookie"
|
||||||
|
cookie_config = {
|
||||||
|
session = true
|
||||||
|
path = "/toaster"
|
||||||
|
}
|
||||||
|
terminal = true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field = "header"
|
||||||
|
field_value = "x-user-id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source_ip = true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
camel: `
|
||||||
|
Kind = "service-resolver"
|
||||||
|
Name = "main"
|
||||||
|
LoadBalancer = {
|
||||||
|
Policy = "ring_hash"
|
||||||
|
RingHashConfig = {
|
||||||
|
MinimumRingSize = 1
|
||||||
|
MaximumRingSize = 2
|
||||||
|
}
|
||||||
|
HashPolicies = [
|
||||||
|
{
|
||||||
|
Field = "cookie"
|
||||||
|
FieldValue = "good-cookie"
|
||||||
|
CookieConfig = {
|
||||||
|
TTL = "1s"
|
||||||
|
Path = "/oven"
|
||||||
|
}
|
||||||
|
Terminal = true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Field = "cookie"
|
||||||
|
FieldValue = "less-good-cookie"
|
||||||
|
CookieConfig = {
|
||||||
|
Session = true
|
||||||
|
Path = "/toaster"
|
||||||
|
}
|
||||||
|
Terminal = true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Field = "header"
|
||||||
|
FieldValue = "x-user-id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
SourceIP = true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
expect: &ServiceResolverConfigEntry{
|
||||||
|
Kind: "service-resolver",
|
||||||
|
Name: "main",
|
||||||
|
LoadBalancer: &LoadBalancer{
|
||||||
|
Policy: LBPolicyRingHash,
|
||||||
|
RingHashConfig: &RingHashConfig{
|
||||||
|
MinimumRingSize: 1,
|
||||||
|
MaximumRingSize: 2,
|
||||||
|
},
|
||||||
|
HashPolicies: []HashPolicy{
|
||||||
|
{
|
||||||
|
Field: HashPolicyCookie,
|
||||||
|
FieldValue: "good-cookie",
|
||||||
|
CookieConfig: &CookieConfig{
|
||||||
|
TTL: 1 * time.Second,
|
||||||
|
Path: "/oven",
|
||||||
|
},
|
||||||
|
Terminal: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Field: HashPolicyCookie,
|
||||||
|
FieldValue: "less-good-cookie",
|
||||||
|
CookieConfig: &CookieConfig{
|
||||||
|
Session: true,
|
||||||
|
Path: "/toaster",
|
||||||
|
},
|
||||||
|
Terminal: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Field: HashPolicyHeader,
|
||||||
|
FieldValue: "x-user-id",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
SourceIP: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "service-resolver: envoy least request kitchen sink",
|
||||||
|
snake: `
|
||||||
|
kind = "service-resolver"
|
||||||
|
name = "main"
|
||||||
|
load_balancer = {
|
||||||
|
policy = "least_request"
|
||||||
|
least_request_config = {
|
||||||
|
choice_count = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
camel: `
|
||||||
|
Kind = "service-resolver"
|
||||||
|
Name = "main"
|
||||||
|
LoadBalancer = {
|
||||||
|
Policy = "least_request"
|
||||||
|
LeastRequestConfig = {
|
||||||
|
ChoiceCount = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
expect: &ServiceResolverConfigEntry{
|
||||||
|
Kind: "service-resolver",
|
||||||
|
Name: "main",
|
||||||
|
LoadBalancer: &LoadBalancer{
|
||||||
|
Policy: LBPolicyLeastRequest,
|
||||||
|
LeastRequestConfig: &LeastRequestConfig{
|
||||||
|
ChoiceCount: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "ingress-gateway: kitchen sink",
|
name: "ingress-gateway: kitchen sink",
|
||||||
snake: `
|
snake: `
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
||||||
envoyroute "github.com/envoyproxy/go-control-plane/envoy/api/v2/route"
|
envoyroute "github.com/envoyproxy/go-control-plane/envoy/api/v2/route"
|
||||||
|
@ -614,8 +615,16 @@ func injectLBToRouteAction(lb *structs.LoadBalancer, action *envoyroute.RouteAct
|
||||||
Name: policy.FieldValue,
|
Name: policy.FieldValue,
|
||||||
}
|
}
|
||||||
if policy.CookieConfig != nil {
|
if policy.CookieConfig != nil {
|
||||||
cookie.Ttl = ptypes.DurationProto(policy.CookieConfig.TTL)
|
|
||||||
cookie.Path = policy.CookieConfig.Path
|
cookie.Path = policy.CookieConfig.Path
|
||||||
|
|
||||||
|
if policy.CookieConfig.TTL != 0*time.Second {
|
||||||
|
cookie.Ttl = ptypes.DurationProto(policy.CookieConfig.TTL)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Envoy will generate a session cookie if the ttl is present and zero.
|
||||||
|
if policy.CookieConfig.Session {
|
||||||
|
cookie.Ttl = ptypes.DurationProto(0 * time.Second)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result = append(result, &envoyroute.RouteAction_HashPolicy{
|
result = append(result, &envoyroute.RouteAction_HashPolicy{
|
||||||
PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{
|
PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{
|
||||||
|
|
|
@ -376,6 +376,62 @@ func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "non-zero session ttl gets zeroed out",
|
||||||
|
lb: &structs.LoadBalancer{
|
||||||
|
Policy: structs.LBPolicyMaglev,
|
||||||
|
HashPolicies: []structs.HashPolicy{
|
||||||
|
{
|
||||||
|
Field: structs.HashPolicyCookie,
|
||||||
|
FieldValue: "oatmeal",
|
||||||
|
CookieConfig: &structs.CookieConfig{
|
||||||
|
TTL: 10 * time.Second,
|
||||||
|
Session: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: envoyroute.RouteAction{
|
||||||
|
HashPolicy: []*envoyroute.RouteAction_HashPolicy{
|
||||||
|
{
|
||||||
|
PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{
|
||||||
|
Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{
|
||||||
|
Name: "oatmeal",
|
||||||
|
Ttl: ptypes.DurationProto(0 * time.Second),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "zero value ttl omitted if not session cookie",
|
||||||
|
lb: &structs.LoadBalancer{
|
||||||
|
Policy: structs.LBPolicyMaglev,
|
||||||
|
HashPolicies: []structs.HashPolicy{
|
||||||
|
{
|
||||||
|
Field: structs.HashPolicyCookie,
|
||||||
|
FieldValue: "oatmeal",
|
||||||
|
CookieConfig: &structs.CookieConfig{
|
||||||
|
Path: "/oven",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: envoyroute.RouteAction{
|
||||||
|
HashPolicy: []*envoyroute.RouteAction_HashPolicy{
|
||||||
|
{
|
||||||
|
PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{
|
||||||
|
Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{
|
||||||
|
Name: "oatmeal",
|
||||||
|
Path: "/oven",
|
||||||
|
Ttl: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "source addr",
|
name: "source addr",
|
||||||
lb: &structs.LoadBalancer{
|
lb: &structs.LoadBalancer{
|
||||||
|
@ -417,6 +473,14 @@ func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) {
|
||||||
Path: "/oven",
|
Path: "/oven",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Field: structs.HashPolicyCookie,
|
||||||
|
FieldValue: "chocolate-chip",
|
||||||
|
CookieConfig: &structs.CookieConfig{
|
||||||
|
Session: true,
|
||||||
|
Path: "/oven",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Field: structs.HashPolicyHeader,
|
Field: structs.HashPolicyHeader,
|
||||||
FieldValue: "special-header",
|
FieldValue: "special-header",
|
||||||
|
@ -443,6 +507,15 @@ func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Cookie_{
|
||||||
|
Cookie: &envoyroute.RouteAction_HashPolicy_Cookie{
|
||||||
|
Name: "chocolate-chip",
|
||||||
|
Ttl: ptypes.DurationProto(0 * time.Second),
|
||||||
|
Path: "/oven",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{
|
PolicySpecifier: &envoyroute.RouteAction_HashPolicy_Header_{
|
||||||
Header: &envoyroute.RouteAction_HashPolicy_Header{
|
Header: &envoyroute.RouteAction_HashPolicy_Header{
|
||||||
|
|
|
@ -36,6 +36,12 @@
|
||||||
},
|
},
|
||||||
"terminal": true
|
"terminal": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cookie": {
|
||||||
|
"name": "chocolate-chip",
|
||||||
|
"ttl": "0s"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"header": {
|
"header": {
|
||||||
"headerName": "x-user-id"
|
"headerName": "x-user-id"
|
||||||
|
|
|
@ -36,6 +36,12 @@
|
||||||
},
|
},
|
||||||
"terminal": true
|
"terminal": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cookie": {
|
||||||
|
"name": "chocolate-chip",
|
||||||
|
"ttl": "0s"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"header": {
|
"header": {
|
||||||
"headerName": "x-user-id"
|
"headerName": "x-user-id"
|
||||||
|
|
|
@ -36,6 +36,12 @@
|
||||||
},
|
},
|
||||||
"terminal": true
|
"terminal": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cookie": {
|
||||||
|
"name": "chocolate-chip",
|
||||||
|
"ttl": "0s"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"header": {
|
"header": {
|
||||||
"headerName": "x-user-id"
|
"headerName": "x-user-id"
|
||||||
|
|
|
@ -36,6 +36,12 @@
|
||||||
},
|
},
|
||||||
"terminal": true
|
"terminal": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cookie": {
|
||||||
|
"name": "chocolate-chip",
|
||||||
|
"ttl": "0s"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"header": {
|
"header": {
|
||||||
"headerName": "x-user-id"
|
"headerName": "x-user-id"
|
||||||
|
|
|
@ -37,6 +37,12 @@
|
||||||
},
|
},
|
||||||
"terminal": true
|
"terminal": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cookie": {
|
||||||
|
"name": "chocolate-chip",
|
||||||
|
"ttl": "0s"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"header": {
|
"header": {
|
||||||
"headerName": "x-user-id"
|
"headerName": "x-user-id"
|
||||||
|
|
|
@ -37,6 +37,12 @@
|
||||||
},
|
},
|
||||||
"terminal": true
|
"terminal": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cookie": {
|
||||||
|
"name": "chocolate-chip",
|
||||||
|
"ttl": "0s"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"header": {
|
"header": {
|
||||||
"headerName": "x-user-id"
|
"headerName": "x-user-id"
|
||||||
|
|
|
@ -37,6 +37,12 @@
|
||||||
},
|
},
|
||||||
"terminal": true
|
"terminal": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cookie": {
|
||||||
|
"name": "chocolate-chip",
|
||||||
|
"ttl": "0s"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"header": {
|
"header": {
|
||||||
"headerName": "x-user-id"
|
"headerName": "x-user-id"
|
||||||
|
|
|
@ -37,6 +37,12 @@
|
||||||
},
|
},
|
||||||
"terminal": true
|
"terminal": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cookie": {
|
||||||
|
"name": "chocolate-chip",
|
||||||
|
"ttl": "0s"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"header": {
|
"header": {
|
||||||
"headerName": "x-user-id"
|
"headerName": "x-user-id"
|
||||||
|
|
|
@ -269,7 +269,10 @@ type HashPolicy struct {
|
||||||
// CookieConfig contains configuration for the "cookie" hash policy type.
|
// CookieConfig contains configuration for the "cookie" hash policy type.
|
||||||
// This is specified to have Envoy generate a cookie for a client on its first request.
|
// This is specified to have Envoy generate a cookie for a client on its first request.
|
||||||
type CookieConfig struct {
|
type CookieConfig struct {
|
||||||
// TTL for generated cookies
|
// Generates a session cookie with no expiration.
|
||||||
|
Session bool `json:",omitempty"`
|
||||||
|
|
||||||
|
// TTL for generated cookies. Cannot be specified for session cookies.
|
||||||
TTL time.Duration `json:",omitempty"`
|
TTL time.Duration `json:",omitempty"`
|
||||||
|
|
||||||
// The path to set for the cookie
|
// The path to set for the cookie
|
||||||
|
|
|
@ -326,6 +326,14 @@ func TestAPI_ConfigEntry_ServiceResolver_LoadBalancer(t *testing.T) {
|
||||||
TTL: 20 * time.Millisecond,
|
TTL: 20 * time.Millisecond,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Field: "cookie",
|
||||||
|
FieldValue: "sugar",
|
||||||
|
CookieConfig: &CookieConfig{
|
||||||
|
Session: true,
|
||||||
|
Path: "/tin",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
SourceIP: true,
|
SourceIP: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -613,6 +613,112 @@ func TestDecodeConfigEntry(t *testing.T) {
|
||||||
Name: "main",
|
Name: "main",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "service-resolver: envoy hash lb kitchen sink",
|
||||||
|
body: `
|
||||||
|
{
|
||||||
|
"Kind": "service-resolver",
|
||||||
|
"Name": "main",
|
||||||
|
"LoadBalancer": {
|
||||||
|
"Policy": "ring_hash",
|
||||||
|
"RingHashConfig": {
|
||||||
|
"MinimumRingSize": 1,
|
||||||
|
"MaximumRingSize": 2
|
||||||
|
},
|
||||||
|
"HashPolicies": [
|
||||||
|
{
|
||||||
|
"Field": "cookie",
|
||||||
|
"FieldValue": "good-cookie",
|
||||||
|
"CookieConfig": {
|
||||||
|
"TTL": "1s",
|
||||||
|
"Path": "/oven"
|
||||||
|
},
|
||||||
|
"Terminal": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "cookie",
|
||||||
|
"FieldValue": "less-good-cookie",
|
||||||
|
"CookieConfig": {
|
||||||
|
"Session": true,
|
||||||
|
"Path": "/toaster"
|
||||||
|
},
|
||||||
|
"Terminal": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "header",
|
||||||
|
"FieldValue": "x-user-id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"SourceIP": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
expect: &ServiceResolverConfigEntry{
|
||||||
|
Kind: "service-resolver",
|
||||||
|
Name: "main",
|
||||||
|
LoadBalancer: &LoadBalancer{
|
||||||
|
Policy: "ring_hash",
|
||||||
|
RingHashConfig: &RingHashConfig{
|
||||||
|
MinimumRingSize: 1,
|
||||||
|
MaximumRingSize: 2,
|
||||||
|
},
|
||||||
|
HashPolicies: []HashPolicy{
|
||||||
|
{
|
||||||
|
Field: "cookie",
|
||||||
|
FieldValue: "good-cookie",
|
||||||
|
CookieConfig: &CookieConfig{
|
||||||
|
TTL: 1 * time.Second,
|
||||||
|
Path: "/oven",
|
||||||
|
},
|
||||||
|
Terminal: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Field: "cookie",
|
||||||
|
FieldValue: "less-good-cookie",
|
||||||
|
CookieConfig: &CookieConfig{
|
||||||
|
Session: true,
|
||||||
|
Path: "/toaster",
|
||||||
|
},
|
||||||
|
Terminal: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Field: "header",
|
||||||
|
FieldValue: "x-user-id",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
SourceIP: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "service-resolver: envoy least request kitchen sink",
|
||||||
|
body: `
|
||||||
|
{
|
||||||
|
"Kind": "service-resolver",
|
||||||
|
"Name": "main",
|
||||||
|
"LoadBalancer": {
|
||||||
|
"Policy": "least_request",
|
||||||
|
"LeastRequestConfig": {
|
||||||
|
"ChoiceCount": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
expect: &ServiceResolverConfigEntry{
|
||||||
|
Kind: "service-resolver",
|
||||||
|
Name: "main",
|
||||||
|
LoadBalancer: &LoadBalancer{
|
||||||
|
Policy: "least_request",
|
||||||
|
LeastRequestConfig: &LeastRequestConfig{
|
||||||
|
ChoiceCount: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "ingress-gateway",
|
name: "ingress-gateway",
|
||||||
body: `
|
body: `
|
||||||
|
|
|
@ -1187,6 +1187,15 @@ func TestParseConfigEntry(t *testing.T) {
|
||||||
}
|
}
|
||||||
terminal = true
|
terminal = true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field = "cookie"
|
||||||
|
field_value = "less-good-cookie"
|
||||||
|
cookie_config = {
|
||||||
|
session = true
|
||||||
|
path = "/toaster"
|
||||||
|
}
|
||||||
|
terminal = true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field = "header"
|
field = "header"
|
||||||
field_value = "x-user-id"
|
field_value = "x-user-id"
|
||||||
|
@ -1216,6 +1225,15 @@ func TestParseConfigEntry(t *testing.T) {
|
||||||
}
|
}
|
||||||
Terminal = true
|
Terminal = true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Field = "cookie"
|
||||||
|
FieldValue = "less-good-cookie"
|
||||||
|
CookieConfig = {
|
||||||
|
Session = true
|
||||||
|
Path = "/toaster"
|
||||||
|
}
|
||||||
|
Terminal = true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Field = "header"
|
Field = "header"
|
||||||
FieldValue = "x-user-id"
|
FieldValue = "x-user-id"
|
||||||
|
@ -1246,6 +1264,15 @@ func TestParseConfigEntry(t *testing.T) {
|
||||||
},
|
},
|
||||||
"terminal": true
|
"terminal": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"field": "cookie",
|
||||||
|
"field_value": "less-good-cookie",
|
||||||
|
"cookie_config": {
|
||||||
|
"session": true,
|
||||||
|
"path": "/toaster"
|
||||||
|
},
|
||||||
|
"terminal": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"field": "header",
|
"field": "header",
|
||||||
"field_value": "x-user-id"
|
"field_value": "x-user-id"
|
||||||
|
@ -1277,6 +1304,15 @@ func TestParseConfigEntry(t *testing.T) {
|
||||||
},
|
},
|
||||||
"Terminal": true
|
"Terminal": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"Field": "cookie",
|
||||||
|
"FieldValue": "less-good-cookie",
|
||||||
|
"CookieConfig": {
|
||||||
|
"Session": true,
|
||||||
|
"Path": "/toaster"
|
||||||
|
},
|
||||||
|
"Terminal": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"Field": "header",
|
"Field": "header",
|
||||||
"FieldValue": "x-user-id"
|
"FieldValue": "x-user-id"
|
||||||
|
@ -1307,6 +1343,15 @@ func TestParseConfigEntry(t *testing.T) {
|
||||||
},
|
},
|
||||||
Terminal: true,
|
Terminal: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Field: structs.HashPolicyCookie,
|
||||||
|
FieldValue: "less-good-cookie",
|
||||||
|
CookieConfig: &api.CookieConfig{
|
||||||
|
Session: true,
|
||||||
|
Path: "/toaster",
|
||||||
|
},
|
||||||
|
Terminal: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Field: structs.HashPolicyHeader,
|
Field: structs.HashPolicyHeader,
|
||||||
FieldValue: "x-user-id",
|
FieldValue: "x-user-id",
|
||||||
|
|
|
@ -206,7 +206,9 @@ LoadBalancer = {
|
||||||
- `CookieConfig` `(CookieConfig)` - Additional configuration for the "cookie" hash policy type.
|
- `CookieConfig` `(CookieConfig)` - Additional configuration for the "cookie" hash policy type.
|
||||||
This is specified to have Envoy generate a cookie for a client on its first request.
|
This is specified to have Envoy generate a cookie for a client on its first request.
|
||||||
|
|
||||||
- `TTL` `(duration: 0s)` - TTL for generated cookies.
|
- `Session` `(bool: false)` - Generates a session cookie with no expiration.
|
||||||
|
|
||||||
|
- `TTL` `(duration: 0s)` - TTL for generated cookies. Cannot be specified for session cookies.
|
||||||
|
|
||||||
- `Path` `(string: "")` - The path to set for the cookie.
|
- `Path` `(string: "")` - The path to set for the cookie.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue